// In-memory rate limiter keyed by IP const loginAttempts = new Map< string, { count: number; resetAt: number } >(); const WINDOW_MS = 60_000; // 1 minute window const MAX_ATTEMPTS = 5; // max 5 attempts per window const LOCKOUT_MS = 15 * 60_000; // 15 minute lockout export function checkRateLimit(ip: string): { allowed: boolean; retryAfterMs: number; } { const now = Date.now(); const entry = loginAttempts.get(ip); if (!entry || now > entry.resetAt) { loginAttempts.set(ip, { count: 1, resetAt: now + WINDOW_MS }); return { allowed: true, retryAfterMs: 0 }; } if (entry.count >= MAX_ATTEMPTS) { return { allowed: false, retryAfterMs: entry.resetAt - now, }; } entry.count++; return { allowed: true, retryAfterMs: 0 }; } export function clearRateLimit(ip: string): void { loginAttempts.delete(ip); }