mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-14 02:31:34 -06:00
feat: rate limit per user per env sync user identification endpoint (#2090)
Co-authored-by: review-agent-prime[bot] <147289438+review-agent-prime[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6ae782b984
commit
2425dc5459
@@ -5,6 +5,7 @@ import {
|
||||
LOGIN_RATE_LIMIT,
|
||||
SHARE_RATE_LIMIT,
|
||||
SIGNUP_RATE_LIMIT,
|
||||
SYNC_USER_IDENTIFICATION_RATE_LIMIT,
|
||||
} from "@formbricks/lib/constants";
|
||||
|
||||
export const signUpLimiter = rateLimit({
|
||||
@@ -24,3 +25,8 @@ export const shareUrlLimiter = rateLimit({
|
||||
interval: SHARE_RATE_LIMIT.interval,
|
||||
allowedPerInterval: SHARE_RATE_LIMIT.allowedPerInterval,
|
||||
});
|
||||
|
||||
export const syncUserIdentificationLimiter = rateLimit({
|
||||
interval: SYNC_USER_IDENTIFICATION_RATE_LIMIT.interval,
|
||||
allowedPerInterval: SYNC_USER_IDENTIFICATION_RATE_LIMIT.allowedPerInterval,
|
||||
});
|
||||
|
||||
@@ -16,3 +16,11 @@ export const shareUrlRoute = (url: string): boolean => {
|
||||
|
||||
export const isWebAppRoute = (url: string): boolean =>
|
||||
url.startsWith("/environments") && url !== "/api/auth/signout";
|
||||
|
||||
export const isSyncWithUserIdentificationEndpoint = (
|
||||
url: string
|
||||
): { environmentId: string; userId: string } | false => {
|
||||
const regex = /\/api\/v1\/client\/([^/]+)\/in-app\/sync\/([^/]+)/;
|
||||
const match = url.match(regex);
|
||||
return match ? { environmentId: match[1], userId: match[2] } : false;
|
||||
};
|
||||
|
||||
@@ -3,9 +3,11 @@ import {
|
||||
loginLimiter,
|
||||
shareUrlLimiter,
|
||||
signUpLimiter,
|
||||
syncUserIdentificationLimiter,
|
||||
} from "@/app/middleware/bucket";
|
||||
import {
|
||||
clientSideApiRoute,
|
||||
isSyncWithUserIdentificationEndpoint,
|
||||
isWebAppRoute,
|
||||
loginRoute,
|
||||
shareUrlRoute,
|
||||
@@ -52,6 +54,12 @@ export async function middleware(request: NextRequest) {
|
||||
await signUpLimiter.check(ip);
|
||||
} else if (clientSideApiRoute(request.nextUrl.pathname)) {
|
||||
await clientSideApiEndpointsLimiter.check(ip);
|
||||
|
||||
const envIdAndUserId = isSyncWithUserIdentificationEndpoint(request.nextUrl.pathname);
|
||||
if (envIdAndUserId) {
|
||||
const { environmentId, userId } = envIdAndUserId;
|
||||
await syncUserIdentificationLimiter.check(`${environmentId}-${userId}`);
|
||||
}
|
||||
} else if (shareUrlRoute(request.nextUrl.pathname)) {
|
||||
await shareUrlLimiter.check(ip);
|
||||
}
|
||||
|
||||
@@ -135,6 +135,11 @@ export const SHARE_RATE_LIMIT = {
|
||||
allowedPerInterval: 30,
|
||||
};
|
||||
|
||||
export const SYNC_USER_IDENTIFICATION_RATE_LIMIT = {
|
||||
interval: 60 * 1000, // 1 minute
|
||||
allowedPerInterval: 5,
|
||||
};
|
||||
|
||||
export const DEBUG = process.env.DEBUG === "1";
|
||||
|
||||
// Enterprise License constant
|
||||
|
||||
Reference in New Issue
Block a user