@revealui/security 0.0.1-pre.1 → 0.2.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/SecurityValidation.ts","../src/RateLimiterService.ts","../src/RateLimitingService.ts","../src/CSRFService.ts","../src/EncryptionService.ts","../src/SecurityMonitoringService.ts","../src/SecurityService.ts","../src/SessionService.ts","../src/TokenService.ts"],"sourcesContent":["/**\r\n * Centralized Security Validation Utilities\r\n *\r\n * Provides consistent security validation across all server actions\r\n */\r\n\r\nimport { z } from 'zod';\r\n\r\n// Environment validation schema\r\nconst EnvironmentSchema = z.object({\r\n PAYLOAD_SECRET: z.string().min(32, 'PAYLOAD_SECRET must be at least 32 characters'),\r\n MCP_ENCRYPTION_KEY: z.string().min(64, 'MCP_ENCRYPTION_KEY must be at least 64 characters'),\r\n TURSO_URL: z.string().url().optional(),\r\n TURSO_AUTH_TOKEN: z.string().optional(),\r\n SUPPORT_EMAIL: z.string().email().optional(),\r\n});\r\n\r\n// Rate limiting configuration\r\nexport interface RateLimitConfig {\r\n windowMs: number;\r\n maxRequests: number;\r\n keyGenerator?: (input: unknown) => string;\r\n}\r\n\r\n// Default rate limiting configurations\r\nexport const RATE_LIMITS = {\r\n CHAT: { windowMs: 60 * 1000, maxRequests: 10 }, // 10 requests per minute\r\n CONTENT: { windowMs: 60 * 1000, maxRequests: 5 }, // 5 requests per minute\r\n CONTACT: { windowMs: 15 * 60 * 1000, maxRequests: 3 }, // 3 requests per 15 minutes\r\n RECOMMENDATIONS: { windowMs: 60 * 1000, maxRequests: 20 }, // 20 requests per minute\r\n} as const;\r\n\r\n// Rate limiting store (in production, use Redis or similar)\r\nconst rateLimitStore = new Map<string, { count: number; resetTime: number }>();\r\n\r\n/**\r\n * Validate environment variables\r\n */\r\nexport async function validateEnvironment(): Promise<void> {\r\n const validation = EnvironmentSchema.safeParse(process.env);\r\n\r\n if (!validation.success) {\r\n const errors = validation.error.issues\r\n .map(issue => `${issue.path.join('.')}: ${issue.message}`)\r\n .join(', ');\r\n\r\n throw new Error(`Environment validation failed: ${errors}`);\r\n }\r\n}\r\n\r\n/**\r\n * Check rate limiting for a given key\r\n */\r\nexport async function checkRateLimit(\r\n key: string,\r\n config: RateLimitConfig\r\n): Promise<{ allowed: boolean; remaining: number; resetTime: number }> {\r\n const now = Date.now();\r\n\r\n // Clean up expired entries\r\n for (const [k, v] of rateLimitStore.entries()) {\r\n if (v.resetTime < now) {\r\n rateLimitStore.delete(k);\r\n }\r\n }\r\n\r\n const entry = rateLimitStore.get(key);\r\n\r\n if (!entry || entry.resetTime < now) {\r\n // New window or first request\r\n rateLimitStore.set(key, { count: 1, resetTime: now + config.windowMs });\r\n return {\r\n allowed: true,\r\n remaining: config.maxRequests - 1,\r\n resetTime: now + config.windowMs,\r\n };\r\n }\r\n\r\n if (entry.count >= config.maxRequests) {\r\n return {\r\n allowed: false,\r\n remaining: 0,\r\n resetTime: entry.resetTime,\r\n };\r\n }\r\n\r\n // Increment counter\r\n entry.count++;\r\n rateLimitStore.set(key, entry);\r\n\r\n return {\r\n allowed: true,\r\n remaining: config.maxRequests - entry.count,\r\n resetTime: entry.resetTime,\r\n };\r\n}\r\n\r\n/**\r\n * Generate rate limit key for user-based limiting\r\n */\r\nexport function generateRateLimitKey(userId: string, action: string): string {\r\n return `rate_limit:${action}:${userId}`;\r\n}\r\n\r\n/**\r\n * Generate rate limit key for IP-based limiting\r\n */\r\nexport function generateIPRateLimitKey(ip: string, action: string): string {\r\n return `rate_limit:${action}:ip:${ip}`;\r\n}\r\n\r\n/**\r\n * Validate CSRF token (basic implementation)\r\n */\r\nexport async function validateCSRFToken(token: string, sessionToken: string): Promise<boolean> {\r\n // In a real implementation, you'd validate against a secure session store\r\n // For now, we'll do a basic comparison\r\n return token === sessionToken && token.length > 0;\r\n}\r\n\r\n/**\r\n * Sanitize input to prevent XSS\r\n * Basic sanitization - in production, use a proper HTML sanitizer library\r\n */\r\nexport function sanitizeInput(input: string): string {\r\n // Basic XSS prevention - remove script tags and event handlers\r\n return input\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/on\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi, '')\r\n .replace(/javascript:/gi, '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Validate and sanitize user input\r\n */\r\nexport function validateAndSanitizeInput<T>(\r\n input: T,\r\n schema: z.ZodSchema<T>\r\n): { success: true; data: T } | { success: false; error: string } {\r\n try {\r\n const validation = schema.safeParse(input);\r\n\r\n if (!validation.success) {\r\n return {\r\n success: false,\r\n error: validation.error.issues.map(i => i.message).join(', '),\r\n };\r\n }\r\n\r\n // Sanitize string fields\r\n const sanitized = sanitizeObject(validation.data);\r\n\r\n return {\r\n success: true,\r\n data: sanitized,\r\n };\r\n } catch (error) {\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Validation failed',\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Recursively sanitize object properties\r\n */\r\nfunction sanitizeObject(obj: unknown): unknown {\r\n if (typeof obj === 'string') {\r\n return sanitizeInput(obj);\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(sanitizeObject);\r\n }\r\n\r\n if (obj && typeof obj === 'object') {\r\n const sanitized: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n sanitized[key] = sanitizeObject(value);\r\n }\r\n return sanitized;\r\n }\r\n\r\n return obj;\r\n}\r\n\r\n/**\r\n * Security headers for responses\r\n */\r\nexport const SECURITY_HEADERS = {\r\n 'X-Content-Type-Options': 'nosniff',\r\n 'X-Frame-Options': 'DENY',\r\n 'X-XSS-Protection': '1; mode=block',\r\n 'Referrer-Policy': 'strict-origin-when-cross-origin',\r\n 'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',\r\n} as const;\r\n\r\n/**\r\n * Log security events\r\n */\r\nexport function logSecurityEvent(\r\n event: string,\r\n details: Record<string, unknown>,\r\n severity: 'low' | 'medium' | 'high' | 'critical' = 'medium'\r\n): void {\r\n console.log(`[SECURITY-${severity.toUpperCase()}] ${event}:`, {\r\n timestamp: new Date().toISOString(),\r\n severity,\r\n ...details,\r\n });\r\n}\r\n\r\n","const devLogger = {\r\n debug: (...args: unknown[]) => console.debug('[security]', ...args),\r\n info: (...args: unknown[]) => console.log('[security]', ...args),\r\n warn: (...args: unknown[]) => console.warn('[security]', ...args),\r\n error: (...args: unknown[]) => console.error('[security]', ...args),\r\n forService: (_name: string) => ({\r\n debug: (...args: unknown[]) => console.debug('[security]', ...args),\r\n info: (...args: unknown[]) => console.log('[security]', ...args),\r\n warn: (...args: unknown[]) => console.warn('[security]', ...args),\r\n error: (...args: unknown[]) => console.error('[security]', ...args),\r\n }),\r\n};\r\nimport type {Payload} from 'payload';\r\n\r\ntype RateLimitConfig = {\r\n windowMs?: number;\r\n maxRequests?: number;\r\n skipSuccessfulRequests?: boolean;\r\n skipFailedRequests?: boolean;\r\n standardHeaders?: boolean;\r\n legacyHeaders?: boolean;\r\n};\r\ntype RateLimitResult = {\r\n allowed: boolean;\r\n remaining: number;\r\n resetTime: number;\r\n retryAfter?: number;\r\n};\r\ntype RateLimitState = {\r\n count: number;\r\n resetTime: number;\r\n lastRequestTime: number;\r\n};\r\n\r\n/**\r\n * Rate Limiter Service using Next.js 15 patterns\r\n * Provides multiple rate limiting algorithms with in-memory storage\r\n * Optimized for Vercel deployment without external dependencies\r\n */\r\nexport class RateLimiterService {\r\n private readonly config: Required<RateLimitConfig>;\r\n private readonly inMemoryStore = new Map<string, RateLimitState>();\r\n private cleanupInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\n constructor(config: RateLimitConfig) {\r\n this.config = {\r\n windowMs: config.windowMs ?? 15 * 60 * 1000, // 15 minutes\r\n maxRequests: config.maxRequests ?? 100,\r\n skipSuccessfulRequests: config.skipSuccessfulRequests ?? false,\r\n skipFailedRequests: config.skipFailedRequests ?? false,\r\n standardHeaders: config.standardHeaders ?? true,\r\n legacyHeaders: config.legacyHeaders ?? false,\r\n };\r\n\r\n // Start cleanup interval to prevent memory leaks\r\n this.startCleanupInterval();\r\n }\r\n\r\n setPayload(_payload: Payload): void {\r\n // Payload is accepted for compatibility but not currently used.\r\n }\r\n\r\n /**\r\n * Check rate limit using token bucket algorithm\r\n */\r\n checkTokenBucket(\r\n key: string,\r\n tokens: number = 1,\r\n capacity: number = 10,\r\n refillRate: number = 1,\r\n refillTime: number = 100\r\n ): RateLimitResult {\r\n try {\r\n const now = Date.now();\r\n const bucketKey = `rate_limit:token_bucket:${key}`;\r\n const current = this.inMemoryStore.get(bucketKey);\r\n\r\n let currentTokens = capacity;\r\n let lastRefill = now;\r\n\r\n if (current) {\r\n currentTokens = current.count;\r\n lastRefill = current.lastRequestTime;\r\n }\r\n\r\n // Calculate refill\r\n const timePassed = now - lastRefill;\r\n const refillAmount = Math.floor(timePassed / refillTime) * refillRate;\r\n currentTokens = Math.min(capacity, currentTokens + refillAmount);\r\n\r\n // Check if we can consume tokens\r\n if (currentTokens >= tokens) {\r\n currentTokens = currentTokens - tokens;\r\n this.inMemoryStore.set(bucketKey, {\r\n count: currentTokens,\r\n resetTime: now + refillTime,\r\n lastRequestTime: now,\r\n });\r\n\r\n devLogger.debug('Rate limit check', {\r\n key,\r\n algorithm: 'token_bucket',\r\n allowed: true,\r\n remaining: currentTokens,\r\n resetTime: now + refillTime,\r\n tokens,\r\n capacity,\r\n refillRate,\r\n });\r\n\r\n return {\r\n allowed: true,\r\n remaining: currentTokens,\r\n resetTime: now + refillTime,\r\n };\r\n }\r\n const resetTime = lastRefill + refillTime;\r\n devLogger.warn('Rate limit blocked', {\r\n key,\r\n algorithm: 'token_bucket',\r\n remaining: currentTokens,\r\n resetTime,\r\n tokens,\r\n });\r\n\r\n return {\r\n allowed: false,\r\n remaining: currentTokens,\r\n resetTime,\r\n retryAfter: Math.ceil((resetTime - now) / 1000),\r\n };\r\n } catch (error) {\r\n devLogger.error('Rate limiter error', error instanceof Error ? error : undefined, {\r\n key,\r\n algorithm: 'token_bucket',\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n });\r\n // Fail open - allow request if rate limiting fails\r\n return {\r\n allowed: true,\r\n remaining: capacity,\r\n resetTime: Date.now() + refillTime,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Check rate limit using sliding window algorithm\r\n */\r\n checkSlidingWindow(\r\n key: string,\r\n windowMs: number = this.config.windowMs,\r\n maxRequests: number = this.config.maxRequests\r\n ): RateLimitResult {\r\n try {\r\n const now = Date.now();\r\n const windowKey = `rate_limit:sliding_window:${key}`;\r\n const current = this.inMemoryStore.get(windowKey);\r\n\r\n let requests: number[] = [];\r\n if (current) {\r\n requests = [current.count]; // Simplified - in real implementation, you'd store timestamps\r\n }\r\n\r\n // Remove expired entries (simplified)\r\n const windowStart = now - windowMs;\r\n requests = requests.filter(timestamp => timestamp >= windowStart);\r\n\r\n // Check if we can add another request\r\n if (requests.length < maxRequests) {\r\n requests.push(now);\r\n this.inMemoryStore.set(windowKey, {\r\n count: requests.length,\r\n resetTime: now + windowMs,\r\n lastRequestTime: now,\r\n });\r\n\r\n devLogger.debug('Rate limit check', {\r\n key,\r\n algorithm: 'sliding_window',\r\n allowed: true,\r\n remaining: maxRequests - requests.length,\r\n resetTime: now + windowMs,\r\n });\r\n\r\n return {\r\n allowed: true,\r\n remaining: maxRequests - requests.length,\r\n resetTime: now + windowMs,\r\n };\r\n }\r\n const oldest = Math.min(...requests);\r\n const resetTime = oldest + windowMs;\r\n\r\n devLogger.warn('Rate limit blocked', {\r\n key,\r\n algorithm: 'sliding_window',\r\n remaining: 0,\r\n resetTime,\r\n });\r\n\r\n return {\r\n allowed: false,\r\n remaining: 0,\r\n resetTime,\r\n retryAfter: Math.ceil((resetTime - now) / 1000),\r\n };\r\n } catch (error) {\r\n devLogger.error('Rate limiter error', error instanceof Error ? error : undefined, {\r\n key,\r\n algorithm: 'sliding_window',\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n });\r\n // Fail open - allow request if rate limiting fails\r\n return {\r\n allowed: true,\r\n remaining: maxRequests,\r\n resetTime: Date.now() + windowMs,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Check rate limit using leaky bucket algorithm\r\n */\r\n checkLeakyBucket(\r\n key: string,\r\n capacity: number = 10,\r\n leakRate: number = 1,\r\n leakTime: number = 100\r\n ): RateLimitResult {\r\n try {\r\n const now = Date.now();\r\n const bucketKey = `rate_limit:leaky_bucket:${key}`;\r\n const current = this.inMemoryStore.get(bucketKey);\r\n\r\n let currentLevel = 0;\r\n let lastLeak = now;\r\n\r\n if (current) {\r\n currentLevel = current.count;\r\n lastLeak = current.lastRequestTime;\r\n }\r\n\r\n // Calculate leak\r\n const timePassed = now - lastLeak;\r\n const leakAmount = Math.floor(timePassed / leakTime) * leakRate;\r\n currentLevel = Math.max(0, currentLevel - leakAmount);\r\n\r\n // Check if we can add to the bucket\r\n if (currentLevel < capacity) {\r\n currentLevel++;\r\n this.inMemoryStore.set(bucketKey, {\r\n count: currentLevel,\r\n resetTime: now + leakTime,\r\n lastRequestTime: now,\r\n });\r\n\r\n devLogger.debug('Rate limit check', {\r\n key,\r\n algorithm: 'leaky_bucket',\r\n allowed: true,\r\n remaining: capacity - currentLevel,\r\n resetTime: now + leakTime,\r\n });\r\n\r\n return {\r\n allowed: true,\r\n remaining: capacity - currentLevel,\r\n resetTime: now + leakTime,\r\n };\r\n }\r\n const resetTime = lastLeak + leakTime;\r\n devLogger.warn('Rate limit blocked', {\r\n key,\r\n algorithm: 'leaky_bucket',\r\n remaining: 0,\r\n resetTime,\r\n });\r\n\r\n return {\r\n allowed: false,\r\n remaining: 0,\r\n resetTime,\r\n retryAfter: Math.ceil((resetTime - now) / 1000),\r\n };\r\n } catch (error) {\r\n devLogger.error('Rate limiter error', error instanceof Error ? error : undefined, {\r\n key,\r\n algorithm: 'leaky_bucket',\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n });\r\n // Fail open - allow request if rate limiting fails\r\n return {\r\n allowed: true,\r\n remaining: capacity,\r\n resetTime: Date.now() + leakTime,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Reset rate limit for a key\r\n */\r\n resetRateLimit(key: string): void {\r\n const patterns = [\r\n `rate_limit:token_bucket:${key}`,\r\n `rate_limit:sliding_window:${key}`,\r\n `rate_limit:leaky_bucket:${key}`,\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n this.inMemoryStore.delete(pattern);\r\n }\r\n\r\n devLogger.debug('Rate limit reset', { key });\r\n }\r\n\r\n /**\r\n * Get current rate limit state\r\n */\r\n getRateLimitState(key: string): RateLimitState | null {\r\n const patterns = [\r\n `rate_limit:token_bucket:${key}`,\r\n `rate_limit:sliding_window:${key}`,\r\n `rate_limit:leaky_bucket:${key}`,\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const state = this.inMemoryStore.get(pattern);\r\n if (state) {\r\n return state;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Update rate limit state\r\n */\r\n updateRateLimitState(key: string, state: RateLimitState): void {\r\n this.inMemoryStore.set(key, state);\r\n }\r\n\r\n /**\r\n * Get rate limiter statistics\r\n */\r\n getStats(): { totalKeys: number; memoryUsage: number } {\r\n return {\r\n totalKeys: this.inMemoryStore.size,\r\n memoryUsage: this.inMemoryStore.size,\r\n };\r\n }\r\n\r\n /**\r\n * Clean up expired entries\r\n */\r\n cleanup(): void {\r\n const now = Date.now();\r\n const maxAge = 24 * 60 * 60 * 1000; // 24 hours\r\n\r\n for (const [key, state] of this.inMemoryStore.entries()) {\r\n if (now - state.lastRequestTime > maxAge) {\r\n this.inMemoryStore.delete(key);\r\n }\r\n }\r\n\r\n devLogger.debug('Cleaned up expired rate limit entries', {\r\n remaining: this.inMemoryStore.size,\r\n });\r\n }\r\n\r\n /**\r\n * Start cleanup interval\r\n */\r\n private startCleanupInterval(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n }\r\n\r\n // Clean up every hour\r\n this.cleanupInterval = setInterval(\r\n () => {\r\n this.cleanup();\r\n },\r\n 60 * 60 * 1000\r\n );\r\n }\r\n\r\n /**\r\n * Stop cleanup interval\r\n */\r\n stopCleanupInterval(): void {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n }\r\n }\r\n\r\n /**\r\n * Dispose of the service\r\n */\r\n dispose(): void {\r\n this.stopCleanupInterval();\r\n this.inMemoryStore.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create RateLimiterService\r\n */\r\nexport const getRateLimiterService = (config?: RateLimitConfig): RateLimiterService => {\r\n return new RateLimiterService(config ?? {});\r\n};\r\n\r\n","/**\r\n * Rate Limiting Middleware for Server Actions\r\n *\r\n * Provides rate limiting functionality for Next.js 16 server actions\r\n */\r\n\r\nimport {headers} from 'next/headers';\r\nconst RATE_LIMITS = { default: { limit: 100, windowMs: 60_000 } } as const;\r\nconst generateRateLimitKey = (id: string) => `rate:${id}`;\r\nconst generateIPRateLimitKey = (ip: string) => `rate:ip:${ip}`;\r\nasync function checkRateLimit(\r\n _key: string,\r\n _limit: number,\r\n _windowMs: number\r\n): Promise<RateLimitResult> {\r\n // No-op in library context; allow\r\n return { allowed: true, remaining: _limit, resetTime: Date.now() + _windowMs };\r\n}\r\n\r\nexport interface RateLimitResult {\r\n allowed: boolean;\r\n remaining: number;\r\n resetTime: number;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Apply rate limiting to server actions\r\n */\r\nexport async function withRateLimit<T extends any[], R>(\r\n action: (...args: T) => Promise<R>,\r\n config: {\r\n type: keyof typeof RATE_LIMITS;\r\n userId?: string;\r\n customKey?: string;\r\n }\r\n) {\r\n return async (...args: T): Promise<R> => {\r\n const headersList = await headers();\r\n const ip = headersList.get('x-forwarded-for') ?? headersList.get('x-real-ip') ?? 'unknown';\r\n\r\n // Generate rate limit key\r\n const key =\r\n config.customKey ??\r\n (config.userId ? generateRateLimitKey(config.userId) : generateIPRateLimitKey(ip));\r\n\r\n // Check rate limit\r\n const rateLimitResult = await checkRateLimit(\r\n key,\r\n RATE_LIMITS[config.type].limit,\r\n RATE_LIMITS[config.type].windowMs\r\n );\r\n\r\n if (!rateLimitResult.allowed) {\r\n throw new Error(\r\n `Rate limit exceeded. Try again in ${Math.ceil((rateLimitResult.resetTime - Date.now()) / 1000)} seconds.`\r\n );\r\n }\r\n\r\n // Execute the action\r\n return await action(...args);\r\n };\r\n}\r\n\r\n/**\r\n * Rate limiting decorator for class methods\r\n */\r\nexport function RateLimited(type: keyof typeof RATE_LIMITS, userId?: string) {\r\n return (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => {\r\n const originalMethod = descriptor.value;\r\n\r\n descriptor.value = async function (...args: any[]) {\r\n const headersList = await headers();\r\n const ip = headersList.get('x-forwarded-for') ?? headersList.get('x-real-ip') ?? 'unknown';\r\n\r\n const key = userId ? generateRateLimitKey(userId) : generateIPRateLimitKey(ip);\r\n\r\n const rateLimitResult = await checkRateLimit(\r\n key,\r\n RATE_LIMITS[type].limit,\r\n RATE_LIMITS[type].windowMs\r\n );\r\n\r\n if (!rateLimitResult.allowed) {\r\n throw new Error(\r\n `Rate limit exceeded. Try again in ${Math.ceil((rateLimitResult.resetTime - Date.now()) / 1000)} seconds.`\r\n );\r\n }\r\n\r\n return await originalMethod.apply(this, args);\r\n };\r\n\r\n return descriptor;\r\n };\r\n}\r\n\r\n/**\r\n * Get client IP address\r\n */\r\nexport async function getClientIP(): Promise<string> {\r\n const headersList = await headers();\r\n return headersList.get('x-forwarded-for') ?? headersList.get('x-real-ip') ?? 'unknown';\r\n}\r\n\r\n/**\r\n * Check if request is from a trusted source\r\n */\r\nexport async function isTrustedSource(): Promise<boolean> {\r\n const headersList = await headers();\r\n const userAgent = headersList.get('user-agent') || '';\r\n const origin = headersList.get('origin') || '';\r\n\r\n // Check for common bot patterns\r\n const botPatterns = [/bot/i, /crawler/i, /spider/i, /scraper/i, /curl/i, /wget/i];\r\n\r\n const isBot = botPatterns.some(pattern => pattern.test(userAgent));\r\n\r\n // Check for trusted origins (configure as needed)\r\n const trustedOrigins = [\r\n process.env.NEXT_PUBLIC_APP_URL,\r\n 'http://localhost:3000',\r\n 'https://localhost:3000',\r\n ].filter(Boolean);\r\n\r\n const isTrustedOrigin = trustedOrigins.includes(origin);\r\n\r\n return !isBot && isTrustedOrigin;\r\n}\r\n\r\n/**\r\n * Enhanced rate limiting with user context\r\n */\r\nexport async function checkUserRateLimit(\r\n userId: string,\r\n action: keyof typeof RATE_LIMITS,\r\n customConfig?: Partial<(typeof RATE_LIMITS)[keyof typeof RATE_LIMITS]>\r\n): Promise<RateLimitResult> {\r\n const config = { ...RATE_LIMITS[action], ...customConfig };\r\n const key = generateRateLimitKey(userId);\r\n\r\n return await checkRateLimit(key, config.limit, config.windowMs);\r\n}\r\n\r\n/**\r\n * Rate limiting for anonymous users\r\n */\r\nexport async function checkAnonymousRateLimit(\r\n action: keyof typeof RATE_LIMITS,\r\n customConfig?: Partial<(typeof RATE_LIMITS)[keyof typeof RATE_LIMITS]>\r\n): Promise<RateLimitResult> {\r\n const ip = await getClientIP();\r\n const config = { ...RATE_LIMITS[action], ...customConfig };\r\n const key = generateIPRateLimitKey(ip);\r\n\r\n return await checkRateLimit(key, config.limit, config.windowMs);\r\n}\r\n\r\n","type SecurityOptions = {\r\n algorithm?: 'sha256' | 'sha1' | 'sha512';\r\n encoding?: 'hex' | 'base64' | 'base64url';\r\n tokenLength?: number;\r\n tokenExpiry?: number;\r\n};\r\nimport {createHmac,randomBytes} from 'crypto';\r\nimport type {Payload} from 'payload';\r\n\r\nexport class CSRFService {\r\n private readonly options: Required<SecurityOptions>;\r\n\r\n constructor(\r\n private readonly payload: Payload,\r\n options: SecurityOptions = {}\r\n ) {\r\n this.options = {\r\n algorithm: options.algorithm ?? 'sha256',\r\n encoding: options.encoding ?? 'hex',\r\n tokenLength: options.tokenLength ?? 32,\r\n tokenExpiry: options.tokenExpiry ?? 24 * 60 * 60 * 1000, // 24 hours\r\n };\r\n }\r\n\r\n async generateCsrfToken(sessionId: string): Promise<string> {\r\n try {\r\n const token = randomBytes(this.options.tokenLength);\r\n const hmac = createHmac(this.options.algorithm, process.env.PAYLOAD_SECRET ?? '');\r\n\r\n hmac.update(sessionId);\r\n hmac.update(token);\r\n\r\n const signature = hmac.digest(this.options.encoding);\r\n const csrfToken = `${token.toString(this.options.encoding)}.${signature}`;\r\n\r\n this.payload.logger.debug('CSRF token generated successfully');\r\n return csrfToken;\r\n } catch (error) {\r\n this.payload.logger.error('Failed to generate CSRF token', error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n async validateCsrfToken(token: string, sessionId: string): Promise<boolean> {\r\n try {\r\n const [tokenPart, signature] = token.split('.');\r\n if (!tokenPart || !signature) {\r\n this.payload.logger.warn('Invalid CSRF token format');\r\n return false;\r\n }\r\n\r\n const hmac = createHmac(this.options.algorithm, process.env.PAYLOAD_SECRET ?? '');\r\n hmac.update(sessionId);\r\n hmac.update(Buffer.from(tokenPart, this.options.encoding));\r\n\r\n const expectedSignature = hmac.digest(this.options.encoding);\r\n const isValid = signature === expectedSignature;\r\n\r\n if (isValid) {\r\n this.payload.logger.debug('CSRF token validated successfully');\r\n } else {\r\n this.payload.logger.warn('CSRF token validation failed');\r\n }\r\n\r\n return isValid;\r\n } catch (error) {\r\n this.payload.logger.error('Failed to validate CSRF token', error as Error);\r\n return false;\r\n }\r\n }\r\n}\r\n\r\n","import type {ServiceResult} from '@revealui/core';\r\nimport {InfrastructureService} from '@revealui/core';\r\nimport type {ScryptOptions} from 'crypto';\r\nimport {\r\n createCipheriv,\r\n createDecipheriv,\r\n randomBytes,\r\n scrypt as scryptCallback,\r\n} from 'node:crypto';\r\nimport type {Payload} from 'payload';\r\nimport {promisify} from 'util';\r\n\r\ntype NodeCipher = ReturnType<typeof createCipheriv>;\r\ntype NodeDecipher = ReturnType<typeof createDecipheriv>;\r\n\r\ntype BufferEncodingFormat = 'hex' | 'base64' | 'base64url';\r\n\r\ntype ScryptAsync = (\r\n password: string | Buffer,\r\n salt: Buffer | string,\r\n keylen: number,\r\n options?: ScryptOptions\r\n) => Promise<Buffer>;\r\n\r\nconst scryptAsync: ScryptAsync = promisify(scryptCallback);\r\n\r\ninterface EncryptionMetadata {\r\n algorithm: string;\r\n iv: string;\r\n authTag: string;\r\n salt: string;\r\n}\r\n\r\ninterface EncryptedData {\r\n data: string;\r\n metadata: EncryptionMetadata;\r\n}\r\n\r\ninterface EncryptionOptions {\r\n algorithm?: string;\r\n keyLength?: number;\r\n saltLength?: number;\r\n ivLength?: number;\r\n iterations?: number;\r\n encoding?: BufferEncodingFormat;\r\n}\r\n\r\ntype AuthenticatedCipher = NodeCipher & {\r\n getAuthTag: () => Buffer;\r\n};\r\n\r\ntype AuthenticatedDecipher = NodeDecipher & {\r\n setAuthTag: (buffer: Buffer) => void;\r\n};\r\n\r\n/**\r\n * Type guards using contract types\r\n */\r\nfunction isAuthenticatedCipher(cipher: NodeCipher): cipher is AuthenticatedCipher {\r\n return typeof (cipher as Partial<AuthenticatedCipher>).getAuthTag === 'function';\r\n}\r\n\r\nfunction isAuthenticatedDecipher(decipher: NodeDecipher): decipher is AuthenticatedDecipher {\r\n return typeof (decipher as Partial<AuthenticatedDecipher>).setAuthTag === 'function';\r\n}\r\n\r\n/**\r\n * Encryption Infrastructure Service following DDD and Hexagonal Architecture principles.\r\n *\r\n * Acts as a Secondary/Driven Adapter in the Ports & Adapters architecture,\r\n * providing secure encryption and decryption capabilities for sensitive data.\r\n */\r\nexport class EncryptionService extends InfrastructureService {\r\n private readonly options: Required<EncryptionOptions>;\r\n\r\n constructor(payload: Payload, options: EncryptionOptions = {}) {\r\n super(payload, 'EncryptionService');\r\n\r\n this.options = {\r\n algorithm: options.algorithm ?? 'aes-256-gcm',\r\n keyLength: options.keyLength ?? 32,\r\n saltLength: options.saltLength ?? 16,\r\n ivLength: options.ivLength ?? 12,\r\n iterations: options.iterations ?? 100000,\r\n encoding: options.encoding ?? 'hex',\r\n };\r\n }\r\n\r\n /**\r\n * Encrypts data using the configured algorithm with comprehensive error handling.\r\n */\r\n async encrypt(\r\n data: string,\r\n customOptions?: Partial<EncryptionOptions>\r\n ): Promise<ServiceResult<EncryptedData>> {\r\n return this.executeInfrastructureOperation(async () => {\r\n if (typeof data !== 'string' || data.length === 0) {\r\n throw new Error('Data to encrypt must be a non-empty string');\r\n }\r\n\r\n const effectiveOptions = { ...this.options, ...customOptions };\r\n\r\n this.logger.debug('Starting data encryption', {\r\n algorithm: effectiveOptions.algorithm,\r\n dataLength: data.length,\r\n serviceName: this.serviceName,\r\n operation: 'encrypt',\r\n });\r\n\r\n const salt = randomBytes(effectiveOptions.saltLength);\r\n const iv = randomBytes(effectiveOptions.ivLength);\r\n\r\n const key = await this.deriveKey(salt, effectiveOptions);\r\n const cipher = createCipheriv(effectiveOptions.algorithm, key, iv);\r\n\r\n const encrypted = Buffer.concat([cipher.update(data, 'utf8'), cipher.final()]);\r\n\r\n // Type-safe auth tag extraction\r\n if (isAuthenticatedCipher(cipher) !== true) {\r\n throw new Error('Cipher does not support authentication');\r\n }\r\n const authTag = cipher.getAuthTag();\r\n\r\n const result: EncryptedData = {\r\n data: encrypted.toString(effectiveOptions.encoding),\r\n metadata: {\r\n algorithm: effectiveOptions.algorithm,\r\n iv: iv.toString(effectiveOptions.encoding),\r\n authTag: authTag.toString(effectiveOptions.encoding),\r\n salt: salt.toString(effectiveOptions.encoding),\r\n },\r\n };\r\n\r\n this.logger.debug('Data encrypted successfully', {\r\n algorithm: effectiveOptions.algorithm,\r\n originalLength: data.length,\r\n encryptedLength: result.data.length,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n }, 'encrypt');\r\n }\r\n\r\n /**\r\n * Decrypts data using the metadata provided with comprehensive validation.\r\n */\r\n async decrypt(encryptedData: EncryptedData): Promise<ServiceResult<string>> {\r\n return this.executeInfrastructureOperation(async () => {\r\n if (!encryptedData || !encryptedData.data || !encryptedData.metadata) {\r\n throw new Error('Invalid encrypted data structure');\r\n }\r\n\r\n const { data, metadata } = encryptedData;\r\n\r\n // Validate metadata completeness\r\n const requiredFields = ['algorithm', 'iv', 'authTag', 'salt'];\r\n for (const field of requiredFields) {\r\n const fieldValue = metadata[field as keyof typeof metadata];\r\n if (fieldValue === undefined || fieldValue === null || fieldValue === '') {\r\n throw new Error(`Missing required encryption metadata field: ${field}`);\r\n }\r\n }\r\n\r\n this.logger.debug('Starting data decryption', {\r\n algorithm: metadata.algorithm,\r\n encryptedLength: data.length,\r\n serviceName: this.serviceName,\r\n operation: 'decrypt',\r\n });\r\n\r\n const key = await this.deriveKey(Buffer.from(metadata.salt, this.options.encoding), {\r\n ...this.options,\r\n algorithm: metadata.algorithm,\r\n });\r\n\r\n const decipher = createDecipheriv(\r\n metadata.algorithm,\r\n key,\r\n Buffer.from(metadata.iv, this.options.encoding)\r\n );\r\n\r\n // Type-safe auth tag setting\r\n if (isAuthenticatedDecipher(decipher) !== true) {\r\n throw new Error('Decipher does not support authentication');\r\n }\r\n decipher.setAuthTag(Buffer.from(metadata.authTag, this.options.encoding));\r\n\r\n const decrypted = Buffer.concat([\r\n decipher.update(Buffer.from(data, this.options.encoding)),\r\n decipher.final(),\r\n ]);\r\n\r\n const result = decrypted.toString('utf8');\r\n\r\n this.logger.debug('Data decrypted successfully', {\r\n algorithm: metadata.algorithm,\r\n encryptedLength: data.length,\r\n decryptedLength: result.length,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n }, 'decrypt');\r\n }\r\n\r\n /**\r\n * Encrypts multiple data items in batch with optimized processing.\r\n */\r\n async encryptBatch(\r\n dataItems: string[],\r\n customOptions?: Partial<EncryptionOptions>\r\n ): Promise<\r\n ServiceResult<{\r\n successful: EncryptedData[];\r\n failed: Array<{ data: string; error: string }>;\r\n }>\r\n > {\r\n return this.executeInfrastructureOperation(async () => {\r\n if (!Array.isArray(dataItems) || dataItems.length === 0) {\r\n throw new Error('Data items array must contain at least one item');\r\n }\r\n\r\n this.logger.info('Starting batch encryption', {\r\n itemCount: dataItems.length,\r\n serviceName: this.serviceName,\r\n operation: 'encryptBatch',\r\n });\r\n\r\n const successful: EncryptedData[] = [];\r\n const failed: Array<{ data: string; error: string }> = [];\r\n\r\n // Process items in parallel with controlled concurrency\r\n const encryptionPromises = dataItems.map(async data => {\r\n try {\r\n const result = await this.encrypt(data, customOptions);\r\n if (result.success && result.data) {\r\n successful.push(result.data);\r\n } else {\r\n failed.push({\r\n data,\r\n error: result.error ?? 'Unknown encryption error',\r\n });\r\n }\r\n } catch (error) {\r\n failed.push({\r\n data,\r\n error: error instanceof Error ? error.message : 'Unknown encryption error',\r\n });\r\n }\r\n });\r\n\r\n await Promise.allSettled(encryptionPromises);\r\n\r\n this.logger.info('Batch encryption completed', {\r\n totalItems: dataItems.length,\r\n successful: successful.length,\r\n failed: failed.length,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return { successful, failed };\r\n }, 'encryptBatch');\r\n }\r\n\r\n /**\r\n * Generates cryptographically secure random data.\r\n */\r\n async generateRandomData(\r\n length: number = 32,\r\n encoding: 'hex' | 'base64' | 'base64url' = 'hex'\r\n ): Promise<ServiceResult<string>> {\r\n return this.executeInfrastructureOperation(async () => {\r\n if (length <= 0 || length > 1024) {\r\n throw new Error('Random data length must be between 1 and 1024 bytes');\r\n }\r\n\r\n this.logger.debug('Generating random data', {\r\n length,\r\n encoding,\r\n serviceName: this.serviceName,\r\n operation: 'generateRandomData',\r\n });\r\n\r\n const randomData = randomBytes(length);\r\n const result = randomData.toString(encoding);\r\n\r\n this.logger.debug('Random data generated successfully', {\r\n length,\r\n encoding,\r\n outputLength: result.length,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n }, 'generateRandomData');\r\n }\r\n\r\n /**\r\n * Validates the integrity of encrypted data by attempting decryption.\r\n */\r\n async validateEncryptedData(\r\n encryptedData: EncryptedData\r\n ): Promise<ServiceResult<{ valid: boolean; error?: string | undefined }>> {\r\n return this.executeInfrastructureOperation(async () => {\r\n if (!encryptedData) {\r\n throw new Error('Encrypted data is required');\r\n }\r\n\r\n this.logger.debug('Validating encrypted data integrity', {\r\n algorithm: encryptedData.metadata.algorithm,\r\n serviceName: this.serviceName,\r\n operation: 'validateEncryptedData',\r\n });\r\n\r\n try {\r\n const decryptResult = await this.decrypt(encryptedData);\r\n const valid = decryptResult.success && !!decryptResult.data;\r\n\r\n this.logger.debug('Encrypted data validation completed', {\r\n valid,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return valid\r\n ? { valid, error: undefined }\r\n : {\r\n valid,\r\n error: decryptResult.error ?? 'Decryption failed',\r\n };\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown validation error';\r\n\r\n this.logger.debug('Encrypted data validation failed', {\r\n error: errorMessage,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return { valid: false, error: errorMessage };\r\n }\r\n }, 'validateEncryptedData');\r\n }\r\n\r\n /**\r\n * Derives encryption key from password and salt using PBKDF2.\r\n * @private\r\n */\r\n private async deriveKey(salt: Buffer, options: Partial<EncryptionOptions> = {}): Promise<Buffer> {\r\n const effectiveOptions = { ...this.options, ...options };\r\n\r\n const secret = process.env.PAYLOAD_SECRET;\r\n if (!secret || secret === '') {\r\n throw new Error('PAYLOAD_SECRET environment variable is required for encryption');\r\n }\r\n\r\n return scryptAsync(secret, salt, effectiveOptions.keyLength);\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected override async onInitialize(): Promise<void> {\r\n this.logger.info('Initializing EncryptionService', {\r\n algorithm: this.options.algorithm,\r\n keyLength: this.options.keyLength,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n // Verify PAYLOAD_SECRET is available\r\n if (!process.env.PAYLOAD_SECRET) {\r\n throw new Error('PAYLOAD_SECRET environment variable is required for EncryptionService');\r\n }\r\n\r\n // Test encryption/decryption functionality\r\n try {\r\n const testData = 'encryption-test-data';\r\n const encrypted = await this.encrypt(testData);\r\n if (!encrypted.success || !encrypted.data) {\r\n throw new Error('Encryption test failed');\r\n }\r\n\r\n const decrypted = await this.decrypt(encrypted.data);\r\n if (!decrypted.success || decrypted.data !== testData) {\r\n throw new Error('Decryption test failed');\r\n }\r\n\r\n this.logger.debug('EncryptionService initialization test passed', {\r\n serviceName: this.serviceName,\r\n });\r\n } catch (error) {\r\n throw new Error(\r\n `EncryptionService initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected override async onCleanup(): Promise<void> {\r\n this.logger.info('Cleaning up EncryptionService', {\r\n serviceName: this.serviceName,\r\n });\r\n // Clear any sensitive data from memory if needed\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected async onHealthCheck(): Promise<void> {\r\n // Verify encryption/decryption is working\r\n try {\r\n const testData = 'health-check-data';\r\n const encrypted = await this.encrypt(testData);\r\n if (!encrypted.success || !encrypted.data) {\r\n throw new Error('Health check encryption failed');\r\n }\r\n\r\n const decrypted = await this.decrypt(encrypted.data);\r\n if (!decrypted.success || decrypted.data !== testData) {\r\n throw new Error('Health check decryption failed');\r\n }\r\n } catch (error) {\r\n throw new Error(\r\n `EncryptionService health check failed: ${error instanceof Error ? error.message : 'Unknown error'}`\r\n );\r\n }\r\n }\r\n}\r\n\r\n","const devLogger = {\r\n info: (...args: unknown[]) => console.log('[security]', ...args),\r\n warn: (...args: unknown[]) => console.warn('[security]', ...args),\r\n error: (...args: unknown[]) => console.error('[security]', ...args),\r\n};\r\n\r\nexport type SecurityEventType =\r\n | 'authentication'\r\n | 'authorization'\r\n | 'data_access'\r\n | 'system'\r\n | 'policy_violation'\r\n | 'threat_detection';\r\n\r\nexport type SecuritySeverity = 'low' | 'medium' | 'high' | 'critical';\r\n\r\nexport interface SecurityEvent {\r\n id: string;\r\n type: SecurityEventType;\r\n severity: SecuritySeverity;\r\n message: string;\r\n userId?: string;\r\n ipAddress?: string;\r\n userAgent?: string;\r\n timestamp: Date;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport type SecurityAlertType = 'threshold_exceeded' | 'policy_violation' | 'anomaly_detected';\r\n\r\nexport interface SecurityAlert {\r\n id: string;\r\n type: SecurityAlertType;\r\n severity: SecuritySeverity;\r\n message: string;\r\n timestamp: Date;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport interface SecurityMetrics {\r\n totalEvents: number;\r\n eventsByType: Record<string, number>;\r\n eventsBySeverity: Record<string, number>;\r\n averageResponseTime: number;\r\n lastEventTime?: Date;\r\n}\r\n\r\n// ======\r\n// PURE FUNCTIONS\r\n// ======\r\n\r\n/**\r\n * Create a security event\r\n */\r\nexport const createSecurityEvent = (\r\n type: SecurityEvent['type'],\r\n severity: SecurityEvent['severity'],\r\n message: string,\r\n options?: {\r\n userId?: string;\r\n ipAddress?: string;\r\n userAgent?: string;\r\n metadata?: Record<string, unknown>;\r\n }\r\n): SecurityEvent => {\r\n const baseEvent: SecurityEvent = {\r\n id: crypto.randomUUID(),\r\n type,\r\n severity,\r\n message,\r\n timestamp: new Date(),\r\n ...(options?.metadata ? { metadata: options.metadata } : {}),\r\n ...(options?.userId !== undefined ? { userId: options.userId } : {}),\r\n ...(options?.ipAddress !== undefined ? { ipAddress: options.ipAddress } : {}),\r\n ...(options?.userAgent !== undefined ? { userAgent: options.userAgent } : {}),\r\n };\r\n\r\n return baseEvent;\r\n};\r\n\r\n/**\r\n * Calculate security metrics from events\r\n */\r\nexport const calculateSecurityMetrics = (events: SecurityEvent[]): SecurityMetrics => {\r\n if (events.length === 0) {\r\n return {\r\n totalEvents: 0,\r\n eventsByType: {},\r\n eventsBySeverity: {},\r\n averageResponseTime: 0,\r\n };\r\n }\r\n\r\n const eventsByType = events.reduce<Record<string, number>>((acc, event) => {\r\n acc[event.type] = (acc[event.type] || 0) + 1;\r\n return acc;\r\n }, {});\r\n\r\n const eventsBySeverity = events.reduce<Record<string, number>>((acc, event) => {\r\n acc[event.severity] = (acc[event.severity] || 0) + 1;\r\n return acc;\r\n }, {});\r\n\r\n const lastEventTime =\r\n events.length > 0 ? new Date(Math.max(...events.map(e => e.timestamp.getTime()))) : undefined;\r\n\r\n return {\r\n totalEvents: events.length,\r\n eventsByType,\r\n eventsBySeverity,\r\n averageResponseTime: 0, // Would be calculated from actual response times\r\n ...(lastEventTime !== undefined ? { lastEventTime } : {}),\r\n };\r\n};\r\n\r\n/**\r\n * Check if an event should trigger an alert\r\n */\r\nexport const shouldTriggerAlert = (\r\n event: SecurityEvent,\r\n thresholds: {\r\n criticalCount: number;\r\n highCount: number;\r\n mediumCount: number;\r\n timeWindowMs: number;\r\n }\r\n): boolean => {\r\n // Check if event severity meets threshold criteria\r\n const now = new Date();\r\n const timeWindowStart = new Date(now.getTime() - thresholds.timeWindowMs);\r\n\r\n // Get recent events within the time window\r\n const recentEvents = events.filter(\r\n event => event.timestamp >= timeWindowStart && event.timestamp <= now\r\n );\r\n\r\n // Count events by severity within the time window\r\n const criticalCount = recentEvents.filter(e => e.severity === 'critical').length;\r\n const highCount = recentEvents.filter(e => e.severity === 'high').length;\r\n const mediumCount = recentEvents.filter(e => e.severity === 'medium').length;\r\n\r\n // Check if thresholds are exceeded\r\n if (criticalCount >= thresholds.criticalCount) return true;\r\n if (highCount >= thresholds.highCount) return true;\r\n if (mediumCount >= thresholds.mediumCount) return true;\r\n\r\n // Also trigger for critical events regardless of count\r\n if (event.severity === 'critical') return true;\r\n\r\n return false;\r\n};\r\n\r\n/**\r\n * Create a security alert from an event\r\n */\r\nexport const createSecurityAlert = (\r\n event: SecurityEvent,\r\n alertType: SecurityAlert['type'] = 'threshold_exceeded'\r\n): SecurityAlert => ({\r\n id: crypto.randomUUID(),\r\n type: alertType,\r\n severity: event.severity,\r\n message: `Security alert: ${event.message}`,\r\n timestamp: new Date(),\r\n metadata: {\r\n originalEventId: event.id,\r\n originalEventType: event.type,\r\n ...event.metadata,\r\n },\r\n});\r\n\r\n/**\r\n * Filter events by criteria\r\n */\r\nexport const filterEvents = (\r\n events: SecurityEvent[],\r\n criteria: {\r\n type?: SecurityEvent['type'];\r\n severity?: SecurityEvent['severity'];\r\n userId?: string;\r\n timeRange?: { start: Date; end: Date };\r\n }\r\n): SecurityEvent[] => {\r\n return events.filter(event => {\r\n if (criteria.type && event.type !== criteria.type) return false;\r\n if (criteria.severity && event.severity !== criteria.severity) return false;\r\n if (criteria.userId && event.userId !== criteria.userId) return false;\r\n if (criteria.timeRange) {\r\n const eventTime = event.timestamp.getTime();\r\n const startTime = criteria.timeRange.start.getTime();\r\n const endTime = criteria.timeRange.end.getTime();\r\n if (eventTime < startTime || eventTime > endTime) return false;\r\n }\r\n return true;\r\n });\r\n};\r\n\r\n// ======\r\n// STATE MANAGEMENT\r\n// ======\r\n\r\n// In-memory storage (in production, this would be a database)\r\nlet events: SecurityEvent[] = [];\r\nlet alerts: SecurityAlert[] = [];\r\n\r\n/**\r\n * Add an event to the security monitoring system\r\n */\r\nexport const addSecurityEvent = (event: SecurityEvent): void => {\r\n events.push(event);\r\n\r\n // Log the event\r\n devLogger.info('Security event recorded', {\r\n eventId: event.id,\r\n type: event.type,\r\n severity: event.severity,\r\n message: event.message,\r\n userId: event.userId,\r\n timestamp: event.timestamp.toISOString(),\r\n });\r\n\r\n // Check if alert should be triggered\r\n if (\r\n shouldTriggerAlert(event, {\r\n criticalCount: 1,\r\n highCount: 5,\r\n mediumCount: 10,\r\n timeWindowMs: 60000, // 1 minute\r\n })\r\n ) {\r\n const alert = createSecurityAlert(event);\r\n alerts.push(alert);\r\n\r\n devLogger.warn('Security alert triggered', {\r\n alertId: alert.id,\r\n eventId: event.id,\r\n severity: alert.severity,\r\n message: alert.message,\r\n });\r\n }\r\n};\r\n\r\n/**\r\n * Get all security events\r\n */\r\nexport const getSecurityEvents = (): SecurityEvent[] => [...events];\r\n\r\n/**\r\n * Get all security alerts\r\n */\r\nexport const getSecurityAlerts = (): SecurityAlert[] => [...alerts];\r\n\r\n/**\r\n * Get security metrics\r\n */\r\nexport const getSecurityMetrics = (): SecurityMetrics => calculateSecurityMetrics(events);\r\n\r\n/**\r\n * Clear all events and alerts (for testing)\r\n */\r\nexport const clearSecurityData = (): void => {\r\n events = [];\r\n alerts = [];\r\n};\r\n\r\n// ======\r\n// UTILITY FUNCTIONS\r\n// ======\r\n\r\n/**\r\n * Log authentication event\r\n */\r\nexport const logAuthenticationEvent = (\r\n userId: string,\r\n success: boolean,\r\n options?: {\r\n ipAddress?: string;\r\n userAgent?: string;\r\n metadata?: Record<string, unknown>;\r\n }\r\n): void => {\r\n const eventOptions: Parameters<typeof createSecurityEvent>[3] = {\r\n userId,\r\n ...(options?.ipAddress !== undefined ? { ipAddress: options.ipAddress } : {}),\r\n ...(options?.userAgent !== undefined ? { userAgent: options.userAgent } : {}),\r\n metadata: {\r\n success,\r\n ...options?.metadata,\r\n },\r\n };\r\n\r\n const event = createSecurityEvent(\r\n 'authentication',\r\n success ? 'low' : 'high',\r\n `Authentication ${success ? 'successful' : 'failed'} for user ${userId}`,\r\n eventOptions\r\n );\r\n\r\n addSecurityEvent(event);\r\n};\r\n\r\n/**\r\n * Log authorization event\r\n */\r\nexport const logAuthorizationEvent = (\r\n userId: string,\r\n resource: string,\r\n action: string,\r\n granted: boolean,\r\n options?: {\r\n ipAddress?: string;\r\n userAgent?: string;\r\n metadata?: Record<string, unknown>;\r\n }\r\n): void => {\r\n const eventOptions: Parameters<typeof createSecurityEvent>[3] = {\r\n userId,\r\n ...(options?.ipAddress !== undefined ? { ipAddress: options.ipAddress } : {}),\r\n ...(options?.userAgent !== undefined ? { userAgent: options.userAgent } : {}),\r\n metadata: {\r\n resource,\r\n action,\r\n granted,\r\n ...options?.metadata,\r\n },\r\n };\r\n\r\n const event = createSecurityEvent(\r\n 'authorization',\r\n granted ? 'low' : 'medium',\r\n `Authorization ${granted ? 'granted' : 'denied'} for user ${userId} on ${resource}:${action}`,\r\n eventOptions\r\n );\r\n\r\n addSecurityEvent(event);\r\n};\r\n\r\n/**\r\n * Log data access event\r\n */\r\nexport const logDataAccessEvent = (\r\n userId: string,\r\n collection: string,\r\n operation: 'create' | 'read' | 'update' | 'delete',\r\n recordId?: string,\r\n options?: {\r\n ipAddress?: string;\r\n userAgent?: string;\r\n metadata?: Record<string, unknown>;\r\n }\r\n): void => {\r\n const eventOptions: Parameters<typeof createSecurityEvent>[3] = {\r\n userId,\r\n ...(options?.ipAddress !== undefined ? { ipAddress: options.ipAddress } : {}),\r\n ...(options?.userAgent !== undefined ? { userAgent: options.userAgent } : {}),\r\n metadata: {\r\n collection,\r\n operation,\r\n recordId,\r\n ...options?.metadata,\r\n },\r\n };\r\n\r\n const event = createSecurityEvent(\r\n 'data_access',\r\n operation === 'delete' ? 'medium' : 'low',\r\n `Data access: ${operation} on ${collection}${recordId ? ` (${recordId})` : ''} by user ${userId}`,\r\n eventOptions\r\n );\r\n\r\n addSecurityEvent(event);\r\n};\r\n\r\n/**\r\n * Get events for a specific user\r\n */\r\nexport const getUserEvents = (userId: string): SecurityEvent[] => filterEvents(events, { userId });\r\n\r\n/**\r\n * Get events by severity\r\n */\r\nexport const getEventsBySeverity = (severity: SecurityEvent['severity']): SecurityEvent[] =>\r\n filterEvents(events, { severity });\r\n\r\n/**\r\n * Get events in time range\r\n */\r\nexport const getEventsInTimeRange = (start: Date, end: Date): SecurityEvent[] =>\r\n filterEvents(events, { timeRange: { start, end } });\r\n\r\n// ======\r\n// EXPORTED API\r\n// ======\r\n\r\nexport const SecurityMonitoringService = {\r\n // Event management\r\n addEvent: addSecurityEvent,\r\n getEvents: getSecurityEvents,\r\n getUserEvents,\r\n getEventsBySeverity,\r\n getEventsInTimeRange,\r\n\r\n // Alert management\r\n getAlerts: getSecurityAlerts,\r\n\r\n // Metrics\r\n getMetrics: getSecurityMetrics,\r\n\r\n // Utility functions\r\n logAuthenticationEvent,\r\n logAuthorizationEvent,\r\n logDataAccessEvent,\r\n\r\n // Testing utilities\r\n clearData: clearSecurityData,\r\n\r\n // Pure functions for composition\r\n createEvent: createSecurityEvent,\r\n createAlert: createSecurityAlert,\r\n filterEvents,\r\n calculateMetrics: calculateSecurityMetrics,\r\n};\r\n\r\n","import { type NextRequest, NextResponse } from 'next/server';\r\nimport { createHmac } from 'node:crypto';\r\n\r\nasync function getPayloadClient() {\r\n return { logger: console as any };\r\n}\r\n\r\nconst logger = {\r\n info: (message: string, ...args: unknown[]) => console.log(`[SecurityService] ${message}`, ...args),\r\n warn: (message: string, ...args: unknown[]) => console.warn(`[SecurityService] ${message}`, ...args),\r\n error: (message: string, ...args: unknown[]) => console.error(`[SecurityService] ${message}`, ...args),\r\n};\r\n\r\n// PayloadCMS native logging is used via payload.logger\r\n\r\nexport async function securityMiddleware(req: NextRequest): Promise<NextResponse | undefined> {\r\n const response = new NextResponse();\r\n\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.info(`Security middleware started for ${req.method} ${req.url}`);\r\n } catch {\r\n logger.info(`Security middleware started for ${req.method} ${req.url}`);\r\n }\r\n\r\n // Add security headers\r\n response.headers.set('X-Content-Type-Options', 'nosniff');\r\n response.headers.set('X-Frame-Options', 'DENY');\r\n response.headers.set('X-XSS-Protection', '1; mode=block');\r\n response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');\r\n response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');\r\n\r\n // Enhanced CSP based on request context\r\n const isApiRoute = req.nextUrl.pathname.startsWith('/api');\r\n const csp = isApiRoute\r\n ? \"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'\"\r\n : \"default-src 'self'\";\r\n response.headers.set('Content-Security-Policy', csp);\r\n\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.info('Security middleware completed');\r\n } catch {\r\n logger.info('Security middleware completed');\r\n }\r\n\r\n // Let the request continue\r\n return;\r\n}\r\n\r\n// --- Security Factory ---\r\nexport function createSecurity(config: {\r\n csrfSecret: string;\r\n tokenExpiry: { access: number; refresh: number };\r\n}) {\r\n return {\r\n generateCsrfToken(sessionId: string): string {\r\n // Simple HMAC-based CSRF token\r\n return createHmac('sha256', config.csrfSecret).update(sessionId).digest('hex');\r\n },\r\n isTokenExpired(exp: number): boolean {\r\n return Date.now() / 1000 > exp;\r\n },\r\n getAccessTokenExpiry(): number {\r\n return config.tokenExpiry.access;\r\n },\r\n getRefreshTokenExpiry(): number {\r\n return config.tokenExpiry.refresh;\r\n },\r\n };\r\n}\r\n\r\n","const logger = {\r\n info: (message: string, ...args: unknown[]) => console.log(`[SessionService] ${message}`, ...args),\r\n warn: (message: string, ...args: unknown[]) => console.warn(`[SessionService] ${message}`, ...args),\r\n error: (message: string, ...args: unknown[]) => console.error(`[SessionService] ${message}`, ...args),\r\n};\r\n\r\nconst devLogger = {\r\n info: (...args: unknown[]) => logger.info(String(args[0]), ...args.slice(1)),\r\n warn: (...args: unknown[]) => logger.warn(String(args[0]), ...args.slice(1)),\r\n error: (...args: unknown[]) => logger.error(String(args[0]), ...args.slice(1)),\r\n forService: (_name: string) => ({\r\n info: (...args: unknown[]) => logger.info(String(args[0]), ...args.slice(1)),\r\n warn: (...args: unknown[]) => logger.warn(String(args[0]), ...args.slice(1)),\r\n error: (...args: unknown[]) => logger.error(String(args[0]), ...args.slice(1)),\r\n }),\r\n};\r\n\r\ninterface SessionRecord {\r\n id: string;\r\n userId: string;\r\n token: string;\r\n device?: string;\r\n expiresAt: Date;\r\n lastActiveAt?: Date;\r\n isActive: boolean;\r\n updatedAt: Date;\r\n createdAt: Date;\r\n}\r\n\r\n// UserService integration removed - use UserServiceCoordinator directly when needed\r\ntype PayloadStub = {\r\n logger: {\r\n info: (...args: unknown[]) => void;\r\n warn: (...args: unknown[]) => void;\r\n error: (...args: unknown[]) => void;\r\n };\r\n};\r\n\r\nasync function getPayloadClient(): Promise<PayloadStub> {\r\n return {\r\n logger: {\r\n info: (...args: unknown[]) => logger.info(String(args[0]), ...args.slice(1)),\r\n warn: (...args: unknown[]) => logger.warn(String(args[0]), ...args.slice(1)),\r\n error: (...args: unknown[]) => logger.error(String(args[0]), ...args.slice(1)),\r\n },\r\n };\r\n}\r\n\r\nfunction generateUUID(): string {\r\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\r\n return crypto.randomUUID();\r\n }\r\n // Fallback for environments without crypto.randomUUID\r\n return `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, c => {\r\n const r = (Math.random() * 16) | 0;\r\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\r\n return v.toString(16);\r\n });\r\n}\r\n\r\nclass SessionRepository {\r\n private readonly sessions = new Map<string, SessionRecord>();\r\n\r\n constructor(private readonly payload: PayloadStub) {\r\n void this.payload;\r\n }\r\n\r\n private createSessionId(): string {\r\n try {\r\n return generateUUID();\r\n } catch {\r\n return `session_${Date.now().toString(36)}`;\r\n }\r\n }\r\n\r\n private createToken(): string {\r\n try {\r\n return `token_${generateUUID()}`;\r\n } catch {\r\n return `token_${Date.now().toString(36)}`;\r\n }\r\n }\r\n\r\n async create(data: Partial<SessionRecord>): Promise<ValidationResultData<SessionRecord>> {\r\n if (!data.userId) {\r\n return {\r\n success: false,\r\n errors: [{ message: 'userId is required', path: 'create' }],\r\n };\r\n }\r\n\r\n const now = new Date();\r\n const session: SessionRecord = {\r\n id: data.id ?? this.createSessionId(),\r\n userId: data.userId,\r\n token: data.token ?? this.createToken(),\r\n expiresAt: data.expiresAt\r\n ? new Date(data.expiresAt)\r\n : new Date(now.getTime() + 1000 * 60 * 60),\r\n lastActiveAt: data.lastActiveAt ? new Date(data.lastActiveAt) : now,\r\n isActive: data.isActive ?? true,\r\n updatedAt: now,\r\n createdAt: now,\r\n ...(data.device !== undefined ? { device: data.device } : {}),\r\n };\r\n\r\n this.sessions.set(session.id, session);\r\n\r\n return { success: true, data: session };\r\n }\r\n\r\n async findById(id: string | number): Promise<ValidationResultData<SessionRecord>> {\r\n const session = this.sessions.get(String(id));\r\n if (!session) {\r\n return {\r\n success: false,\r\n errors: [{ message: 'Session not found', path: 'findById' }],\r\n };\r\n }\r\n\r\n return { success: true, data: session };\r\n }\r\n\r\n async delete(id: string | number): Promise<ValidationResultData> {\r\n const key = String(id);\r\n if (!this.sessions.has(key)) {\r\n return {\r\n success: false,\r\n errors: [{ message: 'Session not found', path: 'delete' }],\r\n };\r\n }\r\n\r\n this.sessions.delete(key);\r\n return { success: true };\r\n }\r\n\r\n async revokeAllUserSessions(userId: string): Promise<ValidationResultData> {\r\n let removed = false;\r\n for (const [key, session] of this.sessions.entries()) {\r\n if (session.userId === userId) {\r\n this.sessions.delete(key);\r\n removed = true;\r\n }\r\n }\r\n\r\n if (!removed) {\r\n return {\r\n success: false,\r\n errors: [{ message: 'No sessions found for user', path: 'revokeAllUserSessions' }],\r\n };\r\n }\r\n\r\n return { success: true };\r\n }\r\n\r\n async findAll(): Promise<ValidationResultData<SessionRecord[]>> {\r\n return { success: true, data: Array.from(this.sessions.values()) };\r\n }\r\n\r\n async update(\r\n id: string,\r\n data: Partial<SessionRecord>\r\n ): Promise<ValidationResultData<SessionRecord>> {\r\n const existing = this.sessions.get(id);\r\n if (!existing) {\r\n return {\r\n success: false,\r\n errors: [{ message: 'Session not found', path: 'update' }],\r\n };\r\n }\r\n\r\n const updated: SessionRecord = {\r\n ...existing,\r\n ...(data.userId !== undefined ? { userId: data.userId } : {}),\r\n ...(data.token !== undefined ? { token: data.token } : {}),\r\n ...(data.device !== undefined ? { device: data.device } : {}),\r\n ...(data.expiresAt !== undefined ? { expiresAt: new Date(data.expiresAt) } : {}),\r\n ...(data.lastActiveAt !== undefined ? { lastActiveAt: new Date(data.lastActiveAt) } : {}),\r\n ...(data.isActive !== undefined ? { isActive: data.isActive } : {}),\r\n updatedAt: new Date(),\r\n };\r\n\r\n this.sessions.set(id, updated);\r\n return { success: true, data: updated };\r\n }\r\n}\r\n\r\n/**\r\n * SessionService provides session management logic for user authentication.\r\n * It supports creating, validating, and invalidating sessions, and uses a repository for persistence.\r\n */\r\n\r\n// PayloadCMS native logging is used via payload.logger\r\n\r\ntype UserSession = SessionRecord;\r\ntype ValidationResultError = string | { message: string; path: string };\r\ntype ValidationResultData<T = unknown> = {\r\n success: boolean;\r\n data?: T;\r\n errors?: ValidationResultError[];\r\n};\r\n\r\nexport class SessionService {\r\n private repository: SessionRepository | null = null;\r\n\r\n constructor(repository?: SessionRepository) {\r\n if (repository) {\r\n this.repository = repository;\r\n }\r\n }\r\n\r\n private async getRepository(): Promise<SessionRepository> {\r\n if (!this.repository) {\r\n const payload = await getPayloadClient();\r\n this.repository = new SessionRepository(payload);\r\n }\r\n return this.repository;\r\n }\r\n\r\n /**\r\n * Creates a new session for a user.\r\n */\r\n async createSession(data: Partial<SessionRecord>): Promise<ValidationResultData<SessionRecord>> {\r\n if (!data.userId || typeof data.userId !== 'string') {\r\n return {\r\n success: false,\r\n errors: [\r\n {\r\n message: 'userId is required',\r\n path: 'userId',\r\n },\r\n ],\r\n };\r\n }\r\n const repository = await this.getRepository();\r\n const result = await repository.create(data);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Failed to create session', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('Failed to create session', { errors: result.errors });\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Validates a session by ID, checks for expiration, and deletes if expired.\r\n */\r\n async validateSession(sessionId: string): Promise<ValidationResultData<UserSession>> {\r\n try {\r\n const repository = await this.getRepository();\r\n const result = await repository.findById(sessionId);\r\n\r\n if (!result.success || !result.data) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.warn('Invalid session', { sessionId, errors: result.errors });\r\n } catch {\r\n devLogger.warn('Invalid session', { sessionId, errors: result.errors });\r\n }\r\n return {\r\n success: false,\r\n errors: result.errors ?? [{ message: 'Session not found', path: 'validateSession' }],\r\n };\r\n }\r\n\r\n const session = result.data;\r\n if (session.expiresAt.getTime() < Date.now()) {\r\n await repository.delete(sessionId);\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.info('Session expired and deleted', { sessionId });\r\n } catch {\r\n devLogger.info('Session expired and deleted', { sessionId });\r\n }\r\n\r\n return {\r\n success: false,\r\n errors: [{ message: 'Session expired', path: 'validateSession' }],\r\n };\r\n }\r\n\r\n // Fetch user data using UserServiceCoordinator\r\n const userResult = { success: true, data: { id: session.userId } } as const;\r\n if (!userResult.success || !userResult.data) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('User not found for session', {\r\n sessionId,\r\n userId: session.userId,\r\n });\r\n } catch {\r\n devLogger.error('User not found for session', {\r\n sessionId,\r\n userId: session.userId,\r\n });\r\n }\r\n return {\r\n success: false,\r\n errors: [{ message: 'User not found for session', path: 'validateSession' }],\r\n };\r\n }\r\n\r\n return { success: true, data: session };\r\n } catch (error) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Session validation failed', { error });\r\n } catch {\r\n devLogger.error('Session validation failed', { error });\r\n }\r\n return {\r\n success: false,\r\n errors: [{ message: 'Session validation failed', path: 'validateSession' }],\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Invalidates (deletes) a session by ID.\r\n */\r\n async invalidateSession(sessionId: string): Promise<ValidationResultData> {\r\n try {\r\n const repository = await this.getRepository();\r\n const result = await repository.delete(sessionId);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Session invalidation failed', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('Session invalidation failed', {\r\n errors: result.errors,\r\n });\r\n }\r\n return result;\r\n }\r\n return result;\r\n } catch (error) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Session invalidation failed', { error });\r\n } catch {\r\n devLogger.error('Session invalidation failed', { error });\r\n }\r\n return {\r\n success: false,\r\n errors: [\r\n {\r\n message: 'Session invalidation failed',\r\n path: 'invalidateSession',\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Invalidates (deletes) all sessions for a user by userId.\r\n */\r\n async invalidateAllUserSessions(userId: string): Promise<ValidationResultData> {\r\n try {\r\n const repository = await this.getRepository();\r\n const result = await repository.revokeAllUserSessions(userId);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('User sessions invalidation failed', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('User sessions invalidation failed', {\r\n errors: result.errors,\r\n });\r\n }\r\n return result;\r\n }\r\n return result;\r\n } catch (error) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('User sessions invalidation failed', {\r\n error,\r\n });\r\n } catch {\r\n devLogger.error('User sessions invalidation failed', { error });\r\n }\r\n return {\r\n success: false,\r\n errors: [\r\n {\r\n message: 'Failed to invalidate user sessions',\r\n path: 'invalidateAllUserSessions',\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n\r\n async getSessionById(id: string): Promise<ValidationResultData<SessionRecord>> {\r\n const repository = await this.getRepository();\r\n const result = await repository.findById(id);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.warn('Session not found', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.warn('Session not found', { errors: result.errors });\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async getAllSessions(): Promise<ValidationResultData<SessionRecord[]>> {\r\n const repository = await this.getRepository();\r\n const result = await repository.findAll();\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Failed to fetch sessions', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('Failed to fetch sessions', {\r\n errors: result.errors,\r\n });\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async updateSession(\r\n id: string,\r\n data: Partial<SessionRecord>\r\n ): Promise<ValidationResultData<SessionRecord>> {\r\n const repository = await this.getRepository();\r\n const result = await repository.update(id, data);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Failed to update session', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('Failed to update session', { errors: result.errors });\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n async deleteSession(id: string): Promise<ValidationResultData> {\r\n const repository = await this.getRepository();\r\n const result = await repository.delete(id);\r\n if (!result.success) {\r\n try {\r\n const payload = await getPayloadClient();\r\n payload.logger.error('Failed to delete session', {\r\n errors: result.errors,\r\n });\r\n } catch {\r\n devLogger.error('Failed to delete session', { errors: result.errors });\r\n }\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nexport const sessionService = new SessionService();\r\n\r\n","import { InfrastructureService } from '@revealui/core';\r\nimport type { Payload, PayloadRequest } from 'payload';\r\n\r\nclass AppError extends Error {\r\n constructor(\r\n public code: string,\r\n message: string,\r\n public cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'AppError';\r\n if (cause) {\r\n this.cause = cause;\r\n }\r\n }\r\n}\r\n\r\nconst ErrorCode = {\r\n TOKEN_INVALID: 'TOKEN_INVALID',\r\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\r\n AUTHENTICATION_ERROR: 'AUTHENTICATION_ERROR',\r\n INTERNAL_ERROR: 'INTERNAL_ERROR',\r\n} as const;\r\n\r\n/**\r\n * Token Service using PayloadCMS native authentication\r\n *\r\n * Leverages PayloadCMS built-in JWT handling, authentication,\r\n * and user management instead of custom implementations.\r\n *\r\n * NOTE: This service uses overrideAccess: true for password reset and account unlock\r\n * operations as these are system-level operations that need to bypass normal access control.\r\n * Regular user authentication operations respect normal access control.\r\n */\r\nexport class TokenService extends InfrastructureService {\r\n constructor(protected readonly payload: Payload) {\r\n super(payload, 'TokenService');\r\n }\r\n\r\n /**\r\n * Authenticate user and generate access token using PayloadCMS native login\r\n * @param credentials User login credentials\r\n * @param req Optional PayloadRequest for context\r\n * @returns Login result with user data and token\r\n */\r\n async login(credentials: { email: string; password: string }, req?: PayloadRequest) {\r\n try {\r\n this.logger.debug('Attempting user login', {\r\n email: credentials.email,\r\n serviceName: this.serviceName,\r\n operation: 'login',\r\n });\r\n\r\n const result = await this.payload.login({\r\n collection: 'users',\r\n data: {\r\n email: credentials.email,\r\n password: credentials.password,\r\n },\r\n ...(req && { req }),\r\n });\r\n\r\n this.logger.info('User login successful', {\r\n userId: result.user.id,\r\n email: result.user.email,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n this.logger.error('User login failed', {\r\n email: credentials.email,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.AUTHENTICATION_ERROR,\r\n 'Login failed',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Verify user by ID using PayloadCMS native functionality\r\n * @param userId User ID to verify\r\n * @returns User data if exists\r\n */\r\n async verifyUser(userId: string | number) {\r\n try {\r\n this.logger.debug('Verifying user', {\r\n userId,\r\n serviceName: this.serviceName,\r\n operation: 'verifyUser',\r\n });\r\n\r\n // Read operations respect collection-level access control\r\n const user = await this.payload.findByID({\r\n collection: 'users',\r\n id: userId,\r\n });\r\n\r\n this.logger.debug('User verification successful', {\r\n userId: user.id,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return user;\r\n } catch (error) {\r\n this.logger.error('User verification failed', {\r\n userId,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.AUTHENTICATION_ERROR,\r\n 'User verification failed',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Generate password reset token using PayloadCMS native functionality\r\n * @param email User email address\r\n * @returns Password reset token\r\n */\r\n async generatePasswordResetToken(email: string) {\r\n try {\r\n this.logger.debug('Generating password reset token', {\r\n email,\r\n serviceName: this.serviceName,\r\n operation: 'generatePasswordResetToken',\r\n });\r\n\r\n const token = await this.payload.forgotPassword({\r\n collection: 'users',\r\n data: { email },\r\n });\r\n\r\n this.logger.info('Password reset token generated', {\r\n email,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return token;\r\n } catch (error) {\r\n this.logger.error('Password reset token generation failed', {\r\n email,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.INTERNAL_ERROR,\r\n 'Failed to generate password reset token',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Reset user password using PayloadCMS native functionality\r\n * @param token Password reset token\r\n * @param newPassword New password\r\n * @returns Reset result with user and new token\r\n *\r\n * NOTE: Uses overrideAccess: true as this is a system-level password reset operation\r\n * that requires bypassing normal access control for security token validation.\r\n */\r\n async resetPassword(token: string, newPassword: string) {\r\n try {\r\n this.logger.debug('Resetting password', {\r\n serviceName: this.serviceName,\r\n operation: 'resetPassword',\r\n });\r\n\r\n const result = await this.payload.resetPassword({\r\n collection: 'users',\r\n data: {\r\n token,\r\n password: newPassword,\r\n },\r\n overrideAccess: true, // System-level operation for password reset flow\r\n });\r\n\r\n this.logger.info('Password reset successful', {\r\n userId: result.user?.id,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n this.logger.error('Password reset failed', {\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.AUTHENTICATION_ERROR,\r\n 'Password reset failed',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Verify email using PayloadCMS native functionality\r\n * @param token Email verification token\r\n * @returns Verification success status\r\n */\r\n async verifyEmail(token: string) {\r\n try {\r\n this.logger.debug('Verifying email', {\r\n serviceName: this.serviceName,\r\n operation: 'verifyEmail',\r\n });\r\n\r\n const result = await this.payload.verifyEmail({\r\n collection: 'users',\r\n token,\r\n });\r\n\r\n this.logger.info('Email verification completed', {\r\n success: result,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n this.logger.error('Email verification failed', {\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.AUTHENTICATION_ERROR,\r\n 'Email verification failed',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Unlock user account using PayloadCMS native functionality\r\n * @param email User email address\r\n * @param password User password\r\n * @returns Unlock success status\r\n *\r\n * NOTE: Uses overrideAccess: true as this is a system-level account unlock operation\r\n * that requires bypassing normal access control for account recovery.\r\n */\r\n async unlockUser(email: string, password: string) {\r\n try {\r\n this.logger.debug('Unlocking user account', {\r\n email,\r\n serviceName: this.serviceName,\r\n operation: 'unlockUser',\r\n });\r\n\r\n const result = await this.payload.unlock({\r\n collection: 'users',\r\n data: { email, password },\r\n overrideAccess: true, // System-level operation for account recovery\r\n });\r\n\r\n this.logger.info('User account unlock completed', {\r\n email,\r\n success: result,\r\n serviceName: this.serviceName,\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n this.logger.error('User account unlock failed', {\r\n email,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n serviceName: this.serviceName,\r\n });\r\n throw new AppError(\r\n ErrorCode.AUTHENTICATION_ERROR,\r\n 'User account unlock failed',\r\n error instanceof Error ? error : new Error(String(error))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected onInitialize(): void {\r\n this.logger.info('TokenService initialized with PayloadCMS native auth', {\r\n serviceName: this.serviceName,\r\n });\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected onCleanup(): void {\r\n // No cleanup needed as PayloadCMS handles JWT lifecycle\r\n this.logger.info('TokenService cleaned up', {\r\n serviceName: this.serviceName,\r\n });\r\n }\r\n\r\n /**\r\n * @inheritdoc\r\n */\r\n protected onHealthCheck(): void {\r\n // Basic health check - PayloadCMS handles JWT internally\r\n this.logger.debug('TokenService health check passed', {\r\n serviceName: this.serviceName,\r\n });\r\n }\r\n}\r\n\r\n// Export factory function for PayloadCMS integration\r\nexport function createTokenService(payload: Payload): TokenService {\r\n return new TokenService(payload);\r\n}\r\n\r\n"],"mappings":"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","names":["RATE_LIMITS","generateRateLimitKey","generateIPRateLimitKey","checkRateLimit","randomBytes","devLogger","events","event","createHmac","logger","devLogger","getPayloadClient","InfrastructureService"]}
1
+ {"version":3,"sources":["../src/audit.ts","../src/auth.ts","../src/authorization.ts","../src/encryption.ts","../src/gdpr.ts","../src/gdpr-storage.ts","../src/logger.ts","../src/headers.ts"],"sourcesContent":["/**\n * Audit Logging System\n *\n * Track security-relevant events and user actions for compliance\n */\n\nexport type AuditEventType =\n | 'auth.login'\n | 'auth.logout'\n | 'auth.failed_login'\n | 'auth.password_change'\n | 'auth.password_reset'\n | 'auth.mfa_enabled'\n | 'auth.mfa_disabled'\n | 'user.create'\n | 'user.update'\n | 'user.delete'\n | 'user.view'\n | 'data.create'\n | 'data.read'\n | 'data.update'\n | 'data.delete'\n | 'data.export'\n | 'permission.grant'\n | 'permission.revoke'\n | 'role.assign'\n | 'role.remove'\n | 'config.change'\n | 'security.violation'\n | 'security.alert'\n | 'gdpr.consent'\n | 'gdpr.data_request'\n | 'gdpr.data_deletion'\n | `data.${string}`\n | `permission.${string}`\n | `security.${string}`\n | `gdpr.${string}`;\n\nexport type AuditSeverity = 'low' | 'medium' | 'high' | 'critical';\n\nexport interface AuditEvent {\n id: string;\n timestamp: string;\n type: AuditEventType;\n severity: AuditSeverity;\n actor: {\n id: string;\n type: 'user' | 'system' | 'api';\n ip?: string;\n userAgent?: string;\n };\n resource?: {\n type: string;\n id: string;\n name?: string;\n };\n action: string;\n result: 'success' | 'failure' | 'partial';\n changes?: {\n before?: Record<string, unknown>;\n after?: Record<string, unknown>;\n };\n metadata?: Record<string, unknown>;\n message?: string;\n}\n\nexport interface AuditQuery {\n types?: AuditEventType[];\n actorId?: string;\n resourceType?: string;\n resourceId?: string;\n startDate?: Date;\n endDate?: Date;\n severity?: AuditSeverity[];\n result?: ('success' | 'failure' | 'partial')[];\n limit?: number;\n offset?: number;\n}\n\nexport interface AuditStorage {\n write(event: AuditEvent): Promise<void>;\n query(query: AuditQuery): Promise<AuditEvent[]>;\n count(query: AuditQuery): Promise<number>;\n}\n\n/**\n * Audit logging system\n */\nexport class AuditSystem {\n private storage: AuditStorage;\n private filters: Array<(event: AuditEvent) => boolean> = [];\n\n constructor(storage: AuditStorage) {\n this.storage = storage;\n }\n\n /**\n * Log audit event\n */\n async log(event: Omit<AuditEvent, 'id' | 'timestamp'>): Promise<void> {\n const fullEvent: AuditEvent = {\n ...event,\n id: crypto.randomUUID(),\n timestamp: new Date().toISOString(),\n };\n\n // Apply filters\n const shouldLog = this.filters.every((filter) => filter(fullEvent));\n\n if (!shouldLog) {\n return;\n }\n\n await this.storage.write(fullEvent);\n }\n\n /**\n * Log authentication event\n */\n async logAuth(\n type: Extract<\n AuditEventType,\n 'auth.login' | 'auth.logout' | 'auth.failed_login' | 'auth.password_change'\n >,\n actorId: string,\n result: 'success' | 'failure',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n await this.log({\n type,\n severity: result === 'failure' ? 'medium' : 'low',\n actor: {\n id: actorId,\n type: 'user',\n },\n action: (type as string).replace('auth.', ''),\n result,\n metadata,\n });\n }\n\n /**\n * Log data access event\n */\n async logDataAccess(\n action: 'create' | 'read' | 'update' | 'delete',\n actorId: string,\n resourceType: string,\n resourceId: string,\n result: 'success' | 'failure',\n changes?: { before?: Record<string, unknown>; after?: Record<string, unknown> },\n ): Promise<void> {\n await this.log({\n type: `data.${action}` as AuditEventType,\n severity: action === 'delete' ? 'high' : 'medium',\n actor: {\n id: actorId,\n type: 'user',\n },\n resource: {\n type: resourceType,\n id: resourceId,\n },\n action,\n result,\n changes,\n });\n }\n\n /**\n * Log permission change\n */\n async logPermissionChange(\n action: 'grant' | 'revoke',\n actorId: string,\n targetUserId: string,\n permission: string,\n result: 'success' | 'failure',\n ): Promise<void> {\n await this.log({\n type: `permission.${action}` as AuditEventType,\n severity: 'high',\n actor: {\n id: actorId,\n type: 'user',\n },\n resource: {\n type: 'user',\n id: targetUserId,\n },\n action,\n result,\n metadata: {\n permission,\n },\n });\n }\n\n /**\n * Log security event\n */\n async logSecurityEvent(\n type: 'violation' | 'alert',\n severity: AuditSeverity,\n actorId: string,\n message: string,\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n await this.log({\n type: `security.${type}` as AuditEventType,\n severity,\n actor: {\n id: actorId,\n type: 'user',\n },\n action: type,\n result: 'failure',\n message,\n metadata,\n });\n }\n\n /**\n * Log GDPR event\n */\n async logGDPREvent(\n type: 'consent' | 'data_request' | 'data_deletion',\n actorId: string,\n result: 'success' | 'failure',\n metadata?: Record<string, unknown>,\n ): Promise<void> {\n await this.log({\n type: `gdpr.${type}` as AuditEventType,\n severity: 'high',\n actor: {\n id: actorId,\n type: 'user',\n },\n action: type,\n result,\n metadata,\n });\n }\n\n /**\n * Query audit logs\n */\n async query(query: AuditQuery): Promise<AuditEvent[]> {\n return this.storage.query(query);\n }\n\n /**\n * Count audit logs\n */\n async count(query: AuditQuery): Promise<number> {\n return this.storage.count(query);\n }\n\n /**\n * Add filter\n */\n addFilter(filter: (event: AuditEvent) => boolean): void {\n this.filters.push(filter);\n }\n\n /**\n * Remove filter\n */\n removeFilter(filter: (event: AuditEvent) => boolean): void {\n const index = this.filters.indexOf(filter);\n if (index > -1) {\n this.filters.splice(index, 1);\n }\n }\n}\n\n/**\n * In-memory audit storage (for development)\n */\nexport class InMemoryAuditStorage implements AuditStorage {\n private events: AuditEvent[] = [];\n private maxEvents: number;\n\n constructor(maxEvents: number = 10000) {\n this.maxEvents = maxEvents;\n }\n\n async write(event: AuditEvent): Promise<void> {\n this.events.push(event);\n\n // Trim old events\n if (this.events.length > this.maxEvents) {\n this.events.shift();\n }\n }\n\n async query(query: AuditQuery): Promise<AuditEvent[]> {\n let results = [...this.events];\n\n // Filter by type\n if (query.types && query.types.length > 0) {\n results = results.filter((e) => query.types?.includes(e.type));\n }\n\n // Filter by actor\n if (query.actorId) {\n results = results.filter((e) => e.actor.id === query.actorId);\n }\n\n // Filter by resource\n if (query.resourceType) {\n results = results.filter((e) => e.resource?.type === query.resourceType);\n }\n\n if (query.resourceId) {\n results = results.filter((e) => e.resource?.id === query.resourceId);\n }\n\n // Filter by date range\n if (query.startDate) {\n const startDate = query.startDate;\n results = results.filter((e) => new Date(e.timestamp) >= startDate);\n }\n\n if (query.endDate) {\n const endDate = query.endDate;\n results = results.filter((e) => new Date(e.timestamp) <= endDate);\n }\n\n // Filter by severity\n if (query.severity && query.severity.length > 0) {\n results = results.filter((e) => query.severity?.includes(e.severity));\n }\n\n // Filter by result\n if (query.result && query.result.length > 0) {\n results = results.filter((e) => query.result?.includes(e.result));\n }\n\n // Sort by timestamp (newest first)\n results.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n // Apply pagination\n const offset = query.offset || 0;\n const limit = query.limit || 100;\n\n return results.slice(offset, offset + limit);\n }\n\n async count(query: AuditQuery): Promise<number> {\n const results = await this.query({ ...query, limit: undefined, offset: undefined });\n return results.length;\n }\n\n /**\n * Clear all events\n */\n clear(): void {\n this.events = [];\n }\n\n /**\n * Get all events\n */\n getAll(): AuditEvent[] {\n return [...this.events];\n }\n}\n\n/**\n * Audit trail decorator\n */\nexport function AuditTrail(\n type: AuditEventType,\n action: string,\n options?: {\n severity?: AuditSeverity;\n captureChanges?: boolean;\n resourceType?: string;\n },\n) {\n return (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (\n this: { user?: { id?: string }; audit?: AuditSystem },\n ...args: unknown[]\n ) {\n const actorId = this.user?.id || 'system';\n const before = options?.captureChanges ? args[0] : undefined;\n\n let result: 'success' | 'failure' | 'partial' = 'success';\n let error: Error | undefined;\n\n try {\n const returnValue = await originalMethod.apply(this, args);\n\n // Log audit event\n if (this.audit) {\n await this.audit.log({\n type,\n severity: options?.severity || 'medium',\n actor: {\n id: actorId,\n type: 'user',\n },\n resource: options?.resourceType\n ? {\n type: options.resourceType,\n id: (args[0] as { id?: string })?.id || 'unknown',\n }\n : undefined,\n action,\n result,\n changes: options?.captureChanges\n ? {\n before: before as Record<string, unknown> | undefined,\n after: returnValue as Record<string, unknown> | undefined,\n }\n : undefined,\n });\n }\n\n return returnValue;\n } catch (err) {\n result = 'failure';\n error = err as Error;\n\n // Log failure\n if (this.audit) {\n await this.audit.log({\n type,\n severity: 'high',\n actor: {\n id: actorId,\n type: 'user',\n },\n resource: options?.resourceType\n ? {\n type: options.resourceType,\n id: (args[0] as { id?: string })?.id || 'unknown',\n }\n : undefined,\n action,\n result,\n message: error.message,\n });\n }\n\n throw error;\n }\n };\n\n return descriptor;\n };\n}\n\n/**\n * Audit middleware\n */\nexport function createAuditMiddleware<TRequest = unknown, TResponse = unknown>(\n audit: AuditSystem,\n getUser: (request: TRequest) => { id: string; ip?: string; userAgent?: string },\n) {\n return async (\n request: TRequest & { method: string; url: string },\n next: () => Promise<TResponse & { status?: number }>,\n ) => {\n const user = getUser(request);\n const startTime = Date.now();\n\n try {\n const response = await next();\n\n // Log successful request\n await audit.log({\n type: 'data.read',\n severity: 'low',\n actor: {\n id: user.id,\n type: 'user',\n ip: user.ip,\n userAgent: user.userAgent,\n },\n action: request.method,\n result: 'success',\n metadata: {\n path: request.url,\n duration: Date.now() - startTime,\n status: response.status,\n },\n });\n\n return response;\n } catch (error) {\n // Log failed request\n await audit.log({\n type: 'data.read',\n severity: 'medium',\n actor: {\n id: user.id,\n type: 'user',\n ip: user.ip,\n userAgent: user.userAgent,\n },\n action: request.method,\n result: 'failure',\n message: error instanceof Error ? error.message : 'Unknown error',\n metadata: {\n path: request.url,\n duration: Date.now() - startTime,\n },\n });\n\n throw error;\n }\n };\n}\n\n/**\n * Audit report generator\n */\nexport class AuditReportGenerator {\n constructor(private audit: AuditSystem) {}\n\n /**\n * Generate security report\n */\n async generateSecurityReport(\n startDate: Date,\n endDate: Date,\n ): Promise<{\n totalEvents: number;\n securityViolations: number;\n failedLogins: number;\n permissionChanges: number;\n dataExports: number;\n criticalEvents: AuditEvent[];\n }> {\n const allEvents = await this.audit.query({\n startDate,\n endDate,\n });\n\n const securityViolations = allEvents.filter((e) => e.type.startsWith('security.')).length;\n\n const failedLogins = allEvents.filter((e) => e.type === 'auth.failed_login').length;\n\n const permissionChanges = allEvents.filter((e) => e.type.startsWith('permission.')).length;\n\n const dataExports = allEvents.filter((e) => e.type === 'data.export').length;\n\n const criticalEvents = allEvents.filter((e) => e.severity === 'critical');\n\n return {\n totalEvents: allEvents.length,\n securityViolations,\n failedLogins,\n permissionChanges,\n dataExports,\n criticalEvents,\n };\n }\n\n /**\n * Generate user activity report\n */\n async generateUserActivityReport(\n userId: string,\n startDate: Date,\n endDate: Date,\n ): Promise<{\n totalActions: number;\n actionsByType: Record<string, number>;\n failedActions: number;\n recentActions: AuditEvent[];\n }> {\n const events = await this.audit.query({\n actorId: userId,\n startDate,\n endDate,\n });\n\n const actionsByType = events.reduce(\n (acc, event) => {\n acc[event.type] = (acc[event.type] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>,\n );\n\n const failedActions = events.filter((e) => e.result === 'failure').length;\n\n return {\n totalActions: events.length,\n actionsByType,\n failedActions,\n recentActions: events.slice(0, 10),\n };\n }\n\n /**\n * Generate compliance report\n */\n async generateComplianceReport(\n startDate: Date,\n endDate: Date,\n ): Promise<{\n dataAccesses: number;\n dataModifications: number;\n dataDeletions: number;\n gdprRequests: number;\n auditTrailComplete: boolean;\n }> {\n const events = await this.audit.query({\n startDate,\n endDate,\n });\n\n const dataAccesses = events.filter((e) => e.type === 'data.read').length;\n\n const dataModifications = events.filter(\n (e) => e.type === 'data.update' || e.type === 'data.create',\n ).length;\n\n const dataDeletions = events.filter((e) => e.type === 'data.delete').length;\n\n const gdprRequests = events.filter((e) => e.type.startsWith('gdpr.')).length;\n\n // Check if audit trail is complete (no gaps)\n const auditTrailComplete = this.checkAuditTrailContinuity(events);\n\n return {\n dataAccesses,\n dataModifications,\n dataDeletions,\n gdprRequests,\n auditTrailComplete,\n };\n }\n\n /**\n * Check audit trail continuity\n */\n private checkAuditTrailContinuity(events: AuditEvent[]): boolean {\n if (events.length === 0) return true;\n\n // Sort by timestamp\n const sorted = events.sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),\n );\n\n // Check for gaps (simplified - just check if we have events)\n return sorted.length > 0;\n }\n}\n\n/**\n * Global audit system\n */\nexport const audit = new AuditSystem(new InMemoryAuditStorage());\n","/**\n * Authentication Utilities\n *\n * OAuth support, password hashing, and two-factor authentication.\n * JWT-based auth was removed — session auth is handled by @revealui/auth.\n */\n\nimport { createHmac, timingSafeEqual } from 'node:crypto';\n\nexport interface User {\n id: string;\n email: string;\n username?: string;\n roles: string[];\n permissions: string[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * OAuth configuration\n */\nexport interface OAuthConfig {\n provider: 'google' | 'github' | 'microsoft' | 'custom';\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n scope?: string[];\n authorizationUrl?: string;\n tokenUrl?: string;\n userInfoUrl?: string;\n}\n\n/**\n * OAuth provider configurations\n */\nexport const OAuthProviders = {\n google: {\n authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',\n tokenUrl: 'https://oauth2.googleapis.com/token',\n userInfoUrl: 'https://www.googleapis.com/oauth2/v2/userinfo',\n scope: ['openid', 'email', 'profile'],\n },\n github: {\n authorizationUrl: 'https://github.com/login/oauth/authorize',\n tokenUrl: 'https://github.com/login/oauth/access_token',\n userInfoUrl: 'https://api.github.com/user',\n scope: ['user:email'],\n },\n microsoft: {\n authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n userInfoUrl: 'https://graph.microsoft.com/v1.0/me',\n scope: ['openid', 'email', 'profile'],\n },\n};\n\n/**\n * OAuth client\n */\nexport class OAuthClient {\n private config: OAuthConfig;\n\n constructor(config: OAuthConfig) {\n // Provider defaults fill in missing fields; user-provided config takes precedence\n this.config = {\n ...OAuthProviders[config.provider as keyof typeof OAuthProviders],\n ...config,\n };\n }\n\n /**\n * Get authorization URL\n */\n getAuthorizationUrl(state?: string): string {\n const params = new URLSearchParams({\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n response_type: 'code',\n scope: (this.config.scope || []).join(' '),\n });\n\n if (state) {\n params.append('state', state);\n }\n\n return `${this.config.authorizationUrl}?${params.toString()}`;\n }\n\n /**\n * Exchange code for token\n */\n async exchangeCodeForToken(code: string): Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n }> {\n if (!this.config.tokenUrl) throw new Error('tokenUrl is required for OAuth');\n const response = await fetch(this.config.tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n client_id: this.config.clientId,\n client_secret: this.config.clientSecret,\n code,\n grant_type: 'authorization_code',\n redirect_uri: this.config.redirectUri,\n }),\n });\n\n if (!response.ok) {\n let detail = '';\n try {\n const body = await response.text();\n detail = `: ${response.status} ${body.slice(0, 200)}`;\n } catch {\n detail = `: ${response.status}`;\n }\n throw new Error(`Failed to exchange code for token${detail}`);\n }\n\n return response.json() as Promise<{\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n }>;\n }\n\n /**\n * Get user info\n */\n async getUserInfo(accessToken: string): Promise<{\n id: string;\n email: string;\n name?: string;\n picture?: string;\n }> {\n if (!this.config.userInfoUrl) throw new Error('userInfoUrl is required for OAuth');\n const response = await fetch(this.config.userInfoUrl, {\n headers: {\n // biome-ignore lint/style/useNamingConvention: HTTP header convention\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n let detail = '';\n try {\n const body = await response.text();\n detail = `: ${response.status} ${body.slice(0, 200)}`;\n } catch {\n detail = `: ${response.status}`;\n }\n throw new Error(`Failed to fetch user info${detail}`);\n }\n\n return response.json() as Promise<{\n id: string;\n email: string;\n name?: string;\n picture?: string;\n }>;\n }\n}\n\n/**\n * Password hashing utilities\n *\n * Uses PBKDF2 with a random salt for secure password hashing.\n *\n * @deprecated Use `@revealui/auth` instead — it uses bcrypt which is more\n * resistant to GPU brute-force attacks. This PBKDF2 implementation will be\n * removed in a future major version.\n */\n\nconst PH_ITERATIONS = 100000;\nconst PH_KEY_LENGTH = 64;\nconst PH_DIGEST = 'sha512';\n\n/**\n * Hash password with PBKDF2 and random salt\n */\nasync function hashPassword(password: string): Promise<string> {\n const { pbkdf2, randomBytes: rb } = await import('node:crypto');\n const salt = rb(16).toString('hex');\n\n return new Promise((resolve, reject) => {\n pbkdf2(password, salt, PH_ITERATIONS, PH_KEY_LENGTH, PH_DIGEST, (err, derivedKey) => {\n if (err) reject(err);\n else resolve(`${salt}:${derivedKey.toString('hex')}`);\n });\n });\n}\n\n/**\n * Verify password against stored hash\n */\nasync function verifyPassword(password: string, storedHash: string): Promise<boolean> {\n const { pbkdf2, timingSafeEqual: tse } = await import('node:crypto');\n const [salt, hash] = storedHash.split(':');\n\n if (!(salt && hash)) {\n return false;\n }\n\n return new Promise((resolve, reject) => {\n pbkdf2(password, salt, PH_ITERATIONS, PH_KEY_LENGTH, PH_DIGEST, (err, derivedKey) => {\n if (err) reject(err);\n else {\n const derived = Buffer.from(derivedKey.toString('hex'), 'utf-8');\n const expected = Buffer.from(hash, 'utf-8');\n if (derived.length !== expected.length) {\n resolve(false);\n } else {\n resolve(tse(derived, expected));\n }\n }\n });\n });\n}\n\nexport const PasswordHasher = {\n hash: hashPassword,\n verify: verifyPassword,\n} as const;\n\n/**\n * Two-factor authentication\n */\n\n/**\n * Base32 encode\n */\nfunction base32Encode(buffer: Uint8Array): string {\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n let result = '';\n let bits = 0;\n let value = 0;\n\n for (const byte of buffer) {\n if (byte === undefined) continue;\n value = (value << 8) | byte;\n bits += 8;\n\n while (bits >= 5) {\n result += alphabet[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n\n if (bits > 0) {\n result += alphabet[(value << (5 - bits)) & 31];\n }\n\n return result;\n}\n\n/**\n * HMAC-SHA1 implementation for TOTP\n */\nfunction totpHmac(key: string, message: string): Uint8Array {\n const hmacDigest = createHmac('sha1', key).update(message).digest();\n return new Uint8Array(hmacDigest);\n}\n\n/**\n * Generate TOTP secret\n */\nfunction generateSecret(): string {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n const buffer = new Uint8Array(20);\n crypto.getRandomValues(buffer);\n return base32Encode(buffer);\n}\n\n/**\n * Generate TOTP code\n */\nfunction generateCode(secret: string, timestamp?: number): string {\n const time = Math.floor((timestamp || Date.now()) / 30000);\n const hmacDigest = totpHmac(secret, time.toString());\n // biome-ignore lint/style/noNonNullAssertion: HMAC-SHA1 always produces 20 bytes; buffer indices are guaranteed valid\n const offset = hmacDigest[hmacDigest.length - 1]! & 0x0f;\n // biome-ignore lint/style/noNonNullAssertion: HMAC-SHA1 always produces 20 bytes; buffer indices are guaranteed valid\n const b0 = hmacDigest[offset]! & 0x7f;\n // biome-ignore lint/style/noNonNullAssertion: HMAC-SHA1 always produces 20 bytes; buffer indices are guaranteed valid\n const b1 = hmacDigest[offset + 1]! & 0xff;\n // biome-ignore lint/style/noNonNullAssertion: HMAC-SHA1 always produces 20 bytes; buffer indices are guaranteed valid\n const b2 = hmacDigest[offset + 2]! & 0xff;\n // biome-ignore lint/style/noNonNullAssertion: HMAC-SHA1 always produces 20 bytes; buffer indices are guaranteed valid\n const b3 = hmacDigest[offset + 3]! & 0xff;\n const code = ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3) % 1000000;\n\n return code.toString().padStart(6, '0');\n}\n\n/**\n * Verify TOTP code\n */\nfunction verifyCode(secret: string, code: string, window: number = 1): boolean {\n const timestamp = Date.now();\n\n // Check current and adjacent time windows\n for (let i = -window; i <= window; i++) {\n const testTime = timestamp + i * 30000;\n const testCode = generateCode(secret, testTime);\n\n if (\n testCode.length === code.length &&\n timingSafeEqual(Buffer.from(testCode), Buffer.from(code))\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nexport const TwoFactorAuth = {\n generateSecret,\n generateCode,\n verifyCode,\n} as const;\n","/**\n * Authorization System\n *\n * Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC)\n */\n\nexport interface Permission {\n resource: string;\n action: string;\n conditions?: Record<string, unknown>;\n}\n\nexport interface Role {\n id: string;\n name: string;\n description?: string;\n permissions: Permission[];\n inherits?: string[];\n}\n\nexport interface Policy {\n id: string;\n name: string;\n effect: 'allow' | 'deny';\n resources: string[];\n actions: string[];\n conditions?: PolicyCondition[];\n priority?: number;\n}\n\nexport interface PolicyCondition {\n field: string;\n operator: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains';\n value: unknown;\n}\n\nexport interface AuthorizationContext {\n user: {\n id: string;\n roles: string[];\n attributes?: Record<string, unknown>;\n };\n resource?: {\n type: string;\n id?: string;\n owner?: string;\n attributes?: Record<string, unknown>;\n };\n environment?: {\n time?: Date;\n ip?: string;\n userAgent?: string;\n };\n}\n\n/**\n * Authorization system\n */\nexport class AuthorizationSystem {\n private roles: Map<string, Role> = new Map();\n private policies: Map<string, Policy> = new Map();\n\n /**\n * Register role\n */\n registerRole(role: Role): void {\n this.roles.set(role.id, role);\n }\n\n /**\n * Get role\n */\n getRole(roleId: string): Role | undefined {\n return this.roles.get(roleId);\n }\n\n /**\n * Register policy\n */\n registerPolicy(policy: Policy): void {\n this.policies.set(policy.id, policy);\n }\n\n /**\n * Check if user has permission (RBAC)\n */\n hasPermission(userRoles: string[], resource: string, action: string): boolean {\n // Get all permissions for user's roles\n const permissions = this.getUserPermissions(userRoles);\n\n // Check if any permission matches\n return permissions.some(\n (permission) =>\n this.matchesResource(permission.resource, resource) &&\n this.matchesAction(permission.action, action),\n );\n }\n\n /**\n * Check access with policies (ABAC)\n */\n checkAccess(\n context: AuthorizationContext,\n resource: string,\n action: string,\n ): { allowed: boolean; reason?: string } {\n // Check RBAC first\n if (this.hasPermission(context.user.roles, resource, action)) {\n return { allowed: true };\n }\n\n // Check policies\n const applicablePolicies = this.getApplicablePolicies(resource, action, context);\n\n // Sort by priority (higher priority first)\n applicablePolicies.sort((a, b) => (b.priority || 0) - (a.priority || 0));\n\n // Apply first matching policy\n for (const policy of applicablePolicies) {\n if (this.evaluateConditions(policy.conditions || [], context)) {\n return {\n allowed: policy.effect === 'allow',\n reason: policy.effect === 'deny' ? `Denied by policy: ${policy.name}` : undefined,\n };\n }\n }\n\n return { allowed: false, reason: 'No matching policy' };\n }\n\n /**\n * Get all permissions for roles\n */\n private getUserPermissions(roleIds: string[]): Permission[] {\n const permissions: Permission[] = [];\n const visited = new Set<string>();\n\n const addRolePermissions = (roleId: string) => {\n if (visited.has(roleId)) return;\n\n visited.add(roleId);\n\n const role = this.roles.get(roleId);\n if (!role) return;\n\n // Add role permissions\n permissions.push(...role.permissions);\n\n // Add inherited permissions\n if (role.inherits) {\n role.inherits.forEach((inheritedRoleId) => {\n addRolePermissions(inheritedRoleId);\n });\n }\n };\n\n roleIds.forEach(addRolePermissions);\n\n return permissions;\n }\n\n /**\n * Get applicable policies\n */\n private getApplicablePolicies(\n resource: string,\n action: string,\n _context: AuthorizationContext,\n ): Policy[] {\n return Array.from(this.policies.values()).filter((policy) => {\n // Check if resource matches\n const resourceMatches = policy.resources.some((r) => this.matchesResource(r, resource));\n\n // Check if action matches\n const actionMatches = policy.actions.some((a) => this.matchesAction(a, action));\n\n return resourceMatches && actionMatches;\n });\n }\n\n /**\n * Match resource pattern\n */\n private matchesResource(pattern: string, resource: string): boolean {\n if (pattern === '*') return true;\n if (pattern === resource) return true;\n\n // Convert glob pattern to regex\n const regex = new RegExp(\n `^${pattern.replace(/\\./g, '\\\\.').replace(/\\*/g, '.*').replace(/\\?/g, '.')}$`,\n );\n\n return regex.test(resource);\n }\n\n /**\n * Match action pattern\n */\n private matchesAction(pattern: string, action: string): boolean {\n if (pattern === '*') return true;\n if (pattern === action) return true;\n\n // Support wildcards like \"read:*\"\n const regex = new RegExp(\n `^${pattern.replace(/\\./g, '\\\\.').replace(/\\*/g, '.*').replace(/\\?/g, '.')}$`,\n );\n\n return regex.test(action);\n }\n\n /**\n * Evaluate policy conditions\n */\n private evaluateConditions(\n conditions: PolicyCondition[],\n context: AuthorizationContext,\n ): boolean {\n return conditions.every((condition) => {\n const value = this.getContextValue(condition.field, context);\n return this.evaluateCondition(condition, value);\n });\n }\n\n /**\n * Get value from context\n */\n private getContextValue(field: string, context: AuthorizationContext): unknown {\n const parts = field.split('.');\n\n let value: unknown = context;\n\n for (const part of parts) {\n if (value && typeof value === 'object' && part in value) {\n value = (value as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return value;\n }\n\n /**\n * Evaluate single condition\n */\n private evaluateCondition(condition: PolicyCondition, value: unknown): boolean {\n switch (condition.operator) {\n case 'eq':\n return value === condition.value;\n\n case 'ne':\n return value !== condition.value;\n\n case 'gt':\n return typeof value === 'number' && value > (condition.value as number);\n\n case 'gte':\n return typeof value === 'number' && value >= (condition.value as number);\n\n case 'lt':\n return typeof value === 'number' && value < (condition.value as number);\n\n case 'lte':\n return typeof value === 'number' && value <= (condition.value as number);\n\n case 'in':\n return Array.isArray(condition.value) && condition.value.includes(value);\n\n case 'contains':\n return (\n typeof value === 'string' &&\n typeof condition.value === 'string' &&\n value.includes(condition.value)\n );\n\n default:\n return false;\n }\n }\n\n /**\n * Check if user owns resource\n */\n ownsResource(userId: string, resource: { owner?: string }): boolean {\n return resource.owner === userId;\n }\n\n /**\n * Clear all roles and policies\n */\n clear(): void {\n this.roles.clear();\n this.policies.clear();\n }\n}\n\n/**\n * Global authorization instance\n */\nexport const authorization = new AuthorizationSystem();\n\n/**\n * Common roles — aligned with DB schema (`users.role` column)\n * and `UserRoleSchema` in @revealui/contracts.\n *\n * Values: owner | admin | editor | viewer | agent | contributor\n */\nexport const CommonRoles: Record<string, Role> = {\n owner: {\n id: 'owner',\n name: 'Owner',\n description: 'Full control — inherits admin',\n permissions: [{ resource: '*', action: '*' }],\n inherits: ['admin'],\n },\n admin: {\n id: 'admin',\n name: 'Administrator',\n description: 'Full system access',\n permissions: [{ resource: '*', action: '*' }],\n },\n editor: {\n id: 'editor',\n name: 'Editor',\n description: 'Can read and modify content',\n permissions: [\n { resource: 'content', action: 'read' },\n { resource: 'content', action: 'create' },\n { resource: 'content', action: 'update' },\n { resource: 'profile', action: 'read' },\n { resource: 'profile', action: 'update' },\n { resource: 'sites', action: 'read' },\n { resource: 'marketplace', action: 'read' },\n ],\n },\n viewer: {\n id: 'viewer',\n name: 'Viewer',\n description: 'Read-only access',\n permissions: [\n { resource: 'content', action: 'read' },\n { resource: 'profile', action: 'read' },\n { resource: 'sites', action: 'read' },\n { resource: 'public', action: 'read' },\n ],\n },\n agent: {\n id: 'agent',\n name: 'AI Agent',\n description: 'Can execute tasks and read content',\n permissions: [\n { resource: 'tasks', action: 'create' },\n { resource: 'tasks', action: 'read' },\n { resource: 'content', action: 'read' },\n { resource: 'rag', action: 'read' },\n { resource: 'rag', action: 'create' },\n ],\n },\n contributor: {\n id: 'contributor',\n name: 'Contributor',\n description: 'Can suggest changes — create drafts but not publish or delete',\n permissions: [\n { resource: 'content', action: 'read' },\n { resource: 'content', action: 'create' },\n { resource: 'profile', action: 'read' },\n { resource: 'profile', action: 'update' },\n ],\n },\n} satisfies Record<string, Role>;\n\n/**\n * Permission builder\n */\nexport class PermissionBuilder {\n private permission: Partial<Permission> = {};\n\n resource(resource: string): this {\n this.permission.resource = resource;\n return this;\n }\n\n action(action: string): this {\n this.permission.action = action;\n return this;\n }\n\n conditions(conditions: Record<string, unknown>): this {\n this.permission.conditions = conditions;\n return this;\n }\n\n build(): Permission {\n if (!(this.permission.resource && this.permission.action)) {\n throw new Error('Resource and action are required');\n }\n\n return this.permission as Permission;\n }\n}\n\n/**\n * Policy builder\n */\nexport class PolicyBuilder {\n private policy: Partial<Policy> = {\n effect: 'allow',\n resources: [],\n actions: [],\n conditions: [],\n };\n\n id(id: string): this {\n this.policy.id = id;\n return this;\n }\n\n name(name: string): this {\n this.policy.name = name;\n return this;\n }\n\n allow(): this {\n this.policy.effect = 'allow';\n return this;\n }\n\n deny(): this {\n this.policy.effect = 'deny';\n return this;\n }\n\n resources(...resources: string[]): this {\n this.policy.resources = resources;\n return this;\n }\n\n actions(...actions: string[]): this {\n this.policy.actions = actions;\n return this;\n }\n\n condition(field: string, operator: PolicyCondition['operator'], value: unknown): this {\n if (!this.policy.conditions) {\n this.policy.conditions = [];\n }\n\n this.policy.conditions.push({ field, operator, value });\n return this;\n }\n\n priority(priority: number): this {\n this.policy.priority = priority;\n return this;\n }\n\n build(): Policy {\n if (!(this.policy.id && this.policy.name)) {\n throw new Error('ID and name are required');\n }\n\n return this.policy as Policy;\n }\n}\n\n/**\n * Authorization decorators\n */\nexport function RequirePermission(resource: string, action: string) {\n return (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value;\n\n descriptor.value = function (this: { user?: { roles?: string[] } }, ...args: unknown[]) {\n const userRoles = this.user?.roles || [];\n\n if (!authorization.hasPermission(userRoles, resource, action)) {\n throw new Error(`Permission denied: ${resource}:${action}`);\n }\n\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n\nexport function RequireRole(requiredRole: string) {\n return (_target: object, _propertyKey: string, descriptor: PropertyDescriptor) => {\n const originalMethod = descriptor.value;\n\n descriptor.value = function (this: { user?: { roles?: string[] } }, ...args: unknown[]) {\n const userRoles = this.user?.roles || [];\n\n if (!userRoles.includes(requiredRole)) {\n throw new Error(`Role required: ${requiredRole}`);\n }\n\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n\n/**\n * Authorization middleware\n */\nexport function createAuthorizationMiddleware<TRequest = unknown>(\n getUser: (request: TRequest) => { id: string; roles: string[] },\n resource: string,\n action: string,\n) {\n return (request: TRequest, next: () => Promise<unknown>) => {\n const user = getUser(request);\n\n if (!authorization.hasPermission(user.roles, resource, action)) {\n throw new Error(`Permission denied: ${resource}:${action}`);\n }\n\n return next();\n };\n}\n\n/**\n * Resource ownership check\n */\nexport function canAccessResource(\n userId: string,\n userRoles: string[],\n resource: {\n type: string;\n id?: string;\n owner?: string;\n },\n action: string,\n): boolean {\n // Check if user has permission\n if (authorization.hasPermission(userRoles, resource.type, action)) {\n return true;\n }\n\n // Check if user owns the resource\n if (authorization.ownsResource(userId, resource)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Attribute-based access control helper\n */\nexport function checkAttributeAccess(\n context: AuthorizationContext,\n resource: string,\n action: string,\n requiredAttributes?: Record<string, unknown>,\n): boolean {\n // Check basic permission\n const { allowed } = authorization.checkAccess(context, resource, action);\n\n if (!allowed) {\n return false;\n }\n\n // Check required attributes\n if (requiredAttributes) {\n const userAttributes = context.user.attributes || {};\n\n return Object.entries(requiredAttributes).every(\n ([key, value]) => userAttributes[key] === value,\n );\n }\n\n return true;\n}\n\n/**\n * Permission cache for performance\n */\nexport class PermissionCache {\n private cache: Map<string, { allowed: boolean; expiresAt: number }> = new Map();\n private ttl: number;\n private maxEntries: number;\n\n constructor(ttl: number = 300000, maxEntries: number = 10_000) {\n // 5 minutes default, 10k max entries\n this.ttl = ttl;\n this.maxEntries = maxEntries;\n }\n\n /**\n * Get cached permission\n */\n get(userId: string, resource: string, action: string): boolean | undefined {\n const key = this.getCacheKey(userId, resource, action);\n const cached = this.cache.get(key);\n\n if (!cached) {\n return undefined;\n }\n\n // Check expiration\n if (Date.now() > cached.expiresAt) {\n this.cache.delete(key);\n return undefined;\n }\n\n return cached.allowed;\n }\n\n /**\n * Set cached permission\n */\n set(userId: string, resource: string, action: string, allowed: boolean): void {\n const key = this.getCacheKey(userId, resource, action);\n\n // Evict expired entries when approaching max size\n if (this.cache.size >= this.maxEntries) {\n const now = Date.now();\n for (const [k, v] of this.cache) {\n if (now > v.expiresAt) this.cache.delete(k);\n }\n // If still over limit after purge, drop oldest entries (FIFO via Map insertion order)\n if (this.cache.size >= this.maxEntries) {\n const excess = this.cache.size - this.maxEntries + 1;\n const keys = this.cache.keys();\n for (let i = 0; i < excess; i++) {\n const next = keys.next();\n if (!next.done) this.cache.delete(next.value);\n }\n }\n }\n\n this.cache.set(key, {\n allowed,\n expiresAt: Date.now() + this.ttl,\n });\n }\n\n /**\n * Clear cache for user\n */\n clearUser(userId: string): void {\n for (const key of this.cache.keys()) {\n if (key.startsWith(`${userId}:`)) {\n this.cache.delete(key);\n }\n }\n }\n\n /**\n * Clear all cache\n */\n clear(): void {\n this.cache.clear();\n }\n\n /**\n * Get cache key\n */\n private getCacheKey(userId: string, resource: string, action: string): string {\n return `${userId}:${resource}:${action}`;\n }\n}\n\n/**\n * Global permission cache\n */\nexport const permissionCache = new PermissionCache();\n","/**\n * Encryption Utilities\n *\n * Data encryption for at-rest and in-transit protection\n */\n\nexport interface EncryptionConfig {\n algorithm: 'AES-GCM' | 'AES-CTR';\n keySize: 128 | 192 | 256;\n ivSize?: number;\n /** Allow key export via exportKey(). Default: false (keys are non-extractable). */\n extractable?: boolean;\n}\n\nexport interface EncryptedData {\n data: string;\n iv: string;\n tag?: string;\n algorithm: string;\n}\n\nconst DEFAULT_CONFIG: EncryptionConfig = {\n algorithm: 'AES-GCM',\n keySize: 256,\n ivSize: 12,\n};\n\n/**\n * Encryption system\n */\nexport class EncryptionSystem {\n private config: EncryptionConfig;\n private keys: Map<string, CryptoKey> = new Map();\n\n constructor(config: Partial<EncryptionConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Generate encryption key\n */\n async generateKey(keyId?: string): Promise<CryptoKey> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n const key = await crypto.subtle.generateKey(\n {\n name: this.config.algorithm,\n length: this.config.keySize,\n },\n this.config.extractable ?? false, // non-extractable by default — prevents key exfiltration\n ['encrypt', 'decrypt'],\n );\n\n if (keyId) {\n this.keys.set(keyId, key);\n }\n\n return key;\n }\n\n /**\n * Import key from raw data\n */\n async importKey(keyData: ArrayBuffer, keyId?: string): Promise<CryptoKey> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n const key = await crypto.subtle.importKey(\n 'raw',\n keyData,\n {\n name: this.config.algorithm,\n length: this.config.keySize,\n },\n true,\n ['encrypt', 'decrypt'],\n );\n\n if (keyId) {\n this.keys.set(keyId, key);\n }\n\n return key;\n }\n\n /**\n * Export key to raw data\n */\n async exportKey(key: CryptoKey): Promise<ArrayBuffer> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n return crypto.subtle.exportKey('raw', key);\n }\n\n /**\n * Encrypt data\n */\n async encrypt(data: string, keyOrId: CryptoKey | string): Promise<EncryptedData> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n // Get key\n const key = typeof keyOrId === 'string' ? this.keys.get(keyOrId) : keyOrId;\n\n if (!key) {\n throw new Error('Key not found');\n }\n\n // Generate IV\n const iv = crypto.getRandomValues(new Uint8Array(this.config.ivSize || 12));\n\n // Encode data\n const encoder = new TextEncoder();\n const encodedData = encoder.encode(data);\n\n // Encrypt\n const encrypted = await crypto.subtle.encrypt(\n {\n name: this.config.algorithm,\n iv,\n },\n key,\n encodedData,\n );\n\n // Convert to base64\n const encryptedArray = new Uint8Array(encrypted);\n const ivArray = new Uint8Array(iv);\n\n return {\n data: this.arrayBufferToBase64(encryptedArray),\n iv: this.arrayBufferToBase64(ivArray),\n algorithm: this.config.algorithm,\n };\n }\n\n /**\n * Decrypt data\n */\n async decrypt(encryptedData: EncryptedData, keyOrId: CryptoKey | string): Promise<string> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n // Get key\n const key = typeof keyOrId === 'string' ? this.keys.get(keyOrId) : keyOrId;\n\n if (!key) {\n throw new Error('Key not found');\n }\n\n // Decode data\n const data = this.base64ToArrayBuffer(encryptedData.data);\n const iv = this.base64ToArrayBuffer(encryptedData.iv);\n\n // Decrypt\n const decrypted = await crypto.subtle.decrypt(\n {\n name: encryptedData.algorithm,\n iv: iv as BufferSource,\n },\n key,\n data as BufferSource,\n );\n\n // Decode text\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n }\n\n /**\n * Encrypt object\n */\n async encryptObject<T extends Record<string, unknown>>(\n obj: T,\n keyOrId: CryptoKey | string,\n ): Promise<EncryptedData> {\n const json = JSON.stringify(obj);\n return this.encrypt(json, keyOrId);\n }\n\n /**\n * Decrypt object\n */\n async decryptObject<T extends Record<string, unknown>>(\n encryptedData: EncryptedData,\n keyOrId: CryptoKey | string,\n ): Promise<T> {\n const json = await this.decrypt(encryptedData, keyOrId);\n return JSON.parse(json);\n }\n\n /**\n * Hash data\n */\n async hash(\n data: string,\n algorithm: 'SHA-256' | 'SHA-384' | 'SHA-512' = 'SHA-256',\n ): Promise<string> {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n const encoder = new TextEncoder();\n const encodedData = encoder.encode(data);\n const hashBuffer = await crypto.subtle.digest(algorithm, encodedData);\n\n return this.arrayBufferToBase64(new Uint8Array(hashBuffer));\n }\n\n /**\n * Generate random bytes\n */\n randomBytes(length: number): Uint8Array {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n return crypto.getRandomValues(new Uint8Array(length));\n }\n\n /**\n * Generate random string\n */\n randomString(\n length: number,\n charset: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\n ): string {\n // Rejection sampling to avoid modulo bias:\n // Only accept bytes below the largest multiple of charset.length that fits in a byte.\n const maxValid = 256 - (256 % charset.length);\n const result: string[] = [];\n while (result.length < length) {\n const bytes = this.randomBytes(length - result.length + 16);\n for (const byte of bytes) {\n if (byte < maxValid) {\n result.push(charset[byte % charset.length] as string);\n if (result.length === length) break;\n }\n }\n }\n return result.join('');\n }\n\n /**\n * Convert ArrayBuffer to base64\n */\n private arrayBufferToBase64(buffer: Uint8Array): string {\n const bytes = Array.from(buffer);\n const binary = bytes.map((byte) => String.fromCharCode(byte)).join('');\n\n if (typeof btoa !== 'undefined') {\n return btoa(binary);\n }\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(binary, 'binary').toString('base64');\n }\n\n throw new Error('No base64 encoding available');\n }\n\n /**\n * Convert base64 to ArrayBuffer\n */\n private base64ToArrayBuffer(base64: string): Uint8Array {\n let binary: string;\n\n if (typeof atob !== 'undefined') {\n binary = atob(base64);\n } else if (typeof Buffer !== 'undefined') {\n binary = Buffer.from(base64, 'base64').toString('binary');\n } else {\n throw new Error('No base64 decoding available');\n }\n\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return bytes;\n }\n\n /**\n * Store key\n */\n storeKey(keyId: string, key: CryptoKey): void {\n this.keys.set(keyId, key);\n }\n\n /**\n * Get key\n */\n getKey(keyId: string): CryptoKey | undefined {\n return this.keys.get(keyId);\n }\n\n /**\n * Remove key\n */\n removeKey(keyId: string): void {\n this.keys.delete(keyId);\n }\n\n /**\n * Clear all keys\n */\n clearKeys(): void {\n this.keys.clear();\n }\n}\n\n/**\n * Global encryption instance\n */\nexport const encryption = new EncryptionSystem();\n\n/**\n * Field-level encryption\n */\nexport class FieldEncryption {\n private encryption: EncryptionSystem;\n private key: CryptoKey | null = null;\n\n constructor(encryption: EncryptionSystem) {\n this.encryption = encryption;\n }\n\n /**\n * Initialize with key\n */\n async initialize(key: CryptoKey): Promise<void> {\n this.key = key;\n }\n\n /**\n * Encrypt field\n */\n async encryptField(value: unknown): Promise<EncryptedData> {\n if (!this.key) {\n throw new Error('Encryption not initialized');\n }\n\n const stringValue = typeof value === 'string' ? value : JSON.stringify(value);\n return this.encryption.encrypt(stringValue, this.key);\n }\n\n /**\n * Decrypt field\n */\n async decryptField(encryptedData: EncryptedData): Promise<unknown> {\n if (!this.key) {\n throw new Error('Encryption not initialized');\n }\n\n const decrypted = await this.encryption.decrypt(encryptedData, this.key);\n\n // Try to parse as JSON\n try {\n return JSON.parse(decrypted);\n } catch {\n return decrypted;\n }\n }\n\n /**\n * Encrypt object fields\n */\n async encryptFields<T extends Record<string, unknown>>(obj: T, fields: (keyof T)[]): Promise<T> {\n const result = { ...obj };\n\n for (const field of fields) {\n if (field in result) {\n result[field] = (await this.encryptField(result[field])) as unknown as T[keyof T];\n }\n }\n\n return result;\n }\n\n /**\n * Decrypt object fields\n */\n async decryptFields<T extends Record<string, unknown>>(obj: T, fields: (keyof T)[]): Promise<T> {\n const result = { ...obj };\n\n for (const field of fields) {\n if (field in result && typeof result[field] === 'object' && result[field] !== null) {\n const encryptedData = result[field] as unknown as EncryptedData;\n if ('data' in encryptedData && 'iv' in encryptedData) {\n result[field] = (await this.decryptField(encryptedData)) as unknown as T[keyof T];\n }\n }\n }\n\n return result;\n }\n}\n\n/**\n * Key rotation\n */\nexport class KeyRotationManager {\n private encryption: EncryptionSystem;\n private currentKeyId: string;\n private oldKeys: Map<string, CryptoKey> = new Map();\n private keyCreationDates: Map<string, Date> = new Map();\n\n constructor(encryption: EncryptionSystem, initialKeyId: string) {\n this.encryption = encryption;\n this.currentKeyId = initialKeyId;\n this.keyCreationDates.set(initialKeyId, new Date());\n }\n\n /**\n * Rotate to new key\n */\n async rotate(newKeyId: string, newKey: CryptoKey): Promise<void> {\n // Store old key\n const oldKey = this.encryption.getKey(this.currentKeyId);\n if (oldKey) {\n this.oldKeys.set(this.currentKeyId, oldKey);\n }\n\n // Set new key\n this.encryption.storeKey(newKeyId, newKey);\n this.currentKeyId = newKeyId;\n this.keyCreationDates.set(newKeyId, new Date());\n }\n\n /**\n * Re-encrypt data with new key\n */\n async reencrypt(encryptedData: EncryptedData, oldKeyId: string): Promise<EncryptedData> {\n // Get keys\n const oldKey = this.oldKeys.get(oldKeyId) || this.encryption.getKey(oldKeyId);\n const newKey = this.encryption.getKey(this.currentKeyId);\n\n if (!(oldKey && newKey)) {\n throw new Error('Keys not found');\n }\n\n // Decrypt with old key\n const decrypted = await this.encryption.decrypt(encryptedData, oldKey);\n\n // Encrypt with new key\n return this.encryption.encrypt(decrypted, newKey);\n }\n\n /**\n * Get current key ID\n */\n getCurrentKeyId(): string {\n return this.currentKeyId;\n }\n\n /**\n * Clean up old keys created before the specified date.\n * Never removes the current active key.\n */\n cleanupOldKeys(olderThan: Date): void {\n for (const [keyId, createdAt] of this.keyCreationDates.entries()) {\n if (keyId !== this.currentKeyId && createdAt < olderThan) {\n this.oldKeys.delete(keyId);\n this.encryption.removeKey(keyId);\n this.keyCreationDates.delete(keyId);\n }\n }\n }\n}\n\n/**\n * Envelope encryption for large data\n */\nexport class EnvelopeEncryption {\n private encryption: EncryptionSystem;\n private masterKey: CryptoKey;\n\n constructor(encryption: EncryptionSystem, masterKey: CryptoKey) {\n this.encryption = encryption;\n this.masterKey = masterKey;\n }\n\n /**\n * Encrypt with envelope encryption\n */\n async encrypt(data: string): Promise<{\n encryptedData: EncryptedData;\n encryptedKey: EncryptedData;\n }> {\n // Generate data encryption key (DEK)\n const dek = await this.encryption.generateKey();\n\n // Encrypt data with DEK\n const encryptedData = await this.encryption.encrypt(data, dek);\n\n // Export DEK\n const dekRaw = await this.encryption.exportKey(dek);\n const dekBase64 = this.arrayBufferToBase64(new Uint8Array(dekRaw));\n\n // Encrypt DEK with master key\n const encryptedKey = await this.encryption.encrypt(dekBase64, this.masterKey);\n\n return { encryptedData, encryptedKey };\n }\n\n /**\n * Decrypt with envelope encryption\n */\n async decrypt(encryptedData: EncryptedData, encryptedKey: EncryptedData): Promise<string> {\n // Decrypt DEK with master key\n const dekBase64 = await this.encryption.decrypt(encryptedKey, this.masterKey);\n const dekRaw = this.base64ToArrayBuffer(dekBase64);\n\n // Import DEK\n const dek = await this.encryption.importKey(dekRaw.buffer as ArrayBuffer);\n\n // Decrypt data with DEK\n return this.encryption.decrypt(encryptedData, dek);\n }\n\n private arrayBufferToBase64(buffer: Uint8Array): string {\n const bytes = Array.from(buffer);\n const binary = bytes.map((byte) => String.fromCharCode(byte)).join('');\n return typeof btoa !== 'undefined'\n ? btoa(binary)\n : Buffer.from(binary, 'binary').toString('base64');\n }\n\n private base64ToArrayBuffer(base64: string): Uint8Array {\n const binary =\n typeof atob !== 'undefined' ? atob(base64) : Buffer.from(base64, 'base64').toString('binary');\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n}\n\n/**\n * Data masking utilities\n */\n\n/**\n * Mask email\n */\nfunction maskEmail(email: string): string {\n const [local, domain] = email.split('@');\n if (!(local && domain)) return email;\n\n const maskedLocal =\n local.length > 2\n ? local[0] + '*'.repeat(local.length - 2) + local[local.length - 1]\n : `${local[0]}*`;\n\n return `${maskedLocal}@${domain}`;\n}\n\n/**\n * Mask phone number\n */\nfunction maskPhone(phone: string): string {\n const digits = phone.replace(/\\D/g, '');\n if (digits.length < 4) return phone;\n\n const lastFour = digits.slice(-4);\n const masked = '*'.repeat(digits.length - 4) + lastFour;\n\n return phone.replace(/\\d/g, (char, index) => {\n const digitIndex = phone.slice(0, index + 1).replace(/\\D/g, '').length - 1;\n return masked[digitIndex] || char;\n });\n}\n\n/**\n * Mask credit card\n */\nfunction maskCreditCard(card: string): string {\n const digits = card.replace(/\\D/g, '');\n if (digits.length < 4) return card;\n\n const lastFour = digits.slice(-4);\n return `****-****-****-${lastFour}`;\n}\n\n/**\n * Mask SSN\n */\nfunction maskSSN(ssn: string): string {\n const digits = ssn.replace(/\\D/g, '');\n if (digits.length !== 9) return ssn;\n\n return `***-**-${digits.slice(-4)}`;\n}\n\n/**\n * Mask string (keep first and last character)\n */\nfunction maskString(str: string, keepChars: number = 1): string {\n if (str.length <= keepChars * 2) {\n return '*'.repeat(str.length);\n }\n\n const prefix = str.slice(0, keepChars);\n const suffix = str.slice(-keepChars);\n const masked = '*'.repeat(str.length - keepChars * 2);\n\n return `${prefix}${masked}${suffix}`;\n}\n\nexport const DataMasking = {\n maskEmail,\n maskPhone,\n maskCreditCard,\n maskSSN,\n maskString,\n} as const;\n\n/**\n * Secure random token generator\n */\n\n/**\n * Generate secure token. `length` is the number of random bytes;\n * the returned string is hex-encoded, so it will be `length * 2` characters.\n */\nfunction generateToken(length: number = 32): string {\n const bytes = encryption.randomBytes(length);\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate UUID v4\n */\nfunction generateUUID(): string {\n const crypto = globalThis.crypto;\n if (!crypto) {\n throw new Error('Crypto API not available');\n }\n\n return crypto.randomUUID();\n}\n\n/**\n * Generate API key\n */\nfunction generateAPIKey(prefix: string = 'sk'): string {\n const token = generateToken(32);\n return `${prefix}_${token}`;\n}\n\n/**\n * Generate session ID\n */\nfunction generateSessionID(): string {\n return generateToken(64);\n}\n\nexport const TokenGenerator = {\n generate: generateToken,\n generateUUID,\n generateAPIKey,\n generateSessionID,\n} as const;\n","/**\n * GDPR Compliance Utilities\n *\n * Data privacy, consent management, data export, and right to be forgotten\n */\n\nimport { createHash, createHmac } from 'node:crypto';\nimport { type BreachStorage, type GDPRStorage, InMemoryBreachStorage } from './gdpr-storage.js';\nimport { getSecurityLogger } from './logger.js';\n\nexport type ConsentType =\n | 'necessary'\n | 'functional'\n | 'analytics'\n | 'marketing'\n | 'personalization';\n\nexport type DataCategory =\n | 'personal'\n | 'sensitive'\n | 'financial'\n | 'health'\n | 'behavioral'\n | 'location';\n\nexport interface ConsentRecord {\n id: string;\n userId: string;\n type: ConsentType;\n granted: boolean;\n timestamp: string;\n expiresAt?: string;\n source: 'explicit' | 'implicit' | 'legitimate_interest';\n version: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DataProcessingPurpose {\n id: string;\n name: string;\n description: string;\n legalBasis:\n | 'consent'\n | 'contract'\n | 'legal_obligation'\n | 'vital_interest'\n | 'public_interest'\n | 'legitimate_interest';\n dataCategories: DataCategory[];\n retentionPeriod: number; // days\n consentRequired: boolean;\n}\n\nexport interface PersonalDataExport {\n userId: string;\n exportedAt: string;\n data: {\n profile: Record<string, unknown>;\n activities: Record<string, unknown>[];\n consents: ConsentRecord[];\n dataProcessing: DataProcessingPurpose[];\n };\n format: 'json' | 'csv' | 'pdf';\n}\n\nexport interface DataDeletionRequest {\n id: string;\n userId: string;\n requestedAt: string;\n processedAt?: string;\n status: 'pending' | 'processing' | 'completed' | 'failed';\n dataCategories: DataCategory[];\n reason?: string;\n retainedData?: string[];\n deletedData?: string[];\n}\n\n/**\n * Consent management system\n */\nexport class ConsentManager {\n private readonly storage: GDPRStorage;\n private consentVersion: string = '1.0.0';\n\n constructor(storage: GDPRStorage) {\n this.storage = storage;\n }\n\n /**\n * Grant consent\n */\n async grantConsent(\n userId: string,\n type: ConsentType,\n source: ConsentRecord['source'] = 'explicit',\n expiresIn?: number,\n ): Promise<ConsentRecord> {\n const consent: ConsentRecord = {\n id: crypto.randomUUID(),\n userId,\n type,\n granted: true,\n timestamp: new Date().toISOString(),\n expiresAt: expiresIn ? new Date(Date.now() + expiresIn).toISOString() : undefined,\n source,\n version: this.consentVersion,\n };\n\n await this.storage.setConsent(userId, type, consent);\n\n return consent;\n }\n\n /**\n * Revoke consent\n */\n async revokeConsent(userId: string, type: ConsentType): Promise<void> {\n const existing = await this.storage.getConsent(userId, type);\n\n if (existing) {\n existing.granted = false;\n existing.timestamp = new Date().toISOString();\n await this.storage.setConsent(userId, type, existing);\n }\n }\n\n /**\n * Check if consent is granted\n */\n async hasConsent(userId: string, type: ConsentType): Promise<boolean> {\n const consent = await this.storage.getConsent(userId, type);\n\n if (!consent?.granted) {\n return false;\n }\n\n // Check if expired\n if (consent.expiresAt && new Date(consent.expiresAt) < new Date()) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Get all consents for user\n */\n async getUserConsents(userId: string): Promise<ConsentRecord[]> {\n return this.storage.getConsentsByUser(userId);\n }\n\n /**\n * Update consent version\n */\n setConsentVersion(version: string): void {\n this.consentVersion = version;\n }\n\n /**\n * Check if consent needs renewal\n */\n async needsRenewal(userId: string, type: ConsentType, maxAge: number): Promise<boolean> {\n const consent = await this.storage.getConsent(userId, type);\n\n if (!consent?.granted) {\n return true;\n }\n\n const age = Date.now() - new Date(consent.timestamp).getTime();\n return age >= maxAge;\n }\n\n /**\n * Get consent statistics\n */\n async getStatistics(): Promise<{\n total: number;\n granted: number;\n revoked: number;\n expired: number;\n byType: Record<ConsentType, number>;\n }> {\n const consents = await this.storage.getAllConsents();\n const now = new Date();\n\n const granted = consents.filter((c) => c.granted).length;\n const revoked = consents.filter((c) => !c.granted).length;\n const expired = consents.filter((c) => c.expiresAt && new Date(c.expiresAt) < now).length;\n\n const byType = consents.reduce(\n (acc, c) => {\n acc[c.type] = (acc[c.type] || 0) + 1;\n return acc;\n },\n {} as Record<ConsentType, number>,\n );\n\n return {\n total: consents.length,\n granted,\n revoked,\n expired,\n byType,\n };\n }\n}\n\n/**\n * Escape a value for safe CSV inclusion.\n * Prevents CSV injection by prefixing formula-triggering characters (=, +, -, @, \\t, \\r)\n * with a single quote, and escapes embedded quotes/commas per RFC 4180.\n */\nfunction escapeCsvField(value: string): string {\n // Prefix formula-triggering characters to prevent CSV injection in spreadsheet apps\n let safe = /^[=+\\-@\\t\\r]/.test(value) ? `'${value}` : value;\n // RFC 4180: escape double quotes by doubling them\n safe = safe.replace(/\"/g, '\"\"');\n // Always quote the field to handle commas, newlines, and quotes\n return `\"${safe}\"`;\n}\n\n/**\n * Data export system\n */\nexport class DataExportSystem {\n /**\n * Export user data\n */\n async exportUserData(\n userId: string,\n getUserData: (userId: string) => Promise<{\n profile: Record<string, unknown>;\n activities: Record<string, unknown>[];\n consents: ConsentRecord[];\n }>,\n format: PersonalDataExport['format'] = 'json',\n ): Promise<PersonalDataExport> {\n const data = await getUserData(userId);\n\n const exportData: PersonalDataExport = {\n userId,\n exportedAt: new Date().toISOString(),\n data: {\n profile: data.profile,\n activities: data.activities,\n consents: data.consents,\n dataProcessing: [],\n },\n format,\n };\n\n return exportData;\n }\n\n /**\n * Format export as JSON\n */\n formatAsJSON(exportData: PersonalDataExport): string {\n return JSON.stringify(exportData, null, 2);\n }\n\n /**\n * Format export as CSV\n */\n formatAsCSV(exportData: PersonalDataExport): string {\n const lines: string[] = [];\n\n // Profile data\n lines.push('Type,Key,Value');\n Object.entries(exportData.data.profile).forEach(([key, value]) => {\n lines.push(`Profile,${escapeCsvField(key)},${escapeCsvField(String(value))}`);\n });\n\n // Activities\n exportData.data.activities.forEach((activity, index) => {\n Object.entries(activity).forEach(([key, value]) => {\n lines.push(`Activity ${index + 1},${escapeCsvField(key)},${escapeCsvField(String(value))}`);\n });\n });\n\n return lines.join('\\n');\n }\n\n /**\n * Create download link\n */\n createDownloadLink(content: string, _filename: string, mimeType: string): string {\n const blob = new Blob([content], { type: mimeType });\n return URL.createObjectURL(blob);\n }\n}\n\n/**\n * Data deletion system (Right to be Forgotten)\n */\nexport class DataDeletionSystem {\n private readonly storage: GDPRStorage;\n\n constructor(storage: GDPRStorage) {\n this.storage = storage;\n }\n\n /**\n * Request data deletion\n */\n async requestDeletion(\n userId: string,\n dataCategories: DataCategory[],\n reason?: string,\n ): Promise<DataDeletionRequest> {\n const request: DataDeletionRequest = {\n id: crypto.randomUUID(),\n userId,\n requestedAt: new Date().toISOString(),\n status: 'pending',\n dataCategories,\n reason,\n };\n\n await this.storage.setDeletionRequest(request);\n\n return request;\n }\n\n /**\n * Process deletion request\n */\n async processDeletion(\n requestId: string,\n deleteData: (\n userId: string,\n categories: DataCategory[],\n ) => Promise<{\n deleted: string[];\n retained: string[];\n }>,\n ): Promise<void> {\n const request = await this.storage.getDeletionRequest(requestId);\n\n if (!request) {\n throw new Error('Deletion request not found');\n }\n\n request.status = 'processing';\n await this.storage.setDeletionRequest(request);\n\n try {\n const result = await deleteData(request.userId, request.dataCategories);\n\n request.status = 'completed';\n request.processedAt = new Date().toISOString();\n request.deletedData = result.deleted;\n request.retainedData = result.retained;\n await this.storage.setDeletionRequest(request);\n } catch (error) {\n request.status = 'failed';\n await this.storage.setDeletionRequest(request);\n throw error;\n }\n }\n\n /**\n * Get deletion request\n */\n async getRequest(requestId: string): Promise<DataDeletionRequest | undefined> {\n return this.storage.getDeletionRequest(requestId);\n }\n\n /**\n * Get user deletion requests\n */\n async getUserRequests(userId: string): Promise<DataDeletionRequest[]> {\n return this.storage.getDeletionRequestsByUser(userId);\n }\n\n /**\n * Check if data can be deleted\n */\n canDelete(_dataCategory: DataCategory, legalBasis: DataProcessingPurpose['legalBasis']): boolean {\n // Data with legal obligation or vital interest cannot be deleted\n if (legalBasis === 'legal_obligation' || legalBasis === 'vital_interest') {\n return false;\n }\n\n return true;\n }\n\n /**\n * Calculate retention period\n */\n calculateRetentionEnd(createdAt: Date, retentionPeriod: number): Date {\n return new Date(createdAt.getTime() + retentionPeriod * 24 * 60 * 60 * 1000);\n }\n\n /**\n * Check if data should be deleted (retention period expired)\n */\n shouldDelete(createdAt: Date, retentionPeriod: number): boolean {\n const retentionEnd = this.calculateRetentionEnd(createdAt, retentionPeriod);\n return new Date() > retentionEnd;\n }\n}\n\n/**\n * Data anonymization utilities\n */\n\n/**\n * Hash value (irreversible) using SHA-256\n */\nfunction hashValue(value: string): string {\n const digest = createHash('sha256').update(value).digest('hex');\n return `hash_${digest}`;\n}\n\n/**\n * Anonymize user data\n */\nfunction anonymizeUser(user: Record<string, unknown>): Record<string, unknown> {\n return {\n ...user,\n email: hashValue(user.email as string),\n name: 'Anonymous User',\n phone: undefined,\n address: undefined,\n ip: undefined,\n };\n}\n\n/**\n * Pseudonymize data (one-way, key-dependent)\n *\n * Uses HMAC-SHA256 — cryptographically bound to the key, resistant to\n * length-extension attacks and GPU brute-force (unlike plain SHA-256).\n */\nfunction pseudonymize(value: string, key: string): string {\n const hmac = createHmac('sha256', key).update(value).digest('hex');\n return `pseudo_${hmac.substring(0, 16)}`;\n}\n\n/**\n * Anonymize dataset\n */\nfunction anonymizeDataset<T extends Record<string, unknown>>(\n data: T[],\n sensitiveFields: (keyof T)[],\n): T[] {\n return data.map((item) => {\n const anonymized = { ...item };\n\n sensitiveFields.forEach((field) => {\n if (field in anonymized && typeof anonymized[field] === 'string') {\n anonymized[field] = hashValue(anonymized[field] as string) as T[keyof T];\n }\n });\n\n return anonymized;\n });\n}\n\n/**\n * K-anonymity check\n */\nfunction checkKAnonymity<T extends Record<string, unknown>>(\n data: T[],\n quasiIdentifiers: (keyof T)[],\n k: number,\n): boolean {\n // Group by quasi-identifiers\n const groups = new Map<string, number>();\n\n data.forEach((item) => {\n const key = quasiIdentifiers.map((field) => String(item[field])).join('|');\n\n groups.set(key, (groups.get(key) || 0) + 1);\n });\n\n // Check if all groups have at least k members\n return Array.from(groups.values()).every((count) => count >= k);\n}\n\nexport const DataAnonymization = {\n anonymizeUser,\n pseudonymize,\n hashValue,\n anonymizeDataset,\n checkKAnonymity,\n} as const;\n\n/**\n * Privacy policy manager\n */\nexport class PrivacyPolicyManager {\n private policies: Map<string, { version: string; content: string; effectiveDate: Date }> =\n new Map();\n private currentVersion: string = '1.0.0';\n\n /**\n * Add policy version\n */\n addPolicy(version: string, content: string, effectiveDate: Date): void {\n this.policies.set(version, { version, content, effectiveDate });\n this.currentVersion = version;\n }\n\n /**\n * Get current policy\n */\n getCurrentPolicy(): { version: string; content: string; effectiveDate: Date } | undefined {\n return this.policies.get(this.currentVersion);\n }\n\n /**\n * Get policy by version\n */\n getPolicy(\n version: string,\n ): { version: string; content: string; effectiveDate: Date } | undefined {\n return this.policies.get(version);\n }\n\n /**\n * Check if user accepted current policy\n */\n hasAcceptedCurrent(userAcceptedVersion: string): boolean {\n return userAcceptedVersion === this.currentVersion;\n }\n\n /**\n * Get all versions\n */\n getAllVersions(): string[] {\n return Array.from(this.policies.keys());\n }\n}\n\n/**\n * Cookie consent banner\n */\nexport interface CookieConsentConfig {\n necessary: boolean;\n functional: boolean;\n analytics: boolean;\n marketing: boolean;\n}\n\nexport class CookieConsentManager {\n private config: CookieConsentConfig = {\n necessary: true,\n functional: false,\n analytics: false,\n marketing: false,\n };\n\n /**\n * Set consent configuration\n */\n setConsent(config: Partial<CookieConsentConfig>): void {\n this.config = { ...this.config, ...config };\n this.saveToStorage();\n }\n\n /**\n * Get consent configuration\n */\n getConsent(): CookieConsentConfig {\n return { ...this.config };\n }\n\n /**\n * Check if specific consent is granted\n */\n hasConsent(type: keyof CookieConsentConfig): boolean {\n return this.config[type];\n }\n\n /**\n * Save to storage\n */\n private saveToStorage(): void {\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem('cookie-consent', JSON.stringify(this.config));\n }\n }\n\n /**\n * Load from storage\n */\n loadFromStorage(): void {\n if (typeof localStorage !== 'undefined') {\n const stored = localStorage.getItem('cookie-consent');\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n // Validate shape before assigning — only accept known boolean fields\n // to prevent malicious scripts from injecting arbitrary config.\n if (typeof parsed === 'object' && parsed !== null) {\n this.config = {\n necessary: true, // always required\n analytics: typeof parsed.analytics === 'boolean' ? parsed.analytics : false,\n marketing: typeof parsed.marketing === 'boolean' ? parsed.marketing : false,\n functional: typeof parsed.functional === 'boolean' ? parsed.functional : true,\n };\n }\n } catch {\n // Ignore parse errors\n }\n }\n }\n }\n\n /**\n * Clear consent\n */\n clearConsent(): void {\n this.config = {\n necessary: true,\n functional: false,\n analytics: false,\n marketing: false,\n };\n\n if (typeof localStorage !== 'undefined') {\n localStorage.removeItem('cookie-consent');\n }\n }\n}\n\n/**\n * Data breach notification system\n */\nexport interface DataBreach {\n id: string;\n detectedAt: string;\n reportedAt?: string;\n type: 'unauthorized_access' | 'data_loss' | 'data_leak' | 'system_compromise';\n severity: 'low' | 'medium' | 'high' | 'critical';\n affectedUsers: string[];\n dataCategories: DataCategory[];\n description: string;\n mitigation?: string;\n status: 'detected' | 'investigating' | 'notified' | 'resolved';\n}\n\nexport class DataBreachManager {\n private readonly storage: BreachStorage;\n\n constructor(storage?: BreachStorage) {\n if (storage) {\n this.storage = storage;\n } else {\n getSecurityLogger().warn(\n 'DataBreachManager: using in-memory storage — breach records will be lost on restart. ' +\n 'For production GDPR compliance, pass a database-backed BreachStorage.',\n );\n this.storage = new InMemoryBreachStorage();\n }\n }\n\n /**\n * Report data breach\n */\n async reportBreach(\n breach: Omit<DataBreach, 'id' | 'detectedAt' | 'status'>,\n ): Promise<DataBreach> {\n const fullBreach: DataBreach = {\n ...breach,\n id: crypto.randomUUID(),\n detectedAt: new Date().toISOString(),\n status: 'detected',\n };\n\n await this.storage.setBreach(fullBreach);\n\n // Auto-notify if critical\n if (fullBreach.severity === 'critical') {\n await this.notifyAuthorities(fullBreach);\n }\n\n return fullBreach;\n }\n\n /**\n * Notify authorities (required within 72 hours under GDPR)\n */\n async notifyAuthorities(breach: DataBreach): Promise<void> {\n await this.storage.updateBreach(breach.id, {\n reportedAt: new Date().toISOString(),\n status: 'notified',\n });\n\n // In production, integrate with data protection authority API\n getSecurityLogger().info('Breach reported to authorities', { breachId: breach.id });\n }\n\n /**\n * Notify affected users\n */\n async notifyAffectedUsers(\n breachId: string,\n notifyFn: (userId: string, breach: DataBreach) => Promise<void>,\n ): Promise<void> {\n const breach = await this.storage.getBreach(breachId);\n\n if (!breach) {\n throw new Error('Breach not found');\n }\n\n for (const userId of breach.affectedUsers) {\n await notifyFn(userId, breach);\n }\n }\n\n /**\n * Check if breach notification is required\n */\n requiresNotification(breach: DataBreach): boolean {\n // Notification required for high risk breaches\n return (\n breach.severity === 'high' ||\n breach.severity === 'critical' ||\n breach.dataCategories.includes('sensitive') ||\n breach.dataCategories.includes('financial')\n );\n }\n\n /**\n * Get breach\n */\n async getBreach(id: string): Promise<DataBreach | undefined> {\n return this.storage.getBreach(id);\n }\n\n /**\n * Get all breaches\n */\n async getAllBreaches(): Promise<DataBreach[]> {\n return this.storage.getAllBreaches();\n }\n}\n\n/**\n * Factory functions for GDPR subsystems.\n *\n * `ConsentManager` and `DataDeletionSystem` require a `GDPRStorage` implementation.\n * Use `InMemoryGDPRStorage` only in tests — production MUST use a database-backed store.\n *\n * `DataExportSystem`, `PrivacyPolicyManager`, `CookieConsentManager`, and\n * `DataBreachManager` are stateless or client-side only, so singletons are safe.\n */\nexport function createConsentManager(storage: GDPRStorage): ConsentManager {\n return new ConsentManager(storage);\n}\n\nexport function createDataDeletionSystem(storage: GDPRStorage): DataDeletionSystem {\n return new DataDeletionSystem(storage);\n}\n\nexport const dataExportSystem = new DataExportSystem();\nexport const privacyPolicyManager = new PrivacyPolicyManager();\nexport const cookieConsentManager = new CookieConsentManager();\nexport function createDataBreachManager(storage?: BreachStorage): DataBreachManager {\n return new DataBreachManager(storage);\n}\n\nexport const dataBreachManager = new DataBreachManager();\n","/**\n * GDPR Storage Abstraction\n *\n * Record-oriented storage interface for GDPR compliance data.\n * Provides a clean seam for replacing the default in-memory implementation\n * with a database-backed store in production.\n */\n\nimport type { ConsentRecord, ConsentType, DataBreach, DataDeletionRequest } from './gdpr.js';\n\n/**\n * Storage interface for GDPR consent records and deletion requests.\n *\n * All methods are async to support database-backed implementations.\n * The default `InMemoryGDPRStorage` is suitable for testing and development\n * but must be replaced with a persistent store for production use.\n */\nexport interface GDPRStorage {\n // ── Consent Records ──────────────────────────────────────────────\n\n /**\n * Store or update a consent record, keyed by `userId:consentType`.\n */\n setConsent(userId: string, type: ConsentType, record: ConsentRecord): Promise<void>;\n\n /**\n * Retrieve a consent record by user and type. Returns `undefined` if not found.\n */\n getConsent(userId: string, type: ConsentType): Promise<ConsentRecord | undefined>;\n\n /**\n * Retrieve all consent records for a given user.\n */\n getConsentsByUser(userId: string): Promise<ConsentRecord[]>;\n\n /**\n * Retrieve every consent record in storage (used for aggregate statistics).\n */\n getAllConsents(): Promise<ConsentRecord[]>;\n\n // ── Deletion Requests ────────────────────────────────────────────\n\n /**\n * Store a deletion request, keyed by its `id`.\n */\n setDeletionRequest(request: DataDeletionRequest): Promise<void>;\n\n /**\n * Retrieve a deletion request by ID. Returns `undefined` if not found.\n */\n getDeletionRequest(requestId: string): Promise<DataDeletionRequest | undefined>;\n\n /**\n * Retrieve all deletion requests for a given user.\n */\n getDeletionRequestsByUser(userId: string): Promise<DataDeletionRequest[]>;\n}\n\n/**\n * Storage interface for data breach records.\n *\n * All methods are async to support database-backed implementations.\n * The default `InMemoryBreachStorage` is suitable for testing and development\n * but must be replaced with a persistent store for production GDPR compliance.\n */\nexport interface BreachStorage {\n /**\n * Store a data breach record.\n */\n setBreach(breach: DataBreach): Promise<void>;\n\n /**\n * Retrieve a breach by ID. Returns `undefined` if not found.\n */\n getBreach(id: string): Promise<DataBreach | undefined>;\n\n /**\n * Retrieve all breach records.\n */\n getAllBreaches(): Promise<DataBreach[]>;\n\n /**\n * Update an existing breach record (e.g., status change, add mitigation).\n */\n updateBreach(id: string, updates: Partial<DataBreach>): Promise<void>;\n}\n\n/**\n * In-memory implementation of `BreachStorage`.\n *\n * WARNING: All data is lost on process restart or serverless cold start.\n * GDPR requires breach records be retained — use database-backed storage in production.\n */\nexport class InMemoryBreachStorage implements BreachStorage {\n private breaches: Map<string, DataBreach> = new Map();\n\n async setBreach(breach: DataBreach): Promise<void> {\n this.breaches.set(breach.id, breach);\n }\n\n async getBreach(id: string): Promise<DataBreach | undefined> {\n return this.breaches.get(id);\n }\n\n async getAllBreaches(): Promise<DataBreach[]> {\n return Array.from(this.breaches.values());\n }\n\n async updateBreach(id: string, updates: Partial<DataBreach>): Promise<void> {\n const existing = this.breaches.get(id);\n if (existing) {\n this.breaches.set(id, { ...existing, ...updates });\n }\n }\n}\n\n/**\n * In-memory implementation of `GDPRStorage`.\n *\n * WARNING: All data is lost on process restart or serverless cold start.\n * Use this only for development, testing, or as a reference implementation.\n * Production deployments MUST supply a database-backed `GDPRStorage`.\n */\nexport class InMemoryGDPRStorage implements GDPRStorage {\n private consents: Map<string, ConsentRecord> = new Map();\n private deletionRequests: Map<string, DataDeletionRequest> = new Map();\n\n // ── Consent Records ──────────────────────────────────────────────\n\n async setConsent(userId: string, type: ConsentType, record: ConsentRecord): Promise<void> {\n this.consents.set(`${userId}:${type}`, record);\n }\n\n async getConsent(userId: string, type: ConsentType): Promise<ConsentRecord | undefined> {\n return this.consents.get(`${userId}:${type}`);\n }\n\n async getConsentsByUser(userId: string): Promise<ConsentRecord[]> {\n return Array.from(this.consents.values()).filter((c) => c.userId === userId);\n }\n\n async getAllConsents(): Promise<ConsentRecord[]> {\n return Array.from(this.consents.values());\n }\n\n // ── Deletion Requests ────────────────────────────────────────────\n\n async setDeletionRequest(request: DataDeletionRequest): Promise<void> {\n this.deletionRequests.set(request.id, request);\n }\n\n async getDeletionRequest(requestId: string): Promise<DataDeletionRequest | undefined> {\n return this.deletionRequests.get(requestId);\n }\n\n async getDeletionRequestsByUser(userId: string): Promise<DataDeletionRequest[]> {\n return Array.from(this.deletionRequests.values()).filter((r) => r.userId === userId);\n }\n}\n","/**\n * Internal logger for @revealui/security.\n *\n * Defaults to `console`. Consumers should call `configureSecurityLogger()`\n * to supply a structured logger (e.g. from `@revealui/utils/logger`).\n */\n\nexport interface SecurityLogger {\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\nlet securityLogger: SecurityLogger = console;\n\n/**\n * Replace the default console logger with a structured logger.\n */\nexport function configureSecurityLogger(logger: SecurityLogger): void {\n securityLogger = logger;\n}\n\n/**\n * Get the current security logger instance.\n */\nexport function getSecurityLogger(): SecurityLogger {\n return securityLogger;\n}\n","/**\n * Security Headers and CORS Configuration\n *\n * HTTP security headers and CORS policy management\n */\n\nimport { getSecurityLogger } from './logger.js';\n\nexport interface SecurityHeadersConfig {\n contentSecurityPolicy?: string | ContentSecurityPolicyConfig;\n strictTransportSecurity?: boolean | HSTSConfig;\n xFrameOptions?: 'DENY' | 'SAMEORIGIN' | string;\n xContentTypeOptions?: boolean;\n referrerPolicy?: ReferrerPolicyValue;\n permissionsPolicy?: string | PermissionsPolicyConfig;\n crossOriginEmbedderPolicy?: 'require-corp' | 'credentialless';\n crossOriginOpenerPolicy?: 'same-origin' | 'same-origin-allow-popups' | 'unsafe-none';\n crossOriginResourcePolicy?: 'same-origin' | 'same-site' | 'cross-origin';\n}\n\nexport interface ContentSecurityPolicyConfig {\n defaultSrc?: string[];\n scriptSrc?: string[];\n styleSrc?: string[];\n imgSrc?: string[];\n fontSrc?: string[];\n connectSrc?: string[];\n frameSrc?: string[];\n objectSrc?: string[];\n mediaSrc?: string[];\n workerSrc?: string[];\n childSrc?: string[];\n formAction?: string[];\n frameAncestors?: string[];\n baseUri?: string[];\n manifestSrc?: string[];\n upgradeInsecureRequests?: boolean;\n blockAllMixedContent?: boolean;\n reportUri?: string;\n reportTo?: string;\n}\n\nexport interface HSTSConfig {\n maxAge: number;\n includeSubDomains?: boolean;\n preload?: boolean;\n}\n\nexport type ReferrerPolicyValue =\n | 'no-referrer'\n | 'no-referrer-when-downgrade'\n | 'origin'\n | 'origin-when-cross-origin'\n | 'same-origin'\n | 'strict-origin'\n | 'strict-origin-when-cross-origin'\n | 'unsafe-url';\n\nexport interface PermissionsPolicyConfig {\n accelerometer?: string[];\n ambientLightSensor?: string[];\n autoplay?: string[];\n battery?: string[];\n camera?: string[];\n displayCapture?: string[];\n documentDomain?: string[];\n encryptedMedia?: string[];\n fullscreen?: string[];\n geolocation?: string[];\n gyroscope?: string[];\n magnetometer?: string[];\n microphone?: string[];\n midi?: string[];\n payment?: string[];\n pictureInPicture?: string[];\n publicKeyCredentials?: string[];\n screenWakeLock?: string[];\n syncXhr?: string[];\n usb?: string[];\n webShare?: string[];\n xrSpatialTracking?: string[];\n}\n\nexport interface CORSConfig {\n origin?: string | string[] | ((origin: string) => boolean);\n methods?: string[];\n allowedHeaders?: string[];\n exposedHeaders?: string[];\n credentials?: boolean;\n maxAge?: number;\n preflightContinue?: boolean;\n optionsSuccessStatus?: number;\n}\n\n/**\n * Security headers manager\n */\nexport class SecurityHeaders {\n private config: SecurityHeadersConfig;\n\n constructor(config: SecurityHeadersConfig = {}) {\n this.config = config;\n }\n\n /**\n * Get all security headers\n */\n getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n\n // Content Security Policy\n if (this.config.contentSecurityPolicy) {\n headers['Content-Security-Policy'] = this.buildCSP(this.config.contentSecurityPolicy);\n }\n\n // Strict Transport Security\n if (this.config.strictTransportSecurity) {\n headers['Strict-Transport-Security'] = this.buildHSTS(this.config.strictTransportSecurity);\n }\n\n // X-Frame-Options\n if (this.config.xFrameOptions) {\n headers['X-Frame-Options'] = this.config.xFrameOptions;\n }\n\n // X-Content-Type-Options\n if (this.config.xContentTypeOptions !== false) {\n headers['X-Content-Type-Options'] = 'nosniff';\n }\n\n // Referrer-Policy\n if (this.config.referrerPolicy) {\n headers['Referrer-Policy'] = this.config.referrerPolicy;\n }\n\n // Permissions-Policy\n if (this.config.permissionsPolicy) {\n headers['Permissions-Policy'] = this.buildPermissionsPolicy(this.config.permissionsPolicy);\n }\n\n // Cross-Origin headers\n if (this.config.crossOriginEmbedderPolicy) {\n headers['Cross-Origin-Embedder-Policy'] = this.config.crossOriginEmbedderPolicy;\n }\n\n if (this.config.crossOriginOpenerPolicy) {\n headers['Cross-Origin-Opener-Policy'] = this.config.crossOriginOpenerPolicy;\n }\n\n if (this.config.crossOriginResourcePolicy) {\n headers['Cross-Origin-Resource-Policy'] = this.config.crossOriginResourcePolicy;\n }\n\n return headers;\n }\n\n /**\n * Build Content Security Policy header\n */\n private buildCSP(config: string | ContentSecurityPolicyConfig): string {\n if (typeof config === 'string') {\n return config;\n }\n\n const directives: string[] = [];\n\n const addDirective = (name: string, values?: string[]) => {\n if (values && values.length > 0) {\n directives.push(`${name} ${values.join(' ')}`);\n }\n };\n\n addDirective('default-src', config.defaultSrc);\n addDirective('script-src', config.scriptSrc);\n addDirective('style-src', config.styleSrc);\n addDirective('img-src', config.imgSrc);\n addDirective('font-src', config.fontSrc);\n addDirective('connect-src', config.connectSrc);\n addDirective('frame-src', config.frameSrc);\n addDirective('object-src', config.objectSrc);\n addDirective('media-src', config.mediaSrc);\n addDirective('worker-src', config.workerSrc);\n addDirective('child-src', config.childSrc);\n addDirective('form-action', config.formAction);\n addDirective('frame-ancestors', config.frameAncestors);\n addDirective('base-uri', config.baseUri);\n addDirective('manifest-src', config.manifestSrc);\n\n if (config.upgradeInsecureRequests) {\n directives.push('upgrade-insecure-requests');\n }\n\n if (config.blockAllMixedContent) {\n directives.push('block-all-mixed-content');\n }\n\n if (config.reportUri) {\n directives.push(`report-uri ${config.reportUri}`);\n }\n\n if (config.reportTo) {\n directives.push(`report-to ${config.reportTo}`);\n }\n\n return directives.join('; ');\n }\n\n /**\n * Build HSTS header\n */\n private buildHSTS(config: boolean | HSTSConfig): string {\n if (config === true) {\n return 'max-age=31536000; includeSubDomains';\n }\n\n if (config === false) {\n return '';\n }\n\n // config is now HSTSConfig\n const parts = [`max-age=${config.maxAge}`];\n\n if (config.includeSubDomains) {\n parts.push('includeSubDomains');\n }\n\n if (config.preload) {\n parts.push('preload');\n }\n\n return parts.join('; ');\n }\n\n /**\n * Build Permissions-Policy header\n */\n private buildPermissionsPolicy(config: string | PermissionsPolicyConfig): string {\n if (typeof config === 'string') {\n return config;\n }\n\n const policies: string[] = [];\n\n Object.entries(config).forEach(([feature, origins]) => {\n if (!origins || origins.length === 0) {\n policies.push(`${feature}=()`);\n } else if (origins.includes('*')) {\n policies.push(`${feature}=*`);\n } else {\n const originsList = origins.map((o: string) => `\"${o}\"`).join(' ');\n policies.push(`${feature}=(${originsList})`);\n }\n });\n\n return policies.join(', ');\n }\n\n /**\n * Apply headers to response\n */\n applyHeaders(response: Response): Response {\n const headers = this.getHeaders();\n\n Object.entries(headers).forEach(([name, value]) => {\n response.headers.set(name, value);\n });\n\n return response;\n }\n}\n\n/**\n * CORS manager\n */\nexport class CORSManager {\n private config: Required<CORSConfig>;\n\n constructor(config: CORSConfig = {}) {\n this.config = {\n origin: config.origin ?? [],\n methods: config.methods || ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: config.allowedHeaders || ['Content-Type', 'Authorization'],\n exposedHeaders: config.exposedHeaders || [],\n credentials: config.credentials ?? false,\n maxAge: config.maxAge || 86400,\n preflightContinue: config.preflightContinue ?? false,\n optionsSuccessStatus: config.optionsSuccessStatus || 204,\n };\n }\n\n /**\n * Check if origin is allowed\n */\n isOriginAllowed(origin: string): boolean {\n const { origin: allowedOrigin } = this.config;\n\n if (allowedOrigin === '*') {\n return true;\n }\n\n if (typeof allowedOrigin === 'function') {\n return allowedOrigin(origin);\n }\n\n if (typeof allowedOrigin === 'string') {\n return origin === allowedOrigin;\n }\n\n if (Array.isArray(allowedOrigin)) {\n return allowedOrigin.includes(origin);\n }\n\n return false;\n }\n\n /**\n * Get CORS headers\n */\n getCORSHeaders(origin: string): Record<string, string> {\n const headers: Record<string, string> = {};\n\n // Access-Control-Allow-Origin\n if (this.isOriginAllowed(origin)) {\n headers['Access-Control-Allow-Origin'] = this.config.origin === '*' ? '*' : origin;\n }\n\n // Vary: Origin — required when Access-Control-Allow-Origin is not '*' so caches\n // don't serve a response allowed for origin A to origin B.\n if (this.config.origin !== '*') {\n headers.Vary = 'Origin';\n }\n\n // Access-Control-Allow-Credentials — incompatible with origin: '*' per Fetch spec\n if (this.config.credentials && this.config.origin !== '*') {\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n\n // Access-Control-Expose-Headers\n if (this.config.exposedHeaders.length > 0) {\n headers['Access-Control-Expose-Headers'] = this.config.exposedHeaders.join(', ');\n }\n\n return headers;\n }\n\n /**\n * Get preflight headers\n */\n getPreflightHeaders(origin: string): Record<string, string> {\n const headers = this.getCORSHeaders(origin);\n\n // Access-Control-Allow-Methods\n headers['Access-Control-Allow-Methods'] = this.config.methods.join(', ');\n\n // Access-Control-Allow-Headers\n headers['Access-Control-Allow-Headers'] = this.config.allowedHeaders.join(', ');\n\n // Access-Control-Max-Age\n headers['Access-Control-Max-Age'] = this.config.maxAge.toString();\n\n return headers;\n }\n\n /**\n * Handle CORS request\n */\n handleRequest(request: Request): Response | null {\n const origin = request.headers.get('Origin');\n\n if (!origin) {\n return null;\n }\n\n // Handle preflight\n if (request.method === 'OPTIONS') {\n return this.handlePreflight(request, origin);\n }\n\n return null;\n }\n\n /**\n * Handle preflight request\n */\n handlePreflight(_request: Request, origin: string): Response {\n if (!this.isOriginAllowed(origin)) {\n return new Response(null, { status: 403 });\n }\n\n const headers = this.getPreflightHeaders(origin);\n\n return new Response(null, {\n status: this.config.optionsSuccessStatus,\n headers,\n });\n }\n\n /**\n * Apply CORS headers to response\n */\n applyHeaders(response: Response, origin: string): Response {\n if (!this.isOriginAllowed(origin)) {\n return response;\n }\n\n const headers = this.getCORSHeaders(origin);\n\n Object.entries(headers).forEach(([name, value]) => {\n response.headers.set(name, value);\n });\n\n return response;\n }\n}\n\n/**\n * Common security header presets\n */\nexport const SecurityPresets = {\n /**\n * Strict security (recommended for production)\n */\n strict: (): SecurityHeadersConfig => ({\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n fontSrc: [\"'self'\", 'data:'],\n connectSrc: [\"'self'\"],\n frameSrc: [\"'none'\"],\n objectSrc: [\"'none'\"],\n baseUri: [\"'self'\"],\n formAction: [\"'self'\"],\n frameAncestors: [\"'none'\"],\n upgradeInsecureRequests: true,\n },\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n preload: true,\n },\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n referrerPolicy: 'strict-origin-when-cross-origin',\n crossOriginEmbedderPolicy: 'require-corp',\n crossOriginOpenerPolicy: 'same-origin',\n crossOriginResourcePolicy: 'same-origin',\n }),\n\n /**\n * Moderate security (balanced)\n */\n moderate: (): SecurityHeadersConfig => ({\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\", \"'unsafe-inline'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n fontSrc: [\"'self'\", 'data:', 'https:'],\n connectSrc: [\"'self'\", 'https:'],\n frameAncestors: [\"'self'\"],\n },\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n xFrameOptions: 'SAMEORIGIN',\n xContentTypeOptions: true,\n referrerPolicy: 'origin-when-cross-origin',\n }),\n\n /**\n * Development (permissive)\n */\n development: (): SecurityHeadersConfig => ({\n xContentTypeOptions: true,\n referrerPolicy: 'no-referrer-when-downgrade',\n }),\n};\n\n/**\n * Common CORS presets\n */\nexport const CORSPresets = {\n /**\n * Strict CORS (same origin only)\n */\n strict: (): CORSConfig => ({\n origin: [],\n methods: ['GET', 'POST', 'PUT', 'DELETE'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n credentials: true,\n maxAge: 86400,\n }),\n\n /**\n * Moderate CORS (specific origins)\n */\n moderate: (allowedOrigins: string[]): CORSConfig => ({\n origin: allowedOrigins,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n exposedHeaders: ['X-Total-Count'],\n credentials: true,\n maxAge: 86400,\n }),\n\n /**\n * Permissive CORS (all origins) — development only.\n * Logs a warning if used when NODE_ENV === 'production'.\n */\n permissive: (): CORSConfig => {\n if (process.env.NODE_ENV === 'production') {\n getSecurityLogger().warn(\n '[SecurityPresets] CORS permissive preset used in production — this allows all origins. Use moderate() with explicit origins instead.',\n );\n }\n return {\n origin: '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n allowedHeaders: ['*'],\n credentials: false,\n maxAge: 86400,\n };\n },\n\n /**\n * API CORS (public read-only APIs) — credentials disabled.\n * Logs a warning if used when NODE_ENV === 'production'.\n */\n api: (): CORSConfig => {\n if (process.env.NODE_ENV === 'production') {\n getSecurityLogger().warn(\n '[SecurityPresets] CORS api preset uses origin:\"*\". For production, pass explicit origins to moderate() instead.',\n );\n }\n return {\n origin: '*',\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'],\n exposedHeaders: ['X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-RateLimit-Reset'],\n credentials: false,\n maxAge: 86400,\n };\n },\n};\n\n/**\n * Security middleware creator\n */\nexport function createSecurityMiddleware(\n securityConfig?: SecurityHeadersConfig,\n corsConfig?: CORSConfig,\n) {\n const security = new SecurityHeaders(securityConfig);\n const cors = new CORSManager(corsConfig);\n\n return async (request: Request, next: () => Promise<Response>): Promise<Response> => {\n const origin = request.headers.get('Origin');\n\n // Handle CORS preflight\n if (origin && request.method === 'OPTIONS') {\n const preflightResponse = cors.handleRequest(request);\n if (preflightResponse) {\n return preflightResponse;\n }\n }\n\n // Process request\n const response = await next();\n\n // Apply security headers\n security.applyHeaders(response);\n\n // Apply CORS headers\n if (origin) {\n cors.applyHeaders(response, origin);\n }\n\n return response;\n };\n}\n\n/**\n * Rate limiting headers\n */\nexport function setRateLimitHeaders(\n response: Response,\n limit: number,\n remaining: number,\n reset: number,\n): void {\n response.headers.set('X-RateLimit-Limit', limit.toString());\n response.headers.set('X-RateLimit-Remaining', remaining.toString());\n response.headers.set('X-RateLimit-Reset', reset.toString());\n}\n"],"mappings":"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","names":["audit","crypto","crypto","encryption","createHmac","createHmac"]}