-
Notifications
You must be signed in to change notification settings - Fork 35
Feature: Implement Sign-Up Rate Limiting #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
e788636
97d71d1
2aeb968
a6f4fa9
1c8e1ed
89caac5
424358e
228ae45
87fc2c3
2a92b5a
b17f560
ada193f
a950aa5
b9adb0f
3f7d1d4
9fbb68b
2ac2a5c
2010cc0
b837c7c
5b7ad4b
0f99957
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,7 @@ | ||
| export const ALLOW_SEO_INDEXING = process.env.ALLOW_SEO_INDEXING === '1' | ||
| export const VERBOSE = process.env.NEXT_PUBLIC_VERBOSE === '1' | ||
| export const INCLUDE_BILLING = process.env.NEXT_PUBLIC_INCLUDE_BILLING === '1' | ||
| export const ENABLE_SIGN_UP_RATE_LIMITING = | ||
| process.env.ENABLE_SIGN_UP_RATE_LIMITING === '1' && | ||
| process.env.KV_REST_API_URL && | ||
| process.env.KV_REST_API_TOKEN | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Rate Limiting Flag Evaluates IncorrectlyThe |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| import { KV_KEYS } from '@/configs/keys' | ||
| import { kv } from '@/lib/clients/kv' | ||
| import { l } from '@/lib/clients/logger/logger' | ||
| import { serializeError } from 'serialize-error' | ||
|
|
||
| const SIGN_UP_LIMIT_PER_WINDOW = | ||
| Number(process.env.SIGN_UP_LIMIT_PER_WINDOW) || 1 | ||
| const SIGN_UP_WINDOW_HOURS = Number(process.env.SIGN_UP_WINDOW_HOURS) || 24 | ||
|
|
||
| /** | ||
| * Check if an identifier (IP address) has exceeded the successful sign-up limit | ||
| * @param identifier - IP address to check rate limiting for | ||
| * @returns Promise<boolean> - true if rate limited, false if allowed | ||
| */ | ||
| export async function isSignUpRateLimited( | ||
| identifier: string | ||
| ): Promise<boolean> { | ||
| try { | ||
| const key = KV_KEYS.SIGN_UP_RATE_LIMIT(identifier) | ||
| const attempts = await kv.get(key) | ||
|
|
||
| if (!attempts) { | ||
| return false | ||
| } | ||
|
|
||
| const attemptCount = parseInt(attempts as string, 10) | ||
| return attemptCount >= SIGN_UP_LIMIT_PER_WINDOW | ||
| } catch (error) { | ||
| l.error({ | ||
| key: 'sign_up_rate_limit:check_error', | ||
| error: serializeError(error), | ||
| context: { | ||
| identifier, | ||
| }, | ||
| }) | ||
| // on error, allow the request to proceed | ||
| return false | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Increment the successful sign-up counter for an identifier (IP) | ||
| * @param identifier - IP address to increment counter for | ||
| */ | ||
| export async function incrementSignUpAttempts( | ||
| identifier: string | ||
| ): Promise<void> { | ||
| try { | ||
| const key = KV_KEYS.SIGN_UP_RATE_LIMIT(identifier) | ||
| const current = await kv.get(key) | ||
| const currentCount = current ? parseInt(current as string, 10) : 0 | ||
| const newCount = currentCount + 1 | ||
ben-fornefeld marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| await kv.set(key, newCount.toString(), { | ||
| ex: SIGN_UP_WINDOW_HOURS * 3600, | ||
| }) | ||
|
|
||
| l.debug({ | ||
| key: 'sign_up_rate_limit:increment', | ||
| context: { | ||
| identifier, | ||
| attempts: newCount, | ||
| }, | ||
| }) | ||
| } catch (error) { | ||
| l.error({ | ||
| key: 'sign_up_rate_limit:increment_error', | ||
| error: serializeError(error), | ||
| context: { | ||
| identifier, | ||
| }, | ||
| }) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.