import { handlers } from '@/lib/auth' import { checkRateLimit } from '@/lib/rate-limit' const AUTH_RATE_LIMIT = 10 // requests per window const AUTH_RATE_WINDOW_MS = 60 * 1000 // 1 minute const CSRF_RATE_LIMIT = 20 // requests per window const CSRF_RATE_WINDOW_MS = 15 * 60 * 1000 // 15 minutes function getClientIp(req: Request): string { return ( req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || req.headers.get('x-real-ip') || 'unknown' ) } function withPostRateLimit(handler: (req: Request) => Promise) { return async (req: Request) => { const ip = getClientIp(req) const { success, resetAt } = checkRateLimit(`auth:${ip}`, AUTH_RATE_LIMIT, AUTH_RATE_WINDOW_MS) if (!success) { return new Response(JSON.stringify({ error: 'Too many authentication attempts' }), { status: 429, headers: { 'Content-Type': 'application/json', 'Retry-After': String(Math.ceil((resetAt - Date.now()) / 1000)), }, }) } return handler(req) } } function withGetRateLimit(handler: (req: Request) => Promise) { return async (req: Request) => { // Rate-limit the CSRF token endpoint to prevent token farming const url = new URL(req.url) if (url.pathname.endsWith('/csrf')) { const ip = getClientIp(req) const { success, resetAt } = checkRateLimit(`csrf:${ip}`, CSRF_RATE_LIMIT, CSRF_RATE_WINDOW_MS) if (!success) { return new Response(JSON.stringify({ error: 'Too many requests' }), { status: 429, headers: { 'Content-Type': 'application/json', 'Retry-After': String(Math.ceil((resetAt - Date.now()) / 1000)), }, }) } } return handler(req) } } export const GET = withGetRateLimit(handlers.GET as (req: Request) => Promise) export const POST = withPostRateLimit(handlers.POST as (req: Request) => Promise)