mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 03:15:06 +03:00
feat(www): rate limit cio subscribe form routes
This commit is contained in:
1 parent
a9a2832237
commit
513d9ea459
3 files changed
+49
-2
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
import { CustomerioTrackClient } from '~/lib/customerio'
|
||||
import { createRateLimiter } from '~/lib/rate-limit'
|
||||
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
@@ -12,7 +12,16 @@ const isValidEmail = (email: string): boolean => {
|
||||
return emailPattern.test(email)
|
||||
}
|
||||
|
||||
const isRateLimited = createRateLimiter({ max: 5, windowMs: 60 * 1000 })
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (isRateLimited(req)) {
|
||||
return new Response(JSON.stringify({ message: 'Too many requests. Try again later.' }), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 429,
|
||||
})
|
||||
}
|
||||
|
||||
const body = await req.json()
|
||||
const { firstName, lastName, email } = body
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { POST } from './route'
|
||||
|
||||
vi.mock('server-only', () => ({}))
|
||||
vi.mock('@sentry/nextjs', () => ({ captureException: vi.fn() }))
|
||||
|
||||
const makeRequest = (ip: string) =>
|
||||
new Request('http://localhost/api-v2/submit-form-subprocessor-updates', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'x-forwarded-for': ip },
|
||||
body: JSON.stringify({}),
|
||||
})
|
||||
|
||||
describe('submit-form-subprocessor-updates rate limiting', () => {
|
||||
it('returns 429 on the sixth request in a window from one ip', async () => {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const res = await POST(makeRequest('203.0.113.7'))
|
||||
expect(res.status).toBe(422)
|
||||
}
|
||||
const res = await POST(makeRequest('203.0.113.7'))
|
||||
expect(res.status).toBe(429)
|
||||
})
|
||||
|
||||
it('does not rate limit a different ip', async () => {
|
||||
const res = await POST(makeRequest('203.0.113.8'))
|
||||
expect(res.status).toBe(422)
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Sentry from '@sentry/nextjs'
|
||||
|
||||
import { CustomerioTrackClient } from '~/lib/customerio'
|
||||
import { createRateLimiter } from '~/lib/rate-limit'
|
||||
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
@@ -12,7 +12,16 @@ const isValidEmail = (email: string): boolean => {
|
||||
return emailPattern.test(email)
|
||||
}
|
||||
|
||||
const isRateLimited = createRateLimiter({ max: 5, windowMs: 60 * 1000 })
|
||||
|
||||
export async function POST(req: Request) {
|
||||
if (isRateLimited(req)) {
|
||||
return new Response(JSON.stringify({ message: 'Too many requests. Try again later.' }), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 429,
|
||||
})
|
||||
}
|
||||
|
||||
const body = await req.json()
|
||||
const { firstName, lastName, email } = body
|
||||
|
||||
|
||||
Reference in new issue
Block a user