feat(auth): add login_attempts schema, lockout config, dummy-hash helper
All checks were successful
Deploy to Homelab / deploy (push) Successful in 29s
All checks were successful
Deploy to Homelab / deploy (push) Successful in 29s
Lays the foundation for brute-force defense: per-username attempt tracking table, configurable lockout/rate-limit thresholds, and a memoized dummy bcrypt hash so unknown-user paths can be timed identically to wrong-password paths in a later step. Adds @fastify/rate-limit dependency for upcoming per-IP rate-limit on login routes.
This commit is contained in:
@@ -10,6 +10,12 @@ export interface Config {
|
||||
baseUrl: string;
|
||||
cookieSecure: boolean;
|
||||
trustProxy: boolean;
|
||||
lockoutThreshold: number;
|
||||
lockoutBaseSeconds: number;
|
||||
lockoutMaxSeconds: number;
|
||||
loginMinResponseMs: number;
|
||||
loginRateLimitMax: number;
|
||||
loginRateLimitWindowSeconds: number;
|
||||
}
|
||||
|
||||
export function loadConfig(): Config {
|
||||
@@ -30,5 +36,11 @@ export function loadConfig(): Config {
|
||||
baseUrl: process.env.BASE_URL ?? 'http://localhost:3000',
|
||||
cookieSecure: process.env.COOKIE_SECURE === 'true',
|
||||
trustProxy: process.env.TRUST_PROXY === 'true',
|
||||
lockoutThreshold: parseInt(process.env.LOCKOUT_THRESHOLD ?? '5', 10),
|
||||
lockoutBaseSeconds: parseInt(process.env.LOCKOUT_BASE_SECONDS ?? '30', 10),
|
||||
lockoutMaxSeconds: parseInt(process.env.LOCKOUT_MAX_SECONDS ?? '3600', 10),
|
||||
loginMinResponseMs: parseInt(process.env.LOGIN_MIN_RESPONSE_MS ?? '350', 10),
|
||||
loginRateLimitMax: parseInt(process.env.LOGIN_RATE_LIMIT_MAX ?? '10', 10),
|
||||
loginRateLimitWindowSeconds: parseInt(process.env.LOGIN_RATE_LIMIT_WINDOW_SECONDS ?? '60', 10),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user