diff --git a/src/lib/auth/index.ts b/src/lib/auth/index.ts index fb30c773..9fd77827 100644 --- a/src/lib/auth/index.ts +++ b/src/lib/auth/index.ts @@ -109,6 +109,31 @@ function buildAuth() { secure: process.env.NODE_ENV === 'production', sameSite: 'strict' as const, }, + // Trust the X-Forwarded-For chain when running behind Caddy/Nginx in + // production so the IP that rate-limit + audit logging see is the + // real client, not the proxy. Skipped in dev (no proxy in front). + ipAddress: { + ipAddressHeaders: isProd ? ['x-forwarded-for', 'x-real-ip'] : [], + }, + }, + + // Rate limiting (post-audit F7) — without this, brute-force is wide + // open. Tight caps on the credential-eating endpoints; loose default + // for everything else so legitimate fan-out (multi-widget dashboards + // that hit /get-session repeatedly) isn't hampered. + rateLimit: { + enabled: true, + window: 60, + max: 120, + // Memory storage resets on restart. For multi-replica prod, swap + // to `storage: 'database'` once the rateLimit migration is run. + storage: 'memory', + customRules: { + '/sign-in/email': { window: 60, max: 5 }, + '/sign-up/email': { window: 60, max: 3 }, + '/forget-password': { window: 60, max: 3 }, + '/reset-password': { window: 60, max: 5 }, + }, }, logger: {