@focura/auth-core 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -25
- package/dist/index.d.ts +182 -93
- package/dist/index.js +410 -131
- package/dist/index.js.map +1 -1
- package/package.json +23 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/middleware/sessionTimeout.ts","../src/tokens/backendToken.ts","../src/revocation/tokenRevocation.ts","../src/refresh/refreshLock.ts","../src/session/sessionManager.ts","../src/session/sessionBinding.ts","../src/lockout/accountLockout.ts","../src/audit/auditLog.ts","../src/totp/totp.ts","../src/index.ts","../src/middleware/middlewareFactory.ts","../src/errors/index.ts","../src/validation/auth.validation.ts"],"names":["crypto","bindingError","user","SessionTimeoutManager"],"mappings":"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","file":"index.js","sourcesContent":["// @focura/auth-core — Default configuration and config merge utility\n\nimport type { AuthCoreConfig, AuditSeverity, AuditEventType } from \"./types.js\";\n\nexport const DEFAULTS = {\n keyPrefix: \"focura:\",\n issuer: \"focura-app\",\n audience: \"focura-backend\",\n accessTokenExpiry: \"15m\",\n refreshTokenExpiry: \"7d\",\n sseTokenExpiry: \"30s\",\n currentVersion: 1,\n maxConcurrentSessions: 5,\n sessionMetadataTtl: 7 * 24 * 60 * 60,\n lockoutMaxFailures: 10,\n lockoutSeconds: 15 * 60,\n lockoutWindowSeconds: 60 * 60,\n refreshLockTtlSeconds: 45,\n refreshDedupeTtlSeconds: 30,\n revokedSessionTtl: 7 * 24 * 60 * 60,\n inactivityTimeout: 7 * 24 * 60 * 60,\n absoluteTimeout: 7 * 24 * 60 * 60,\n} as const;\n\nexport function resolveConfig(raw: AuthCoreConfig) {\n return {\n ...raw,\n keyPrefix: raw.keyPrefix ?? DEFAULTS.keyPrefix,\n issuer: raw.jwt.issuer ?? DEFAULTS.issuer,\n audience: raw.jwt.audience ?? DEFAULTS.audience,\n accessTokenExpiry: raw.jwt.accessTokenExpiry ?? DEFAULTS.accessTokenExpiry,\n refreshTokenExpiry: raw.jwt.refreshTokenExpiry ?? DEFAULTS.refreshTokenExpiry,\n sseTokenExpiry: raw.jwt.sseTokenExpiry ?? DEFAULTS.sseTokenExpiry,\n currentVersion: raw.jwt.currentVersion ?? DEFAULTS.currentVersion,\n maxConcurrentSessions: raw.session?.maxConcurrent ?? DEFAULTS.maxConcurrentSessions,\n sessionMetadataTtl: raw.session?.metadataTtl ?? DEFAULTS.sessionMetadataTtl,\n lockoutMaxFailures: raw.lockout?.maxFailures ?? DEFAULTS.lockoutMaxFailures,\n lockoutSeconds: raw.lockout?.lockoutSeconds ?? DEFAULTS.lockoutSeconds,\n lockoutWindowSeconds: raw.lockout?.windowSeconds ?? DEFAULTS.lockoutWindowSeconds,\n inactivityTimeout: raw.session?.inactivityTimeout ?? 7 * 24 * 60 * 60,\n absoluteTimeout: raw.session?.absoluteTimeout ?? 7 * 24 * 60 * 60,\n };\n}\n\nexport type ResolvedConfig = ReturnType<typeof resolveConfig>;\n\nexport const AUDIT_SEVERITY: Record<AuditEventType, AuditSeverity> = {\n LOGIN_SUCCESS: \"info\",\n LOGIN_FAILED: \"warn\",\n LOGIN_BLOCKED: \"warn\",\n LOGOUT: \"info\",\n LOGOUT_ALL_DEVICES: \"info\",\n TOKEN_REFRESHED: \"info\",\n TOKEN_REVOKED: \"info\",\n TOKEN_EXPIRED: \"info\",\n TOKEN_VERSION_MISMATCH: \"warn\",\n TOKEN_REPLAY_DETECTED: \"critical\",\n EXCHANGE_SUCCESS: \"info\",\n EXCHANGE_FAILED: \"warn\",\n SSE_CONNECTED: \"info\",\n SSE_DISCONNECTED: \"info\",\n ACCOUNT_LOCKED: \"critical\",\n TOTP_VERIFIED: \"info\",\n TOTP_FAILED: \"warn\",\n PERMISSION_DENIED: \"warn\",\n EMAIL_NOT_VERIFIED: \"warn\",\n SESSION_HIJACK_DETECTED: \"critical\",\n SESSION_BOUND: \"info\",\n SESSION_REBOUND: \"info\",\n SESSION_TIMEOUT: \"info\",\n MAX_SESSIONS_REACHED: \"warn\",\n SESSION_REVOKED: \"info\",\n SESSIONS_REVOKED: \"info\",\n DEVICE_MISMATCH: \"warn\",\n SUSPICIOUS_IP_CHANGE: \"warn\",\n CSRF_VALIDATION_FAILED: \"warn\",\n UNAUTHORIZED_ACCESS: \"warn\",\n RATE_LIMIT_EXCEEDED: \"warn\",\n MALWARE_DETECTED: \"critical\",\n SUSPICIOUS_ACTIVITY: \"warn\",\n DATA_EXPORT: \"info\",\n DATA_DELETION: \"critical\",\n SENSITIVE_DATA_ACCESS: \"warn\",\n WORKSPACE_CREATED: \"info\",\n WORKSPACE_DELETED: \"critical\",\n MEMBER_ADDED: \"info\",\n MEMBER_REMOVED: \"info\",\n ROLE_CHANGED: \"info\",\n SUBSCRIPTION_CREATED: \"info\",\n SUBSCRIPTION_CANCELLED: \"info\",\n PAYMENT_FAILED: \"warn\",\n};\n","import type { RedisAdapter, SessionLifecycle } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class SessionTimeoutManager implements SessionLifecycle {\n private readonly inactivityTimeout: number;\n private readonly absoluteTimeout: number;\n private readonly prefix: string;\n\n constructor(\n private readonly redis: RedisAdapter,\n config?: { inactivityTimeout?: number; absoluteTimeout?: number; prefix?: string },\n ) {\n this.inactivityTimeout = config?.inactivityTimeout ?? DEFAULTS.inactivityTimeout;\n this.absoluteTimeout = config?.absoluteTimeout ?? DEFAULTS.absoluteTimeout;\n this.prefix = config?.prefix ?? DEFAULTS.keyPrefix;\n }\n\n private createdKey(sessionId: string): string {\n return `${this.prefix}session:created:${sessionId}`;\n }\n\n private activityKey(sessionId: string): string {\n return `${this.prefix}session:activity:${sessionId}`;\n }\n\n async recordCreation(sessionId: string): Promise<void> {\n const now = Date.now();\n await this.redis.setex(this.createdKey(sessionId), this.absoluteTimeout, now.toString());\n await this.redis.setex(this.activityKey(sessionId), this.inactivityTimeout, now.toString());\n }\n\n async invalidate(sessionId: string): Promise<void> {\n await this.redis.del(this.createdKey(sessionId), this.activityKey(sessionId));\n }\n\n async isTracked(sessionId: string): Promise<boolean> {\n return (await this.redis.exists(this.createdKey(sessionId))) === 1;\n }\n\n async isInactive(sessionId: string): Promise<boolean> {\n const exists = await this.redis.exists(this.activityKey(sessionId));\n return exists !== 1;\n }\n\n async updateActivity(sessionId: string): Promise<boolean> {\n try {\n const result = await this.redis.setex(this.activityKey(sessionId), this.inactivityTimeout, Date.now().toString());\n return result === \"OK\";\n } catch {\n return false;\n }\n }\n}\n","import jwt from \"jsonwebtoken\";\nimport crypto from \"crypto\";\nimport type { TokenPair, TokenPayload, TokenConfig } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class TokenManager {\n private readonly privateKey: string;\n private readonly publicKey: string;\n private readonly issuer: string;\n private readonly audience: string;\n private readonly accessTokenExpiry: string;\n private readonly refreshTokenExpiry: string;\n private readonly sseTokenExpiry: string;\n private readonly currentVersion: number;\n\n constructor(config: TokenConfig) {\n this.privateKey = config.privateKey;\n this.publicKey = config.publicKey;\n this.issuer = config.issuer ?? DEFAULTS.issuer;\n this.audience = config.audience ?? DEFAULTS.audience;\n this.accessTokenExpiry = config.accessTokenExpiry ?? DEFAULTS.accessTokenExpiry;\n this.refreshTokenExpiry = config.refreshTokenExpiry ?? DEFAULTS.refreshTokenExpiry;\n this.sseTokenExpiry = config.sseTokenExpiry ?? DEFAULTS.sseTokenExpiry;\n this.currentVersion = config.currentVersion ?? DEFAULTS.currentVersion;\n }\n\n createAccessToken(p: { id: string; email: string; role: string; sessionId: string }): string {\n return jwt.sign(\n {\n sub: p.id,\n email: p.email,\n role: p.role,\n type: \"access\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n sessionId: p.sessionId,\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.accessTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n createRefreshToken(p: { id: string; email: string; role: string; sessionId: string }): string {\n return jwt.sign(\n {\n sub: p.id,\n email: p.email,\n role: p.role,\n type: \"refresh\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n sessionId: p.sessionId,\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.refreshTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n createTokenPair(p: { id: string; email: string; role: string; sessionId?: string }): TokenPair {\n const sessionId = p.sessionId || crypto.randomUUID();\n const payload = { ...p, sessionId };\n return {\n accessToken: this.createAccessToken(payload),\n refreshToken: this.createRefreshToken(payload),\n accessTokenExpiry: Date.now() + TokenManager.parseExpiry(this.accessTokenExpiry),\n refreshTokenExpiry: Date.now() + TokenManager.parseExpiry(this.refreshTokenExpiry),\n };\n }\n\n createSseToken(userId: string): string {\n return jwt.sign(\n {\n sub: userId,\n type: \"sse\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.sseTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n verifyToken(token: string, expectedType?: TokenPayload[\"type\"]): TokenPayload {\n const decoded = jwt.verify(token, this.publicKey, {\n algorithms: [\"RS256\"],\n issuer: this.issuer,\n audience: this.audience,\n }) as jwt.JwtPayload;\n\n if (decoded.version !== this.currentVersion) throw new Error(\"Token version mismatch\");\n if (expectedType && decoded.type !== expectedType) throw new Error(`Expected '${expectedType}', got '${decoded.type}'`);\n\n return {\n id: decoded.sub ?? \"\",\n email: decoded.email,\n role: decoded.role,\n type: decoded.type,\n version: decoded.version,\n jti: decoded.jti ?? \"\",\n sessionId: decoded.sessionId,\n };\n }\n\n getPublicKey(): string {\n return this.publicKey;\n }\n\n getAccessTokenExpiry(): string {\n return this.accessTokenExpiry;\n }\n\n getRefreshTokenExpiry(): string {\n return this.refreshTokenExpiry;\n }\n\n getSseTokenExpiry(): string {\n return this.sseTokenExpiry;\n }\n\n getCurrentVersion(): number {\n return this.currentVersion;\n }\n\n getIssuer(): string {\n return this.issuer;\n }\n\n getAudience(): string {\n return this.audience;\n }\n\n static parseExpiry(expiry: string): number {\n const match = expiry.match(/^(\\d+)([smhd])$/);\n if (!match) throw new Error(`Invalid expiry: ${expiry}`);\n const unit = match[2]!;\n const multipliers: Record<string, number> = { s: 1000, m: 60000, h: 3600000, d: 86400000 };\n return parseInt(match[1]!, 10) * multipliers[unit]!;\n }\n\n static extractJti(token: string): string {\n try {\n const payload = JSON.parse(Buffer.from(token.split(\".\")[1]!, \"base64url\").toString(\"utf-8\"));\n return payload.jti ?? \"\";\n } catch {\n return \"\";\n }\n }\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class TokenRevocation {\n constructor(\n private readonly redis: RedisAdapter,\n private readonly prefix: string = DEFAULTS.keyPrefix,\n ) {}\n\n private refreshIndexKey(userId: string): string {\n return `${this.prefix}refresh:index:${userId}`;\n }\n\n private refreshTokenKey(userId: string, jti: string): string {\n return `${this.prefix}refresh:${userId}:${jti}`;\n }\n\n private revokedAccessKey(jti: string): string {\n return `${this.prefix}revoked:access:${jti}`;\n }\n\n private sseKey(jti: string): string {\n return `${this.prefix}sse:${jti}`;\n }\n\n private sessionRevokedKey(sessionId: string): string {\n return `${this.prefix}session:revoked:${sessionId}`;\n }\n\n async revokeAccessToken(jti: string, expiresInSeconds: number): Promise<void> {\n try {\n await this.redis.setex(this.revokedAccessKey(jti), expiresInSeconds, \"1\");\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke access token:\", err);\n }\n }\n\n async isAccessTokenRevoked(jti: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.revokedAccessKey(jti));\n return val === \"1\";\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check revoked access token:\", err);\n return false;\n }\n }\n\n async storeRefreshToken(userId: string, jti: string, expiresInSeconds: number): Promise<void> {\n try {\n const tokenKey = this.refreshTokenKey(userId, jti);\n await this.redis.setex(tokenKey, expiresInSeconds, JSON.stringify({ jti, createdAt: Date.now() }));\n await this.redis.sadd(this.refreshIndexKey(userId), tokenKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to store refresh token:\", err);\n }\n }\n\n async isRefreshTokenValid(userId: string, jti: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.refreshTokenKey(userId, jti));\n return val !== null;\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check refresh token validity:\", err);\n return false;\n }\n }\n\n async revokeRefreshToken(userId: string, jti: string): Promise<void> {\n try {\n const tokenKey = this.refreshTokenKey(userId, jti);\n await this.redis.del(tokenKey);\n await this.redis.srem(this.refreshIndexKey(userId), tokenKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke refresh token:\", err);\n }\n }\n\n async revokeAllRefreshTokens(userId: string): Promise<void> {\n try {\n const idxKey = this.refreshIndexKey(userId);\n let keys = await this.redis.smembers(idxKey);\n\n if (keys.length === 0) {\n let cursor = \"0\";\n const pattern = `${this.prefix}refresh:${userId}:*`;\n do {\n const [nextCursor, found] = await this.redis.scan(cursor, \"MATCH\", pattern, \"COUNT\", \"100\");\n cursor = nextCursor;\n keys.push(...found);\n } while (cursor !== \"0\");\n }\n\n if (keys.length > 0) await this.redis.del(...keys);\n await this.redis.del(idxKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke all refresh tokens:\", err);\n }\n }\n\n async rotateRefreshToken(\n userId: string,\n oldJti: string,\n newJti: string,\n expiresInSeconds: number,\n ): Promise<boolean> {\n const oldKey = this.refreshTokenKey(userId, oldJti);\n const newKey = this.refreshTokenKey(userId, newJti);\n const indexKey = this.refreshIndexKey(userId);\n\n try {\n const result = await this.redis.eval<number>(\n `if redis.call(\"EXISTS\", KEYS[1]) == 1 then\n redis.call(\"DEL\", KEYS[1])\n redis.call(\"SETEX\", KEYS[2], ARGV[1], ARGV[2])\n redis.call(\"SREM\", KEYS[3], KEYS[1])\n redis.call(\"SADD\", KEYS[3], KEYS[2])\n return 1\n else\n return 0\n end`,\n 3,\n oldKey,\n newKey,\n indexKey,\n expiresInSeconds.toString(),\n JSON.stringify({ jti: newJti, createdAt: Date.now() }),\n );\n\n return result === 1;\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async storeSseToken(jti: string, userId: string, ttlSeconds: number): Promise<void> {\n try {\n await this.redis.setex(this.sseKey(jti), ttlSeconds, userId);\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async consumeSseToken(jti: string): Promise<string | null> {\n const key = this.sseKey(jti);\n try {\n const userId = await this.redis.eval<string | null>(\n `local v = redis.call(\"GET\", KEYS[1])\n if v then redis.call(\"DEL\", KEYS[1]) end\n return v`,\n 1,\n key,\n );\n return typeof userId === \"string\" ? userId : null;\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async markSessionRevoked(sessionId: string): Promise<void> {\n try {\n await this.redis.setex(this.sessionRevokedKey(sessionId), DEFAULTS.revokedSessionTtl, \"1\");\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to mark session revoked:\", err);\n }\n }\n\n async isSessionRevoked(sessionId: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.sessionRevokedKey(sessionId));\n return val === \"1\";\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check revoked session:\", err);\n return false;\n }\n }\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class RefreshLock {\n constructor(\n private readonly redis: RedisAdapter,\n private readonly prefix: string = DEFAULTS.keyPrefix,\n ) {}\n\n private lockKey(sessionId: string): string {\n return `${this.prefix}refresh:lock:${sessionId}`;\n }\n\n async acquire(sessionId: string): Promise<boolean> {\n try {\n const result = await this.redis.setnx(\n this.lockKey(sessionId),\n \"1\",\n );\n return result === 1;\n } catch (err) {\n console.error(\"[RefreshLock] Failed to acquire lock:\", err);\n return false;\n }\n }\n\n async release(sessionId: string): Promise<void> {\n try {\n await this.redis.del(this.lockKey(sessionId));\n } catch (err) {\n console.error(\"[RefreshLock] Failed to release lock:\", err);\n }\n }\n\n async isLocked(sessionId: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.lockKey(sessionId));\n return !!val;\n } catch (err) {\n console.error(\"[RefreshLock] Failed to check lock status:\", err);\n return false;\n }\n }\n}\n","import type { RedisAdapter, AuditLogger, SessionMetadata } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class SessionManager {\n private readonly maxConcurrent: number;\n\n constructor(\n private readonly redis: RedisAdapter,\n private readonly tokenRevocation: { markSessionRevoked(id: string): Promise<void> },\n private readonly auditLogger?: AuditLogger,\n prefix: string = DEFAULTS.keyPrefix,\n maxConcurrent?: number,\n ) {\n this.prefix = prefix;\n this.maxConcurrent = maxConcurrent ?? DEFAULTS.maxConcurrentSessions;\n }\n\n private readonly prefix: string;\n\n private sessionKey(userId: string): string {\n return `${this.prefix}user:sessions:${userId}`;\n }\n\n private metadataKey(sessionId: string): string {\n return `${this.prefix}session:metadata:${sessionId}`;\n }\n\n async trackUserSession(userId: string, sessionId: string): Promise<void> {\n try {\n const key = this.sessionKey(userId);\n const members = await this.redis.smembers(key);\n\n if (members.length >= this.maxConcurrent) {\n this.auditLogger?.log(\"MAX_SESSIONS_REACHED\", {\n userId,\n sessionCount: members.length,\n limit: this.maxConcurrent,\n });\n const evictedSession = await this.pickLeastActiveSession(members);\n await this.redis.srem(key, evictedSession);\n await this.redis.del(this.metadataKey(evictedSession));\n await this.tokenRevocation.markSessionRevoked(evictedSession);\n }\n\n await this.redis.sadd(key, sessionId);\n await this.redis.expire(key, DEFAULTS.sessionMetadataTtl);\n } catch (err) {\n console.error(`[SessionManager] Failed to track session for user ${userId}:`, err);\n }\n }\n\n private async pickLeastActiveSession(members: string[]): Promise<string> {\n let leastActive = members[0]!;\n let leastActiveAt = Infinity;\n for (const member of members) {\n let lastActivity = 0;\n try {\n const meta = await this.redis.get(this.metadataKey(member));\n if (meta) lastActivity = JSON.parse(meta).lastActivity ?? 0;\n } catch {\n lastActivity = 0;\n }\n if (lastActivity < leastActiveAt) {\n leastActiveAt = lastActivity;\n leastActive = member;\n }\n }\n return leastActive;\n }\n\n async revokeUserSession(userId: string, sessionId: string): Promise<void> {\n try {\n await this.redis.srem(this.sessionKey(userId), sessionId);\n await this.redis.del(this.metadataKey(sessionId));\n } catch (err) {\n console.error(`[SessionManager] Failed to revoke session for user ${userId}:`, err);\n }\n }\n\n async getUserActiveSessions(userId: string): Promise<\n Array<{\n sessionId: string;\n deviceInfo: string;\n ipAddress?: string;\n lastActivity: string;\n createdAt: string;\n }>\n > {\n try {\n const sessionIds = await this.redis.smembers(this.sessionKey(userId));\n const sessions = [];\n for (const sessionId of sessionIds) {\n const metadata = await this.redis.get(this.metadataKey(sessionId));\n if (metadata) {\n try {\n const parsed: SessionMetadata & { createdAt?: number } = JSON.parse(metadata);\n sessions.push({\n sessionId,\n deviceInfo: parsed.userAgent ?? \"\",\n ipAddress: parsed.ipAddress,\n lastActivity: new Date(parsed.lastActivity).toISOString(),\n createdAt: new Date(parsed.createdAt ?? parsed.lastActivity).toISOString(),\n });\n } catch {\n console.warn(`[SessionManager] Corrupted metadata for session ${sessionId}, skipping`);\n }\n }\n }\n return sessions;\n } catch (err) {\n console.error(`[SessionManager] Failed to get sessions for user ${userId}:`, err);\n return [];\n }\n }\n}\n","import crypto from \"crypto\";\nimport type { SessionMetadata } from \"../types.js\";\n\nconst SERVER_TO_SERVER_UA =\n /^(node|undici|axios|curl|go-http-client|python-requests|java\\/|okhttp|superagent)/i;\n\nexport function looksLikeServerToServerUA(userAgent: string): boolean {\n return !userAgent || SERVER_TO_SERVER_UA.test(userAgent);\n}\n\nexport function looksLikeServerToServerRequest(req: {\n headers: Record<string, string | string[] | undefined>;\n}): boolean {\n const ua = (req.headers[\"user-agent\"] as string | undefined) ?? \"\";\n if (looksLikeServerToServerUA(ua)) return true;\n return !req.headers[\"accept-language\"] && !req.headers[\"accept-encoding\"];\n}\n\nexport function normalizeUserAgent(userAgent: string): string {\n const ua = userAgent || \"\";\n const mobile = /Mobile|Android|iPhone|iPad|iPod/i.test(ua);\n const browser = /Edg\\//i.test(ua)\n ? \"Edge\"\n : /OPR\\/|Opera/i.test(ua)\n ? \"Opera\"\n : /Firefox\\/|FxiOS/i.test(ua)\n ? \"Firefox\"\n : /CriOS\\/|Chrome\\//i.test(ua)\n ? \"Chrome\"\n : /Safari\\//i.test(ua)\n ? \"Safari\"\n : \"Other\";\n const os = /Android/i.test(ua)\n ? \"Android\"\n : /iPhone|iPad|iPod/i.test(ua)\n ? \"iOS\"\n : /Windows/i.test(ua)\n ? \"Windows\"\n : /Macintosh|Mac OS X/i.test(ua)\n ? \"macOS\"\n : /Linux/i.test(ua)\n ? \"Linux\"\n : \"Other\";\n return `${browser}|${os}|${mobile ? \"mobile\" : \"desktop\"}`;\n}\n\nfunction primaryLanguage(acceptLanguage: string): string {\n const first = (acceptLanguage || \"\").split(\",\")[0]?.trim() ?? \"\";\n return first ? first.split(\"-\")[0]!.toLowerCase() : \"\";\n}\n\nexport function generateDeviceFingerprint(req: {\n headers: Record<string, string | string[] | undefined>;\n}): string {\n const components = [\n normalizeUserAgent((req.headers[\"user-agent\"] as string) || \"\"),\n primaryLanguage((req.headers[\"accept-language\"] as string) || \"\"),\n ].join(\"|\");\n\n return crypto.createHash(\"sha256\").update(components).digest(\"hex\").substring(0, 32);\n}\n\nexport function getClientIp(req: {\n ip?: string;\n headers: Record<string, string | string[] | undefined>;\n socket?: { remoteAddress?: string };\n}): string {\n if (typeof req.ip === \"string\" && req.ip.length > 0) {\n return req.ip.startsWith(\"::ffff:\") ? req.ip.slice(7) : req.ip;\n }\n const forwarded = req.headers[\"x-forwarded-for\"];\n if (typeof forwarded === \"string\") return forwarded.split(\",\")[0]!.trim();\n const ip = req.socket?.remoteAddress || \"unknown\";\n return ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n}\n\nexport function createSessionMetadata(req: {\n ip?: string;\n headers: Record<string, string | string[] | undefined>;\n socket?: { remoteAddress?: string };\n}): SessionMetadata {\n return {\n deviceId: null,\n ipAddress: getClientIp(req),\n userAgent: (req.headers[\"user-agent\"] as string) || \"unknown\",\n lastActivity: Date.now(),\n };\n}\n\nexport function isPrivateIp(ip: string): boolean {\n if (!ip || ip === \"unknown\") return true;\n const normalized = ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(normalized)) {\n const [a, b] = normalized.split(\".\").map(Number);\n return (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 172 && b! >= 16 && b! <= 31) ||\n (a === 192 && b === 168) ||\n (a === 169 && b === 254)\n );\n }\n return (\n normalized === \"::1\" ||\n /^fe80:/i.test(normalized) ||\n /^fc/i.test(normalized) ||\n /^fd/i.test(normalized)\n );\n}\n\nexport function validateSessionBinding(\n req: { headers: Record<string, string | string[] | undefined>; ip?: string; socket?: { remoteAddress?: string } },\n storedMetadata: SessionMetadata,\n): { valid: boolean; reason?: string } {\n const currentDeviceId = generateDeviceFingerprint(req);\n const currentIp = getClientIp(req);\n\n if (currentDeviceId !== storedMetadata.deviceId) {\n return { valid: false, reason: \"DEVICE_MISMATCH\" };\n }\n if (currentIp !== storedMetadata.ipAddress) {\n if (isPrivateIp(currentIp) || isPrivateIp(storedMetadata.ipAddress)) {\n return { valid: true };\n }\n const timeSinceLastActivity = Date.now() - storedMetadata.lastActivity;\n const maxIpChangeInterval = 5 * 60 * 1000;\n if (timeSinceLastActivity < maxIpChangeInterval) {\n return { valid: false, reason: \"SUSPICIOUS_IP_CHANGE\" };\n }\n }\n return { valid: true };\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class AccountLockout {\n private readonly maxFailures: number;\n private readonly lockoutSeconds: number;\n private readonly windowSeconds: number;\n private readonly prefix: string;\n\n constructor(\n private readonly redis: RedisAdapter,\n config?: { maxFailures?: number; lockoutSeconds?: number; windowSeconds?: number; prefix?: string },\n ) {\n this.maxFailures = config?.maxFailures ?? DEFAULTS.lockoutMaxFailures;\n this.lockoutSeconds = config?.lockoutSeconds ?? DEFAULTS.lockoutSeconds;\n this.windowSeconds = config?.windowSeconds ?? DEFAULTS.lockoutWindowSeconds;\n this.prefix = config?.prefix ?? `${DEFAULTS.keyPrefix}lockout`;\n }\n\n async recordFailedAttempt(\n identifier: string,\n ): Promise<{ locked: boolean; unlocksAt?: Date; attempts: number }> {\n try {\n const failKey = `${this.prefix}:failures:${identifier}`;\n const lockKey = `${this.prefix}:locked:${identifier}`;\n\n const existingLock = await this.redis.get(lockKey);\n if (existingLock) {\n return { locked: true, unlocksAt: new Date(Number(existingLock)), attempts: this.maxFailures };\n }\n\n const pipe = this.redis.pipeline();\n pipe.incr(failKey);\n pipe.expire(failKey, this.windowSeconds);\n const results = await pipe.exec();\n const attempts = (results?.[0]?.[1] as number) ?? 1;\n\n if (attempts >= this.maxFailures) {\n const unlocksAt = Date.now() + this.lockoutSeconds * 1000;\n await this.redis.setex(lockKey, this.lockoutSeconds, String(unlocksAt));\n return { locked: true, unlocksAt: new Date(unlocksAt), attempts };\n }\n\n return { locked: false, attempts };\n } catch (err) {\n console.error(\"[AccountLockout] Failed to record failed attempt:\", err);\n return { locked: false, attempts: 0 };\n }\n }\n\n async clearFailedAttempts(identifier: string): Promise<void> {\n try {\n await this.redis.del(`${this.prefix}:failures:${identifier}`, `${this.prefix}:locked:${identifier}`);\n } catch (err) {\n console.error(\"[AccountLockout] Failed to clear failed attempts:\", err);\n }\n }\n\n async isAccountLocked(identifier: string): Promise<{ locked: boolean; unlocksAt?: Date }> {\n try {\n const lockedUntil = await this.redis.get(`${this.prefix}:locked:${identifier}`);\n if (!lockedUntil) return { locked: false };\n return { locked: true, unlocksAt: new Date(Number(lockedUntil)) };\n } catch (err) {\n console.error(\"[AccountLockout] Failed to check account lock status:\", err);\n return { locked: false };\n }\n }\n}\n","import type { AuditEventType, AuditLogger, AuditSeverity } from \"../types.js\";\nimport { AUDIT_SEVERITY } from \"../config.js\";\n\nexport class AuditLog {\n constructor(private readonly logger?: AuditLogger) {}\n\n log(\n event: AuditEventType,\n data: Omit<Record<string, unknown>, \"event\" | \"timestamp\" | \"severity\">,\n ): void {\n const severity: AuditSeverity = AUDIT_SEVERITY[event] ?? \"info\";\n const entry = { event, severity, timestamp: new Date().toISOString(), ...data };\n const output = JSON.stringify(entry);\n\n if (severity === \"critical\") {\n console.error(`[AUDIT:CRITICAL] ${output}`);\n } else if (severity === \"warn\") {\n console.warn(`[AUDIT:WARN] ${output}`);\n } else {\n console.info(`[AUDIT:INFO] ${output}`);\n }\n\n if (this.logger) {\n void this.logger.log(event, data).catch((err) => {\n if (process.env.NODE_ENV !== \"test\") {\n console.error(\"[AuditLog] Failed to persist audit event:\", (err as Error)?.message ?? err);\n }\n });\n }\n }\n}\n","import { generateSecret, generateURI, verify } from \"otplib\";\n\nexport class TotpManager {\n private readonly issuer: string;\n\n constructor(issuer = \"Auth\") {\n this.issuer = issuer;\n }\n\n generateSecret(): string {\n return generateSecret();\n }\n\n createUri(secret: string, email: string): string {\n return generateURI({ issuer: this.issuer, label: email, secret });\n }\n\n async verify(token: string, secret: string): Promise<boolean> {\n try {\n const result = verify({ token, secret });\n const normalized = result as unknown as boolean | { valid: boolean };\n if (typeof normalized === \"boolean\") return normalized;\n return normalized.valid === true;\n } catch {\n return false;\n }\n }\n}\n","export type {\n RedisAdapter,\n RedisPipeline,\n UserStore,\n User,\n CacheAdapter,\n AuditLogger,\n ObservabilitySink,\n ErrorFactory,\n SessionLifecycle,\n RateLimiterFactory,\n ZodSchema,\n TokenConfig,\n LockoutConfig,\n SessionConfig,\n AuthCoreConfig,\n TokenPayload,\n TokenPair,\n DeviceFingerprint,\n SessionMetadata,\n AuditEventType,\n AuditSeverity,\n} from \"./types.js\";\n\nexport { TokenManager } from \"./tokens/index.js\";\nexport { TokenRevocation } from \"./revocation/index.js\";\nexport { RefreshLock } from \"./refresh/index.js\";\nexport { SessionManager } from \"./session/index.js\";\nexport {\n generateDeviceFingerprint,\n validateSessionBinding,\n createSessionMetadata,\n getClientIp,\n isPrivateIp,\n looksLikeServerToServerRequest,\n looksLikeServerToServerUA,\n normalizeUserAgent,\n} from \"./session/index.js\";\nexport { AccountLockout } from \"./lockout/index.js\";\nexport { AuditLog } from \"./audit/index.js\";\nexport { TotpManager } from \"./totp/index.js\";\nexport { SessionTimeoutManager } from \"./middleware/sessionTimeout.js\";\nexport { MiddlewareFactory } from \"./middleware/middlewareFactory.js\";\nexport type { AuthRequest } from \"./middleware/middlewareFactory.js\";\nexport { exchangeSchema, refreshSchema, logoutSchema } from \"./validation/auth.validation.js\";\nexport {\n UnauthorizedError,\n TokenExpiredError,\n InvalidTokenError,\n TokenRevokedError,\n EmailNotVerifiedError,\n AccountBannedError,\n ForbiddenError,\n SessionHijackError,\n BadRequestError,\n ValidationError,\n defaultErrors,\n} from \"./errors/index.js\";\nexport { DEFAULTS, resolveConfig, AUDIT_SEVERITY } from \"./config.js\";\nexport type { ResolvedConfig } from \"./config.js\";\n","import crypto from \"crypto\";\nimport type {\n RedisAdapter,\n AuthCoreConfig,\n ErrorFactory,\n AuditLogger,\n ObservabilitySink,\n CacheAdapter,\n User,\n SessionMetadata,\n} from \"../types.js\";\nimport { resolveConfig, DEFAULTS, type ResolvedConfig } from \"../config.js\";\nimport { TokenManager } from \"../tokens/backendToken.js\";\nimport { TokenRevocation } from \"../revocation/tokenRevocation.js\";\nimport { defaultErrors } from \"../errors/index.js\";\nimport {\n getClientIp,\n generateDeviceFingerprint,\n isPrivateIp,\n looksLikeServerToServerRequest,\n looksLikeServerToServerUA,\n validateSessionBinding,\n} from \"../session/sessionBinding.js\";\nimport { AuditLog } from \"../audit/auditLog.js\";\n\nexport interface AuthRequest {\n user?: {\n id: string;\n email: string;\n role: string;\n name?: string | null;\n tokenJti?: string;\n sessionId?: string;\n };\n headers: Record<string, string | string[] | undefined>;\n ip?: string;\n socket?: { remoteAddress?: string };\n body?: Record<string, unknown>;\n params?: Record<string, unknown>;\n query?: Record<string, unknown>;\n path?: string;\n method?: string;\n originalUrl?: string;\n [key: string]: unknown;\n}\n\ninterface JwtPayload {\n sub: string;\n email: string;\n role: string;\n jti: string;\n version: number;\n type: string;\n sessionId?: string;\n}\n\nexport class MiddlewareFactory {\n private readonly config: ResolvedConfig;\n private readonly tokenManager: TokenManager;\n private readonly tokenRevocation: TokenRevocation;\n private readonly errors: ErrorFactory;\n private readonly audit: AuditLog;\n private readonly observability?: ObservabilitySink;\n private readonly cache?: CacheAdapter;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private sessionTimeoutManager: any = null;\n\n constructor(rawConfig: AuthCoreConfig) {\n this.config = resolveConfig(rawConfig);\n this.tokenManager = new TokenManager(rawConfig.jwt);\n this.tokenRevocation = new TokenRevocation(rawConfig.redis, this.config.keyPrefix);\n this.errors = rawConfig.errors ?? defaultErrors;\n this.audit = new AuditLog(rawConfig.auditLogger);\n this.observability = rawConfig.observability;\n this.cache = rawConfig.cache;\n }\n\n getTokenManager(): TokenManager {\n return this.tokenManager;\n }\n\n getTokenRevocation(): TokenRevocation {\n return this.tokenRevocation;\n }\n\n getAuditLog(): AuditLog {\n return this.audit;\n }\n\n getRedis(): RedisAdapter {\n return this.config.redis;\n }\n\n getConfig(): ResolvedConfig {\n return this.config;\n }\n\n async enforceSessionBinding(\n req: AuthRequest,\n decoded: JwtPayload,\n ): Promise<Error | null> {\n if (!decoded.sessionId) return null;\n\n const redis = this.config.redis;\n const metadataKey = `${this.config.keyPrefix}session:metadata:${decoded.sessionId}`;\n const storedMetadata = await redis.get(metadataKey);\n if (!storedMetadata) return null;\n\n let metadata: SessionMetadata;\n try {\n metadata = JSON.parse(storedMetadata);\n } catch {\n return null;\n }\n if (looksLikeServerToServerRequest(req)) return null;\n\n if (metadata.deviceId == null || looksLikeServerToServerUA(metadata.userAgent)) {\n metadata.deviceId = generateDeviceFingerprint(req);\n metadata.ipAddress = getClientIp(req);\n metadata.userAgent = (req.headers[\"user-agent\"] as string) || \"unknown\";\n metadata.lastActivity = Date.now();\n this.audit.log(\"SESSION_BOUND\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n ip: metadata.ipAddress,\n userAgent: metadata.userAgent,\n });\n } else {\n const bindingValidation = validateSessionBinding(req, metadata);\n const currentIp = getClientIp(req);\n\n if (!bindingValidation.valid) {\n const isSameIpDeviceChange =\n bindingValidation.reason === \"DEVICE_MISMATCH\" &&\n (currentIp === metadata.ipAddress ||\n isPrivateIp(currentIp) ||\n isPrivateIp(metadata.ipAddress));\n\n if (isSameIpDeviceChange) {\n metadata.deviceId = generateDeviceFingerprint(req);\n metadata.userAgent = (req.headers[\"user-agent\"] as string) || \"unknown\";\n this.audit.log(\"SESSION_REBOUND\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n ip: currentIp,\n userAgent: metadata.userAgent,\n });\n } else {\n await this.tokenRevocation.revokeAllRefreshTokens(decoded.sub);\n if (decoded.jti && this.cache) {\n await this.cache.delete(`auth:result:${decoded.jti}`);\n }\n this.audit.log(\"SESSION_HIJACK_DETECTED\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n reason: bindingValidation.reason,\n ip: currentIp,\n userAgent: req.headers[\"user-agent\"],\n });\n return this.errors.SessionHijackError(bindingValidation.reason);\n }\n }\n }\n\n metadata.lastActivity = Date.now();\n await redis.setex(metadataKey, this.config.sessionMetadataTtl, JSON.stringify(metadata));\n return null;\n }\n\n createAuthenticateMiddleware() {\n const self = this;\n return async function authenticate(req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) {\n try {\n const authHeader = req.headers.authorization;\n if (typeof authHeader !== \"string\" || !authHeader.startsWith(\"Bearer \")) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NO_TOKEN\"));\n }\n\n const token = authHeader.slice(7).trim();\n if (!token) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NO_TOKEN\"));\n }\n\n let decoded: JwtPayload;\n try {\n decoded = self.tokenManager.verifyToken(token) as unknown as JwtPayload;\n } catch (err: unknown) {\n if ((err as { name?: string }).name === \"TokenExpiredError\") {\n return next(self.errors.TokenExpiredError());\n }\n return next(self.errors.InvalidTokenError());\n }\n\n if (decoded.jti && self.cache) {\n const cacheKey = `auth:result:${decoded.jti}`;\n const cachedResult = await self.cache.get<{ userId: string; valid: boolean }>(cacheKey);\n\n if (cachedResult) {\n if (!cachedResult.valid) return next(self.errors.InvalidTokenError(\"INVALID_TOKEN_CACHED\"));\n const bindingError = await self.enforceSessionBinding(req, decoded);\n if (bindingError) return next(bindingError);\n\n const user = await self.loadUser(decoded.sub);\n if (!user) return next(self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\"));\n if (!user.emailVerified) return next(self.errors.EmailNotVerifiedError());\n if (user.bannedAt) return next(self.errors.AccountBannedError(user.banReason, user.bannedAt));\n\n self.assignUser(req, user, decoded);\n return next();\n }\n }\n\n if (decoded.version !== self.config.currentVersion) {\n return next(self.errors.InvalidTokenError(\"TOKEN_VERSION_MISMATCH\"));\n }\n if (decoded.type !== \"access\") {\n return next(self.errors.InvalidTokenError(\"INVALID_TOKEN_TYPE\"));\n }\n\n const [isRevoked, sessionWasRevoked] = await Promise.all([\n decoded.jti ? self.tokenRevocation.isAccessTokenRevoked(decoded.jti) : Promise.resolve(false),\n decoded.sessionId ? self.tokenRevocation.isSessionRevoked(decoded.sessionId) : Promise.resolve(false),\n ]);\n if (isRevoked) return next(self.errors.TokenRevokedError());\n if (sessionWasRevoked) return next(self.errors.TokenRevokedError());\n\n const [bindingError, cachedUser] = await Promise.all([\n self.enforceSessionBinding(req, decoded),\n self.cache?.get<User>(`auth:user:${decoded.sub}`),\n ]);\n if (bindingError) return next(bindingError);\n\n const user = cachedUser ?? (await self.loadUser(decoded.sub));\n if (!user) return next(self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\"));\n if (!user.emailVerified) return next(self.errors.EmailNotVerifiedError());\n if (user.bannedAt) return next(self.errors.AccountBannedError(user.banReason, user.bannedAt));\n\n if (!cachedUser && user && self.cache) {\n void self.cache.set(`auth:user:${decoded.sub}`, user, 30 * 60).catch(() => {});\n }\n\n if (decoded.jti && self.cache) {\n void self.cache.set(`auth:result:${decoded.jti}`, { userId: decoded.sub, valid: true }, 5 * 60).catch(() => {});\n }\n\n self.assignUser(req, user, decoded);\n self.observability?.setUserContext?.({ id: user.id, email: user.email });\n self.observability?.addBreadcrumb?.({\n message: \"User authenticated successfully\",\n data: { userId: user.id, email: user.email, role: user.role },\n });\n\n next();\n } catch (err) {\n console.error(\"Unexpected authentication error:\", err);\n self.observability?.captureException?.(err as Error, { context: \"authentication\" });\n next(err as Error);\n }\n };\n }\n\n createAuthorizeMiddleware(...roles: string[]) {\n const self = this;\n return function authorize(req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) {\n if (!req.user) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NOT_AUTHENTICATED\"));\n }\n if (!roles.includes(req.user.role)) {\n return next(self.errors.ForbiddenError(\"Insufficient permissions\"));\n }\n next();\n };\n }\n\n createCsrfMiddleware() {\n const self = this;\n const CSRF_TOKEN_LENGTH = 32;\n const CSRF_TOKEN_TTL = 3600;\n\n return {\n generateToken: async (userId: string, sessionId: string): Promise<string> => {\n const token = crypto.randomBytes(CSRF_TOKEN_LENGTH).toString(\"base64url\");\n const key = `${self.config.keyPrefix}csrf:${userId}:${sessionId}`;\n await self.config.redis.setex(key, CSRF_TOKEN_TTL, token);\n return token;\n },\n validateToken: async (userId: string, sessionId: string, token: string): Promise<boolean> => {\n if (!token) return false;\n const key = `${self.config.keyPrefix}csrf:${userId}:${sessionId}`;\n const storedToken = await self.config.redis.get(key);\n if (!storedToken) return false;\n try {\n return crypto.timingSafeEqual(Buffer.from(token, \"base64url\"), Buffer.from(storedToken, \"base64url\"));\n } catch {\n return false;\n }\n },\n middleware() {\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown }; end(): unknown }, next: (err?: Error) => void) => {\n if ([\"GET\", \"HEAD\", \"OPTIONS\"].includes(req.method ?? \"\")) return next();\n if (req.path?.startsWith(\"/webhooks/\") || req.path?.includes(\"/callback\")) return next();\n\n const csrfToken = req.headers[\"x-csrf-token\"] as string;\n if (!req.user?.id) {\n return res.status(401).json({ success: false, message: \"Authentication required\", code: \"NOT_AUTHENTICATED\" });\n }\n\n const sessionId = req.user.sessionId || \"default\";\n const stored = await self.config.redis.get(`${self.config.keyPrefix}csrf:${req.user.id}:${sessionId}`);\n if (!stored || !csrfToken) return res.status(403).json({ success: false, message: \"Invalid CSRF token\", code: \"CSRF_VALIDATION_FAILED\" });\n\n let isValid = false;\n try {\n isValid = crypto.timingSafeEqual(Buffer.from(csrfToken, \"base64url\"), Buffer.from(stored, \"base64url\"));\n } catch {\n isValid = false;\n }\n\n if (!isValid) {\n return res.status(403).json({ success: false, message: \"Invalid CSRF token\", code: \"CSRF_VALIDATION_FAILED\" });\n }\n next();\n };\n },\n };\n }\n\n createRateLimitMiddleware() {\n const self = this;\n return (max: number, windowSeconds: number, keyFn?: (req: AuthRequest) => string | undefined, options?: { failOpen?: boolean }) => {\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) => {\n const ip = getClientIp(req);\n const userKey = keyFn?.(req);\n const key = userKey ? `${self.config.keyPrefix}rl:user:${userKey}` : `${self.config.keyPrefix}rl:backend:${ip}`;\n\n try {\n const redis = self.config.redis;\n const countKey = `${key}:count`;\n const count = await redis.incr(countKey);\n if (count === 1) await redis.expire(countKey, windowSeconds);\n\n if (count > max) {\n return res.status(429).json({ success: false, message: \"Too many requests\", code: \"RATE_LIMIT_EXCEEDED\", retryAfter: windowSeconds });\n }\n\n next();\n } catch (error) {\n if (options?.failOpen) return next();\n return res.status(429).json({ success: false, message: \"Rate limit service unavailable\", code: \"RATE_LIMIT_SERVICE_UNAVAILABLE\", retryAfter: windowSeconds });\n }\n };\n };\n }\n\n createSessionTimeoutMiddleware() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) => {\n const sessionId = req.user?.sessionId;\n if (!sessionId) return next();\n\n if (!self.sessionTimeoutManager) {\n const { SessionTimeoutManager } = await import(\"./sessionTimeout.js\");\n self.sessionTimeoutManager = new SessionTimeoutManager(self.config.redis, {\n inactivityTimeout: self.config.inactivityTimeout,\n absoluteTimeout: self.config.absoluteTimeout,\n prefix: self.config.keyPrefix,\n });\n }\n\n const tracked = await self.sessionTimeoutManager.isTracked(sessionId);\n if (!tracked) return next();\n\n const inactive = await self.sessionTimeoutManager.isInactive(sessionId);\n if (inactive) {\n return res.status(401).json({ success: false, code: \"SESSION_TIMEOUT\", message: \"Session expired\" });\n }\n\n await self.sessionTimeoutManager.updateActivity(sessionId);\n next();\n };\n }\n\n createExchangeHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const ip = getClientIp(req);\n const { userId, email, role, sessionId, timestamp, signature } = req.body as Record<string, string>;\n\n const age = Date.now() - Number(timestamp);\n if (age > 60_000 || age < 0) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Proof expired\" });\n throw self.errors.UnauthorizedError(\"Exchange proof expired\", \"PROOF_EXPIRED\");\n }\n\n const proofPayload = `${userId}${email}${role}${sessionId}${timestamp}`;\n const expected = crypto.createHmac(\"sha256\", self.config.hmacSecret).update(proofPayload).digest(\"hex\");\n\n let valid = false;\n try {\n if (signature) {\n valid = crypto.timingSafeEqual(Buffer.from(signature, \"hex\"), Buffer.from(expected, \"hex\"));\n }\n } catch {\n valid = false;\n }\n\n if (!valid) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Invalid signature\" });\n throw self.errors.UnauthorizedError(\"Invalid exchange proof\", \"INVALID_SIGNATURE\");\n }\n\n const idempotencyKey = `exchange:idempotent:${userId}:${sessionId}:${timestamp}`;\n const existing = await self.config.redis.get(idempotencyKey);\n if (existing) {\n return res.status(200).json(JSON.parse(existing));\n }\n\n const user = await self.config.userStore.findById(userId!);\n if (!user) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"User not found\" });\n throw self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\");\n }\n\n if (user.email.toLowerCase() !== email!.toLowerCase()) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Email mismatch\" });\n throw self.errors.UnauthorizedError(\"Email mismatch\", \"EMAIL_MISMATCH\");\n }\n\n if (!user.emailVerified) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Email not verified\" });\n throw self.errors.UnauthorizedError(\"Email not verified\", \"EMAIL_NOT_VERIFIED\");\n }\n\n const sid = sessionId || crypto.randomUUID();\n const tokens = self.tokenManager.createTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n sessionId: sid,\n });\n\n const refreshTtlSeconds = self.tokenManager.getRefreshTokenExpiry() === \"7d\"\n ? 7 * 24 * 60 * 60\n : TokenManager.parseExpiry(self.tokenManager.getRefreshTokenExpiry()) / 1000;\n\n await self.tokenRevocation.storeRefreshToken(user.id, TokenManager.extractJti(tokens.refreshToken), refreshTtlSeconds);\n\n const sseToken = self.tokenManager.createSseToken(user.id);\n const sseTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getSseTokenExpiry()) / 1000;\n await self.tokenRevocation.storeSseToken(TokenManager.extractJti(sseToken), user.id, sseTtlSeconds);\n\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:created:${sid}`,\n self.config.absoluteTimeout,\n Date.now().toString(),\n );\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:activity:${sid}`,\n self.config.inactivityTimeout,\n Date.now().toString(),\n );\n\n await self.config.redis.setex(idempotencyKey, 90, JSON.stringify(tokens));\n\n self.audit.log(\"EXCHANGE_SUCCESS\", { userId: user.id, email: user.email, ip });\n return res.status(200).json(tokens);\n };\n }\n\n createRefreshHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const { refreshToken } = req.body as { refreshToken: string };\n if (!refreshToken) throw self.errors.BadRequestError(\"Refresh token required\");\n\n let decoded;\n try {\n decoded = self.tokenManager.verifyToken(refreshToken, \"refresh\");\n } catch {\n throw self.errors.UnauthorizedError(\"Invalid refresh token\", \"INVALID_TOKEN\");\n }\n\n const redis = self.config.redis;\n const lockKey = `${self.config.keyPrefix}refresh:lock:${decoded.sessionId}`;\n const lockResult = await redis.set(lockKey, \"1\", \"EX\", 45, \"NX\");\n\n if (lockResult !== \"OK\") {\n throw self.errors.BadRequestError(\"Refresh already in progress\", \"REFRESH_IN_PROGRESS\");\n }\n\n try {\n const dedupeKey = `${self.config.keyPrefix}refresh:dedupe:${decoded.id}:${decoded.jti}`;\n const cached = await redis.get(dedupeKey);\n if (cached) return res.status(200).json(JSON.parse(cached));\n\n const sessionRevokedKey = `${self.config.keyPrefix}session:revoked:${decoded.sessionId}`;\n if ((await redis.get(sessionRevokedKey)) === \"1\") {\n throw self.errors.UnauthorizedError(\"Session revoked\", \"SESSION_REVOKED\");\n }\n\n const createdKey = `${self.config.keyPrefix}session:created:${decoded.sessionId}`;\n if ((await redis.exists(createdKey)) !== 1) {\n throw self.errors.UnauthorizedError(\"Session expired\", \"SESSION_TIMEOUT\");\n }\n\n const newTokens = self.tokenManager.createTokenPair({\n id: decoded.id,\n email: decoded.email,\n role: decoded.role,\n sessionId: decoded.sessionId,\n });\n\n const refreshTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getRefreshTokenExpiry()) / 1000;\n await self.tokenRevocation.rotateRefreshToken(\n decoded.id,\n decoded.jti,\n TokenManager.extractJti(newTokens.refreshToken),\n refreshTtlSeconds,\n );\n\n const newSseToken = self.tokenManager.createSseToken(decoded.id);\n const sseTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getSseTokenExpiry()) / 1000;\n await self.tokenRevocation.storeSseToken(TokenManager.extractJti(newSseToken), decoded.id, sseTtlSeconds);\n\n const response = { ...newTokens, sseToken: newSseToken };\n await redis.setex(dedupeKey, 30, JSON.stringify(response));\n\n self.audit.log(\"TOKEN_REFRESHED\", { userId: decoded.id, sessionId: decoded.sessionId });\n return res.status(200).json(response);\n } finally {\n await redis.del(lockKey);\n }\n };\n }\n\n createLogoutHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const { logoutAll } = req.body as { logoutAll?: boolean };\n const userId = req.user?.id;\n const sessionId = req.user?.sessionId;\n\n if (req.user?.tokenJti) {\n const token = (req.headers.authorization as string)?.slice(7);\n if (token) {\n const expiry = self.tokenManager.getAccessTokenExpiry();\n const ttlSeconds = TokenManager.parseExpiry(expiry) / 1000;\n await self.tokenRevocation.revokeAccessToken(req.user.tokenJti, ttlSeconds);\n }\n }\n\n if (logoutAll && userId) {\n await self.tokenRevocation.revokeAllRefreshTokens(userId);\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:revoked:${sessionId}`,\n DEFAULTS.revokedSessionTtl,\n \"1\",\n );\n self.audit.log(\"LOGOUT_ALL_DEVICES\", { userId });\n } else if (userId && sessionId) {\n await self.config.redis.del(`${self.config.keyPrefix}session:metadata:${sessionId}`);\n self.audit.log(\"LOGOUT\", { userId, sessionId });\n }\n\n return res.status(200).json({ success: true, message: \"Logged out\" });\n };\n }\n\n private async loadUser(id: string): Promise<User | null> {\n try {\n return await this.config.userStore.findById(id);\n } catch {\n return null;\n }\n }\n\n private assignUser(req: AuthRequest, user: User, decoded: JwtPayload): void {\n req.user = {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n tokenJti: decoded.jti,\n sessionId: decoded.sessionId,\n };\n }\n}\n","// @focura/auth-core — Default error classes\n\nexport class UnauthorizedError extends Error {\n public readonly code: string;\n public readonly statusCode = 401;\n constructor(message = \"Unauthorized\", code = \"UNAUTHORIZED\") {\n super(message);\n this.name = \"UnauthorizedError\";\n this.code = code;\n }\n}\n\nexport class TokenExpiredError extends Error {\n public readonly code = \"TOKEN_EXPIRED\";\n public readonly statusCode = 401;\n constructor(message = \"Token expired\") {\n super(message);\n this.name = \"TokenExpiredError\";\n }\n}\n\nexport class InvalidTokenError extends Error {\n public readonly code: string;\n public readonly statusCode = 401;\n constructor(code = \"INVALID_TOKEN\") {\n super(\"Invalid token\");\n this.name = \"InvalidTokenError\";\n this.code = code;\n }\n}\n\nexport class TokenRevokedError extends Error {\n public readonly code = \"TOKEN_REVOKED\";\n public readonly statusCode = 401;\n constructor(message = \"Token has been revoked\") {\n super(message);\n this.name = \"TokenRevokedError\";\n }\n}\n\nexport class EmailNotVerifiedError extends Error {\n public readonly code = \"EMAIL_NOT_VERIFIED\";\n public readonly statusCode = 403;\n constructor(message = \"Email not verified\") {\n super(message);\n this.name = \"EmailNotVerifiedError\";\n }\n}\n\nexport class AccountBannedError extends Error {\n public readonly code = \"ACCOUNT_BANNED\";\n public readonly statusCode = 403;\n public readonly bannedAt?: Date;\n constructor(reason?: string | null, bannedAt?: Date | null) {\n super(reason ?? \"Account has been banned\");\n this.name = \"AccountBannedError\";\n this.bannedAt = bannedAt ?? undefined;\n }\n}\n\nexport class ForbiddenError extends Error {\n public readonly code = \"FORBIDDEN\";\n public readonly statusCode = 403;\n constructor(message = \"Forbidden\") {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class SessionHijackError extends Error {\n public readonly code = \"SESSION_HIJACK_DETECTED\";\n public readonly statusCode = 401;\n constructor(reason?: string) {\n super(reason ?? \"Session hijack detected\");\n this.name = \"SessionHijackError\";\n }\n}\n\nexport class BadRequestError extends Error {\n public readonly code: string;\n public readonly statusCode = 400;\n constructor(message = \"Bad request\", code = \"BAD_REQUEST\") {\n super(message);\n this.name = \"BadRequestError\";\n this.code = code;\n }\n}\n\nexport class ValidationError extends Error {\n public readonly code: string;\n public readonly statusCode = 400;\n public readonly details?: unknown[];\n constructor(message = \"Validation failed\", details?: unknown[], code = \"VALIDATION_ERROR\") {\n super(message);\n this.name = \"ValidationError\";\n this.code = code;\n this.details = details;\n }\n}\n\nimport type { ErrorFactory } from \"../types.js\";\n\nexport const defaultErrors: ErrorFactory = {\n UnauthorizedError: (msg, code) => new UnauthorizedError(msg, code),\n TokenExpiredError: () => new TokenExpiredError(),\n InvalidTokenError: (code) => new InvalidTokenError(code),\n TokenRevokedError: () => new TokenRevokedError(),\n EmailNotVerifiedError: () => new EmailNotVerifiedError(),\n AccountBannedError: (reason, at) => new AccountBannedError(reason, at),\n ForbiddenError: (msg) => new ForbiddenError(msg),\n SessionHijackError: (reason) => new SessionHijackError(reason),\n BadRequestError: (msg, code) => new BadRequestError(msg, code),\n ValidationError: (msg, details, code) => new ValidationError(msg, details, code),\n};\n","import { z } from \"zod\";\n\nexport const exchangeSchema = z.object({\n userId: z.string().uuid(),\n email: z.string().email(),\n role: z.string(),\n sessionId: z.string().uuid(),\n timestamp: z.string().or(z.number()),\n signature: z.string(),\n});\n\nexport const refreshSchema = z.object({\n refreshToken: z.string().min(1),\n});\n\nexport const logoutSchema = z.object({\n logoutAll: z.boolean().optional(),\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/middleware/sessionTimeout.ts","../src/auth/authService.ts","../src/tokens/backendToken.ts","../src/revocation/tokenRevocation.ts","../src/session/sessionManager.ts","../src/lockout/accountLockout.ts","../src/audit/auditLog.ts","../src/totp/totp.ts","../src/errors/index.ts","../src/session/sessionBinding.ts","../src/refresh/refreshLock.ts","../src/index.ts","../src/middleware/middlewareFactory.ts","../src/validation/auth.validation.ts"],"names":["crypto","bindingError","user","SessionTimeoutManager"],"mappings":"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","file":"index.js","sourcesContent":["// @focura/auth-core — Default configuration and config merge utility\n\nimport type { AuthCoreConfig, AuditSeverity, AuditEventType } from \"./types.js\";\n\nexport const DEFAULTS = {\n keyPrefix: \"focura:\",\n issuer: \"focura-app\",\n audience: \"focura-backend\",\n accessTokenExpiry: \"15m\",\n refreshTokenExpiry: \"7d\",\n sseTokenExpiry: \"30s\",\n currentVersion: 1,\n maxConcurrentSessions: 5,\n sessionMetadataTtl: 7 * 24 * 60 * 60,\n lockoutMaxFailures: 10,\n lockoutSeconds: 15 * 60,\n lockoutWindowSeconds: 60 * 60,\n refreshLockTtlSeconds: 45,\n refreshDedupeTtlSeconds: 30,\n revokedSessionTtl: 7 * 24 * 60 * 60,\n inactivityTimeout: 7 * 24 * 60 * 60,\n absoluteTimeout: 7 * 24 * 60 * 60,\n} as const;\n\nexport function resolveConfig(raw: AuthCoreConfig) {\n return {\n ...raw,\n keyPrefix: raw.keyPrefix ?? DEFAULTS.keyPrefix,\n issuer: raw.jwt.issuer ?? DEFAULTS.issuer,\n audience: raw.jwt.audience ?? DEFAULTS.audience,\n accessTokenExpiry: raw.jwt.accessTokenExpiry ?? DEFAULTS.accessTokenExpiry,\n refreshTokenExpiry: raw.jwt.refreshTokenExpiry ?? DEFAULTS.refreshTokenExpiry,\n sseTokenExpiry: raw.jwt.sseTokenExpiry ?? DEFAULTS.sseTokenExpiry,\n currentVersion: raw.jwt.currentVersion ?? DEFAULTS.currentVersion,\n maxConcurrentSessions: raw.session?.maxConcurrent ?? DEFAULTS.maxConcurrentSessions,\n sessionMetadataTtl: raw.session?.metadataTtl ?? DEFAULTS.sessionMetadataTtl,\n lockoutMaxFailures: raw.lockout?.maxFailures ?? DEFAULTS.lockoutMaxFailures,\n lockoutSeconds: raw.lockout?.lockoutSeconds ?? DEFAULTS.lockoutSeconds,\n lockoutWindowSeconds: raw.lockout?.windowSeconds ?? DEFAULTS.lockoutWindowSeconds,\n inactivityTimeout: raw.session?.inactivityTimeout ?? 7 * 24 * 60 * 60,\n absoluteTimeout: raw.session?.absoluteTimeout ?? 7 * 24 * 60 * 60,\n };\n}\n\nexport type ResolvedConfig = ReturnType<typeof resolveConfig>;\n\nexport const AUDIT_SEVERITY: Record<AuditEventType, AuditSeverity> = {\n LOGIN_SUCCESS: \"info\",\n LOGIN_FAILED: \"warn\",\n LOGIN_BLOCKED: \"warn\",\n LOGOUT: \"info\",\n LOGOUT_ALL_DEVICES: \"info\",\n TOKEN_REFRESHED: \"info\",\n TOKEN_REVOKED: \"info\",\n TOKEN_EXPIRED: \"info\",\n TOKEN_VERSION_MISMATCH: \"warn\",\n TOKEN_REPLAY_DETECTED: \"critical\",\n EXCHANGE_SUCCESS: \"info\",\n EXCHANGE_FAILED: \"warn\",\n SSE_CONNECTED: \"info\",\n SSE_DISCONNECTED: \"info\",\n ACCOUNT_LOCKED: \"critical\",\n TOTP_VERIFIED: \"info\",\n TOTP_FAILED: \"warn\",\n PERMISSION_DENIED: \"warn\",\n EMAIL_NOT_VERIFIED: \"warn\",\n SESSION_HIJACK_DETECTED: \"critical\",\n SESSION_BOUND: \"info\",\n SESSION_REBOUND: \"info\",\n SESSION_TIMEOUT: \"info\",\n MAX_SESSIONS_REACHED: \"warn\",\n SESSION_REVOKED: \"info\",\n SESSIONS_REVOKED: \"info\",\n DEVICE_MISMATCH: \"warn\",\n SUSPICIOUS_IP_CHANGE: \"warn\",\n CSRF_VALIDATION_FAILED: \"warn\",\n UNAUTHORIZED_ACCESS: \"warn\",\n RATE_LIMIT_EXCEEDED: \"warn\",\n MALWARE_DETECTED: \"critical\",\n SUSPICIOUS_ACTIVITY: \"warn\",\n DATA_EXPORT: \"info\",\n DATA_DELETION: \"critical\",\n SENSITIVE_DATA_ACCESS: \"warn\",\n WORKSPACE_CREATED: \"info\",\n WORKSPACE_DELETED: \"critical\",\n MEMBER_ADDED: \"info\",\n MEMBER_REMOVED: \"info\",\n ROLE_CHANGED: \"info\",\n SUBSCRIPTION_CREATED: \"info\",\n SUBSCRIPTION_CANCELLED: \"info\",\n PAYMENT_FAILED: \"warn\",\n};\n","import type { RedisAdapter, SessionLifecycle } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class SessionTimeoutManager implements SessionLifecycle {\n private readonly inactivityTimeout: number;\n private readonly absoluteTimeout: number;\n private readonly prefix: string;\n\n constructor(\n private readonly redis: RedisAdapter,\n config?: { inactivityTimeout?: number; absoluteTimeout?: number; prefix?: string },\n ) {\n this.inactivityTimeout = config?.inactivityTimeout ?? DEFAULTS.inactivityTimeout;\n this.absoluteTimeout = config?.absoluteTimeout ?? DEFAULTS.absoluteTimeout;\n this.prefix = config?.prefix ?? DEFAULTS.keyPrefix;\n }\n\n private createdKey(sessionId: string): string {\n return `${this.prefix}session:created:${sessionId}`;\n }\n\n private activityKey(sessionId: string): string {\n return `${this.prefix}session:activity:${sessionId}`;\n }\n\n async recordCreation(sessionId: string): Promise<void> {\n const now = Date.now();\n await this.redis.setex(this.createdKey(sessionId), this.absoluteTimeout, now.toString());\n await this.redis.setex(this.activityKey(sessionId), this.inactivityTimeout, now.toString());\n }\n\n async invalidate(sessionId: string): Promise<void> {\n await this.redis.del(this.createdKey(sessionId), this.activityKey(sessionId));\n }\n\n async isTracked(sessionId: string): Promise<boolean> {\n return (await this.redis.exists(this.createdKey(sessionId))) === 1;\n }\n\n async isInactive(sessionId: string): Promise<boolean> {\n const exists = await this.redis.exists(this.activityKey(sessionId));\n return exists !== 1;\n }\n\n async updateActivity(sessionId: string): Promise<boolean> {\n try {\n const result = await this.redis.setex(this.activityKey(sessionId), this.inactivityTimeout, Date.now().toString());\n return result === \"OK\";\n } catch {\n return false;\n }\n }\n}\n","import crypto from \"crypto\";\nimport type {\n AuthCoreConfig,\n TokenPair,\n User,\n AuditEventType,\n SessionMetadata,\n} from \"../types.js\";\nimport { resolveConfig, DEFAULTS, type ResolvedConfig } from \"../config.js\";\nimport { TokenManager } from \"../tokens/backendToken.js\";\nimport { TokenRevocation } from \"../revocation/tokenRevocation.js\";\nimport { SessionManager } from \"../session/sessionManager.js\";\nimport { AccountLockout } from \"../lockout/accountLockout.js\";\nimport { AuditLog } from \"../audit/auditLog.js\";\nimport { TotpManager } from \"../totp/totp.js\";\nimport { defaultErrors } from \"../errors/index.js\";\nimport type { ErrorFactory } from \"../types.js\";\nimport {\n generateDeviceFingerprint,\n validateSessionBinding,\n getClientIp,\n} from \"../session/sessionBinding.js\";\n\nexport interface ExchangeInput {\n userId: string;\n email: string;\n role: string;\n sessionId?: string;\n timestamp: number;\n signature: string;\n}\n\nexport interface ExchangeResult extends TokenPair {\n sseToken: string;\n sessionId: string;\n}\n\nexport interface VerifyTokenInput {\n token: string;\n ipAddress?: string;\n userAgent?: string;\n}\n\nexport interface VerifyTokenResult {\n user: User;\n payload: {\n id: string;\n email: string;\n role: string;\n jti: string;\n sessionId?: string;\n };\n}\n\nexport interface RefreshInput {\n refreshToken: string;\n}\n\nexport interface RefreshResult extends TokenPair {\n sseToken: string;\n}\n\nexport interface LogoutInput {\n accessToken?: string;\n accessTokenJti?: string;\n userId?: string;\n sessionId?: string;\n logoutAll?: boolean;\n}\n\nexport interface TwoFactorSetupResult {\n secret: string;\n uri: string;\n}\n\nexport interface TwoFactorVerifyInput {\n token: string;\n secret: string;\n}\n\nexport class AuthService {\n readonly tokenManager: TokenManager;\n readonly tokenRevocation: TokenRevocation;\n readonly sessionManager: SessionManager;\n readonly accountLockout: AccountLockout;\n readonly totpManager: TotpManager;\n readonly audit: AuditLog;\n readonly errors: ErrorFactory;\n\n private readonly config: ResolvedConfig;\n private readonly userStore: AuthCoreConfig[\"userStore\"];\n\n constructor(rawConfig: AuthCoreConfig) {\n this.config = resolveConfig(rawConfig);\n this.userStore = rawConfig.userStore;\n this.errors = rawConfig.errors ?? defaultErrors;\n\n this.tokenManager = new TokenManager(rawConfig.jwt);\n this.tokenRevocation = new TokenRevocation(rawConfig.redis, this.config.keyPrefix);\n this.sessionManager = new SessionManager(\n rawConfig.redis,\n this.tokenRevocation,\n rawConfig.auditLogger,\n this.config.keyPrefix,\n this.config.maxConcurrentSessions,\n );\n this.accountLockout = new AccountLockout(rawConfig.redis, {\n maxFailures: this.config.lockoutMaxFailures,\n lockoutSeconds: this.config.lockoutSeconds,\n windowSeconds: this.config.lockoutWindowSeconds,\n prefix: `${this.config.keyPrefix}lockout`,\n });\n this.totpManager = new TotpManager(rawConfig.jwt.issuer ?? \"Auth\");\n this.audit = new AuditLog(rawConfig.auditLogger);\n }\n\n getConfig(): ResolvedConfig {\n return this.config;\n }\n\n getRedis(): AuthCoreConfig[\"redis\"] {\n return this.config.redis;\n }\n\n async exchange(input: ExchangeInput): Promise<ExchangeResult> {\n const age = Date.now() - input.timestamp;\n if (age > 60_000 || age < 0) {\n this.audit.log(\"EXCHANGE_FAILED\", { userId: input.userId, reason: \"Proof expired\" });\n throw this.errors.UnauthorizedError(\"Exchange proof expired\", \"PROOF_EXPIRED\");\n }\n\n const proofPayload = `${input.userId}${input.email}${input.role}${input.sessionId}${input.timestamp}`;\n const expected = crypto.createHmac(\"sha256\", this.config.hmacSecret).update(proofPayload).digest(\"hex\");\n\n let valid = false;\n try {\n if (input.signature) {\n valid = crypto.timingSafeEqual(Buffer.from(input.signature, \"hex\"), Buffer.from(expected, \"hex\"));\n }\n } catch {\n valid = false;\n }\n\n if (!valid) {\n this.audit.log(\"EXCHANGE_FAILED\", { userId: input.userId, reason: \"Invalid signature\" });\n throw this.errors.UnauthorizedError(\"Invalid exchange proof\", \"INVALID_SIGNATURE\");\n }\n\n const idempotencyKey = `exchange:idempotent:${input.userId}:${input.sessionId}:${input.timestamp}`;\n const existing = await this.config.redis.get(idempotencyKey);\n if (existing) {\n return JSON.parse(existing) as ExchangeResult;\n }\n\n const user = await this.userStore.findById(input.userId);\n if (!user) {\n this.audit.log(\"EXCHANGE_FAILED\", { userId: input.userId, reason: \"User not found\" });\n throw this.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\");\n }\n\n if (user.email.toLowerCase() !== input.email.toLowerCase()) {\n this.audit.log(\"EXCHANGE_FAILED\", { userId: input.userId, reason: \"Email mismatch\" });\n throw this.errors.UnauthorizedError(\"Email mismatch\", \"EMAIL_MISMATCH\");\n }\n\n if (!user.emailVerified) {\n this.audit.log(\"EXCHANGE_FAILED\", { userId: input.userId, reason: \"Email not verified\" });\n throw this.errors.UnauthorizedError(\"Email not verified\", \"EMAIL_NOT_VERIFIED\");\n }\n\n const sessionId = input.sessionId || crypto.randomUUID();\n const tokens = this.tokenManager.createTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n sessionId,\n });\n\n const refreshTtlSeconds = TokenManager.parseExpiry(this.tokenManager.getRefreshTokenExpiry()) / 1000;\n await this.tokenRevocation.storeRefreshToken(user.id, TokenManager.extractJti(tokens.refreshToken), refreshTtlSeconds);\n\n const sseToken = this.tokenManager.createSseToken(user.id);\n const sseTtlSeconds = TokenManager.parseExpiry(this.tokenManager.getSseTokenExpiry()) / 1000;\n await this.tokenRevocation.storeSseToken(TokenManager.extractJti(sseToken), user.id, sseTtlSeconds);\n\n await this.config.redis.setex(\n `${this.config.keyPrefix}session:created:${sessionId}`,\n this.config.absoluteTimeout,\n Date.now().toString(),\n );\n await this.config.redis.setex(\n `${this.config.keyPrefix}session:activity:${sessionId}`,\n this.config.inactivityTimeout,\n Date.now().toString(),\n );\n\n await this.sessionManager.trackUserSession(user.id, sessionId);\n\n const result: ExchangeResult = { ...tokens, sseToken, sessionId };\n await this.config.redis.setex(idempotencyKey, 90, JSON.stringify(result));\n\n this.audit.log(\"EXCHANGE_SUCCESS\", { userId: user.id, email: user.email });\n return result;\n }\n\n async verifyToken(input: VerifyTokenInput): Promise<VerifyTokenResult> {\n let decoded;\n try {\n decoded = this.tokenManager.verifyToken(input.token) as {\n id: string;\n email: string;\n role: string;\n jti: string;\n type: string;\n version: number;\n sessionId?: string;\n };\n } catch (err: unknown) {\n if ((err as { name?: string }).name === \"TokenExpiredError\") {\n throw this.errors.TokenExpiredError();\n }\n throw this.errors.InvalidTokenError();\n }\n\n if (decoded.version !== this.config.currentVersion) {\n throw this.errors.InvalidTokenError(\"TOKEN_VERSION_MISMATCH\");\n }\n if (decoded.type !== \"access\") {\n throw this.errors.InvalidTokenError(\"INVALID_TOKEN_TYPE\");\n }\n\n const [isRevoked, sessionWasRevoked] = await Promise.all([\n decoded.jti ? this.tokenRevocation.isAccessTokenRevoked(decoded.jti) : Promise.resolve(false),\n decoded.sessionId ? this.tokenRevocation.isSessionRevoked(decoded.sessionId) : Promise.resolve(false),\n ]);\n if (isRevoked) throw this.errors.TokenRevokedError();\n if (sessionWasRevoked) throw this.errors.TokenRevokedError();\n\n if (decoded.sessionId && input.ipAddress && input.userAgent) {\n const metadataKey = `${this.config.keyPrefix}session:metadata:${decoded.sessionId}`;\n const storedMetadata = await this.config.redis.get(metadataKey);\n if (storedMetadata) {\n let metadata: SessionMetadata;\n try {\n metadata = JSON.parse(storedMetadata);\n } catch {\n metadata = { deviceId: null, ipAddress: input.ipAddress, userAgent: input.userAgent, lastActivity: Date.now() };\n }\n\n if (metadata.deviceId == null) {\n metadata.deviceId = crypto.createHash(\"sha256\")\n .update(`${input.userAgent}|${input.ipAddress}`)\n .digest(\"hex\")\n .substring(0, 32);\n metadata.ipAddress = input.ipAddress;\n metadata.userAgent = input.userAgent;\n metadata.lastActivity = Date.now();\n await this.config.redis.setex(metadataKey, this.config.sessionMetadataTtl, JSON.stringify(metadata));\n } else {\n const req = { headers: { \"user-agent\": input.userAgent }, ip: input.ipAddress } as Parameters<typeof generateDeviceFingerprint>[0];\n const binding = validateSessionBinding(req, metadata);\n if (!binding.valid) {\n await this.tokenRevocation.revokeAllRefreshTokens(decoded.id);\n this.audit.log(\"SESSION_HIJACK_DETECTED\", {\n userId: decoded.id,\n sessionId: decoded.sessionId,\n reason: binding.reason,\n });\n throw this.errors.SessionHijackError(binding.reason);\n }\n metadata.lastActivity = Date.now();\n await this.config.redis.setex(metadataKey, this.config.sessionMetadataTtl, JSON.stringify(metadata));\n }\n }\n }\n\n const user = await this.userStore.findById(decoded.id);\n if (!user) throw this.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\");\n if (!user.emailVerified) throw this.errors.EmailNotVerifiedError();\n if (user.bannedAt) throw this.errors.AccountBannedError(user.banReason, user.bannedAt);\n\n return {\n user,\n payload: {\n id: decoded.id,\n email: decoded.email,\n role: decoded.role,\n jti: decoded.jti,\n sessionId: decoded.sessionId,\n },\n };\n }\n\n async refresh(input: RefreshInput): Promise<RefreshResult> {\n let decoded;\n try {\n decoded = this.tokenManager.verifyToken(input.refreshToken, \"refresh\") as {\n id: string;\n email: string;\n role: string;\n jti: string;\n sessionId: string;\n };\n } catch {\n throw this.errors.UnauthorizedError(\"Invalid refresh token\", \"INVALID_TOKEN\");\n }\n\n const lockKey = `${this.config.keyPrefix}refresh:lock:${decoded.sessionId}`;\n const lockResult = await this.config.redis.set(lockKey, \"1\", \"EX\", DEFAULTS.refreshLockTtlSeconds, \"NX\");\n\n if (lockResult !== \"OK\") {\n throw this.errors.BadRequestError(\"Refresh already in progress\", \"REFRESH_IN_PROGRESS\");\n }\n\n try {\n const dedupeKey = `${this.config.keyPrefix}refresh:dedupe:${decoded.id}:${decoded.jti}`;\n const cached = await this.config.redis.get(dedupeKey);\n if (cached) return JSON.parse(cached) as RefreshResult;\n\n const sessionRevokedKey = `${this.config.keyPrefix}session:revoked:${decoded.sessionId}`;\n if ((await this.config.redis.get(sessionRevokedKey)) === \"1\") {\n throw this.errors.UnauthorizedError(\"Session revoked\", \"SESSION_REVOKED\");\n }\n\n const createdKey = `${this.config.keyPrefix}session:created:${decoded.sessionId}`;\n if ((await this.config.redis.exists(createdKey)) !== 1) {\n throw this.errors.UnauthorizedError(\"Session expired\", \"SESSION_TIMEOUT\");\n }\n\n const newTokens = this.tokenManager.createTokenPair({\n id: decoded.id,\n email: decoded.email,\n role: decoded.role,\n sessionId: decoded.sessionId,\n });\n\n const refreshTtlSeconds = TokenManager.parseExpiry(this.tokenManager.getRefreshTokenExpiry()) / 1000;\n await this.tokenRevocation.rotateRefreshToken(\n decoded.id,\n decoded.jti,\n TokenManager.extractJti(newTokens.refreshToken),\n refreshTtlSeconds,\n );\n\n const newSseToken = this.tokenManager.createSseToken(decoded.id);\n const sseTtlSeconds = TokenManager.parseExpiry(this.tokenManager.getSseTokenExpiry()) / 1000;\n await this.tokenRevocation.storeSseToken(TokenManager.extractJti(newSseToken), decoded.id, sseTtlSeconds);\n\n const response: RefreshResult = { ...newTokens, sseToken: newSseToken };\n await this.config.redis.setex(dedupeKey, DEFAULTS.refreshDedupeTtlSeconds, JSON.stringify(response));\n\n this.audit.log(\"TOKEN_REFRESHED\", { userId: decoded.id, sessionId: decoded.sessionId });\n return response;\n } finally {\n await this.config.redis.del(lockKey);\n }\n }\n\n async logout(input: LogoutInput): Promise<void> {\n if (input.accessTokenJti && input.accessToken) {\n const expiry = this.tokenManager.getAccessTokenExpiry();\n const ttlSeconds = TokenManager.parseExpiry(expiry) / 1000;\n await this.tokenRevocation.revokeAccessToken(input.accessTokenJti, ttlSeconds);\n }\n\n if (input.logoutAll && input.userId) {\n await this.tokenRevocation.revokeAllRefreshTokens(input.userId);\n if (input.sessionId) {\n await this.config.redis.setex(\n `${this.config.keyPrefix}session:revoked:${input.sessionId}`,\n DEFAULTS.revokedSessionTtl,\n \"1\",\n );\n }\n await this.sessionManager.revokeUserSession(input.userId, input.sessionId ?? \"\");\n this.audit.log(\"LOGOUT_ALL_DEVICES\", { userId: input.userId });\n } else if (input.userId && input.sessionId) {\n await this.sessionManager.revokeUserSession(input.userId, input.sessionId);\n this.audit.log(\"LOGOUT\", { userId: input.userId, sessionId: input.sessionId });\n }\n }\n\n async getActiveSessions(userId: string) {\n return this.sessionManager.getUserActiveSessions(userId);\n }\n\n async revokeSession(userId: string, sessionId: string): Promise<void> {\n await this.sessionManager.revokeUserSession(userId, sessionId);\n await this.tokenRevocation.markSessionRevoked(sessionId);\n this.audit.log(\"SESSION_REVOKED\", { userId, sessionId });\n }\n\n generateTwoFactor(): TwoFactorSetupResult {\n const secret = this.totpManager.generateSecret();\n const uri = this.totpManager.createUri(secret, \"\");\n return { secret, uri };\n }\n\n createTwoFactorUri(secret: string, email: string): string {\n return this.totpManager.createUri(secret, email);\n }\n\n async verifyTwoFactor(input: TwoFactorVerifyInput): Promise<boolean> {\n return this.totpManager.verify(input.token, input.secret);\n }\n\n async recordLoginFailure(email: string): Promise<{ locked: boolean; unlocksAt?: Date; attempts: number }> {\n return this.accountLockout.recordFailedAttempt(email);\n }\n\n async clearLoginFailures(email: string): Promise<void> {\n return this.accountLockout.clearFailedAttempts(email);\n }\n\n async isAccountLocked(email: string): Promise<{ locked: boolean; unlocksAt?: Date }> {\n return this.accountLockout.isAccountLocked(email);\n }\n\n log(event: AuditEventType, data: Record<string, unknown>): void {\n this.audit.log(event, data);\n }\n}\n","import jwt from \"jsonwebtoken\";\nimport crypto from \"crypto\";\nimport type { TokenPair, TokenPayload, TokenConfig } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class TokenManager {\n private readonly privateKey: string;\n private readonly publicKey: string;\n private readonly issuer: string;\n private readonly audience: string;\n private readonly accessTokenExpiry: string;\n private readonly refreshTokenExpiry: string;\n private readonly sseTokenExpiry: string;\n private readonly currentVersion: number;\n\n constructor(config: TokenConfig) {\n this.privateKey = config.privateKey;\n this.publicKey = config.publicKey;\n this.issuer = config.issuer ?? DEFAULTS.issuer;\n this.audience = config.audience ?? DEFAULTS.audience;\n this.accessTokenExpiry = config.accessTokenExpiry ?? DEFAULTS.accessTokenExpiry;\n this.refreshTokenExpiry = config.refreshTokenExpiry ?? DEFAULTS.refreshTokenExpiry;\n this.sseTokenExpiry = config.sseTokenExpiry ?? DEFAULTS.sseTokenExpiry;\n this.currentVersion = config.currentVersion ?? DEFAULTS.currentVersion;\n }\n\n createAccessToken(p: { id: string; email: string; role: string; sessionId: string }): string {\n return jwt.sign(\n {\n sub: p.id,\n email: p.email,\n role: p.role,\n type: \"access\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n sessionId: p.sessionId,\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.accessTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n createRefreshToken(p: { id: string; email: string; role: string; sessionId: string }): string {\n return jwt.sign(\n {\n sub: p.id,\n email: p.email,\n role: p.role,\n type: \"refresh\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n sessionId: p.sessionId,\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.refreshTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n createTokenPair(p: { id: string; email: string; role: string; sessionId?: string }): TokenPair {\n const sessionId = p.sessionId || crypto.randomUUID();\n const payload = { ...p, sessionId };\n return {\n accessToken: this.createAccessToken(payload),\n refreshToken: this.createRefreshToken(payload),\n accessTokenExpiry: Date.now() + TokenManager.parseExpiry(this.accessTokenExpiry),\n refreshTokenExpiry: Date.now() + TokenManager.parseExpiry(this.refreshTokenExpiry),\n };\n }\n\n createSseToken(userId: string): string {\n return jwt.sign(\n {\n sub: userId,\n type: \"sse\",\n version: this.currentVersion,\n jti: crypto.randomUUID(),\n },\n this.privateKey,\n {\n algorithm: \"RS256\",\n expiresIn: this.sseTokenExpiry as jwt.SignOptions[\"expiresIn\"],\n issuer: this.issuer,\n audience: this.audience,\n },\n );\n }\n\n verifyToken(token: string, expectedType?: TokenPayload[\"type\"]): TokenPayload {\n const decoded = jwt.verify(token, this.publicKey, {\n algorithms: [\"RS256\"],\n issuer: this.issuer,\n audience: this.audience,\n }) as jwt.JwtPayload;\n\n if (decoded.version !== this.currentVersion) throw new Error(\"Token version mismatch\");\n if (expectedType && decoded.type !== expectedType) throw new Error(`Expected '${expectedType}', got '${decoded.type}'`);\n\n return {\n id: decoded.sub ?? \"\",\n email: decoded.email,\n role: decoded.role,\n type: decoded.type,\n version: decoded.version,\n jti: decoded.jti ?? \"\",\n sessionId: decoded.sessionId,\n };\n }\n\n getPublicKey(): string {\n return this.publicKey;\n }\n\n getAccessTokenExpiry(): string {\n return this.accessTokenExpiry;\n }\n\n getRefreshTokenExpiry(): string {\n return this.refreshTokenExpiry;\n }\n\n getSseTokenExpiry(): string {\n return this.sseTokenExpiry;\n }\n\n getCurrentVersion(): number {\n return this.currentVersion;\n }\n\n getIssuer(): string {\n return this.issuer;\n }\n\n getAudience(): string {\n return this.audience;\n }\n\n static parseExpiry(expiry: string): number {\n const match = expiry.match(/^(\\d+)([smhd])$/);\n if (!match) throw new Error(`Invalid expiry: ${expiry}`);\n const unit = match[2]!;\n const multipliers: Record<string, number> = { s: 1000, m: 60000, h: 3600000, d: 86400000 };\n return parseInt(match[1]!, 10) * multipliers[unit]!;\n }\n\n static extractJti(token: string): string {\n try {\n const payload = JSON.parse(Buffer.from(token.split(\".\")[1]!, \"base64url\").toString(\"utf-8\"));\n return payload.jti ?? \"\";\n } catch {\n return \"\";\n }\n }\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class TokenRevocation {\n constructor(\n private readonly redis: RedisAdapter,\n private readonly prefix: string = DEFAULTS.keyPrefix,\n ) {}\n\n private refreshIndexKey(userId: string): string {\n return `${this.prefix}refresh:index:${userId}`;\n }\n\n private refreshTokenKey(userId: string, jti: string): string {\n return `${this.prefix}refresh:${userId}:${jti}`;\n }\n\n private revokedAccessKey(jti: string): string {\n return `${this.prefix}revoked:access:${jti}`;\n }\n\n private sseKey(jti: string): string {\n return `${this.prefix}sse:${jti}`;\n }\n\n private sessionRevokedKey(sessionId: string): string {\n return `${this.prefix}session:revoked:${sessionId}`;\n }\n\n async revokeAccessToken(jti: string, expiresInSeconds: number): Promise<void> {\n try {\n await this.redis.setex(this.revokedAccessKey(jti), expiresInSeconds, \"1\");\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke access token:\", err);\n }\n }\n\n async isAccessTokenRevoked(jti: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.revokedAccessKey(jti));\n return val === \"1\";\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check revoked access token:\", err);\n return false;\n }\n }\n\n async storeRefreshToken(userId: string, jti: string, expiresInSeconds: number): Promise<void> {\n try {\n const tokenKey = this.refreshTokenKey(userId, jti);\n await this.redis.setex(tokenKey, expiresInSeconds, JSON.stringify({ jti, createdAt: Date.now() }));\n await this.redis.sadd(this.refreshIndexKey(userId), tokenKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to store refresh token:\", err);\n }\n }\n\n async isRefreshTokenValid(userId: string, jti: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.refreshTokenKey(userId, jti));\n return val !== null;\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check refresh token validity:\", err);\n return false;\n }\n }\n\n async revokeRefreshToken(userId: string, jti: string): Promise<void> {\n try {\n const tokenKey = this.refreshTokenKey(userId, jti);\n await this.redis.del(tokenKey);\n await this.redis.srem(this.refreshIndexKey(userId), tokenKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke refresh token:\", err);\n }\n }\n\n async revokeAllRefreshTokens(userId: string): Promise<void> {\n try {\n const idxKey = this.refreshIndexKey(userId);\n let keys = await this.redis.smembers(idxKey);\n\n if (keys.length === 0) {\n let cursor = \"0\";\n const pattern = `${this.prefix}refresh:${userId}:*`;\n do {\n const [nextCursor, found] = await this.redis.scan(cursor, \"MATCH\", pattern, \"COUNT\", \"100\");\n cursor = nextCursor;\n keys.push(...found);\n } while (cursor !== \"0\");\n }\n\n if (keys.length > 0) await this.redis.del(...keys);\n await this.redis.del(idxKey);\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to revoke all refresh tokens:\", err);\n }\n }\n\n async rotateRefreshToken(\n userId: string,\n oldJti: string,\n newJti: string,\n expiresInSeconds: number,\n ): Promise<boolean> {\n const oldKey = this.refreshTokenKey(userId, oldJti);\n const newKey = this.refreshTokenKey(userId, newJti);\n const indexKey = this.refreshIndexKey(userId);\n\n try {\n const result = await this.redis.eval<number>(\n `if redis.call(\"EXISTS\", KEYS[1]) == 1 then\n redis.call(\"DEL\", KEYS[1])\n redis.call(\"SETEX\", KEYS[2], ARGV[1], ARGV[2])\n redis.call(\"SREM\", KEYS[3], KEYS[1])\n redis.call(\"SADD\", KEYS[3], KEYS[2])\n return 1\n else\n return 0\n end`,\n 3,\n oldKey,\n newKey,\n indexKey,\n expiresInSeconds.toString(),\n JSON.stringify({ jti: newJti, createdAt: Date.now() }),\n );\n\n return result === 1;\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async storeSseToken(jti: string, userId: string, ttlSeconds: number): Promise<void> {\n try {\n await this.redis.setex(this.sseKey(jti), ttlSeconds, userId);\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async consumeSseToken(jti: string): Promise<string | null> {\n const key = this.sseKey(jti);\n try {\n const userId = await this.redis.eval<string | null>(\n `local v = redis.call(\"GET\", KEYS[1])\n if v then redis.call(\"DEL\", KEYS[1]) end\n return v`,\n 1,\n key,\n );\n return typeof userId === \"string\" ? userId : null;\n } catch (error: unknown) {\n const err = error as { name?: string };\n if (err?.name === \"MaxRetriesPerRequestError\") {\n throw new Error(\"Redis service temporarily unavailable\");\n }\n throw error;\n }\n }\n\n async markSessionRevoked(sessionId: string): Promise<void> {\n try {\n await this.redis.setex(this.sessionRevokedKey(sessionId), DEFAULTS.revokedSessionTtl, \"1\");\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to mark session revoked:\", err);\n }\n }\n\n async isSessionRevoked(sessionId: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.sessionRevokedKey(sessionId));\n return val === \"1\";\n } catch (err) {\n console.error(\"[TokenRevocation] Failed to check revoked session:\", err);\n return false;\n }\n }\n}\n","import type { RedisAdapter, AuditLogger, SessionMetadata } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class SessionManager {\n private readonly maxConcurrent: number;\n\n constructor(\n private readonly redis: RedisAdapter,\n private readonly tokenRevocation: { markSessionRevoked(id: string): Promise<void> },\n private readonly auditLogger?: AuditLogger,\n prefix: string = DEFAULTS.keyPrefix,\n maxConcurrent?: number,\n ) {\n this.prefix = prefix;\n this.maxConcurrent = maxConcurrent ?? DEFAULTS.maxConcurrentSessions;\n }\n\n private readonly prefix: string;\n\n private sessionKey(userId: string): string {\n return `${this.prefix}user:sessions:${userId}`;\n }\n\n private metadataKey(sessionId: string): string {\n return `${this.prefix}session:metadata:${sessionId}`;\n }\n\n async trackUserSession(userId: string, sessionId: string): Promise<void> {\n try {\n const key = this.sessionKey(userId);\n const members = await this.redis.smembers(key);\n\n if (members.length >= this.maxConcurrent) {\n this.auditLogger?.log(\"MAX_SESSIONS_REACHED\", {\n userId,\n sessionCount: members.length,\n limit: this.maxConcurrent,\n });\n const evictedSession = await this.pickLeastActiveSession(members);\n await this.redis.srem(key, evictedSession);\n await this.redis.del(this.metadataKey(evictedSession));\n await this.tokenRevocation.markSessionRevoked(evictedSession);\n }\n\n await this.redis.sadd(key, sessionId);\n await this.redis.expire(key, DEFAULTS.sessionMetadataTtl);\n } catch (err) {\n console.error(`[SessionManager] Failed to track session for user ${userId}:`, err);\n }\n }\n\n private async pickLeastActiveSession(members: string[]): Promise<string> {\n let leastActive = members[0]!;\n let leastActiveAt = Infinity;\n for (const member of members) {\n let lastActivity = 0;\n try {\n const meta = await this.redis.get(this.metadataKey(member));\n if (meta) lastActivity = JSON.parse(meta).lastActivity ?? 0;\n } catch {\n lastActivity = 0;\n }\n if (lastActivity < leastActiveAt) {\n leastActiveAt = lastActivity;\n leastActive = member;\n }\n }\n return leastActive;\n }\n\n async revokeUserSession(userId: string, sessionId: string): Promise<void> {\n try {\n await this.redis.srem(this.sessionKey(userId), sessionId);\n await this.redis.del(this.metadataKey(sessionId));\n } catch (err) {\n console.error(`[SessionManager] Failed to revoke session for user ${userId}:`, err);\n }\n }\n\n async getUserActiveSessions(userId: string): Promise<\n Array<{\n sessionId: string;\n deviceInfo: string;\n ipAddress?: string;\n lastActivity: string;\n createdAt: string;\n }>\n > {\n try {\n const sessionIds = await this.redis.smembers(this.sessionKey(userId));\n const sessions = [];\n for (const sessionId of sessionIds) {\n const metadata = await this.redis.get(this.metadataKey(sessionId));\n if (metadata) {\n try {\n const parsed: SessionMetadata & { createdAt?: number } = JSON.parse(metadata);\n sessions.push({\n sessionId,\n deviceInfo: parsed.userAgent ?? \"\",\n ipAddress: parsed.ipAddress,\n lastActivity: new Date(parsed.lastActivity).toISOString(),\n createdAt: new Date(parsed.createdAt ?? parsed.lastActivity).toISOString(),\n });\n } catch {\n console.warn(`[SessionManager] Corrupted metadata for session ${sessionId}, skipping`);\n }\n }\n }\n return sessions;\n } catch (err) {\n console.error(`[SessionManager] Failed to get sessions for user ${userId}:`, err);\n return [];\n }\n }\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class AccountLockout {\n private readonly maxFailures: number;\n private readonly lockoutSeconds: number;\n private readonly windowSeconds: number;\n private readonly prefix: string;\n\n constructor(\n private readonly redis: RedisAdapter,\n config?: { maxFailures?: number; lockoutSeconds?: number; windowSeconds?: number; prefix?: string },\n ) {\n this.maxFailures = config?.maxFailures ?? DEFAULTS.lockoutMaxFailures;\n this.lockoutSeconds = config?.lockoutSeconds ?? DEFAULTS.lockoutSeconds;\n this.windowSeconds = config?.windowSeconds ?? DEFAULTS.lockoutWindowSeconds;\n this.prefix = config?.prefix ?? `${DEFAULTS.keyPrefix}lockout`;\n }\n\n async recordFailedAttempt(\n identifier: string,\n ): Promise<{ locked: boolean; unlocksAt?: Date; attempts: number }> {\n try {\n const failKey = `${this.prefix}:failures:${identifier}`;\n const lockKey = `${this.prefix}:locked:${identifier}`;\n\n const existingLock = await this.redis.get(lockKey);\n if (existingLock) {\n return { locked: true, unlocksAt: new Date(Number(existingLock)), attempts: this.maxFailures };\n }\n\n const pipe = this.redis.pipeline();\n pipe.incr(failKey);\n pipe.expire(failKey, this.windowSeconds);\n const results = await pipe.exec();\n const attempts = (results?.[0]?.[1] as number) ?? 1;\n\n if (attempts >= this.maxFailures) {\n const unlocksAt = Date.now() + this.lockoutSeconds * 1000;\n await this.redis.setex(lockKey, this.lockoutSeconds, String(unlocksAt));\n return { locked: true, unlocksAt: new Date(unlocksAt), attempts };\n }\n\n return { locked: false, attempts };\n } catch (err) {\n console.error(\"[AccountLockout] Failed to record failed attempt:\", err);\n return { locked: false, attempts: 0 };\n }\n }\n\n async clearFailedAttempts(identifier: string): Promise<void> {\n try {\n await this.redis.del(`${this.prefix}:failures:${identifier}`, `${this.prefix}:locked:${identifier}`);\n } catch (err) {\n console.error(\"[AccountLockout] Failed to clear failed attempts:\", err);\n }\n }\n\n async isAccountLocked(identifier: string): Promise<{ locked: boolean; unlocksAt?: Date }> {\n try {\n const lockedUntil = await this.redis.get(`${this.prefix}:locked:${identifier}`);\n if (!lockedUntil) return { locked: false };\n return { locked: true, unlocksAt: new Date(Number(lockedUntil)) };\n } catch (err) {\n console.error(\"[AccountLockout] Failed to check account lock status:\", err);\n return { locked: false };\n }\n }\n}\n","import type { AuditEventType, AuditLogger, AuditSeverity } from \"../types.js\";\nimport { AUDIT_SEVERITY } from \"../config.js\";\n\nexport class AuditLog {\n constructor(private readonly logger?: AuditLogger) {}\n\n log(\n event: AuditEventType,\n data: Omit<Record<string, unknown>, \"event\" | \"timestamp\" | \"severity\">,\n ): void {\n const severity: AuditSeverity = AUDIT_SEVERITY[event] ?? \"info\";\n const entry = { event, severity, timestamp: new Date().toISOString(), ...data };\n const output = JSON.stringify(entry);\n\n if (severity === \"critical\") {\n console.error(`[AUDIT:CRITICAL] ${output}`);\n } else if (severity === \"warn\") {\n console.warn(`[AUDIT:WARN] ${output}`);\n } else {\n console.info(`[AUDIT:INFO] ${output}`);\n }\n\n if (this.logger) {\n void this.logger.log(event, data).catch((err) => {\n if (process.env.NODE_ENV !== \"test\") {\n console.error(\"[AuditLog] Failed to persist audit event:\", (err as Error)?.message ?? err);\n }\n });\n }\n }\n}\n","import { generateSecret, generateURI, verify } from \"otplib\";\n\nexport class TotpManager {\n private readonly issuer: string;\n\n constructor(issuer = \"Auth\") {\n this.issuer = issuer;\n }\n\n generateSecret(): string {\n return generateSecret();\n }\n\n createUri(secret: string, email: string): string {\n return generateURI({ issuer: this.issuer, label: email, secret });\n }\n\n async verify(token: string, secret: string): Promise<boolean> {\n try {\n const result = verify({ token, secret });\n const normalized = result as unknown as boolean | { valid: boolean };\n if (typeof normalized === \"boolean\") return normalized;\n return normalized.valid === true;\n } catch {\n return false;\n }\n }\n}\n","// @focura/auth-core — Default error classes\n\nexport class UnauthorizedError extends Error {\n public readonly code: string;\n public readonly statusCode = 401;\n constructor(message = \"Unauthorized\", code = \"UNAUTHORIZED\") {\n super(message);\n this.name = \"UnauthorizedError\";\n this.code = code;\n }\n}\n\nexport class TokenExpiredError extends Error {\n public readonly code = \"TOKEN_EXPIRED\";\n public readonly statusCode = 401;\n constructor(message = \"Token expired\") {\n super(message);\n this.name = \"TokenExpiredError\";\n }\n}\n\nexport class InvalidTokenError extends Error {\n public readonly code: string;\n public readonly statusCode = 401;\n constructor(code = \"INVALID_TOKEN\") {\n super(\"Invalid token\");\n this.name = \"InvalidTokenError\";\n this.code = code;\n }\n}\n\nexport class TokenRevokedError extends Error {\n public readonly code = \"TOKEN_REVOKED\";\n public readonly statusCode = 401;\n constructor(message = \"Token has been revoked\") {\n super(message);\n this.name = \"TokenRevokedError\";\n }\n}\n\nexport class EmailNotVerifiedError extends Error {\n public readonly code = \"EMAIL_NOT_VERIFIED\";\n public readonly statusCode = 403;\n constructor(message = \"Email not verified\") {\n super(message);\n this.name = \"EmailNotVerifiedError\";\n }\n}\n\nexport class AccountBannedError extends Error {\n public readonly code = \"ACCOUNT_BANNED\";\n public readonly statusCode = 403;\n public readonly bannedAt?: Date;\n constructor(reason?: string | null, bannedAt?: Date | null) {\n super(reason ?? \"Account has been banned\");\n this.name = \"AccountBannedError\";\n this.bannedAt = bannedAt ?? undefined;\n }\n}\n\nexport class ForbiddenError extends Error {\n public readonly code = \"FORBIDDEN\";\n public readonly statusCode = 403;\n constructor(message = \"Forbidden\") {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class SessionHijackError extends Error {\n public readonly code = \"SESSION_HIJACK_DETECTED\";\n public readonly statusCode = 401;\n constructor(reason?: string) {\n super(reason ?? \"Session hijack detected\");\n this.name = \"SessionHijackError\";\n }\n}\n\nexport class BadRequestError extends Error {\n public readonly code: string;\n public readonly statusCode = 400;\n constructor(message = \"Bad request\", code = \"BAD_REQUEST\") {\n super(message);\n this.name = \"BadRequestError\";\n this.code = code;\n }\n}\n\nexport class ValidationError extends Error {\n public readonly code: string;\n public readonly statusCode = 400;\n public readonly details?: unknown[];\n constructor(message = \"Validation failed\", details?: unknown[], code = \"VALIDATION_ERROR\") {\n super(message);\n this.name = \"ValidationError\";\n this.code = code;\n this.details = details;\n }\n}\n\nimport type { ErrorFactory } from \"../types.js\";\n\nexport const defaultErrors: ErrorFactory = {\n UnauthorizedError: (msg, code) => new UnauthorizedError(msg, code),\n TokenExpiredError: () => new TokenExpiredError(),\n InvalidTokenError: (code) => new InvalidTokenError(code),\n TokenRevokedError: () => new TokenRevokedError(),\n EmailNotVerifiedError: () => new EmailNotVerifiedError(),\n AccountBannedError: (reason, at) => new AccountBannedError(reason, at),\n ForbiddenError: (msg) => new ForbiddenError(msg),\n SessionHijackError: (reason) => new SessionHijackError(reason),\n BadRequestError: (msg, code) => new BadRequestError(msg, code),\n ValidationError: (msg, details, code) => new ValidationError(msg, details, code),\n};\n","import crypto from \"crypto\";\nimport type { SessionMetadata } from \"../types.js\";\n\nconst SERVER_TO_SERVER_UA =\n /^(node|undici|axios|curl|go-http-client|python-requests|java\\/|okhttp|superagent)/i;\n\nexport function looksLikeServerToServerUA(userAgent: string): boolean {\n return !userAgent || SERVER_TO_SERVER_UA.test(userAgent);\n}\n\nexport function looksLikeServerToServerRequest(req: {\n headers: Record<string, string | string[] | undefined>;\n}): boolean {\n const ua = (req.headers[\"user-agent\"] as string | undefined) ?? \"\";\n if (looksLikeServerToServerUA(ua)) return true;\n return !req.headers[\"accept-language\"] && !req.headers[\"accept-encoding\"];\n}\n\nexport function normalizeUserAgent(userAgent: string): string {\n const ua = userAgent || \"\";\n const mobile = /Mobile|Android|iPhone|iPad|iPod/i.test(ua);\n const browser = /Edg\\//i.test(ua)\n ? \"Edge\"\n : /OPR\\/|Opera/i.test(ua)\n ? \"Opera\"\n : /Firefox\\/|FxiOS/i.test(ua)\n ? \"Firefox\"\n : /CriOS\\/|Chrome\\//i.test(ua)\n ? \"Chrome\"\n : /Safari\\//i.test(ua)\n ? \"Safari\"\n : \"Other\";\n const os = /Android/i.test(ua)\n ? \"Android\"\n : /iPhone|iPad|iPod/i.test(ua)\n ? \"iOS\"\n : /Windows/i.test(ua)\n ? \"Windows\"\n : /Macintosh|Mac OS X/i.test(ua)\n ? \"macOS\"\n : /Linux/i.test(ua)\n ? \"Linux\"\n : \"Other\";\n return `${browser}|${os}|${mobile ? \"mobile\" : \"desktop\"}`;\n}\n\nfunction primaryLanguage(acceptLanguage: string): string {\n const first = (acceptLanguage || \"\").split(\",\")[0]?.trim() ?? \"\";\n return first ? first.split(\"-\")[0]!.toLowerCase() : \"\";\n}\n\nexport function generateDeviceFingerprint(req: {\n headers: Record<string, string | string[] | undefined>;\n}): string {\n const components = [\n normalizeUserAgent((req.headers[\"user-agent\"] as string) || \"\"),\n primaryLanguage((req.headers[\"accept-language\"] as string) || \"\"),\n ].join(\"|\");\n\n return crypto.createHash(\"sha256\").update(components).digest(\"hex\").substring(0, 32);\n}\n\nexport function getClientIp(req: {\n ip?: string;\n headers: Record<string, string | string[] | undefined>;\n socket?: { remoteAddress?: string };\n}): string {\n if (typeof req.ip === \"string\" && req.ip.length > 0) {\n return req.ip.startsWith(\"::ffff:\") ? req.ip.slice(7) : req.ip;\n }\n const forwarded = req.headers[\"x-forwarded-for\"];\n if (typeof forwarded === \"string\") return forwarded.split(\",\")[0]!.trim();\n const ip = req.socket?.remoteAddress || \"unknown\";\n return ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n}\n\nexport function createSessionMetadata(req: {\n ip?: string;\n headers: Record<string, string | string[] | undefined>;\n socket?: { remoteAddress?: string };\n}): SessionMetadata {\n return {\n deviceId: null,\n ipAddress: getClientIp(req),\n userAgent: (req.headers[\"user-agent\"] as string) || \"unknown\",\n lastActivity: Date.now(),\n };\n}\n\nexport function isPrivateIp(ip: string): boolean {\n if (!ip || ip === \"unknown\") return true;\n const normalized = ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(normalized)) {\n const [a, b] = normalized.split(\".\").map(Number);\n return (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 172 && b! >= 16 && b! <= 31) ||\n (a === 192 && b === 168) ||\n (a === 169 && b === 254)\n );\n }\n return (\n normalized === \"::1\" ||\n /^fe80:/i.test(normalized) ||\n /^fc/i.test(normalized) ||\n /^fd/i.test(normalized)\n );\n}\n\nexport function validateSessionBinding(\n req: { headers: Record<string, string | string[] | undefined>; ip?: string; socket?: { remoteAddress?: string } },\n storedMetadata: SessionMetadata,\n): { valid: boolean; reason?: string } {\n const currentDeviceId = generateDeviceFingerprint(req);\n const currentIp = getClientIp(req);\n\n if (currentDeviceId !== storedMetadata.deviceId) {\n return { valid: false, reason: \"DEVICE_MISMATCH\" };\n }\n if (currentIp !== storedMetadata.ipAddress) {\n if (isPrivateIp(currentIp) || isPrivateIp(storedMetadata.ipAddress)) {\n return { valid: true };\n }\n const timeSinceLastActivity = Date.now() - storedMetadata.lastActivity;\n const maxIpChangeInterval = 5 * 60 * 1000;\n if (timeSinceLastActivity < maxIpChangeInterval) {\n return { valid: false, reason: \"SUSPICIOUS_IP_CHANGE\" };\n }\n }\n return { valid: true };\n}\n","import type { RedisAdapter } from \"../types.js\";\nimport { DEFAULTS } from \"../config.js\";\n\nexport class RefreshLock {\n constructor(\n private readonly redis: RedisAdapter,\n private readonly prefix: string = DEFAULTS.keyPrefix,\n ) {}\n\n private lockKey(sessionId: string): string {\n return `${this.prefix}refresh:lock:${sessionId}`;\n }\n\n async acquire(sessionId: string): Promise<boolean> {\n try {\n const result = await this.redis.setnx(\n this.lockKey(sessionId),\n \"1\",\n );\n return result === 1;\n } catch (err) {\n console.error(\"[RefreshLock] Failed to acquire lock:\", err);\n return false;\n }\n }\n\n async release(sessionId: string): Promise<void> {\n try {\n await this.redis.del(this.lockKey(sessionId));\n } catch (err) {\n console.error(\"[RefreshLock] Failed to release lock:\", err);\n }\n }\n\n async isLocked(sessionId: string): Promise<boolean> {\n try {\n const val = await this.redis.get(this.lockKey(sessionId));\n return !!val;\n } catch (err) {\n console.error(\"[RefreshLock] Failed to check lock status:\", err);\n return false;\n }\n }\n}\n","// Primary API\nexport { AuthService } from \"./auth/authService.js\";\nexport type {\n ExchangeInput,\n ExchangeResult,\n VerifyTokenInput,\n VerifyTokenResult,\n RefreshInput,\n RefreshResult as AuthRefreshResult,\n LogoutInput,\n TwoFactorSetupResult,\n TwoFactorVerifyInput,\n} from \"./auth/authService.js\";\n\n// Extension API — Adapter interfaces\nexport type {\n RedisAdapter,\n RedisPipeline,\n UserStore,\n User,\n CacheAdapter,\n AuditLogger,\n ObservabilitySink,\n ErrorFactory,\n SessionLifecycle,\n RateLimiterFactory,\n ZodSchema,\n TokenConfig,\n LockoutConfig,\n SessionConfig,\n AuthCoreConfig,\n TokenPayload,\n TokenPair,\n DeviceFingerprint,\n SessionMetadata,\n AuditEventType,\n AuditSeverity,\n} from \"./types.js\";\n\n// Advanced API — Low-level classes\nexport { TokenManager } from \"./tokens/index.js\";\nexport { TokenRevocation } from \"./revocation/index.js\";\nexport { RefreshLock } from \"./refresh/index.js\";\nexport { SessionManager } from \"./session/index.js\";\nexport {\n generateDeviceFingerprint,\n validateSessionBinding,\n createSessionMetadata,\n getClientIp,\n isPrivateIp,\n looksLikeServerToServerRequest,\n looksLikeServerToServerUA,\n normalizeUserAgent,\n} from \"./session/index.js\";\nexport { AccountLockout } from \"./lockout/index.js\";\nexport { AuditLog } from \"./audit/index.js\";\nexport { TotpManager } from \"./totp/index.js\";\nexport { SessionTimeoutManager } from \"./middleware/sessionTimeout.js\";\nexport { MiddlewareFactory } from \"./middleware/middlewareFactory.js\";\nexport type { AuthRequest } from \"./middleware/middlewareFactory.js\";\nexport { exchangeSchema, refreshSchema, logoutSchema } from \"./validation/auth.validation.js\";\nexport {\n UnauthorizedError,\n TokenExpiredError,\n InvalidTokenError,\n TokenRevokedError,\n EmailNotVerifiedError,\n AccountBannedError,\n ForbiddenError,\n SessionHijackError,\n BadRequestError,\n ValidationError,\n defaultErrors,\n} from \"./errors/index.js\";\nexport { DEFAULTS, resolveConfig, AUDIT_SEVERITY } from \"./config.js\";\nexport type { ResolvedConfig } from \"./config.js\";\n","import crypto from \"crypto\";\nimport type {\n RedisAdapter,\n AuthCoreConfig,\n ErrorFactory,\n AuditLogger,\n ObservabilitySink,\n CacheAdapter,\n User,\n SessionMetadata,\n} from \"../types.js\";\nimport { resolveConfig, DEFAULTS, type ResolvedConfig } from \"../config.js\";\nimport { TokenManager } from \"../tokens/backendToken.js\";\nimport { TokenRevocation } from \"../revocation/tokenRevocation.js\";\nimport { defaultErrors } from \"../errors/index.js\";\nimport {\n getClientIp,\n generateDeviceFingerprint,\n isPrivateIp,\n looksLikeServerToServerRequest,\n looksLikeServerToServerUA,\n validateSessionBinding,\n} from \"../session/sessionBinding.js\";\nimport { AuditLog } from \"../audit/auditLog.js\";\n\nexport interface AuthRequest {\n user?: {\n id: string;\n email: string;\n role: string;\n name?: string | null;\n tokenJti?: string;\n sessionId?: string;\n };\n headers: Record<string, string | string[] | undefined>;\n ip?: string;\n socket?: { remoteAddress?: string };\n body?: Record<string, unknown>;\n params?: Record<string, unknown>;\n query?: Record<string, unknown>;\n path?: string;\n method?: string;\n originalUrl?: string;\n [key: string]: unknown;\n}\n\ninterface JwtPayload {\n sub: string;\n email: string;\n role: string;\n jti: string;\n version: number;\n type: string;\n sessionId?: string;\n}\n\nexport class MiddlewareFactory {\n private readonly config: ResolvedConfig;\n private readonly tokenManager: TokenManager;\n private readonly tokenRevocation: TokenRevocation;\n private readonly errors: ErrorFactory;\n private readonly audit: AuditLog;\n private readonly observability?: ObservabilitySink;\n private readonly cache?: CacheAdapter;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private sessionTimeoutManager: any = null;\n\n constructor(rawConfig: AuthCoreConfig) {\n this.config = resolveConfig(rawConfig);\n this.tokenManager = new TokenManager(rawConfig.jwt);\n this.tokenRevocation = new TokenRevocation(rawConfig.redis, this.config.keyPrefix);\n this.errors = rawConfig.errors ?? defaultErrors;\n this.audit = new AuditLog(rawConfig.auditLogger);\n this.observability = rawConfig.observability;\n this.cache = rawConfig.cache;\n }\n\n getTokenManager(): TokenManager {\n return this.tokenManager;\n }\n\n getTokenRevocation(): TokenRevocation {\n return this.tokenRevocation;\n }\n\n getAuditLog(): AuditLog {\n return this.audit;\n }\n\n getRedis(): RedisAdapter {\n return this.config.redis;\n }\n\n getConfig(): ResolvedConfig {\n return this.config;\n }\n\n async enforceSessionBinding(\n req: AuthRequest,\n decoded: JwtPayload,\n ): Promise<Error | null> {\n if (!decoded.sessionId) return null;\n\n const redis = this.config.redis;\n const metadataKey = `${this.config.keyPrefix}session:metadata:${decoded.sessionId}`;\n const storedMetadata = await redis.get(metadataKey);\n if (!storedMetadata) return null;\n\n let metadata: SessionMetadata;\n try {\n metadata = JSON.parse(storedMetadata);\n } catch {\n return null;\n }\n if (looksLikeServerToServerRequest(req)) return null;\n\n if (metadata.deviceId == null || looksLikeServerToServerUA(metadata.userAgent)) {\n metadata.deviceId = generateDeviceFingerprint(req);\n metadata.ipAddress = getClientIp(req);\n metadata.userAgent = (req.headers[\"user-agent\"] as string) || \"unknown\";\n metadata.lastActivity = Date.now();\n this.audit.log(\"SESSION_BOUND\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n ip: metadata.ipAddress,\n userAgent: metadata.userAgent,\n });\n } else {\n const bindingValidation = validateSessionBinding(req, metadata);\n const currentIp = getClientIp(req);\n\n if (!bindingValidation.valid) {\n const isSameIpDeviceChange =\n bindingValidation.reason === \"DEVICE_MISMATCH\" &&\n (currentIp === metadata.ipAddress ||\n isPrivateIp(currentIp) ||\n isPrivateIp(metadata.ipAddress));\n\n if (isSameIpDeviceChange) {\n metadata.deviceId = generateDeviceFingerprint(req);\n metadata.userAgent = (req.headers[\"user-agent\"] as string) || \"unknown\";\n this.audit.log(\"SESSION_REBOUND\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n ip: currentIp,\n userAgent: metadata.userAgent,\n });\n } else {\n await this.tokenRevocation.revokeAllRefreshTokens(decoded.sub);\n if (decoded.jti && this.cache) {\n await this.cache.delete(`auth:result:${decoded.jti}`);\n }\n this.audit.log(\"SESSION_HIJACK_DETECTED\", {\n userId: decoded.sub,\n sessionId: decoded.sessionId,\n reason: bindingValidation.reason,\n ip: currentIp,\n userAgent: req.headers[\"user-agent\"],\n });\n return this.errors.SessionHijackError(bindingValidation.reason);\n }\n }\n }\n\n metadata.lastActivity = Date.now();\n await redis.setex(metadataKey, this.config.sessionMetadataTtl, JSON.stringify(metadata));\n return null;\n }\n\n createAuthenticateMiddleware() {\n const self = this;\n return async function authenticate(req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) {\n try {\n const authHeader = req.headers.authorization;\n if (typeof authHeader !== \"string\" || !authHeader.startsWith(\"Bearer \")) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NO_TOKEN\"));\n }\n\n const token = authHeader.slice(7).trim();\n if (!token) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NO_TOKEN\"));\n }\n\n let decoded: JwtPayload;\n try {\n decoded = self.tokenManager.verifyToken(token) as unknown as JwtPayload;\n } catch (err: unknown) {\n if ((err as { name?: string }).name === \"TokenExpiredError\") {\n return next(self.errors.TokenExpiredError());\n }\n return next(self.errors.InvalidTokenError());\n }\n\n if (decoded.jti && self.cache) {\n const cacheKey = `auth:result:${decoded.jti}`;\n const cachedResult = await self.cache.get<{ userId: string; valid: boolean }>(cacheKey);\n\n if (cachedResult) {\n if (!cachedResult.valid) return next(self.errors.InvalidTokenError(\"INVALID_TOKEN_CACHED\"));\n const bindingError = await self.enforceSessionBinding(req, decoded);\n if (bindingError) return next(bindingError);\n\n const user = await self.loadUser(decoded.sub);\n if (!user) return next(self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\"));\n if (!user.emailVerified) return next(self.errors.EmailNotVerifiedError());\n if (user.bannedAt) return next(self.errors.AccountBannedError(user.banReason, user.bannedAt));\n\n self.assignUser(req, user, decoded);\n return next();\n }\n }\n\n if (decoded.version !== self.config.currentVersion) {\n return next(self.errors.InvalidTokenError(\"TOKEN_VERSION_MISMATCH\"));\n }\n if (decoded.type !== \"access\") {\n return next(self.errors.InvalidTokenError(\"INVALID_TOKEN_TYPE\"));\n }\n\n const [isRevoked, sessionWasRevoked] = await Promise.all([\n decoded.jti ? self.tokenRevocation.isAccessTokenRevoked(decoded.jti) : Promise.resolve(false),\n decoded.sessionId ? self.tokenRevocation.isSessionRevoked(decoded.sessionId) : Promise.resolve(false),\n ]);\n if (isRevoked) return next(self.errors.TokenRevokedError());\n if (sessionWasRevoked) return next(self.errors.TokenRevokedError());\n\n const [bindingError, cachedUser] = await Promise.all([\n self.enforceSessionBinding(req, decoded),\n self.cache?.get<User>(`auth:user:${decoded.sub}`),\n ]);\n if (bindingError) return next(bindingError);\n\n const user = cachedUser ?? (await self.loadUser(decoded.sub));\n if (!user) return next(self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\"));\n if (!user.emailVerified) return next(self.errors.EmailNotVerifiedError());\n if (user.bannedAt) return next(self.errors.AccountBannedError(user.banReason, user.bannedAt));\n\n if (!cachedUser && user && self.cache) {\n void self.cache.set(`auth:user:${decoded.sub}`, user, 30 * 60).catch(() => {});\n }\n\n if (decoded.jti && self.cache) {\n void self.cache.set(`auth:result:${decoded.jti}`, { userId: decoded.sub, valid: true }, 5 * 60).catch(() => {});\n }\n\n self.assignUser(req, user, decoded);\n self.observability?.setUserContext?.({ id: user.id, email: user.email });\n self.observability?.addBreadcrumb?.({\n message: \"User authenticated successfully\",\n data: { userId: user.id, email: user.email, role: user.role },\n });\n\n next();\n } catch (err) {\n console.error(\"Unexpected authentication error:\", err);\n self.observability?.captureException?.(err as Error, { context: \"authentication\" });\n next(err as Error);\n }\n };\n }\n\n createAuthorizeMiddleware(...roles: string[]) {\n const self = this;\n return function authorize(req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) {\n if (!req.user) {\n return next(self.errors.UnauthorizedError(\"Authentication required\", \"NOT_AUTHENTICATED\"));\n }\n if (!roles.includes(req.user.role)) {\n return next(self.errors.ForbiddenError(\"Insufficient permissions\"));\n }\n next();\n };\n }\n\n createCsrfMiddleware() {\n const self = this;\n const CSRF_TOKEN_LENGTH = 32;\n const CSRF_TOKEN_TTL = 3600;\n\n return {\n generateToken: async (userId: string, sessionId: string): Promise<string> => {\n const token = crypto.randomBytes(CSRF_TOKEN_LENGTH).toString(\"base64url\");\n const key = `${self.config.keyPrefix}csrf:${userId}:${sessionId}`;\n await self.config.redis.setex(key, CSRF_TOKEN_TTL, token);\n return token;\n },\n validateToken: async (userId: string, sessionId: string, token: string): Promise<boolean> => {\n if (!token) return false;\n const key = `${self.config.keyPrefix}csrf:${userId}:${sessionId}`;\n const storedToken = await self.config.redis.get(key);\n if (!storedToken) return false;\n try {\n return crypto.timingSafeEqual(Buffer.from(token, \"base64url\"), Buffer.from(storedToken, \"base64url\"));\n } catch {\n return false;\n }\n },\n middleware() {\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown }; end(): unknown }, next: (err?: Error) => void) => {\n if ([\"GET\", \"HEAD\", \"OPTIONS\"].includes(req.method ?? \"\")) return next();\n if (req.path?.startsWith(\"/webhooks/\") || req.path?.includes(\"/callback\")) return next();\n\n const csrfToken = req.headers[\"x-csrf-token\"] as string;\n if (!req.user?.id) {\n return res.status(401).json({ success: false, message: \"Authentication required\", code: \"NOT_AUTHENTICATED\" });\n }\n\n const sessionId = req.user.sessionId || \"default\";\n const stored = await self.config.redis.get(`${self.config.keyPrefix}csrf:${req.user.id}:${sessionId}`);\n if (!stored || !csrfToken) return res.status(403).json({ success: false, message: \"Invalid CSRF token\", code: \"CSRF_VALIDATION_FAILED\" });\n\n let isValid = false;\n try {\n isValid = crypto.timingSafeEqual(Buffer.from(csrfToken, \"base64url\"), Buffer.from(stored, \"base64url\"));\n } catch {\n isValid = false;\n }\n\n if (!isValid) {\n return res.status(403).json({ success: false, message: \"Invalid CSRF token\", code: \"CSRF_VALIDATION_FAILED\" });\n }\n next();\n };\n },\n };\n }\n\n createRateLimitMiddleware() {\n const self = this;\n return (max: number, windowSeconds: number, keyFn?: (req: AuthRequest) => string | undefined, options?: { failOpen?: boolean }) => {\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) => {\n const ip = getClientIp(req);\n const userKey = keyFn?.(req);\n const key = userKey ? `${self.config.keyPrefix}rl:user:${userKey}` : `${self.config.keyPrefix}rl:backend:${ip}`;\n\n try {\n const redis = self.config.redis;\n const countKey = `${key}:count`;\n const count = await redis.incr(countKey);\n if (count === 1) await redis.expire(countKey, windowSeconds);\n\n if (count > max) {\n return res.status(429).json({ success: false, message: \"Too many requests\", code: \"RATE_LIMIT_EXCEEDED\", retryAfter: windowSeconds });\n }\n\n next();\n } catch (error) {\n if (options?.failOpen) return next();\n return res.status(429).json({ success: false, message: \"Rate limit service unavailable\", code: \"RATE_LIMIT_SERVICE_UNAVAILABLE\", retryAfter: windowSeconds });\n }\n };\n };\n }\n\n createSessionTimeoutMiddleware() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }, next: (err?: Error) => void) => {\n const sessionId = req.user?.sessionId;\n if (!sessionId) return next();\n\n if (!self.sessionTimeoutManager) {\n const { SessionTimeoutManager } = await import(\"./sessionTimeout.js\");\n self.sessionTimeoutManager = new SessionTimeoutManager(self.config.redis, {\n inactivityTimeout: self.config.inactivityTimeout,\n absoluteTimeout: self.config.absoluteTimeout,\n prefix: self.config.keyPrefix,\n });\n }\n\n const tracked = await self.sessionTimeoutManager.isTracked(sessionId);\n if (!tracked) return next();\n\n const inactive = await self.sessionTimeoutManager.isInactive(sessionId);\n if (inactive) {\n return res.status(401).json({ success: false, code: \"SESSION_TIMEOUT\", message: \"Session expired\" });\n }\n\n await self.sessionTimeoutManager.updateActivity(sessionId);\n next();\n };\n }\n\n createExchangeHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const ip = getClientIp(req);\n const { userId, email, role, sessionId, timestamp, signature } = req.body as Record<string, string>;\n\n const age = Date.now() - Number(timestamp);\n if (age > 60_000 || age < 0) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Proof expired\" });\n throw self.errors.UnauthorizedError(\"Exchange proof expired\", \"PROOF_EXPIRED\");\n }\n\n const proofPayload = `${userId}${email}${role}${sessionId}${timestamp}`;\n const expected = crypto.createHmac(\"sha256\", self.config.hmacSecret).update(proofPayload).digest(\"hex\");\n\n let valid = false;\n try {\n if (signature) {\n valid = crypto.timingSafeEqual(Buffer.from(signature, \"hex\"), Buffer.from(expected, \"hex\"));\n }\n } catch {\n valid = false;\n }\n\n if (!valid) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Invalid signature\" });\n throw self.errors.UnauthorizedError(\"Invalid exchange proof\", \"INVALID_SIGNATURE\");\n }\n\n const idempotencyKey = `exchange:idempotent:${userId}:${sessionId}:${timestamp}`;\n const existing = await self.config.redis.get(idempotencyKey);\n if (existing) {\n return res.status(200).json(JSON.parse(existing));\n }\n\n const user = await self.config.userStore.findById(userId!);\n if (!user) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"User not found\" });\n throw self.errors.UnauthorizedError(\"User not found\", \"USER_NOT_FOUND\");\n }\n\n if (user.email.toLowerCase() !== email!.toLowerCase()) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Email mismatch\" });\n throw self.errors.UnauthorizedError(\"Email mismatch\", \"EMAIL_MISMATCH\");\n }\n\n if (!user.emailVerified) {\n self.audit.log(\"EXCHANGE_FAILED\", { userId, email, ip, reason: \"Email not verified\" });\n throw self.errors.UnauthorizedError(\"Email not verified\", \"EMAIL_NOT_VERIFIED\");\n }\n\n const sid = sessionId || crypto.randomUUID();\n const tokens = self.tokenManager.createTokenPair({\n id: user.id,\n email: user.email,\n role: user.role,\n sessionId: sid,\n });\n\n const refreshTtlSeconds = self.tokenManager.getRefreshTokenExpiry() === \"7d\"\n ? 7 * 24 * 60 * 60\n : TokenManager.parseExpiry(self.tokenManager.getRefreshTokenExpiry()) / 1000;\n\n await self.tokenRevocation.storeRefreshToken(user.id, TokenManager.extractJti(tokens.refreshToken), refreshTtlSeconds);\n\n const sseToken = self.tokenManager.createSseToken(user.id);\n const sseTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getSseTokenExpiry()) / 1000;\n await self.tokenRevocation.storeSseToken(TokenManager.extractJti(sseToken), user.id, sseTtlSeconds);\n\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:created:${sid}`,\n self.config.absoluteTimeout,\n Date.now().toString(),\n );\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:activity:${sid}`,\n self.config.inactivityTimeout,\n Date.now().toString(),\n );\n\n await self.config.redis.setex(idempotencyKey, 90, JSON.stringify(tokens));\n\n self.audit.log(\"EXCHANGE_SUCCESS\", { userId: user.id, email: user.email, ip });\n return res.status(200).json(tokens);\n };\n }\n\n createRefreshHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const { refreshToken } = req.body as { refreshToken: string };\n if (!refreshToken) throw self.errors.BadRequestError(\"Refresh token required\");\n\n let decoded;\n try {\n decoded = self.tokenManager.verifyToken(refreshToken, \"refresh\");\n } catch {\n throw self.errors.UnauthorizedError(\"Invalid refresh token\", \"INVALID_TOKEN\");\n }\n\n const redis = self.config.redis;\n const lockKey = `${self.config.keyPrefix}refresh:lock:${decoded.sessionId}`;\n const lockResult = await redis.set(lockKey, \"1\", \"EX\", 45, \"NX\");\n\n if (lockResult !== \"OK\") {\n throw self.errors.BadRequestError(\"Refresh already in progress\", \"REFRESH_IN_PROGRESS\");\n }\n\n try {\n const dedupeKey = `${self.config.keyPrefix}refresh:dedupe:${decoded.id}:${decoded.jti}`;\n const cached = await redis.get(dedupeKey);\n if (cached) return res.status(200).json(JSON.parse(cached));\n\n const sessionRevokedKey = `${self.config.keyPrefix}session:revoked:${decoded.sessionId}`;\n if ((await redis.get(sessionRevokedKey)) === \"1\") {\n throw self.errors.UnauthorizedError(\"Session revoked\", \"SESSION_REVOKED\");\n }\n\n const createdKey = `${self.config.keyPrefix}session:created:${decoded.sessionId}`;\n if ((await redis.exists(createdKey)) !== 1) {\n throw self.errors.UnauthorizedError(\"Session expired\", \"SESSION_TIMEOUT\");\n }\n\n const newTokens = self.tokenManager.createTokenPair({\n id: decoded.id,\n email: decoded.email,\n role: decoded.role,\n sessionId: decoded.sessionId,\n });\n\n const refreshTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getRefreshTokenExpiry()) / 1000;\n await self.tokenRevocation.rotateRefreshToken(\n decoded.id,\n decoded.jti,\n TokenManager.extractJti(newTokens.refreshToken),\n refreshTtlSeconds,\n );\n\n const newSseToken = self.tokenManager.createSseToken(decoded.id);\n const sseTtlSeconds = TokenManager.parseExpiry(self.tokenManager.getSseTokenExpiry()) / 1000;\n await self.tokenRevocation.storeSseToken(TokenManager.extractJti(newSseToken), decoded.id, sseTtlSeconds);\n\n const response = { ...newTokens, sseToken: newSseToken };\n await redis.setex(dedupeKey, 30, JSON.stringify(response));\n\n self.audit.log(\"TOKEN_REFRESHED\", { userId: decoded.id, sessionId: decoded.sessionId });\n return res.status(200).json(response);\n } finally {\n await redis.del(lockKey);\n }\n };\n }\n\n createLogoutHandler() {\n const self = this;\n return async (req: AuthRequest, res: { status(code: number): { json(data: unknown): unknown } }) => {\n const { logoutAll } = req.body as { logoutAll?: boolean };\n const userId = req.user?.id;\n const sessionId = req.user?.sessionId;\n\n if (req.user?.tokenJti) {\n const token = (req.headers.authorization as string)?.slice(7);\n if (token) {\n const expiry = self.tokenManager.getAccessTokenExpiry();\n const ttlSeconds = TokenManager.parseExpiry(expiry) / 1000;\n await self.tokenRevocation.revokeAccessToken(req.user.tokenJti, ttlSeconds);\n }\n }\n\n if (logoutAll && userId) {\n await self.tokenRevocation.revokeAllRefreshTokens(userId);\n await self.config.redis.setex(\n `${self.config.keyPrefix}session:revoked:${sessionId}`,\n DEFAULTS.revokedSessionTtl,\n \"1\",\n );\n self.audit.log(\"LOGOUT_ALL_DEVICES\", { userId });\n } else if (userId && sessionId) {\n await self.config.redis.del(`${self.config.keyPrefix}session:metadata:${sessionId}`);\n self.audit.log(\"LOGOUT\", { userId, sessionId });\n }\n\n return res.status(200).json({ success: true, message: \"Logged out\" });\n };\n }\n\n private async loadUser(id: string): Promise<User | null> {\n try {\n return await this.config.userStore.findById(id);\n } catch {\n return null;\n }\n }\n\n private assignUser(req: AuthRequest, user: User, decoded: JwtPayload): void {\n req.user = {\n id: user.id,\n email: user.email,\n name: user.name,\n role: user.role,\n tokenJti: decoded.jti,\n sessionId: decoded.sessionId,\n };\n }\n}\n","import { z } from \"zod\";\n\nexport const exchangeSchema = z.object({\n userId: z.string().uuid(),\n email: z.string().email(),\n role: z.string(),\n sessionId: z.string().uuid(),\n timestamp: z.string().or(z.number()),\n signature: z.string(),\n});\n\nexport const refreshSchema = z.object({\n refreshToken: z.string().min(1),\n});\n\nexport const logoutSchema = z.object({\n logoutAll: z.boolean().optional(),\n});\n"]}
|