feat(identity): F-005 register/login/logout with argon2 sessions and rate limiting
- Hexagonal identity module: domain ports, use cases, argon2id hasher, pg repos - Migration 002_identity: identity_users + identity_sessions (token hash only) - Opaque 512-bit session tokens; DB stores SHA-256 hash; 7-day TTL in SQL - Cookie HttpOnly + Secure (COOKIE_SECURE, default true) + SameSite=Lax - LoginRateLimiter: 10 failures -> 429 + Retry-After, 15-min cooldown - Anti-enumeration: identical generic 401 + dummy-hash timing equalization - buildApp gains optional pool/cookieSecure; foundation-only app preserved - 47 unit + 14 integration tests; live smoke covers all acceptance criteria
This commit is contained in:
@@ -16,6 +16,8 @@ export interface AppConfig {
|
||||
logLevel: string;
|
||||
databaseUrl: string;
|
||||
redisUrl?: string;
|
||||
/** Session cookie Secure flag. Default true; set COOKIE_SECURE=false for local http dev. */
|
||||
cookieSecure: boolean;
|
||||
/** Initial flag state parsed from FLAG_* vars. */
|
||||
flags: Readonly<Record<string, boolean>>;
|
||||
}
|
||||
@@ -71,6 +73,15 @@ export function loadConfig(env: StringRecord): AppConfig {
|
||||
|
||||
const redisUrl = env.REDIS_URL && env.REDIS_URL !== '' ? env.REDIS_URL : undefined;
|
||||
|
||||
let cookieSecure = true;
|
||||
const rawCookieSecure = env.COOKIE_SECURE;
|
||||
if (rawCookieSecure !== undefined && rawCookieSecure !== '') {
|
||||
const normalized = rawCookieSecure.trim().toLowerCase();
|
||||
if (normalized === 'true') cookieSecure = true;
|
||||
else if (normalized === 'false') cookieSecure = false;
|
||||
else problems.push('COOKIE_SECURE must be "true" or "false"');
|
||||
}
|
||||
|
||||
const flags: Record<string, boolean> = {};
|
||||
for (const [key, raw] of Object.entries(env)) {
|
||||
if (!key.startsWith('FLAG_') || raw === undefined) continue;
|
||||
@@ -92,6 +103,7 @@ export function loadConfig(env: StringRecord): AppConfig {
|
||||
logLevel,
|
||||
databaseUrl: databaseUrl as string,
|
||||
redisUrl,
|
||||
cookieSecure,
|
||||
flags,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user