say-auth 1.0.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/LICENSE.md +21 -0
- package/README.md +121 -0
- package/dist/index.d.mts +312 -0
- package/dist/index.d.ts +312 -0
- package/dist/index.js +1496 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1446 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/constants.ts","../src/services/token-storage.ts","../src/services/token-manager.ts","../src/services/token-blacklist.ts","../src/services/mfa-service.ts","../src/services/rate-limiter.ts","../src/services/audit-logger.ts","../src/services/device-fingerprint.ts","../src/services/session-manager.ts","../src/services/auth-service.ts","../src/hooks/useAuth.ts","../src/hooks/useProtectedRoute.ts","../src/components/AuthProvider.tsx","../src/components/ProtectedRoute.tsx","../src/components/MFASetup.tsx","../src/components/MFAVerification.tsx","../src/components/SessionWarning.tsx","../src/interceptors/axios-interceptors.ts","../src/utils/helpers.ts"],"names":["CryptoJS","OTPAuth","QRCode","base32","AuditAction","axios","useState","useEffect","useRouter","createContext","authService","jsx","Fragment","jsxs","Shield","Check","Copy","Download","AlertCircle"],"mappings":"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","file":"index.js","sourcesContent":["// src/utils/constants.ts\nexport const AUTH_CONFIG = {\n tokenRefreshThreshold: 5 * 60 * 1000, // 5 minutes\n maxLoginAttempts: 5,\n lockoutDuration: 15 * 60 * 1000, // 15 minutes\n sessionTimeout: 30 * 60 * 1000, // 30 minutes\n mfaCodeLength: 6,\n backupCodesCount: 10,\n trustDeviceDuration: 30 * 24 * 60 * 60 * 1000, // 30 days\n};\n\nexport const STORAGE_KEYS = {\n tokens: 'auth_tokens_encrypted',\n user: 'auth_user_encrypted',\n encryptionKey: 'encryption_key',\n deviceId: 'device_id',\n trustedDevices: 'trusted_devices',\n};\n\nexport const API_ENDPOINTS = {\n login: '/auth/login',\n logout: '/auth/logout',\n register: '/auth/register',\n refresh: '/auth/refresh',\n mfaSetup: '/auth/mfa/setup',\n mfaVerify: '/auth/mfa/verify',\n mfaDisable: '/auth/mfa/disable',\n changePassword: '/auth/change-password',\n audit: '/auth/audit',\n};","// src/services/token-storage.ts\nimport CryptoJS from 'crypto-js';\nimport { STORAGE_KEYS } from '../utils/constants';\nimport { AuthTokens, User } from '../types';\n\nexport class SecureTokenStorage {\n private static instance: SecureTokenStorage;\n private encryptionKey: string;\n private memoryCache: Map<string, any> = new Map();\n private readonly TOKEN_VERSION = '2.0'; // Current version\n private readonly SUPPORTED_VERSIONS = ['1.0', '2.0']; // Backward compatible versions\n\n private constructor() {\n this.encryptionKey = this.getOrCreateEncryptionKey();\n }\n\n static getInstance(): SecureTokenStorage {\n if (!SecureTokenStorage.instance) {\n SecureTokenStorage.instance = new SecureTokenStorage();\n }\n return SecureTokenStorage.instance;\n }\n\n private getOrCreateEncryptionKey(): string {\n if (typeof window === 'undefined') return '';\n \n let key = localStorage.getItem(STORAGE_KEYS.encryptionKey);\n if (!key) {\n key = this.generateEncryptionKey();\n localStorage.setItem(STORAGE_KEYS.encryptionKey, key);\n }\n return key;\n }\n\n private generateEncryptionKey(): string {\n return CryptoJS.lib.WordArray.random(32).toString();\n }\n\n private encrypt(data: any): string {\n return CryptoJS.AES.encrypt(JSON.stringify(data), this.encryptionKey).toString();\n }\n\n private decrypt(encrypted: string): any {\n try {\n const bytes = CryptoJS.AES.decrypt(encrypted, this.encryptionKey);\n return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));\n } catch {\n return null;\n }\n }\n\n // NEW: Set tokens with versioning\n setTokens(tokens: AuthTokens): void {\n const dataWithVersion = {\n version: this.TOKEN_VERSION,\n data: tokens,\n timestamp: Date.now(),\n };\n const encrypted = this.encrypt(dataWithVersion);\n \n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEYS.tokens, encrypted);\n }\n this.memoryCache.set('tokens', tokens);\n }\n\n // NEW: Get tokens with backward compatibility\n getTokens(): AuthTokens | null {\n // Check memory cache first (fastest)\n if (this.memoryCache.has('tokens')) {\n return this.memoryCache.get('tokens');\n }\n \n if (typeof window !== 'undefined') {\n const encrypted = localStorage.getItem(STORAGE_KEYS.tokens);\n if (encrypted) {\n const decrypted = this.decrypt(encrypted);\n \n if (decrypted) {\n // Check if it's the new versioned format\n if (decrypted.version && this.SUPPORTED_VERSIONS.includes(decrypted.version)) {\n // Versioned format - extract data\n const tokens = decrypted.data;\n this.memoryCache.set('tokens', tokens);\n \n // Optional: Migrate old format to new version if needed\n if (decrypted.version !== this.TOKEN_VERSION) {\n this.migrateTokenFormat(tokens);\n }\n \n return tokens;\n } \n // Legacy format (no version) - backward compatibility\n else if (decrypted.accessToken) {\n // Legacy format detected, migrate to new version\n const tokens = decrypted as AuthTokens;\n this.migrateTokenFormat(tokens);\n this.memoryCache.set('tokens', tokens);\n return tokens;\n }\n }\n }\n }\n return null;\n }\n\n // NEW: Migrate legacy tokens to versioned format\n private migrateTokenFormat(tokens: AuthTokens): void {\n try {\n const dataWithVersion = {\n version: this.TOKEN_VERSION,\n data: tokens,\n timestamp: Date.now(),\n };\n const encrypted = this.encrypt(dataWithVersion);\n localStorage.setItem(STORAGE_KEYS.tokens, encrypted);\n console.log('Token format migrated to version', this.TOKEN_VERSION);\n } catch (error) {\n console.error('Token migration failed:', error);\n }\n }\n\n // NEW: Check if token needs refresh based on timestamp\n shouldRefreshToken(): boolean {\n if (typeof window === 'undefined') return false;\n \n const encrypted = localStorage.getItem(STORAGE_KEYS.tokens);\n if (!encrypted) return false;\n \n const decrypted = this.decrypt(encrypted);\n if (!decrypted) return false;\n \n // Check if versioned format exists\n if (decrypted.timestamp) {\n const tokenAge = Date.now() - decrypted.timestamp;\n const REFRESH_THRESHOLD = 5 * 60 * 1000; // 5 minutes before expiry\n \n // Get token expiry from the actual token\n const tokens = decrypted.data || decrypted;\n if (tokens.accessToken) {\n try {\n const payload = JSON.parse(atob(tokens.accessToken.split('.')[1]));\n const expiresIn = payload.exp * 1000 - Date.now();\n return expiresIn < REFRESH_THRESHOLD;\n } catch {\n return false;\n }\n }\n }\n \n return false;\n }\n\n // NEW: Get token age (for debugging)\n getTokenAge(): number | null {\n if (typeof window === 'undefined') return null;\n \n const encrypted = localStorage.getItem(STORAGE_KEYS.tokens);\n if (!encrypted) return null;\n \n const decrypted = this.decrypt(encrypted);\n if (decrypted?.timestamp) {\n return Date.now() - decrypted.timestamp;\n }\n \n return null;\n }\n\n setUser(user: User): void {\n const dataWithVersion = {\n version: this.TOKEN_VERSION,\n data: user,\n timestamp: Date.now(),\n };\n const encrypted = this.encrypt(dataWithVersion);\n \n if (typeof window !== 'undefined') {\n localStorage.setItem(STORAGE_KEYS.user, encrypted);\n }\n this.memoryCache.set('user', user);\n }\n\n getUser(): User | null {\n if (this.memoryCache.has('user')) {\n return this.memoryCache.get('user');\n }\n \n if (typeof window !== 'undefined') {\n const encrypted = localStorage.getItem(STORAGE_KEYS.user);\n if (encrypted) {\n const decrypted = this.decrypt(encrypted);\n \n if (decrypted) {\n // Check if it's versioned format\n if (decrypted.version && this.SUPPORTED_VERSIONS.includes(decrypted.version)) {\n const user = decrypted.data;\n this.memoryCache.set('user', user);\n return user;\n }\n // Legacy format\n else if (decrypted.id) {\n this.memoryCache.set('user', decrypted);\n return decrypted;\n }\n }\n }\n }\n return null;\n }\n\n clear(): void {\n this.memoryCache.clear();\n if (typeof window !== 'undefined') {\n localStorage.removeItem(STORAGE_KEYS.tokens);\n localStorage.removeItem(STORAGE_KEYS.user);\n // Note: Don't remove encryption key to preserve it for future sessions\n }\n }\n\n // NEW: Clear everything including encryption key (use with caution)\n hardClear(): void {\n this.memoryCache.clear();\n if (typeof window !== 'undefined') {\n localStorage.removeItem(STORAGE_KEYS.tokens);\n localStorage.removeItem(STORAGE_KEYS.user);\n localStorage.removeItem(STORAGE_KEYS.encryptionKey);\n localStorage.removeItem(STORAGE_KEYS.deviceId);\n localStorage.removeItem(STORAGE_KEYS.trustedDevices);\n }\n }\n\n // NEW: Get storage info (for debugging)\n getStorageInfo(): { hasTokens: boolean; hasUser: boolean; tokenVersion: string | null } {\n let tokenVersion = null;\n \n if (typeof window !== 'undefined') {\n const encrypted = localStorage.getItem(STORAGE_KEYS.tokens);\n if (encrypted) {\n const decrypted = this.decrypt(encrypted);\n if (decrypted?.version) {\n tokenVersion = decrypted.version;\n }\n }\n }\n \n return {\n hasTokens: !!this.getTokens(),\n hasUser: !!this.getUser(),\n tokenVersion,\n };\n }\n}","import { AuthTokens } from \"../types\";\nimport { SecureTokenStorage } from \"./token-storage\";\n\n// src/services/token-manager.ts\nexport class TokenManager {\n private static instance: TokenManager;\n private refreshPromise: Promise<string> | null = null;\n\n static getInstance(): TokenManager {\n if (!TokenManager.instance) {\n TokenManager.instance = new TokenManager();\n }\n return TokenManager.instance;\n }\n\n getAccessToken(): string | null {\n const tokens = SecureTokenStorage.getInstance().getTokens();\n return tokens?.accessToken || null;\n }\n\n isTokenExpired(): boolean {\n const tokens = SecureTokenStorage.getInstance().getTokens();\n if (!tokens) return true;\n \n try {\n const payload = JSON.parse(atob(tokens.accessToken.split('.')[1]));\n return payload.exp * 1000 < Date.now();\n } catch {\n return true;\n }\n }\n\n async refreshToken(refreshFn: () => Promise<AuthTokens>): Promise<string> {\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.refreshPromise = this.performRefresh(refreshFn);\n return this.refreshPromise;\n }\n\n private async performRefresh(refreshFn: () => Promise<AuthTokens>): Promise<string> {\n try {\n const tokens = await refreshFn();\n SecureTokenStorage.getInstance().setTokens(tokens);\n return tokens.accessToken;\n } finally {\n this.refreshPromise = null;\n }\n }\n}","// src/services/token-blacklist.ts\n\nimport { TokenBlacklistEntry } from \"../types\";\n\nexport class TokenBlacklist {\n private static instance: TokenBlacklist;\n private blacklist: Map<string, TokenBlacklistEntry> = new Map();\n private cleanupInterval: NodeJS.Timeout | null = null;\n\n private constructor() {\n this.startCleanup();\n }\n\n static getInstance(): TokenBlacklist {\n if (!TokenBlacklist.instance) {\n TokenBlacklist.instance = new TokenBlacklist();\n }\n return TokenBlacklist.instance;\n }\n\n async addToBlacklist(token: string, userId: string, reason: TokenBlacklistEntry['reason']): Promise<void> {\n try {\n const payload = JSON.parse(atob(token.split('.')[1]));\n const expiresAt = new Date(payload.exp * 1000);\n \n const entry: TokenBlacklistEntry = {\n token,\n userId,\n expiresAt,\n reason,\n };\n \n this.blacklist.set(this.hashToken(token), entry);\n await this.syncToBackend(entry);\n } catch (error) {\n console.error('Failed to blacklist token:', error);\n }\n }\n\n async isBlacklisted(token: string): Promise<boolean> {\n const hashedToken = this.hashToken(token);\n const entry = this.blacklist.get(hashedToken);\n \n if (!entry) return false;\n \n if (entry.expiresAt < new Date()) {\n this.blacklist.delete(hashedToken);\n return false;\n }\n \n return true;\n }\n\n async revokeAllUserTokens(userId: string): Promise<void> {\n for (const [key, entry] of this.blacklist.entries()) {\n if (entry.userId === userId) {\n this.blacklist.delete(key);\n }\n }\n await this.revokeAllOnBackend(userId);\n }\n\n private hashToken(token: string): string {\n let hash = 0;\n for (let i = 0; i < token.length; i++) {\n const char = token.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return hash.toString();\n }\n\n private async syncToBackend(entry: TokenBlacklistEntry): Promise<void> {\n try {\n await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/blacklist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(entry),\n });\n } catch (error) {\n console.error('Failed to sync blacklist to backend');\n }\n }\n\n private async revokeAllOnBackend(userId: string): Promise<void> {\n try {\n await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/revoke-all/${userId}`, {\n method: 'POST',\n });\n } catch (error) {\n console.error('Failed to revoke tokens on backend');\n }\n }\n\n private startCleanup(): void {\n this.cleanupInterval = setInterval(() => {\n const now = new Date();\n for (const [key, entry] of this.blacklist.entries()) {\n if (entry.expiresAt < now) {\n this.blacklist.delete(key);\n }\n }\n }, 60 * 60 * 1000);\n }\n\n stopCleanup(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n }\n}","// src/services/mfa-service.ts\nimport * as OTPAuth from 'otpauth';\nimport QRCode from 'qrcode';\nimport { base32 } from 'rfc4648';\n\nexport class MFAService {\n private static instance: MFAService;\n\n static getInstance(): MFAService {\n if (!MFAService.instance) {\n MFAService.instance = new MFAService();\n }\n return MFAService.instance;\n }\n\n async setupMFA(userId: string, email: string): Promise<{ secret: string; qrCode: string; backupCodes: string[] }> {\n const secret = new OTPAuth.Secret({ size: 20 });\n const secretBase32 = secret.base32;\n \n const totp = new OTPAuth.TOTP({\n issuer: 'YourApp',\n label: email,\n algorithm: 'SHA1',\n digits: 6,\n period: 30,\n secret: secret,\n });\n \n const otpUri = totp.toString();\n const qrCode = await QRCode.toDataURL(otpUri);\n const backupCodes = this.generateBackupCodes();\n \n sessionStorage.setItem(`mfa_setup_${userId}`, secretBase32);\n sessionStorage.setItem(`mfa_backup_${userId}`, JSON.stringify(backupCodes));\n \n return { secret: secretBase32, qrCode, backupCodes };\n }\n\n async verifyAndEnableMFA(userId: string, code: string): Promise<boolean> {\n const storedSecret = sessionStorage.getItem(`mfa_setup_${userId}`);\n if (!storedSecret) return false;\n \n try {\n // rfc4648 uses 'parse' not 'decode'\n const secretBuffer = base32.parse(storedSecret);\n const secret = new OTPAuth.Secret({ buffer: secretBuffer.buffer });\n \n const totp = new OTPAuth.TOTP({\n issuer: 'YourApp',\n label: userId,\n algorithm: 'SHA1',\n digits: 6,\n period: 30,\n secret: secret,\n });\n \n const isValid = totp.validate({ token: code, window: 1 }) !== null;\n \n if (isValid) {\n const backupCodes = JSON.parse(sessionStorage.getItem(`mfa_backup_${userId}`) || '[]');\n await this.saveMFAConfig(userId, storedSecret, backupCodes);\n sessionStorage.removeItem(`mfa_setup_${userId}`);\n sessionStorage.removeItem(`mfa_backup_${userId}`);\n }\n \n return isValid;\n } catch (error) {\n console.error('MFA verification failed:', error);\n return false;\n }\n }\n\n async verifyMFA(userId: string, code: string): Promise<boolean> {\n const mfaSecret = await this.getUserMFASecret(userId);\n if (!mfaSecret) return false;\n \n try {\n // rfc4648 uses 'parse' not 'decode'\n const secretBuffer = base32.parse(mfaSecret);\n const secret = new OTPAuth.Secret({ buffer: secretBuffer.buffer });\n \n const totp = new OTPAuth.TOTP({\n issuer: 'YourApp',\n label: userId,\n algorithm: 'SHA1',\n digits: 6,\n period: 30,\n secret: secret,\n });\n \n return totp.validate({ token: code, window: 1 }) !== null;\n } catch (error) {\n console.error('MFA verification failed:', error);\n return false;\n }\n }\n\n private generateBackupCodes(): string[] {\n const codes: string[] = [];\n for (let i = 0; i < 10; i++) {\n const code = Math.random().toString(36).substring(2, 10).toUpperCase();\n codes.push(code);\n }\n return codes;\n }\n\n private async saveMFAConfig(userId: string, secret: string, backupCodes: string[]): Promise<void> {\n try {\n await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/mfa/enable`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ userId, secret, backupCodes }),\n });\n } catch (error) {\n console.error('Failed to save MFA config:', error);\n throw error;\n }\n }\n\n private async getUserMFASecret(userId: string): Promise<string | null> {\n try {\n const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/mfa/secret/${userId}`);\n if (!response.ok) return null;\n const data = await response.json();\n return data.secret || null;\n } catch (error) {\n console.error('Failed to get user MFA secret:', error);\n return null;\n }\n }\n}","// src/services/rate-limiter.ts\nexport class RateLimiter {\n private static instance: RateLimiter;\n private attempts: Map<string, { count: number; firstAttempt: number; blockedUntil: number }> = new Map();\n private readonly MAX_ATTEMPTS = 5;\n private readonly WINDOW_MS = 15 * 60 * 1000;\n private readonly BLOCK_DURATION_MS = 30 * 60 * 1000;\n\n static getInstance(): RateLimiter {\n if (!RateLimiter.instance) {\n RateLimiter.instance = new RateLimiter();\n }\n return RateLimiter.instance;\n }\n\n checkRateLimit(identifier: string): { allowed: boolean; waitTime?: number } {\n const now = Date.now();\n const record = this.attempts.get(identifier);\n\n if (record && record.blockedUntil > now) {\n return { \n allowed: false, \n waitTime: Math.ceil((record.blockedUntil - now) / 1000) \n };\n }\n\n if (record && (now - record.firstAttempt) > this.WINDOW_MS) {\n this.attempts.delete(identifier);\n return { allowed: true };\n }\n\n if (!record) {\n this.attempts.set(identifier, { count: 1, firstAttempt: now, blockedUntil: 0 });\n return { allowed: true };\n }\n\n record.count++;\n \n if (record.count >= this.MAX_ATTEMPTS) {\n record.blockedUntil = now + this.BLOCK_DURATION_MS;\n this.attempts.set(identifier, record);\n return { \n allowed: false, \n waitTime: Math.ceil(this.BLOCK_DURATION_MS / 1000) \n };\n }\n\n this.attempts.set(identifier, record);\n return { allowed: true };\n }\n\n reset(identifier: string): void {\n this.attempts.delete(identifier);\n }\n}","// src/services/audit-logger.ts\nexport enum AuditAction {\n LOGIN_SUCCESS = 'LOGIN_SUCCESS',\n LOGIN_FAILURE = 'LOGIN_FAILURE',\n LOGOUT = 'LOGOUT',\n REGISTER_SUCCESS = 'REGISTER_SUCCESS',\n PASSWORD_CHANGE = 'PASSWORD_CHANGE',\n TOKEN_REFRESH = 'TOKEN_REFRESH',\n SESSION_TERMINATED = 'SESSION_TERMINATED',\n MFA_ENABLED = 'MFA_ENABLED',\n MFA_DISABLED = 'MFA_DISABLED',\n MFA_VERIFIED = 'MFA_VERIFIED',\n}\n\nexport interface AuditEntry {\n action: AuditAction;\n userId?: string;\n email?: string;\n ipAddress: string;\n userAgent: string;\n timestamp: Date;\n details?: Record<string, any>;\n success: boolean;\n errorMessage?: string;\n}\n\nexport class AuditLogger {\n private static instance: AuditLogger;\n private logQueue: AuditEntry[] = [];\n private isFlushing = false;\n\n static getInstance(): AuditLogger {\n if (!AuditLogger.instance) {\n AuditLogger.instance = new AuditLogger();\n }\n return AuditLogger.instance;\n }\n\n async log(entry: Omit<AuditEntry, 'timestamp' | 'ipAddress' | 'userAgent'>): Promise<void> {\n const fullEntry: AuditEntry = {\n ...entry,\n timestamp: new Date(),\n ipAddress: await this.getClientIP(),\n userAgent: navigator.userAgent,\n };\n \n this.logQueue.push(fullEntry);\n this.scheduleFlush();\n }\n\n private scheduleFlush(): void {\n if (this.isFlushing) return;\n setTimeout(() => this.flush(), 5000);\n }\n\n private async flush(): Promise<void> {\n if (this.logQueue.length === 0) return;\n \n this.isFlushing = true;\n const entries = [...this.logQueue];\n this.logQueue = [];\n \n try {\n await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/audit`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ entries }),\n keepalive: true,\n });\n } catch (error) {\n this.logQueue.unshift(...entries);\n } finally {\n this.isFlushing = false;\n if (this.logQueue.length > 0) {\n this.scheduleFlush();\n }\n }\n }\n\n private async getClientIP(): Promise<string> {\n try {\n const response = await fetch('https://api.ipify.org?format=json');\n const data = await response.json();\n return data.ip;\n } catch {\n return 'unknown';\n }\n }\n}","// src/services/device-fingerprint.ts\nexport class DeviceFingerprint {\n static async generate(): Promise<string> {\n const components = {\n userAgent: navigator.userAgent,\n language: navigator.language,\n platform: navigator.platform,\n screenResolution: `${screen.width}x${screen.height}`,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n hardwareConcurrency: navigator.hardwareConcurrency,\n deviceMemory: (navigator as any).deviceMemory,\n colorDepth: screen.colorDepth,\n };\n \n const fingerprint = await this.hashObject(components);\n return fingerprint;\n }\n\n private static async hashObject(obj: any): Promise<string> {\n const str = JSON.stringify(obj);\n const encoder = new TextEncoder();\n const data = encoder.encode(str);\n const hash = await crypto.subtle.digest('SHA-256', data);\n return Array.from(new Uint8Array(hash))\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n}","// src/services/session-manager.ts\nimport { DeviceFingerprint } from './device-fingerprint';\n\nexport class SessionManager {\n private static instance: SessionManager;\n private activeSessions: Map<string, { deviceId: string; lastActive: Date }> = new Map();\n\n static getInstance(): SessionManager {\n if (!SessionManager.instance) {\n SessionManager.instance = new SessionManager();\n }\n return SessionManager.instance;\n }\n\n async registerSession(userId: string): Promise<string> {\n const deviceId = await DeviceFingerprint.generate();\n this.activeSessions.set(userId, { deviceId, lastActive: new Date() });\n return deviceId;\n }\n\n async validateSession(userId: string, deviceId: string): Promise<boolean> {\n const session = this.activeSessions.get(userId);\n if (!session) return false;\n \n session.lastActive = new Date();\n this.activeSessions.set(userId, session);\n \n return session.deviceId === deviceId;\n }\n\n async terminateSession(userId: string): Promise<void> {\n this.activeSessions.delete(userId);\n }\n\n async terminateAllOtherSessions(userId: string, currentDeviceId: string): Promise<void> {\n const session = this.activeSessions.get(userId);\n if (session && session.deviceId !== currentDeviceId) {\n this.activeSessions.delete(userId);\n }\n }\n\n getActiveSessionsCount(userId: string): number {\n let count = 0;\n for (const [key] of this.activeSessions.entries()) {\n if (key === userId) count++;\n }\n return count;\n }\n}","// src/services/auth-service.ts\nimport axios, { AxiosInstance } from 'axios';\nimport { SecureTokenStorage } from './token-storage';\nimport { TokenManager } from './token-manager';\nimport { TokenBlacklist } from './token-blacklist';\nimport { MFAService } from './mfa-service';\nimport { RateLimiter } from './rate-limiter';\nimport { AuditLogger, AuditAction } from './audit-logger';\nimport { SessionManager } from './session-manager';\nimport { DeviceFingerprint } from './device-fingerprint';\nimport { AuthState, LoginCredentials, RegisterData, User } from '../types';\nimport { API_ENDPOINTS } from '../utils/constants';\n\nexport class AuthService {\n private static instance: AuthService;\n private axiosInstance: AxiosInstance;\n private state: AuthState = {\n user: null,\n tokens: null,\n isAuthenticated: false,\n isLoading: true,\n error: null,\n };\n private listeners: ((state: AuthState) => void)[] = [];\n private baseURL: string;\n\n private constructor(apiUrl?: string) {\n this.baseURL = apiUrl || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001/api';\n this.axiosInstance = axios.create({ \n baseURL: this.baseURL, \n withCredentials: true,\n timeout: 30000,\n });\n this.loadInitialState();\n }\n\n static getInstance(apiUrl?: string): AuthService {\n if (!AuthService.instance) {\n AuthService.instance = new AuthService(apiUrl);\n }\n return AuthService.instance;\n }\n\n // ============ NEW: Retry Logic & Health Check ============\n \n private async makeRequest<T>(\n method: string,\n url: string,\n data?: any,\n retries = 3\n ): Promise<T> {\n let lastError: Error | null = null;\n \n for (let i = 0; i < retries; i++) {\n try {\n const response = await this.axiosInstance.request({ \n method, \n url, \n data,\n // Exponential backoff\n timeout: 30000 * (i + 1),\n });\n return response.data;\n } catch (error: any) {\n lastError = error;\n \n // Don't retry on 4xx errors (client errors)\n if (error.response?.status >= 400 && error.response?.status < 500) {\n throw error;\n }\n \n // Last retry - throw error\n if (i === retries - 1) {\n throw error;\n }\n \n // Wait with exponential backoff before retry\n const delay = 1000 * Math.pow(2, i);\n console.warn(`Request failed, retrying in ${delay}ms... (Attempt ${i + 2}/${retries})`);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n \n throw lastError || new Error('Request failed after multiple retries');\n }\n\n async healthCheck(): Promise<boolean> {\n try {\n const response = await this.axiosInstance.get('/health', { timeout: 5000 });\n return response.status === 200;\n } catch (error) {\n console.error('Health check failed:', error);\n return false;\n }\n }\n\n async healthCheckWithRetry(retries = 2): Promise<boolean> {\n for (let i = 0; i < retries; i++) {\n const isHealthy = await this.healthCheck();\n if (isHealthy) return true;\n if (i < retries - 1) {\n await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));\n }\n }\n return false;\n }\n\n // ============ END NEW METHODS ============\n\n private async loadInitialState(): Promise<void> {\n const tokens = SecureTokenStorage.getInstance().getTokens();\n const user = SecureTokenStorage.getInstance().getUser();\n \n this.state = {\n user,\n tokens,\n isAuthenticated: !!tokens && !TokenManager.getInstance().isTokenExpired(),\n isLoading: false,\n error: null,\n };\n \n this.notifyListeners();\n }\n\n private notifyListeners(): void {\n this.listeners.forEach(listener => listener({ ...this.state }));\n }\n\n subscribe(listener: (state: AuthState) => void): () => void {\n this.listeners.push(listener);\n listener({ ...this.state });\n return () => {\n this.listeners = this.listeners.filter(l => l !== listener);\n };\n }\n\n private updateState(updates: Partial<AuthState>): void {\n this.state = { ...this.state, ...updates };\n this.notifyListeners();\n }\n\n async login(credentials: LoginCredentials): Promise<{ requiresMFA: boolean; user?: User }> {\n this.updateState({ isLoading: true, error: null });\n \n const rateLimit = RateLimiter.getInstance().checkRateLimit(credentials.email);\n if (!rateLimit.allowed) {\n await AuditLogger.getInstance().log({\n action: AuditAction.LOGIN_FAILURE,\n email: credentials.email,\n details: { reason: 'Rate limit exceeded' },\n success: false,\n });\n this.updateState({ isLoading: false, error: `Too many attempts. Try again later.` });\n throw new Error(`Too many attempts. Try again later.`);\n }\n\n try {\n // Use the retry logic for login request\n const response:any = await this.makeRequest('POST', API_ENDPOINTS.login, credentials);\n const { user, requiresMFA, accessToken, refreshToken, expiresIn } = response;\n \n if (requiresMFA) {\n sessionStorage.setItem('temp_auth_email', credentials.email);\n sessionStorage.setItem('temp_auth_user_id', user.id);\n this.updateState({ isLoading: false });\n return { requiresMFA: true };\n }\n \n const deviceId = await SessionManager.getInstance().registerSession(user.id);\n const tokens = { accessToken, refreshToken, expiresIn };\n SecureTokenStorage.getInstance().setTokens(tokens);\n SecureTokenStorage.getInstance().setUser(user);\n \n await AuditLogger.getInstance().log({\n action: AuditAction.LOGIN_SUCCESS,\n userId: user.id,\n email: user.email,\n details: { deviceId },\n success: true,\n });\n \n RateLimiter.getInstance().reset(credentials.email);\n \n this.updateState({\n user,\n tokens,\n isAuthenticated: true,\n isLoading: false,\n error: null,\n });\n \n return { requiresMFA: false, user };\n } catch (error: any) {\n await AuditLogger.getInstance().log({\n action: AuditAction.LOGIN_FAILURE,\n email: credentials.email,\n success: false,\n errorMessage: error.message,\n });\n \n this.updateState({\n isLoading: false,\n error: error.response?.data?.message || error.message || 'Login failed',\n });\n throw error;\n }\n }\n\n async verifyMFA(code: string, trustDevice: boolean = false): Promise<User> {\n const email = sessionStorage.getItem('temp_auth_email');\n const userId = sessionStorage.getItem('temp_auth_user_id');\n \n if (!email || !userId) {\n throw new Error('No pending MFA verification');\n }\n \n const isValid = await MFAService.getInstance().verifyMFA(userId, code);\n if (!isValid) {\n throw new Error('Invalid MFA code');\n }\n \n // Use retry logic for MFA verification\n const response:any = await this.makeRequest('POST', API_ENDPOINTS.mfaVerify, {\n email,\n userId,\n trustDevice,\n });\n \n const { user, accessToken, refreshToken, expiresIn } = response;\n const tokens = { accessToken, refreshToken, expiresIn };\n SecureTokenStorage.getInstance().setTokens(tokens);\n SecureTokenStorage.getInstance().setUser(user);\n \n sessionStorage.removeItem('temp_auth_email');\n sessionStorage.removeItem('temp_auth_user_id');\n \n this.updateState({\n user,\n tokens,\n isAuthenticated: true,\n isLoading: false,\n error: null,\n });\n \n return user;\n }\n\n async register(data: RegisterData): Promise<User> {\n this.updateState({ isLoading: true, error: null });\n \n try {\n // Use retry logic for registration\n const response:any = await this.makeRequest('POST', API_ENDPOINTS.register, data);\n const { user, accessToken, refreshToken, expiresIn } = response;\n \n const tokens = { accessToken, refreshToken, expiresIn };\n SecureTokenStorage.getInstance().setTokens(tokens);\n SecureTokenStorage.getInstance().setUser(user);\n \n await AuditLogger.getInstance().log({\n action: AuditAction.REGISTER_SUCCESS,\n userId: user.id,\n email: user.email,\n success: true,\n });\n \n this.updateState({\n user,\n tokens,\n isAuthenticated: true,\n isLoading: false,\n error: null,\n });\n \n return user;\n } catch (error: any) {\n this.updateState({\n isLoading: false,\n error: error.response?.data?.message || error.message || 'Registration failed',\n });\n throw error;\n }\n }\n\n async logout(reason: 'logout' | 'revoke' | 'security' = 'logout'): Promise<void> {\n const user = SecureTokenStorage.getInstance().getUser();\n const tokens = SecureTokenStorage.getInstance().getTokens();\n \n if (tokens?.accessToken) {\n await TokenBlacklist.getInstance().addToBlacklist(\n tokens.accessToken,\n user?.id || '',\n reason\n );\n }\n \n try {\n await this.axiosInstance.post(API_ENDPOINTS.logout);\n } catch (error) {\n // Ignore logout errors - still clear local state\n console.warn('Logout API call failed, but clearing local state');\n }\n \n SecureTokenStorage.getInstance().clear();\n \n this.updateState({\n user: null,\n tokens: null,\n isAuthenticated: false,\n isLoading: false,\n error: null,\n });\n \n // Only redirect if in browser environment\n if (typeof window !== 'undefined') {\n window.location.href = '/login';\n }\n }\n\n async refreshSession(): Promise<void> {\n try {\n const tokens = SecureTokenStorage.getInstance().getTokens();\n if (!tokens?.refreshToken) throw new Error('No refresh token');\n \n // Use retry logic for refresh\n const response:any = await this.makeRequest('POST', API_ENDPOINTS.refresh, {\n refreshToken: tokens.refreshToken,\n });\n \n const { accessToken, refreshToken, expiresIn } = response;\n SecureTokenStorage.getInstance().setTokens({ accessToken, refreshToken, expiresIn });\n \n this.updateState({\n tokens: { accessToken, refreshToken, expiresIn },\n isAuthenticated: true,\n });\n } catch (error) {\n console.error('Session refresh failed:', error);\n this.logout('security');\n }\n }\n\n async logoutAllDevices(): Promise<void> {\n const user = SecureTokenStorage.getInstance().getUser();\n if (!user) return;\n \n try {\n await TokenBlacklist.getInstance().revokeAllUserTokens(user.id);\n await this.axiosInstance.post('/auth/logout-all');\n } catch (error) {\n console.warn('Logout all devices API call failed');\n }\n \n this.logout('revoke');\n }\n\n async changePassword(currentPassword: string, newPassword: string): Promise<void> {\n const user = SecureTokenStorage.getInstance().getUser();\n \n try {\n await this.makeRequest('POST', API_ENDPOINTS.changePassword, {\n currentPassword,\n newPassword,\n });\n \n await AuditLogger.getInstance().log({\n action: AuditAction.PASSWORD_CHANGE,\n userId: user?.id,\n email: user?.email,\n success: true,\n });\n } catch (error: any) {\n await AuditLogger.getInstance().log({\n action: AuditAction.PASSWORD_CHANGE,\n userId: user?.id,\n email: user?.email,\n success: false,\n errorMessage: error.message,\n });\n throw error;\n }\n }\n\n hasRole(role: string | string[]): boolean {\n if (!this.state.user) return false;\n const roles = Array.isArray(role) ? role : [role];\n return roles.includes(this.state.user.role || '');\n }\n\n getAxiosInstance(): AxiosInstance {\n return this.axiosInstance;\n }\n\n getUser(): User | null {\n return this.state.user;\n }\n\n getState(): AuthState {\n return { ...this.state };\n }\n}","// src/hooks/useAuth.ts\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { AuthState, LoginCredentials, RegisterData } from '../types';\nimport { AuthService } from '../services/auth-service';\n\nexport function useAuth(apiUrl?: string) {\n const [state, setState] = useState<AuthState>(AuthService.getInstance(apiUrl).getState());\n\n useEffect(() => {\n const unsubscribe = AuthService.getInstance(apiUrl).subscribe(setState);\n return unsubscribe;\n }, [apiUrl]);\n\n const login = async (credentials: LoginCredentials) => {\n return AuthService.getInstance(apiUrl).login(credentials);\n };\n\n const verifyMFA = async (code: string, trustDevice: boolean = false) => {\n return AuthService.getInstance(apiUrl).verifyMFA(code, trustDevice);\n };\n\n const register = async (data: RegisterData) => {\n return AuthService.getInstance(apiUrl).register(data);\n };\n\n const logout = async () => {\n return AuthService.getInstance(apiUrl).logout();\n };\n\n const refreshSession = async () => {\n return AuthService.getInstance(apiUrl).refreshSession();\n };\n\n const hasRole = (role: string | string[]) => {\n return AuthService.getInstance(apiUrl).hasRole(role);\n };\n\n return {\n ...state,\n login,\n verifyMFA,\n register,\n logout,\n refreshSession,\n hasRole,\n };\n}","// src/hooks/useProtectedRoute.ts\n'use client';\n\nimport { useEffect } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { useAuth } from './useAuth';\n\nexport function useProtectedRoute(redirectTo = '/login', requiredRole?: string | string[]) {\n const { isAuthenticated, isLoading, hasRole } = useAuth();\n const router = useRouter();\n\n useEffect(() => {\n if (!isLoading && !isAuthenticated) {\n router.push(redirectTo);\n }\n \n if (!isLoading && isAuthenticated && requiredRole && !hasRole(requiredRole)) {\n router.push('/unauthorized');\n }\n }, [isAuthenticated, isLoading, router, redirectTo, requiredRole, hasRole]);\n\n return { isAuthenticated, isLoading };\n}","// src/components/AuthProvider.tsx\n'use client';\n\nimport React, { createContext, useContext, useEffect, useState } from 'react';\nimport { AuthService } from '../services/auth-service';\nimport { AuthState, LoginCredentials, RegisterData, User } from '../types';\n\ninterface AuthContextValue extends AuthState {\nlogin: (credentials: LoginCredentials) => Promise<{ requiresMFA: boolean; user?: User }>;\n register: (data: RegisterData) => Promise<User>;\n logout: () => Promise<void>;\n refreshSession: () => Promise<void>;\n hasRole: (role: string | string[]) => boolean;\n getAxiosInstance: () => any;\n getUser: () => User | null;\n verifyMFA: (code: string, trustDevice?: boolean) => Promise<User>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\ninterface AuthProviderProps {\n children: React.ReactNode;\n apiUrl?: string;\n}\n\nexport function AuthProvider({ children, apiUrl }: AuthProviderProps) {\n const [state, setState] = useState<AuthState>({\n user: null,\n tokens: null,\n isAuthenticated: false,\n isLoading: true,\n error: null,\n });\n\n useEffect(() => {\n const authService = AuthService.getInstance(apiUrl);\n const unsubscribe = authService.subscribe(setState);\n return unsubscribe;\n }, [apiUrl]);\n\n const authService = AuthService.getInstance(apiUrl);\n\n const value: AuthContextValue = {\n ...state,\n login: (credentials) => authService.login(credentials),\n register: (data) => authService.register(data),\n logout: () => authService.logout(),\n refreshSession: () => authService.refreshSession(),\n verifyMFA: (code, trustDevice) => authService.verifyMFA(code, trustDevice),\n hasRole: (role) => authService.hasRole(role),\n getAxiosInstance: () => authService.getAxiosInstance(),\n getUser: () => authService.getUser(),\n };\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport const useAuthContext = () => {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error('useAuthContext must be used within AuthProvider');\n }\n return context;\n};","// src/components/ProtectedRoute.tsx\n'use client';\n\nimport { useProtectedRoute } from \"../hooks/useProtectedRoute\";\n\n\ninterface ProtectedRouteProps {\n children: React.ReactNode;\n requiredRole?: string | string[];\n fallback?: React.ReactNode;\n}\n\nexport function ProtectedRoute({ children, requiredRole, fallback }: ProtectedRouteProps) {\n const { isAuthenticated, isLoading } = useProtectedRoute('/login', requiredRole);\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600\"></div>\n </div>\n );\n }\n\n if (!isAuthenticated) {\n return null;\n }\n\n return <>{children}</>;\n}","// src/components/MFASetup.tsx\n'use client';\n\nimport { useState } from 'react';\nimport { MFAService } from '../services/mfa-service';\nimport { Shield, Copy, Check, Download } from 'lucide-react';\n\ninterface MFASetupProps {\n userId: string;\n email: string;\n onComplete: () => void;\n onCancel: () => void;\n}\n\nexport function MFASetup({ userId, email, onComplete, onCancel }: MFASetupProps) {\n const [step, setStep] = useState<'setup' | 'verify'>('setup');\n const [qrCode, setQrCode] = useState('');\n const [backupCodes, setBackupCodes] = useState<string[]>([]);\n const [verificationCode, setVerificationCode] = useState('');\n const [error, setError] = useState('');\n const [copied, setCopied] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n\n const handleSetup = async () => {\n setIsLoading(true);\n try {\n const result = await MFAService.getInstance().setupMFA(userId, email);\n setQrCode(result.qrCode);\n setBackupCodes(result.backupCodes);\n setStep('verify');\n } catch (err) {\n setError('Failed to setup MFA');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleVerify = async () => {\n if (!verificationCode) {\n setError('Please enter verification code');\n return;\n }\n \n setIsLoading(true);\n try {\n const isValid = await MFAService.getInstance().verifyAndEnableMFA(userId, verificationCode);\n if (isValid) {\n onComplete();\n } else {\n setError('Invalid verification code');\n }\n } catch (err) {\n setError('Verification failed');\n } finally {\n setIsLoading(false);\n }\n };\n\n const copyBackupCodes = () => {\n navigator.clipboard.writeText(backupCodes.join('\\n'));\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n if (step === 'setup') {\n return (\n <div className=\"max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-lg border shadow-xl\">\n <div className=\"text-center mb-6\">\n <div className=\"inline-flex p-3 rounded-full bg-blue-100 dark:bg-blue-900/30 mb-4\">\n <Shield className=\"h-6 w-6 text-blue-600\" />\n </div>\n <h2 className=\"text-xl font-semibold\">Set Up Two-Factor Authentication</h2>\n <p className=\"text-sm text-gray-500 mt-2\">Enhance your account security with 2FA</p>\n </div>\n \n <div className=\"space-y-4\">\n <div className=\"p-4 bg-blue-50 dark:bg-blue-950 rounded-lg\">\n <p className=\"text-sm text-blue-700 dark:text-blue-300\">\n Two-factor authentication adds an extra layer of security to your account.\n You'll need to enter a verification code from your authenticator app when signing in.\n </p>\n </div>\n \n <button\n onClick={handleSetup}\n disabled={isLoading}\n className=\"w-full py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors disabled:opacity-50\"\n >\n {isLoading ? 'Setting up...' : 'Get Started'}\n </button>\n \n <button\n onClick={onCancel}\n className=\"w-full py-2 border rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors\"\n >\n Cancel\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-lg border shadow-xl\">\n <div className=\"text-center mb-6\">\n <h2 className=\"text-xl font-semibold\">Scan QR Code</h2>\n <p className=\"text-sm text-gray-500 mt-2\">Scan this QR code with your authenticator app</p>\n </div>\n \n {qrCode && (\n <div className=\"flex justify-center mb-6\">\n <img src={qrCode} alt=\"QR Code\" className=\"w-48 h-48\" />\n </div>\n )}\n \n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">Backup Codes</label>\n <div className=\"bg-gray-50 dark:bg-gray-800 rounded-lg p-3\">\n <div className=\"grid grid-cols-2 gap-1 font-mono text-xs\">\n {backupCodes.map((code, idx) => (\n <div key={idx}>{code}</div>\n ))}\n </div>\n <div className=\"flex gap-2 mt-3\">\n <button\n onClick={copyBackupCodes}\n className=\"flex-1 py-1.5 text-sm border rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors flex items-center justify-center gap-1\"\n >\n {copied ? <Check className=\"h-3 w-3\" /> : <Copy className=\"h-3 w-3\" />}\n {copied ? 'Copied!' : 'Copy Codes'}\n </button>\n <button\n onClick={() => {\n const blob = new Blob([backupCodes.join('\\n')], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'backup-codes.txt';\n a.click();\n URL.revokeObjectURL(url);\n }}\n className=\"flex-1 py-1.5 text-sm border rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors flex items-center justify-center gap-1\"\n >\n <Download className=\"h-3 w-3\" />\n Download\n </button>\n </div>\n </div>\n <p className=\"text-xs text-gray-500 mt-2\">\n Save these backup codes in a secure place. You can use them to access your account if you lose your device.\n </p>\n </div>\n \n <div>\n <label className=\"block text-sm font-medium mb-2\">Verification Code</label>\n <input\n type=\"text\"\n value={verificationCode}\n onChange={(e) => setVerificationCode(e.target.value)}\n placeholder=\"Enter 6-digit code\"\n className=\"w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent\"\n maxLength={6}\n />\n </div>\n \n {error && (\n <div className=\"p-3 bg-red-50 dark:bg-red-950/50 border border-red-200 rounded-lg text-sm text-red-600\">\n {error}\n </div>\n )}\n \n <button\n onClick={handleVerify}\n disabled={isLoading}\n className=\"w-full py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors disabled:opacity-50\"\n >\n {isLoading ? 'Verifying...' : 'Verify and Enable'}\n </button>\n </div>\n </div>\n );\n}","// src/components/MFAVerification.tsx\n'use client';\n\nimport { useState } from 'react';\nimport { Shield, AlertCircle } from 'lucide-react';\n\ninterface MFAVerificationProps {\n onSubmit: (code: string, trustDevice: boolean) => Promise<void>;\n onBack?: () => void;\n}\n\nexport function MFAVerification({ onSubmit, onBack }: MFAVerificationProps) {\n const [code, setCode] = useState('');\n const [trustDevice, setTrustDevice] = useState(false);\n const [error, setError] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (code.length !== 6) {\n setError('Please enter a valid 6-digit code');\n return;\n }\n \n setIsLoading(true);\n try {\n await onSubmit(code, trustDevice);\n } catch (err: any) {\n setError(err.message || 'Invalid verification code');\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-lg border shadow-xl\">\n <div className=\"text-center mb-6\">\n <div className=\"inline-flex p-3 rounded-full bg-blue-100 dark:bg-blue-900/30 mb-4\">\n <Shield className=\"h-6 w-6 text-blue-600\" />\n </div>\n <h2 className=\"text-xl font-semibold\">Two-Factor Authentication</h2>\n <p className=\"text-sm text-gray-500 mt-2\">Enter the verification code from your authenticator app</p>\n </div>\n \n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium mb-2\">Verification Code</label>\n <input\n type=\"text\"\n value={code}\n onChange={(e) => setCode(e.target.value.replace(/\\D/g, '').slice(0, 6))}\n placeholder=\"000000\"\n className=\"w-full text-center text-2xl tracking-widest font-mono px-3 py-3 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent\"\n maxLength={6}\n autoFocus\n />\n </div>\n \n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={trustDevice}\n onChange={(e) => setTrustDevice(e.target.checked)}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500\"\n />\n <span className=\"text-sm text-gray-600 dark:text-gray-400\">Trust this device for 30 days</span>\n </label>\n \n {error && (\n <div className=\"p-3 bg-red-50 dark:bg-red-950/50 border border-red-200 rounded-lg flex items-start gap-2\">\n <AlertCircle className=\"h-4 w-4 text-red-600 mt-0.5\" />\n <p className=\"text-sm text-red-600\">{error}</p>\n </div>\n )}\n \n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"w-full py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors disabled:opacity-50\"\n >\n {isLoading ? 'Verifying...' : 'Verify & Continue'}\n </button>\n \n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n className=\"w-full py-2 border rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors\"\n >\n Back to Login\n </button>\n )}\n </form>\n </div>\n );\n}","// src/components/SessionWarning.tsx\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useAuth } from '../hooks/useAuth';\n\nexport function SessionWarning({ warningMinutes = 2 }: { warningMinutes?: number }) {\n const { refreshSession } = useAuth();\n const [showWarning, setShowWarning] = useState(false);\n const [timeLeft, setTimeLeft] = useState(0);\n\n useEffect(() => {\n const checkSession = () => {\n const tokens = localStorage.getItem('auth_tokens_encrypted');\n if (!tokens) return;\n \n try {\n const payload = JSON.parse(atob(tokens.split('.')[1]));\n const expiresIn = payload.exp * 1000 - Date.now();\n const minutesLeft = Math.floor(expiresIn / 1000 / 60);\n \n if (minutesLeft <= warningMinutes && minutesLeft > 0) {\n setShowWarning(true);\n setTimeLeft(minutesLeft);\n } else if (minutesLeft <= 0) {\n setShowWarning(false);\n } else {\n setShowWarning(false);\n }\n } catch {\n // Invalid token\n }\n };\n\n checkSession();\n const interval = setInterval(checkSession, 60000);\n return () => clearInterval(interval);\n }, [warningMinutes]);\n\n const handleRefresh = async () => {\n await refreshSession();\n setShowWarning(false);\n };\n\n if (!showWarning) return null;\n\n return (\n <div className=\"fixed bottom-4 right-4 z-50 animate-in slide-in-from-right-5\">\n <div className=\"bg-yellow-50 dark:bg-yellow-950 border border-yellow-200 dark:border-yellow-800 rounded-lg shadow-lg p-4 max-w-sm\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-yellow-800 dark:text-yellow-200\">Session Expiring Soon</h3>\n <p className=\"text-sm text-yellow-700 dark:text-yellow-300 mt-1\">\n Your session will expire in {timeLeft} minute{timeLeft !== 1 ? 's' : ''}.\n Click \"Stay Logged In\" to extend your session.\n </p>\n <div className=\"flex gap-2 mt-3\">\n <button\n onClick={handleRefresh}\n className=\"px-3 py-1 text-sm bg-yellow-600 text-white rounded hover:bg-yellow-700 transition-colors\"\n >\n Stay Logged In\n </button>\n <button\n onClick={() => setShowWarning(false)}\n className=\"px-3 py-1 text-sm border border-yellow-300 rounded hover:bg-yellow-100 dark:hover:bg-yellow-900 transition-colors\"\n >\n Dismiss\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}","// src/interceptors/axios-interceptors.ts\nimport axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosError } from 'axios';\nimport { TokenManager } from '../services/token-manager';\nimport { TokenBlacklist } from '../services/token-blacklist';\nimport { SecureTokenStorage } from '../services/token-storage';\nimport { API_ENDPOINTS } from '../utils/constants';\n\nexport function setupAuthInterceptors(axiosInstance: AxiosInstance, baseURL: string): void {\n // Request interceptor\n axiosInstance.interceptors.request.use(\n async (config) => {\n const token = TokenManager.getInstance().getAccessToken();\n \n if (token) {\n const isBlacklisted = await TokenBlacklist.getInstance().isBlacklisted(token);\n if (isBlacklisted) {\n SecureTokenStorage.getInstance().clear();\n window.location.href = '/login';\n return Promise.reject(new Error('Token revoked'));\n }\n \n if (!TokenManager.getInstance().isTokenExpired()) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n }\n return config;\n },\n (error) => Promise.reject(error)\n );\n\n // Response interceptor\n let isRefreshing = false;\n let failedQueue: Array<{\n resolve: (value: any) => void;\n reject: (reason?: any) => void;\n config: InternalAxiosRequestConfig;\n }> = [];\n\n const processQueue = (error: any | null, token: string | null = null) => {\n failedQueue.forEach(prom => {\n if (error) {\n prom.reject(error);\n } else {\n if (prom.config.headers) {\n prom.config.headers.Authorization = `Bearer ${token}`;\n }\n axiosInstance(prom.config).then(prom.resolve).catch(prom.reject);\n }\n });\n failedQueue = [];\n };\n\n axiosInstance.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };\n \n if (error.response?.status === 401 && !originalRequest._retry) {\n if (isRefreshing) {\n return new Promise((resolve, reject) => {\n failedQueue.push({ resolve, reject, config: originalRequest });\n });\n }\n\n originalRequest._retry = true;\n isRefreshing = true;\n\n try {\n const refreshToken = SecureTokenStorage.getInstance().getTokens()?.refreshToken;\n if (!refreshToken) throw new Error('No refresh token');\n \n const response = await axios.post(`${baseURL}${API_ENDPOINTS.refresh}`, { refreshToken });\n const { accessToken, refreshToken: newRefreshToken } = response.data;\n \n SecureTokenStorage.getInstance().setTokens({\n accessToken,\n refreshToken: newRefreshToken,\n expiresIn: 900,\n });\n\n processQueue(null, accessToken);\n \n if (originalRequest.headers) {\n originalRequest.headers.Authorization = `Bearer ${accessToken}`;\n }\n return axiosInstance(originalRequest);\n } catch (refreshError) {\n processQueue(refreshError);\n SecureTokenStorage.getInstance().clear();\n window.location.href = '/login';\n return Promise.reject(refreshError);\n } finally {\n isRefreshing = false;\n }\n }\n \n return Promise.reject(error);\n }\n );\n}","// src/utils/helpers.ts\nexport function cn(...classes: (string | undefined | false)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n\nexport function getErrorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n if (typeof error === 'string') return error;\n return 'An unexpected error occurred';\n}\n\nexport function isValidEmail(email: string): boolean {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n\nexport function formatDate(date: Date): string {\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n }).format(date);\n}\n\nexport function generateRandomString(length: number): string {\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * characters.length));\n }\n return result;\n}"]}
|