nextjs-secure 0.6.0 → 0.7.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors.ts","../src/utils/time.ts","../src/utils/ip.ts","../src/middleware/rate-limit/stores/memory.ts","../src/middleware/rate-limit/algorithms/sliding-window.ts","../src/middleware/rate-limit/algorithms/fixed-window.ts","../src/middleware/rate-limit/algorithms/token-bucket.ts","../src/middleware/rate-limit/middleware.ts","../src/middleware/csrf/token.ts","../src/middleware/csrf/middleware.ts","../src/middleware/headers/builder.ts","../src/middleware/headers/middleware.ts","../src/middleware/auth/jwt.ts","../src/middleware/auth/middleware.ts","../src/middleware/validation/utils.ts","../src/middleware/validation/validators/schema.ts","../src/middleware/validation/validators/content-type.ts","../src/middleware/validation/sanitizers/path.ts","../src/middleware/validation/validators/file.ts","../src/middleware/validation/sanitizers/xss.ts","../src/middleware/validation/sanitizers/sql.ts","../src/middleware/validation/middleware.ts","../src/middleware/audit/stores/memory.ts","../src/middleware/audit/stores/console.ts","../src/middleware/audit/stores/external.ts","../src/middleware/audit/formatters.ts","../src/middleware/audit/redaction.ts","../src/middleware/audit/events.ts","../src/middleware/audit/middleware.ts","../src/index.ts"],"names":["shouldSkip","response","info","webcrypto","DEFAULT_CONFIG","encoder","hash","defaultErrorResponse","DANGEROUS_PATTERNS","MemoryStore","createMemoryStore","first","last","parts","generateId"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Custom error classes for next-secure\n */\n\n/**\n * Base error class for all next-secure errors\n */\nexport class SecureError extends Error {\n /**\n * HTTP status code\n */\n public readonly statusCode: number\n\n /**\n * Error code for programmatic handling\n */\n public readonly code: string\n\n /**\n * Additional error details\n */\n public readonly details?: Record<string, unknown>\n\n constructor(\n message: string,\n options: {\n statusCode?: number\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, { cause: options.cause })\n this.name = 'SecureError'\n this.statusCode = options.statusCode ?? 500\n this.code = options.code ?? 'SECURE_ERROR'\n this.details = options.details\n\n // Maintains proper stack trace for where error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n }\n\n /**\n * Convert error to JSON response\n */\n toJSON(): Record<string, unknown> {\n return {\n error: this.name,\n message: this.message,\n code: this.code,\n ...(this.details && { details: this.details }),\n }\n }\n\n /**\n * Create a Response object from this error\n */\n toResponse(headers?: HeadersInit): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n status: this.statusCode,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n })\n }\n}\n\n/**\n * Rate limit exceeded error\n */\nexport class RateLimitError extends SecureError {\n /**\n * Seconds until rate limit resets\n */\n public readonly retryAfter: number\n\n /**\n * Unix timestamp when limit resets\n */\n public readonly resetAt: number\n\n constructor(\n options: {\n retryAfter: number\n resetAt: number\n message?: string\n details?: Record<string, unknown>\n }\n ) {\n super(options.message ?? 'Too Many Requests', {\n statusCode: 429,\n code: 'RATE_LIMIT_EXCEEDED',\n details: options.details,\n })\n this.name = 'RateLimitError'\n this.retryAfter = options.retryAfter\n this.resetAt = options.resetAt\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n retryAfter: this.retryAfter,\n }\n }\n\n override toResponse(headers?: HeadersInit): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n status: this.statusCode,\n headers: {\n 'Content-Type': 'application/json',\n 'Retry-After': String(this.retryAfter),\n ...headers,\n },\n })\n }\n}\n\n/**\n * Authentication error\n */\nexport class AuthenticationError extends SecureError {\n constructor(\n message = 'Authentication required',\n options: {\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 401,\n code: options.code ?? 'AUTHENTICATION_REQUIRED',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'AuthenticationError'\n }\n}\n\n/**\n * Authorization error (authenticated but not permitted)\n */\nexport class AuthorizationError extends SecureError {\n constructor(\n message = 'Access denied',\n options: {\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 403,\n code: options.code ?? 'ACCESS_DENIED',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'AuthorizationError'\n }\n}\n\n/**\n * Validation error\n */\nexport class ValidationError extends SecureError {\n /**\n * Field-level validation errors\n */\n public readonly errors: Array<{\n field: string\n message: string\n code?: string\n }>\n\n constructor(\n errors: Array<{ field: string; message: string; code?: string }>,\n message = 'Validation failed'\n ) {\n super(message, {\n statusCode: 400,\n code: 'VALIDATION_ERROR',\n details: { errors },\n })\n this.name = 'ValidationError'\n this.errors = errors\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n errors: this.errors,\n }\n }\n}\n\n/**\n * CSRF token error\n */\nexport class CsrfError extends SecureError {\n constructor(\n message = 'Invalid or missing CSRF token',\n options: {\n details?: Record<string, unknown>\n } = {}\n ) {\n super(message, {\n statusCode: 403,\n code: 'CSRF_TOKEN_INVALID',\n details: options.details,\n })\n this.name = 'CsrfError'\n }\n}\n\n/**\n * Configuration error\n */\nexport class ConfigurationError extends SecureError {\n constructor(\n message: string,\n options: {\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 500,\n code: 'CONFIGURATION_ERROR',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'ConfigurationError'\n }\n}\n\n/**\n * Check if an error is a SecureError\n */\nexport function isSecureError(error: unknown): error is SecureError {\n return error instanceof SecureError\n}\n\n/**\n * Convert unknown error to SecureError\n */\nexport function toSecureError(error: unknown): SecureError {\n if (error instanceof SecureError) {\n return error\n }\n\n if (error instanceof Error) {\n return new SecureError(error.message, {\n cause: error,\n })\n }\n\n return new SecureError(String(error))\n}\n","/**\n * Time parsing and manipulation utilities\n */\n\nimport type { Duration } from '../core/types'\n\n/**\n * Time unit multipliers in milliseconds\n */\nconst TIME_UNITS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n}\n\n/**\n * Extended time unit names\n */\nconst TIME_UNIT_ALIASES: Record<string, string> = {\n millisecond: 'ms',\n milliseconds: 'ms',\n second: 's',\n seconds: 's',\n sec: 's',\n secs: 's',\n minute: 'm',\n minutes: 'm',\n min: 'm',\n mins: 'm',\n hour: 'h',\n hours: 'h',\n hr: 'h',\n hrs: 'h',\n day: 'd',\n days: 'd',\n}\n\n/**\n * Parse a duration string or number to milliseconds\n *\n * @example\n * ```typescript\n * parseDuration('15m') // 900000 (15 minutes)\n * parseDuration('1h') // 3600000 (1 hour)\n * parseDuration('30s') // 30000 (30 seconds)\n * parseDuration('1d') // 86400000 (1 day)\n * parseDuration(60000) // 60000 (already in ms)\n * parseDuration('2 hours') // 7200000 (2 hours)\n * parseDuration('1h 30m') // 5400000 (1.5 hours)\n * ```\n *\n * @param duration - Duration string (e.g., '15m', '1h', '30s') or number in milliseconds\n * @returns Duration in milliseconds\n * @throws Error if the duration format is invalid\n */\nexport function parseDuration(duration: Duration | string): number {\n // If it's already a number, return as-is\n if (typeof duration === 'number') {\n if (duration < 0) {\n throw new Error(`Invalid duration: ${duration}. Duration must be non-negative.`)\n }\n return duration\n }\n\n // Trim and lowercase the string\n const input = duration.trim().toLowerCase()\n\n if (!input) {\n throw new Error('Invalid duration: empty string')\n }\n\n // Try to parse as a simple number (assume milliseconds)\n const numericValue = Number(input)\n if (!isNaN(numericValue)) {\n if (numericValue < 0) {\n throw new Error(`Invalid duration: ${duration}. Duration must be non-negative.`)\n }\n return numericValue\n }\n\n // Handle compound durations like \"1h 30m\" or \"1h30m\"\n let totalMs = 0\n const regex = /(\\d+(?:\\.\\d+)?)\\s*([a-z]+)/g\n let match: RegExpExecArray | null\n let hasMatch = false\n\n while ((match = regex.exec(input)) !== null) {\n hasMatch = true\n const value = parseFloat(match[1])\n let unit = match[2]\n\n // Resolve unit aliases\n if (unit in TIME_UNIT_ALIASES) {\n unit = TIME_UNIT_ALIASES[unit]\n }\n\n // Get multiplier\n const multiplier = TIME_UNITS[unit]\n if (multiplier === undefined) {\n throw new Error(\n `Invalid duration unit: \"${unit}\" in \"${duration}\". ` +\n `Valid units: s, m, h, d (or seconds, minutes, hours, days)`\n )\n }\n\n totalMs += value * multiplier\n }\n\n if (!hasMatch) {\n throw new Error(\n `Invalid duration format: \"${duration}\". ` +\n `Expected format like \"15m\", \"1h\", \"30s\", \"1d\", or \"1h 30m\"`\n )\n }\n\n return Math.floor(totalMs)\n}\n\n/**\n * Format milliseconds to a human-readable duration string\n *\n * @example\n * ```typescript\n * formatDuration(900000) // \"15m\"\n * formatDuration(3600000) // \"1h\"\n * formatDuration(5400000) // \"1h 30m\"\n * formatDuration(86400000) // \"1d\"\n * formatDuration(90061000) // \"1d 1h 1m 1s\"\n * ```\n *\n * @param ms - Duration in milliseconds\n * @param options - Formatting options\n * @returns Human-readable duration string\n */\nexport function formatDuration(\n ms: number,\n options: {\n /**\n * Use long unit names (e.g., \"minutes\" instead of \"m\")\n */\n long?: boolean\n /**\n * Maximum number of units to include\n */\n maxUnits?: number\n /**\n * Separator between units\n */\n separator?: string\n } = {}\n): string {\n const { long = false, maxUnits = 4, separator = ' ' } = options\n\n if (ms < 0) {\n return `-${formatDuration(-ms, options)}`\n }\n\n if (ms === 0) {\n return long ? '0 seconds' : '0s'\n }\n\n const units: Array<{ value: number; short: string; long: string; longPlural: string }> = [\n { value: 86400000, short: 'd', long: 'day', longPlural: 'days' },\n { value: 3600000, short: 'h', long: 'hour', longPlural: 'hours' },\n { value: 60000, short: 'm', long: 'minute', longPlural: 'minutes' },\n { value: 1000, short: 's', long: 'second', longPlural: 'seconds' },\n { value: 1, short: 'ms', long: 'millisecond', longPlural: 'milliseconds' },\n ]\n\n const parts: string[] = []\n let remaining = ms\n\n for (const unit of units) {\n if (parts.length >= maxUnits) break\n if (remaining >= unit.value) {\n const count = Math.floor(remaining / unit.value)\n remaining = remaining % unit.value\n\n if (long) {\n parts.push(`${count} ${count === 1 ? unit.long : unit.longPlural}`)\n } else {\n parts.push(`${count}${unit.short}`)\n }\n }\n }\n\n return parts.join(separator)\n}\n\n/**\n * Get the current timestamp in seconds (Unix timestamp)\n */\nexport function nowInSeconds(): number {\n return Math.floor(Date.now() / 1000)\n}\n\n/**\n * Get the current timestamp in milliseconds\n */\nexport function nowInMs(): number {\n return Date.now()\n}\n\n/**\n * Calculate reset time for a fixed window\n *\n * @param windowMs - Window size in milliseconds\n * @returns Unix timestamp (seconds) when the window resets\n */\nexport function getWindowReset(windowMs: number): number {\n const now = Date.now()\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n return Math.floor(windowEnd / 1000)\n}\n\n/**\n * Get the start of the current window\n *\n * @param windowMs - Window size in milliseconds\n * @returns Timestamp (ms) of window start\n */\nexport function getWindowStart(windowMs: number): number {\n return Math.floor(Date.now() / windowMs) * windowMs\n}\n\n/**\n * Sleep for a specified duration\n *\n * @param duration - Duration to sleep\n * @returns Promise that resolves after the duration\n */\nexport function sleep(duration: Duration | string): Promise<void> {\n const ms = parseDuration(duration)\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Check if a timestamp has expired\n *\n * @param timestampMs - Timestamp in milliseconds\n * @param ttlMs - Time-to-live in milliseconds\n * @returns true if expired\n */\nexport function isExpired(timestampMs: number, ttlMs: number): boolean {\n return Date.now() > timestampMs + ttlMs\n}\n\n/**\n * Calculate time until expiration\n *\n * @param expiresAt - Expiration timestamp in milliseconds\n * @returns Milliseconds until expiration (0 if already expired)\n */\nexport function timeUntilExpiry(expiresAt: number): number {\n return Math.max(0, expiresAt - Date.now())\n}\n\n/**\n * Convert seconds to milliseconds\n */\nexport function secondsToMs(seconds: number): number {\n return seconds * 1000\n}\n\n/**\n * Convert milliseconds to seconds\n */\nexport function msToSeconds(ms: number): number {\n return Math.floor(ms / 1000)\n}\n","/**\n * IP address extraction and validation utilities\n */\n\nimport type { NextRequest } from '../core/types'\n\n/**\n * Headers to check for client IP (in order of priority)\n */\nconst IP_HEADERS = [\n // Cloudflare\n 'cf-connecting-ip',\n // Vercel\n 'x-real-ip',\n // Standard forwarded header (RFC 7239)\n 'x-forwarded-for',\n // AWS ELB\n 'x-client-ip',\n // Azure\n 'client-ip',\n // Fastly\n 'fastly-client-ip',\n // Akamai\n 'true-client-ip',\n // Google Cloud\n 'x-appengine-user-ip',\n // Fly.io\n 'fly-client-ip',\n] as const\n\n/**\n * Localhost/private IP patterns\n */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // IPv4 loopback\n /^10\\./, // Private class A\n /^172\\.(1[6-9]|2[0-9]|3[01])\\./, // Private class B\n /^192\\.168\\./, // Private class C\n /^::1$/, // IPv6 loopback\n /^fe80:/i, // IPv6 link-local\n /^fc00:/i, // IPv6 unique local\n /^fd[0-9a-f]{2}:/i, // IPv6 unique local\n]\n\n/**\n * IPv4 validation regex\n */\nconst IPV4_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/\n\n/**\n * IPv6 validation regex (simplified)\n */\nconst IPV6_REGEX = /^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$|^::1$|^::$|^(?:[a-fA-F0-9]{1,4}:)*:(?:[a-fA-F0-9]{1,4}:)*[a-fA-F0-9]{1,4}$/\n\n/**\n * Options for IP extraction\n */\nexport interface GetIpOptions {\n /**\n * Trust proxy headers (default: true)\n * Set to false in direct-to-client setups\n */\n trustProxy?: boolean\n\n /**\n * Additional headers to check (checked first)\n */\n customHeaders?: string[]\n\n /**\n * Fallback IP when none found\n */\n fallback?: string\n}\n\n/**\n * Extract client IP address from request\n *\n * @example\n * ```typescript\n * // Basic usage\n * const ip = getClientIp(request)\n *\n * // With options\n * const ip = getClientIp(request, {\n * trustProxy: true,\n * customHeaders: ['my-custom-ip-header'],\n * fallback: '0.0.0.0'\n * })\n * ```\n *\n * @param request - Next.js request object\n * @param options - Extraction options\n * @returns Client IP address or fallback\n */\nexport function getClientIp(request: NextRequest, options: GetIpOptions = {}): string {\n const { trustProxy = true, customHeaders = [], fallback = '127.0.0.1' } = options\n\n // First, check if Next.js has already extracted the IP\n if (request.ip) {\n return normalizeIp(request.ip)\n }\n\n if (!trustProxy) {\n return fallback\n }\n\n // Check custom headers first\n for (const header of customHeaders) {\n const value = request.headers.get(header)\n if (value) {\n const ip = parseIpFromHeader(value)\n if (ip) return ip\n }\n }\n\n // Check standard headers\n for (const header of IP_HEADERS) {\n const value = request.headers.get(header)\n if (value) {\n const ip = parseIpFromHeader(value)\n if (ip) return ip\n }\n }\n\n return fallback\n}\n\n/**\n * Parse IP from header value\n * Handles comma-separated lists (x-forwarded-for)\n */\nfunction parseIpFromHeader(headerValue: string): string | null {\n // x-forwarded-for can have multiple IPs: \"client, proxy1, proxy2\"\n // The first one is the client IP\n const ips = headerValue.split(',').map((ip) => ip.trim())\n\n for (const ip of ips) {\n const normalized = normalizeIp(ip)\n if (isValidIp(normalized)) {\n return normalized\n }\n }\n\n return null\n}\n\n/**\n * Normalize an IP address\n * - Removes IPv6 brackets\n * - Removes port numbers\n * - Trims whitespace\n */\nexport function normalizeIp(ip: string): string {\n let normalized = ip.trim()\n\n // Remove IPv6 brackets: [::1] -> ::1\n if (normalized.startsWith('[') && normalized.includes(']')) {\n normalized = normalized.slice(1, normalized.indexOf(']'))\n }\n\n // Remove port: 192.168.1.1:8080 -> 192.168.1.1\n // For IPv4 with port\n if (normalized.includes(':') && !normalized.includes('::')) {\n const lastColon = normalized.lastIndexOf(':')\n const potentialPort = normalized.slice(lastColon + 1)\n if (/^\\d+$/.test(potentialPort)) {\n normalized = normalized.slice(0, lastColon)\n }\n }\n\n // Handle IPv4-mapped IPv6: ::ffff:192.168.1.1 -> 192.168.1.1\n if (normalized.toLowerCase().startsWith('::ffff:')) {\n const ipv4Part = normalized.slice(7)\n if (isValidIpv4(ipv4Part)) {\n return ipv4Part\n }\n }\n\n return normalized\n}\n\n/**\n * Check if an IP address is valid\n */\nexport function isValidIp(ip: string): boolean {\n return isValidIpv4(ip) || isValidIpv6(ip)\n}\n\n/**\n * Check if an IPv4 address is valid\n */\nexport function isValidIpv4(ip: string): boolean {\n return IPV4_REGEX.test(ip)\n}\n\n/**\n * Check if an IPv6 address is valid\n */\nexport function isValidIpv6(ip: string): boolean {\n return IPV6_REGEX.test(ip) || ip === '::1' || ip === '::'\n}\n\n/**\n * Check if an IP is a private/local address\n */\nexport function isPrivateIp(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip))\n}\n\n/**\n * Check if an IP is localhost\n */\nexport function isLocalhost(ip: string): boolean {\n return ip === '127.0.0.1' || ip === '::1' || ip === 'localhost'\n}\n\n/**\n * Create a rate limit key from IP\n * Normalizes and optionally hashes the IP\n */\nexport function createIpKey(\n ip: string,\n options: {\n prefix?: string\n hash?: boolean\n } = {}\n): string {\n const { prefix = 'rl', hash = false } = options\n const normalizedIp = normalizeIp(ip)\n\n if (hash) {\n // Simple hash for privacy (not cryptographic)\n const hashCode = simpleHash(normalizedIp)\n return `${prefix}:ip:${hashCode}`\n }\n\n return `${prefix}:ip:${normalizedIp}`\n}\n\n/**\n * Simple non-cryptographic hash (for key generation)\n */\nfunction simpleHash(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Anonymize an IP address (for logging)\n * IPv4: 192.168.1.100 -> 192.168.1.xxx\n * IPv6: 2001:db8::1 -> 2001:db8::xxx\n */\nexport function anonymizeIp(ip: string): string {\n const normalized = normalizeIp(ip)\n\n if (isValidIpv4(normalized)) {\n const parts = normalized.split('.')\n parts[3] = 'xxx'\n return parts.join('.')\n }\n\n if (isValidIpv6(normalized)) {\n const parts = normalized.split(':')\n if (parts.length > 0) {\n parts[parts.length - 1] = 'xxxx'\n }\n return parts.join(':')\n }\n\n return 'xxx.xxx.xxx.xxx'\n}\n\n/**\n * Get geolocation info from request (if available)\n * Works with Vercel Edge and Cloudflare\n */\nexport function getGeoInfo(request: NextRequest): {\n country?: string\n city?: string\n region?: string\n latitude?: string\n longitude?: string\n} {\n // Vercel provides geo info on the request\n if (request.geo) {\n return {\n country: request.geo.country,\n city: request.geo.city,\n region: request.geo.region,\n latitude: request.geo.latitude,\n longitude: request.geo.longitude,\n }\n }\n\n // Cloudflare headers\n return {\n country: request.headers.get('cf-ipcountry') ?? undefined,\n city: request.headers.get('cf-ipcity') ?? undefined,\n region: request.headers.get('cf-region') ?? undefined,\n latitude: request.headers.get('cf-iplat') ?? undefined,\n longitude: request.headers.get('cf-iplong') ?? undefined,\n }\n}\n","/**\n * In-memory rate limit store\n *\n * Suitable for:\n * - Development\n * - Single-instance deployments\n * - Testing\n *\n * Not suitable for:\n * - Multi-instance/distributed deployments (use Redis/Upstash)\n * - Serverless (data lost between invocations)\n */\n\nimport type { RateLimitStore, MemoryStoreOptions } from '../types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Entry stored in memory\n */\ninterface MemoryEntry {\n count: number\n reset: number // Unix timestamp (seconds)\n createdAt: number // Timestamp (ms)\n}\n\n/**\n * LRU-style memory store for rate limiting\n *\n * Features:\n * - Automatic cleanup of expired entries\n * - LRU eviction when max keys exceeded\n * - Zero dependencies\n * - Edge Runtime compatible\n *\n * @example\n * ```typescript\n * import { MemoryStore } from 'next-secure/rate-limit'\n *\n * const store = new MemoryStore({\n * cleanupInterval: 60000, // 1 minute\n * maxKeys: 10000\n * })\n * ```\n */\nexport class MemoryStore implements RateLimitStore {\n public readonly name = 'memory'\n\n private store: Map<string, MemoryEntry>\n private cleanupTimer: ReturnType<typeof setInterval> | null = null\n private readonly maxKeys: number\n private readonly cleanupInterval: number\n\n constructor(options: MemoryStoreOptions = {}) {\n const { cleanupInterval = 60000, maxKeys = 10000 } = options\n\n this.store = new Map()\n this.maxKeys = maxKeys\n this.cleanupInterval = cleanupInterval\n\n // Start cleanup timer (only in long-running environments)\n if (typeof setInterval !== 'undefined' && cleanupInterval > 0) {\n this.startCleanupTimer()\n }\n }\n\n /**\n * Increment the counter for a key\n *\n * Note: The key should already include window information if needed.\n * This store is algorithm-agnostic - algorithms handle windowing logic.\n */\n async increment(\n key: string,\n windowMs: number\n ): Promise<{ count: number; reset: number }> {\n const now = Date.now()\n const defaultReset = msToSeconds(now + windowMs)\n\n const existing = this.store.get(key)\n\n if (existing) {\n // Increment existing entry\n existing.count++\n // Move to end (LRU update)\n this.store.delete(key)\n this.store.set(key, existing)\n return { count: existing.count, reset: existing.reset }\n }\n\n // New entry\n const entry: MemoryEntry = {\n count: 1,\n reset: defaultReset,\n createdAt: now,\n }\n\n // Check if we need to evict\n if (this.store.size >= this.maxKeys) {\n this.evictOldest()\n }\n\n this.store.set(key, entry)\n return { count: 1, reset: defaultReset }\n }\n\n /**\n * Get the current count for a key\n */\n async get(key: string): Promise<{ count: number; reset: number } | null> {\n const entry = this.store.get(key)\n\n if (!entry) {\n return null\n }\n\n // Check if expired\n const now = Math.floor(Date.now() / 1000)\n if (entry.reset <= now) {\n this.store.delete(key)\n return null\n }\n\n return { count: entry.count, reset: entry.reset }\n }\n\n /**\n * Reset the counter for a key\n */\n async reset(key: string): Promise<void> {\n this.store.delete(key)\n }\n\n /**\n * Check if the store is healthy\n */\n async isHealthy(): Promise<boolean> {\n return true\n }\n\n /**\n * Cleanup expired entries\n */\n async cleanup(): Promise<void> {\n const now = Math.floor(Date.now() / 1000)\n const keysToDelete: string[] = []\n\n for (const [key, entry] of this.store) {\n if (entry.reset <= now) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.store.delete(key)\n }\n }\n\n /**\n * Close the store (stop cleanup timer)\n */\n async close(): Promise<void> {\n this.stopCleanupTimer()\n this.store.clear()\n }\n\n /**\n * Get the current size of the store\n */\n get size(): number {\n return this.store.size\n }\n\n /**\n * Clear all entries\n */\n clear(): void {\n this.store.clear()\n }\n\n /**\n * Start the cleanup timer\n */\n private startCleanupTimer(): void {\n if (this.cleanupTimer) return\n\n this.cleanupTimer = setInterval(() => {\n void this.cleanup()\n }, this.cleanupInterval)\n\n // Unref to not keep the process alive\n if (typeof this.cleanupTimer === 'object' && 'unref' in this.cleanupTimer) {\n (this.cleanupTimer as NodeJS.Timeout).unref()\n }\n }\n\n /**\n * Stop the cleanup timer\n */\n private stopCleanupTimer(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer)\n this.cleanupTimer = null\n }\n }\n\n /**\n * Evict oldest entries when max keys exceeded\n */\n private evictOldest(): void {\n // Map maintains insertion order, so first key is oldest\n const keysToDelete = Math.ceil(this.maxKeys * 0.1) // Delete 10%\n\n let deleted = 0\n for (const key of this.store.keys()) {\n if (deleted >= keysToDelete) break\n this.store.delete(key)\n deleted++\n }\n }\n}\n\n/**\n * Create a memory store with default options\n */\nexport function createMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n return new MemoryStore(options)\n}\n\n/**\n * Global memory store instance (singleton)\n * Useful for serverless environments where you want to reuse across requests\n */\nlet globalStore: MemoryStore | null = null\n\n/**\n * Get or create the global memory store\n */\nexport function getGlobalMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n if (!globalStore) {\n globalStore = new MemoryStore(options)\n }\n return globalStore\n}\n\n/**\n * Reset the global memory store (useful for testing)\n */\nexport function resetGlobalMemoryStore(): void {\n if (globalStore) {\n void globalStore.close()\n globalStore = null\n }\n}\n","/**\n * Sliding Window Rate Limiting Algorithm\n *\n * This algorithm provides a smoother rate limiting experience compared to fixed windows.\n * It uses a weighted calculation based on the previous and current window counts.\n *\n * How it works:\n * 1. Divide time into fixed windows (e.g., 1 minute each)\n * 2. Track request counts for current and previous windows\n * 3. Calculate weighted count based on position within current window\n *\n * Example (100 req/min limit):\n * - Previous window: 80 requests\n * - Current window: 30 requests\n * - 30 seconds into current window (50% through)\n * - Weighted count = 30 + (80 * 0.5) = 70\n * - Since 70 < 100, request is allowed\n *\n * Pros:\n * - Smoother than fixed window\n * - Prevents burst attacks at window boundaries\n * - Memory efficient (only stores 2 counters per key)\n *\n * Cons:\n * - Slightly more complex than fixed window\n * - Not perfectly accurate (approximation)\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Sliding window counter algorithm implementation\n */\nexport class SlidingWindowAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'sliding-window' as const\n\n /**\n * Check if the request should be rate limited\n */\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Calculate window boundaries\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const previousWindowStart = windowStart - windowMs\n\n // Position within current window (0 to 1)\n const windowPosition = (now - windowStart) / windowMs\n\n // Keys for current and previous windows\n const currentKey = `${key}:${windowStart}`\n const previousKey = `${key}:${previousWindowStart}`\n\n // Get counts from both windows\n const [currentData, previousData] = await Promise.all([\n store.get(currentKey),\n store.get(previousKey),\n ])\n\n const currentCount = currentData?.count ?? 0\n const previousCount = previousData?.count ?? 0\n\n // Calculate weighted count using sliding window formula\n // Weight of previous window decreases as we move through current window\n const previousWeight = 1 - windowPosition\n const weightedCount = currentCount + Math.floor(previousCount * previousWeight)\n\n // Calculate reset time (end of current window)\n const reset = msToSeconds(windowEnd)\n\n // Check if limit exceeded\n if (weightedCount >= limit) {\n // Calculate retry time based on when enough requests will \"expire\"\n const retryAfter = this.calculateRetryAfter(\n currentCount,\n previousCount,\n limit,\n windowMs,\n windowPosition\n )\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter,\n }\n }\n\n // Increment current window counter\n await store.increment(currentKey, windowMs)\n\n // Calculate remaining\n const remaining = Math.max(0, limit - weightedCount - 1)\n\n return {\n limit,\n remaining,\n reset,\n limited: false,\n }\n }\n\n /**\n * Calculate how long until the client can make another request\n */\n private calculateRetryAfter(\n currentCount: number,\n previousCount: number,\n limit: number,\n windowMs: number,\n windowPosition: number\n ): number {\n // If previous window is empty, wait until current window resets\n if (previousCount === 0) {\n return Math.ceil((1 - windowPosition) * windowMs / 1000)\n }\n\n // Calculate when the weighted count will drop below limit\n // We need: currentCount + previousCount * (1 - newPosition) < limit\n // Solving for newPosition: newPosition > 1 - (limit - currentCount) / previousCount\n\n const requiredPosition = 1 - (limit - currentCount) / previousCount\n\n if (requiredPosition <= windowPosition) {\n // Should already be under limit, but we got here so add small delay\n return 1\n }\n\n if (requiredPosition >= 1) {\n // Need to wait until next window\n const remainingInCurrentWindow = (1 - windowPosition) * windowMs\n return Math.ceil(remainingInCurrentWindow / 1000)\n }\n\n // Calculate time until we reach required position\n const timeToWait = (requiredPosition - windowPosition) * windowMs\n return Math.ceil(timeToWait / 1000)\n }\n}\n\n/**\n * Create a sliding window algorithm instance\n */\nexport function createSlidingWindowAlgorithm(): SlidingWindowAlgorithm {\n return new SlidingWindowAlgorithm()\n}\n\n/**\n * Sliding Window Log Algorithm (more accurate but uses more memory)\n *\n * This stores individual request timestamps instead of just counters.\n * More accurate but not recommended for high-traffic scenarios.\n */\nexport class SlidingWindowLogAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'sliding-window' as const\n\n /**\n * In-memory log of request timestamps per key\n * For production, this should be stored externally (Redis sorted sets, etc.)\n */\n private logs: Map<string, number[]> = new Map()\n\n /**\n * Maximum log size before cleanup\n */\n private readonly maxLogSize = 10000\n\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n const windowStart = now - windowMs\n\n // Get or create log for this key\n let log = this.logs.get(key) ?? []\n\n // Remove expired entries\n log = log.filter((timestamp) => timestamp > windowStart)\n\n // Calculate reset (when oldest entry expires)\n const oldestTimestamp = log[0] ?? now\n const reset = msToSeconds(oldestTimestamp + windowMs)\n\n // Check if limit exceeded\n if (log.length >= limit) {\n const retryAfter = Math.ceil((oldestTimestamp + windowMs - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Add current request\n log.push(now)\n this.logs.set(key, log)\n\n // Cleanup if too many keys\n if (this.logs.size > this.maxLogSize) {\n this.cleanup()\n }\n\n return {\n limit,\n remaining: Math.max(0, limit - log.length),\n reset,\n limited: false,\n }\n }\n\n /**\n * Remove oldest entries when log size exceeded\n */\n private cleanup(): void {\n const keysToDelete: string[] = []\n const now = Date.now()\n\n for (const [key, log] of this.logs) {\n // Delete empty or very old logs\n if (log.length === 0 || log[log.length - 1]! < now - 3600000) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.logs.delete(key)\n }\n }\n\n /**\n * Clear all logs\n */\n clear(): void {\n this.logs.clear()\n }\n}\n","/**\n * Fixed Window Rate Limiting Algorithm\n *\n * The simplest rate limiting algorithm. Divides time into fixed windows\n * and counts requests within each window.\n *\n * How it works:\n * 1. Divide time into fixed windows (e.g., every minute starting at :00)\n * 2. Count requests within the current window\n * 3. Reset counter when new window starts\n *\n * Example (100 req/min limit):\n * - Window 1 (12:00:00 - 12:00:59): 80 requests -> allowed\n * - Window 2 (12:01:00 - 12:01:59): 0 requests (fresh start)\n *\n * Pros:\n * - Simple to implement\n * - Memory efficient (only 1 counter per key)\n * - Fast (O(1) operations)\n *\n * Cons:\n * - Burst problem: 200 requests possible in 2 seconds at window boundary\n * - 100 requests at 12:00:59 (end of window 1)\n * - 100 requests at 12:01:00 (start of window 2)\n * - Not smooth\n *\n * Use when:\n * - Simplicity is preferred\n * - Burst at boundaries is acceptable\n * - Memory/CPU is very constrained\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Fixed window algorithm implementation\n */\nexport class FixedWindowAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'fixed-window' as const\n\n /**\n * Check if the request should be rate limited\n */\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Calculate window boundaries\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const reset = msToSeconds(windowEnd)\n\n // Create window-specific key\n const windowKey = `${key}:${windowStart}`\n\n // Get current count\n const data = await store.get(windowKey)\n const currentCount = data?.count ?? 0\n\n // Check if limit exceeded\n if (currentCount >= limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Increment counter\n const { count } = await store.increment(windowKey, windowMs)\n\n // Double-check after increment (race condition protection)\n if (count > limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n return {\n limit,\n remaining: Math.max(0, limit - count),\n reset,\n limited: false,\n }\n }\n}\n\n/**\n * Create a fixed window algorithm instance\n */\nexport function createFixedWindowAlgorithm(): FixedWindowAlgorithm {\n return new FixedWindowAlgorithm()\n}\n\n/**\n * Fixed window with burst protection\n *\n * Adds a secondary limit to prevent bursts at window boundaries.\n * For example: 100 req/min with max 20 req/10sec burst.\n */\nexport class FixedWindowWithBurstProtection implements RateLimitAlgorithmImpl {\n public readonly name = 'fixed-window' as const\n\n constructor(\n private readonly burstLimit: number,\n private readonly burstWindowMs: number\n ) {}\n\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Check burst limit first (smaller window)\n const burstWindowStart = Math.floor(now / this.burstWindowMs) * this.burstWindowMs\n const burstKey = `${key}:burst:${burstWindowStart}`\n const burstData = await store.get(burstKey)\n const burstCount = burstData?.count ?? 0\n\n if (burstCount >= this.burstLimit) {\n const burstWindowEnd = burstWindowStart + this.burstWindowMs\n const retryAfter = Math.ceil((burstWindowEnd - now) / 1000)\n\n return {\n limit: this.burstLimit,\n remaining: 0,\n reset: msToSeconds(burstWindowEnd),\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Check main limit\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const windowKey = `${key}:${windowStart}`\n const data = await store.get(windowKey)\n const currentCount = data?.count ?? 0\n\n if (currentCount >= limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset: msToSeconds(windowEnd),\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Increment both counters\n await Promise.all([\n store.increment(windowKey, windowMs),\n store.increment(burstKey, this.burstWindowMs),\n ])\n\n return {\n limit,\n remaining: Math.max(0, limit - currentCount - 1),\n reset: msToSeconds(windowEnd),\n limited: false,\n }\n }\n}\n\n/**\n * Create a fixed window with burst protection\n *\n * @example\n * ```typescript\n * // 100 req/min with max 20 req/10sec burst\n * const algorithm = createFixedWindowWithBurstProtection(20, 10000)\n * ```\n */\nexport function createFixedWindowWithBurstProtection(\n burstLimit: number,\n burstWindowMs: number\n): FixedWindowWithBurstProtection {\n return new FixedWindowWithBurstProtection(burstLimit, burstWindowMs)\n}\n","/**\n * Token Bucket Rate Limiting Algorithm\n *\n * A bucket holds tokens that are consumed by requests. Tokens are refilled\n * at a constant rate. This allows for controlled bursts while maintaining\n * an average rate.\n *\n * How it works:\n * 1. Bucket starts full with 'limit' tokens\n * 2. Each request consumes 1 token (or more for weighted requests)\n * 3. Tokens are refilled at 'limit / window' rate\n * 4. Request is allowed if tokens >= 1\n *\n * Example (100 tokens, refill 100/min = 1.67/sec):\n * - Initial: 100 tokens\n * - 50 requests instantly: 50 tokens remaining (burst allowed)\n * - Wait 30 seconds: 50 + (50 * 1.67) = 100 tokens (refilled)\n * - 100 requests instantly: 0 tokens\n * - Next request: denied until tokens refill\n *\n * Pros:\n * - Allows controlled bursts\n * - Smooth average rate\n * - Good for APIs with sporadic traffic\n *\n * Cons:\n * - More complex state management\n * - Requires storing last refill time\n *\n * Use when:\n * - You want to allow bursts\n * - Traffic is sporadic\n * - User experience matters (can handle burst then wait)\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl, TokenBucketState } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Token bucket algorithm implementation\n */\nexport class TokenBucketAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'token-bucket' as const\n\n /**\n * In-memory bucket states\n * For distributed systems, this should be stored in Redis\n */\n private buckets: Map<string, TokenBucketState> = new Map()\n\n /**\n * Maximum number of buckets to store before cleanup\n */\n private readonly maxBuckets = 10000\n\n /**\n * Check if the request should be rate limited\n *\n * @param store - Not used directly, state stored in memory\n * @param key - Rate limit key\n * @param limit - Maximum tokens (bucket capacity)\n * @param windowMs - Time to refill bucket completely\n */\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Get or create bucket state\n let bucket = this.buckets.get(key)\n\n if (!bucket) {\n // New bucket, start full\n bucket = {\n tokens: limit,\n lastRefill: now,\n }\n } else {\n // Refill tokens based on time elapsed\n bucket = this.refillTokens(bucket, limit, windowMs, now)\n }\n\n // Calculate reset time (when bucket would be full again)\n const tokensNeeded = limit - bucket.tokens\n const refillRate = limit / windowMs // tokens per ms\n const timeToFull = tokensNeeded / refillRate\n const reset = msToSeconds(now + timeToFull)\n\n // Check if we have tokens\n if (bucket.tokens < 1) {\n // Calculate when we'll have 1 token\n const timeToOneToken = (1 - bucket.tokens) / refillRate\n const retryAfter = Math.ceil(timeToOneToken / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Consume a token\n bucket.tokens -= 1\n this.buckets.set(key, bucket)\n\n // Cleanup if too many buckets\n if (this.buckets.size > this.maxBuckets) {\n this.cleanup()\n }\n\n return {\n limit,\n remaining: Math.floor(bucket.tokens),\n reset,\n limited: false,\n }\n }\n\n /**\n * Refill tokens based on time elapsed\n */\n private refillTokens(\n bucket: TokenBucketState,\n limit: number,\n windowMs: number,\n now: number\n ): TokenBucketState {\n const elapsed = now - bucket.lastRefill\n const refillRate = limit / windowMs // tokens per ms\n const tokensToAdd = elapsed * refillRate\n\n return {\n tokens: Math.min(limit, bucket.tokens + tokensToAdd),\n lastRefill: now,\n }\n }\n\n /**\n * Remove old buckets\n */\n private cleanup(): void {\n const now = Date.now()\n const staleThreshold = 3600000 // 1 hour\n\n const keysToDelete: string[] = []\n\n for (const [key, bucket] of this.buckets) {\n if (now - bucket.lastRefill > staleThreshold) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.buckets.delete(key)\n }\n }\n\n /**\n * Get current bucket state (for testing/debugging)\n */\n getBucketState(key: string): TokenBucketState | undefined {\n return this.buckets.get(key)\n }\n\n /**\n * Clear all buckets\n */\n clear(): void {\n this.buckets.clear()\n }\n}\n\n/**\n * Create a token bucket algorithm instance\n */\nexport function createTokenBucketAlgorithm(): TokenBucketAlgorithm {\n return new TokenBucketAlgorithm()\n}\n\n/**\n * Leaky Bucket Algorithm (variation of token bucket)\n *\n * Instead of refilling tokens, requests \"leak\" out of the bucket\n * at a constant rate. This enforces a strict output rate.\n *\n * Think of it as a bucket with a hole at the bottom:\n * - Requests are added to the bucket\n * - Requests leak out at a constant rate\n * - If bucket overflows, request is rejected\n *\n * Use when:\n * - You need strict rate enforcement\n * - Bursts should be queued, not rejected\n * - Output rate must be constant\n */\nexport class LeakyBucketAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'token-bucket' as const // Grouped with token bucket\n\n /**\n * In-memory bucket states\n * Stores the \"water level\" and last leak time\n */\n private buckets: Map<string, { level: number; lastLeak: number }> = new Map()\n\n /**\n * Maximum number of buckets\n */\n private readonly maxBuckets = 10000\n\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Get or create bucket\n let bucket = this.buckets.get(key) ?? { level: 0, lastLeak: now }\n\n // Calculate how much has leaked since last check\n const elapsed = now - bucket.lastLeak\n const leakRate = limit / windowMs // requests per ms\n const leaked = elapsed * leakRate\n\n // Update level (can't go below 0)\n bucket.level = Math.max(0, bucket.level - leaked)\n bucket.lastLeak = now\n\n // Calculate reset time\n const timeToEmpty = bucket.level / leakRate\n const reset = msToSeconds(now + timeToEmpty)\n\n // Check if bucket would overflow\n if (bucket.level + 1 > limit) {\n // Calculate when there's room for 1 more request\n const overflow = bucket.level + 1 - limit\n const timeToRoom = overflow / leakRate\n const retryAfter = Math.ceil(timeToRoom / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Add request to bucket\n bucket.level += 1\n this.buckets.set(key, bucket)\n\n // Cleanup if needed\n if (this.buckets.size > this.maxBuckets) {\n this.cleanup(now)\n }\n\n return {\n limit,\n remaining: Math.floor(limit - bucket.level),\n reset,\n limited: false,\n }\n }\n\n private cleanup(now: number): void {\n const staleThreshold = 3600000\n\n for (const [key, bucket] of this.buckets) {\n if (now - bucket.lastLeak > staleThreshold) {\n this.buckets.delete(key)\n }\n }\n }\n\n clear(): void {\n this.buckets.clear()\n }\n}\n\n/**\n * Create a leaky bucket algorithm instance\n */\nexport function createLeakyBucketAlgorithm(): LeakyBucketAlgorithm {\n return new LeakyBucketAlgorithm()\n}\n","/**\n * Rate Limiting Middleware for Next.js App Router\n *\n * @example\n * ```typescript\n * // Basic usage\n * import { withRateLimit } from 'next-secure/rate-limit'\n *\n * export const GET = withRateLimit(\n * async (req) => Response.json({ data: [] }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // With custom identifier\n * export const GET = withRateLimit(handler, {\n * limit: 100,\n * window: '15m',\n * identifier: (req) => req.headers.get('x-api-key') ?? 'anonymous'\n * })\n *\n * // With Redis store\n * import { createRedisStore } from 'next-secure/rate-limit'\n *\n * const store = createRedisStore({ client: redis })\n *\n * export const GET = withRateLimit(handler, {\n * limit: 100,\n * window: '15m',\n * store\n * })\n * ```\n */\n\nimport type { NextRequest, RateLimitInfo, SecureContext } from '../../core/types'\nimport { RateLimitError } from '../../core/errors'\nimport { parseDuration } from '../../utils/time'\nimport { getClientIp } from '../../utils/ip'\nimport type { RateLimitConfig, RateLimitStore, RateLimitAlgorithmImpl } from './types'\nimport { MemoryStore } from './stores/memory'\nimport { SlidingWindowAlgorithm } from './algorithms/sliding-window'\nimport { FixedWindowAlgorithm } from './algorithms/fixed-window'\nimport { TokenBucketAlgorithm } from './algorithms/token-bucket'\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: Partial<RateLimitConfig> = {\n algorithm: 'sliding-window',\n identifier: 'ip',\n headers: true,\n prefix: 'rl',\n message: 'Too Many Requests',\n statusCode: 429,\n debug: false,\n}\n\n/**\n * Global default store (shared across handlers)\n */\nlet defaultStore: RateLimitStore | null = null\n\n/**\n * Get or create the default memory store\n */\nfunction getDefaultStore(): RateLimitStore {\n if (!defaultStore) {\n defaultStore = new MemoryStore()\n }\n return defaultStore\n}\n\n/**\n * Get algorithm instance by name\n */\nfunction getAlgorithm(name: RateLimitConfig['algorithm']): RateLimitAlgorithmImpl {\n switch (name) {\n case 'fixed-window':\n return new FixedWindowAlgorithm()\n case 'token-bucket':\n return new TokenBucketAlgorithm()\n case 'sliding-window':\n default:\n return new SlidingWindowAlgorithm()\n }\n}\n\n/**\n * Create rate limit headers\n */\nfunction createRateLimitHeaders(info: RateLimitInfo): Headers {\n const headers = new Headers()\n\n headers.set('X-RateLimit-Limit', String(info.limit))\n headers.set('X-RateLimit-Remaining', String(info.remaining))\n headers.set('X-RateLimit-Reset', String(info.reset))\n\n if (info.limited && info.retryAfter) {\n headers.set('Retry-After', String(info.retryAfter))\n }\n\n return headers\n}\n\n/**\n * Merge headers from multiple sources\n */\nfunction mergeHeaders(target: Headers, source: Headers): void {\n source.forEach((value, key) => {\n target.set(key, value)\n })\n}\n\n/**\n * Get client identifier from request\n */\nasync function getIdentifier(\n request: NextRequest,\n identifier: RateLimitConfig['identifier'],\n prefix: string,\n context?: SecureContext\n): Promise<string> {\n if (typeof identifier === 'function') {\n const id = await identifier(request)\n return `${prefix}:custom:${id}`\n }\n\n if (identifier === 'user') {\n // Requires auth middleware to have run first\n const userId = context?.user\n ? (context.user as { id?: string }).id ?? 'anonymous'\n : 'anonymous'\n return `${prefix}:user:${userId}`\n }\n\n // Default: IP-based\n const ip = getClientIp(request)\n return `${prefix}:ip:${ip}`\n}\n\n/**\n * Rate limiting middleware wrapper\n *\n * @example\n * ```typescript\n * // Simple usage\n * export const GET = withRateLimit(\n * async (req) => Response.json({ ok: true }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // With all options\n * export const POST = withRateLimit(\n * async (req, ctx) => {\n * // ctx.rateLimit contains info\n * return Response.json({ remaining: ctx.rateLimit?.remaining })\n * },\n * {\n * limit: 10,\n * window: '1m',\n * algorithm: 'sliding-window',\n * identifier: 'ip',\n * headers: true,\n * onLimit: (req, info) => new Response(\n * JSON.stringify({ error: 'Slow down!' }),\n * { status: 429 }\n * ),\n * skip: (req) => req.headers.get('x-bypass') === 'secret'\n * }\n * )\n * ```\n */\nexport function withRateLimit<TUser = unknown>(\n handler: (\n request: NextRequest,\n context: SecureContext<TUser> & { rateLimit?: RateLimitInfo }\n ) => Promise<Response> | Response,\n config: RateLimitConfig\n): (request: NextRequest, context?: SecureContext<TUser>) => Promise<Response> {\n // Merge config with defaults\n const finalConfig: Required<RateLimitConfig> = {\n ...DEFAULT_CONFIG,\n ...config,\n store: config.store ?? getDefaultStore(),\n } as Required<RateLimitConfig>\n\n // Parse window duration once\n const windowMs = parseDuration(finalConfig.window)\n\n // Get algorithm once\n const algorithm = getAlgorithm(finalConfig.algorithm)\n\n // Debug logging\n const debug = finalConfig.debug\n ? (msg: string, data?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[next-secure:rate-limit] ${msg}`, data ?? '')\n }\n : () => {}\n\n debug('Initialized', {\n limit: finalConfig.limit,\n window: finalConfig.window,\n algorithm: finalConfig.algorithm,\n })\n\n return async (\n request: NextRequest,\n context?: SecureContext<TUser>\n ): Promise<Response> => {\n // Create context if not provided\n const ctx: SecureContext<TUser> & { rateLimit?: RateLimitInfo } = context ?? {\n user: null,\n requestId: crypto.randomUUID(),\n ip: getClientIp(request),\n userAgent: request.headers.get('user-agent') ?? '',\n startTime: Date.now(),\n metadata: {},\n }\n\n try {\n // Check if we should skip rate limiting\n if (finalConfig.skip) {\n const shouldSkip = await finalConfig.skip(request)\n if (shouldSkip) {\n debug('Skipping rate limit check')\n return handler(request, ctx)\n }\n }\n\n // Get identifier\n const key = await getIdentifier(\n request,\n finalConfig.identifier,\n finalConfig.prefix,\n ctx\n )\n debug('Rate limit key', key)\n\n // Check rate limit\n const info = await algorithm.check(\n finalConfig.store,\n key,\n finalConfig.limit,\n windowMs\n )\n debug('Rate limit info', info)\n\n // Add rate limit info to context\n ctx.rateLimit = info\n\n // Check if limited\n if (info.limited) {\n debug('Request rate limited')\n\n // Custom handler\n if (finalConfig.onLimit) {\n const response = await finalConfig.onLimit(request, info)\n\n // Add headers to custom response\n if (finalConfig.headers) {\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(response.headers, rateLimitHeaders)\n }\n\n return response\n }\n\n // Default rate limit response\n const error = new RateLimitError({\n retryAfter: info.retryAfter ?? 60,\n resetAt: info.reset * 1000,\n message: finalConfig.message,\n })\n\n const response = error.toResponse()\n\n if (finalConfig.headers) {\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(response.headers, rateLimitHeaders)\n }\n\n return response\n }\n\n // Call the handler\n const response = await handler(request, ctx)\n\n // Add rate limit headers to successful response\n if (finalConfig.headers) {\n // Clone response to modify headers\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(newResponse.headers, rateLimitHeaders)\n\n return newResponse\n }\n\n return response\n } catch (error) {\n debug('Error in rate limit middleware', error)\n\n // Re-throw RateLimitError\n if (error instanceof RateLimitError) {\n throw error\n }\n\n // For other errors, let the request through (fail open)\n // This prevents rate limiting from blocking all requests on errors\n // eslint-disable-next-line no-console\n console.error('[next-secure:rate-limit] Error:', error)\n return handler(request, ctx)\n }\n }\n}\n\n/**\n * Create a rate limiter instance for reuse\n *\n * @example\n * ```typescript\n * const apiLimiter = createRateLimiter({\n * limit: 100,\n * window: '15m'\n * })\n *\n * export const GET = apiLimiter(async (req) => Response.json({ ok: true }))\n * export const POST = apiLimiter(async (req) => Response.json({ ok: true }))\n * ```\n */\nexport function createRateLimiter(config: RateLimitConfig) {\n return <TUser = unknown>(\n handler: (\n request: NextRequest,\n context: SecureContext<TUser> & { rateLimit?: RateLimitInfo }\n ) => Promise<Response> | Response\n ) => withRateLimit(handler, config)\n}\n\n/**\n * Check rate limit without wrapping a handler\n * Useful for checking rate limit in existing code\n *\n * @example\n * ```typescript\n * export async function GET(req: NextRequest) {\n * const result = await checkRateLimit(req, {\n * limit: 100,\n * window: '15m'\n * })\n *\n * if (!result.success) {\n * return result.response\n * }\n *\n * // Continue with normal logic\n * return Response.json({ ok: true })\n * }\n * ```\n */\nexport async function checkRateLimit(\n request: NextRequest,\n config: RateLimitConfig\n): Promise<{\n success: boolean\n info: RateLimitInfo\n response?: Response\n headers: Headers\n}> {\n const finalConfig = {\n ...DEFAULT_CONFIG,\n ...config,\n store: config.store ?? getDefaultStore(),\n } as Required<RateLimitConfig>\n\n const windowMs = parseDuration(finalConfig.window)\n const algorithm = getAlgorithm(finalConfig.algorithm)\n\n // Check if should skip\n if (finalConfig.skip) {\n const shouldSkip = await finalConfig.skip(request)\n if (shouldSkip) {\n const info: RateLimitInfo = {\n limit: finalConfig.limit,\n remaining: finalConfig.limit,\n reset: Math.floor(Date.now() / 1000) + Math.floor(windowMs / 1000),\n limited: false,\n }\n return { success: true, info, headers: new Headers() }\n }\n }\n\n const key = await getIdentifier(request, finalConfig.identifier, finalConfig.prefix)\n const info = await algorithm.check(finalConfig.store, key, finalConfig.limit, windowMs)\n const headers = finalConfig.headers ? createRateLimitHeaders(info) : new Headers()\n\n if (info.limited) {\n let response: Response\n\n if (finalConfig.onLimit) {\n response = await finalConfig.onLimit(request, info)\n } else {\n const error = new RateLimitError({\n retryAfter: info.retryAfter ?? 60,\n resetAt: info.reset * 1000,\n message: finalConfig.message,\n })\n response = error.toResponse()\n }\n\n if (finalConfig.headers) {\n mergeHeaders(response.headers, headers)\n }\n\n return { success: false, info, response, headers }\n }\n\n return { success: true, info, headers }\n}\n\n/**\n * Reset rate limit for a specific key\n *\n * @example\n * ```typescript\n * // Reset rate limit for an IP\n * await resetRateLimit('ip', '192.168.1.1')\n *\n * // Reset for a user\n * await resetRateLimit('user', 'user-123')\n * ```\n */\nexport async function resetRateLimit(\n type: 'ip' | 'user' | 'custom',\n identifier: string,\n options?: {\n store?: RateLimitStore\n prefix?: string\n }\n): Promise<void> {\n const store = options?.store ?? getDefaultStore()\n const prefix = options?.prefix ?? 'rl'\n const key = `${prefix}:${type}:${identifier}`\n\n await store.reset(key)\n}\n\n/**\n * Get current rate limit status for a key (without incrementing)\n */\nexport async function getRateLimitStatus(\n type: 'ip' | 'user' | 'custom',\n identifier: string,\n options?: {\n store?: RateLimitStore\n prefix?: string\n }\n): Promise<{ count: number; reset: number } | null> {\n const store = options?.store ?? getDefaultStore()\n const prefix = options?.prefix ?? 'rl'\n const key = `${prefix}:${type}:${identifier}`\n\n return store.get(key)\n}\n\n/**\n * Clear all rate limits (useful for testing)\n */\nexport function clearAllRateLimits(): void {\n if (defaultStore && 'clear' in defaultStore) {\n (defaultStore as MemoryStore).clear()\n }\n}\n","import { webcrypto } from 'node:crypto'\n\nconst encoder = new TextEncoder()\n\n/**\n * Generate random bytes as hex string\n */\nexport function randomBytes(length: number): string {\n const bytes = new Uint8Array(length)\n webcrypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Create HMAC signature\n */\nasync function createSignature(data: string, secret: string): Promise<string> {\n const key = await webcrypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n\n const sig = await webcrypto.subtle.sign('HMAC', key, encoder.encode(data))\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks\n */\nfunction safeCompare(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n\n let result = 0\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return result === 0\n}\n\n/**\n * Create a signed CSRF token\n */\nexport async function createToken(\n secret: string,\n length: number = 32\n): Promise<string> {\n const data = randomBytes(length)\n const sig = await createSignature(data, secret)\n return `${data}.${sig}`\n}\n\n/**\n * Verify a signed CSRF token\n */\nexport async function verifyToken(\n token: string,\n secret: string\n): Promise<boolean> {\n if (!token || typeof token !== 'string') return false\n\n const parts = token.split('.')\n if (parts.length !== 2) return false\n\n const [data, sig] = parts\n if (!data || !sig) return false\n\n try {\n const expected = await createSignature(data, secret)\n return safeCompare(sig, expected)\n } catch {\n return false\n }\n}\n\n/**\n * Compare two tokens (constant-time)\n */\nexport function tokensMatch(a: string, b: string): boolean {\n if (!a || !b) return false\n return safeCompare(a, b)\n}\n","import type { NextRequest } from 'next/server'\nimport type { CSRFConfig, CSRFCookieOptions } from './types'\nimport { createToken, verifyToken, tokensMatch } from './token'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\nconst DEFAULT_COOKIE: CSRFCookieOptions = {\n name: '__csrf',\n path: '/',\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 86400, // 24h\n}\n\nconst DEFAULT_CONFIG: Required<Omit<CSRFConfig, 'skip' | 'onError'>> = {\n cookie: DEFAULT_COOKIE,\n headerName: 'x-csrf-token',\n fieldName: '_csrf',\n secret: '',\n tokenLength: 32,\n protectedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'],\n}\n\nfunction getSecret(config: CSRFConfig): string {\n const secret = config.secret || process.env.CSRF_SECRET\n if (!secret) {\n throw new Error(\n 'CSRF secret is required. Set config.secret or CSRF_SECRET env variable.'\n )\n }\n return secret\n}\n\nfunction buildCookieString(name: string, value: string, opts: CSRFCookieOptions): string {\n let cookie = `${name}=${value}`\n\n if (opts.path) cookie += `; Path=${opts.path}`\n if (opts.domain) cookie += `; Domain=${opts.domain}`\n if (opts.maxAge) cookie += `; Max-Age=${opts.maxAge}`\n if (opts.httpOnly) cookie += '; HttpOnly'\n if (opts.secure) cookie += '; Secure'\n if (opts.sameSite) cookie += `; SameSite=${opts.sameSite}`\n\n return cookie\n}\n\n/**\n * Extract token from request (header or body)\n */\nasync function extractToken(\n req: NextRequest,\n headerName: string,\n fieldName: string\n): Promise<string | null> {\n // check header first\n const headerToken = req.headers.get(headerName)\n if (headerToken) return headerToken\n\n // try to get from form data\n const contentType = req.headers.get('content-type') || ''\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n try {\n const cloned = req.clone()\n const formData = await cloned.formData()\n const token = formData.get(fieldName)\n if (typeof token === 'string') return token\n } catch {\n // ignore parse errors\n }\n }\n\n if (contentType.includes('application/json')) {\n try {\n const cloned = req.clone()\n const body = await cloned.json()\n if (body && typeof body[fieldName] === 'string') {\n return body[fieldName]\n }\n } catch {\n // ignore parse errors\n }\n }\n\n return null\n}\n\nfunction defaultErrorResponse(_req: NextRequest, reason: string): Response {\n return new Response(JSON.stringify({ error: 'CSRF validation failed', reason }), {\n status: 403,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\n/**\n * CSRF protection middleware\n *\n * Uses double submit cookie pattern:\n * 1. Server sets a signed token in a cookie\n * 2. Client sends the same token in header/body\n * 3. Server compares both values\n */\nexport function withCSRF(handler: RouteHandler, config: CSRFConfig = {}): RouteHandler {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const headerName = config.headerName || DEFAULT_CONFIG.headerName\n const fieldName = config.fieldName || DEFAULT_CONFIG.fieldName\n const protectedMethods = config.protectedMethods || DEFAULT_CONFIG.protectedMethods\n const onError = config.onError || defaultErrorResponse\n\n return async (req: NextRequest): Promise<Response> => {\n const method = req.method.toUpperCase()\n\n // skip unprotected methods\n if (!protectedMethods.includes(method)) {\n return handler(req)\n }\n\n // custom skip logic\n if (config.skip) {\n const shouldSkip = await config.skip(req)\n if (shouldSkip) return handler(req)\n }\n\n const cookieName = cookieOpts.name || '__csrf'\n const cookieToken = req.cookies.get(cookieName)?.value\n\n // no cookie = first request, reject\n if (!cookieToken) {\n return onError(req, 'missing_cookie')\n }\n\n // verify cookie token is valid (signed by us)\n const cookieValid = await verifyToken(cookieToken, secret)\n if (!cookieValid) {\n return onError(req, 'invalid_cookie')\n }\n\n // get token from request\n const requestToken = await extractToken(req, headerName, fieldName)\n if (!requestToken) {\n return onError(req, 'missing_token')\n }\n\n // compare tokens\n if (!tokensMatch(cookieToken, requestToken)) {\n return onError(req, 'token_mismatch')\n }\n\n return handler(req)\n }\n}\n\n/**\n * Generate a new CSRF token and cookie header\n * Use this in GET routes to set the initial token\n */\nexport async function generateCSRF(config: CSRFConfig = {}): Promise<{\n token: string\n cookieHeader: string\n}> {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const tokenLength = config.tokenLength || DEFAULT_CONFIG.tokenLength\n const cookieName = cookieOpts.name || '__csrf'\n\n const token = await createToken(secret, tokenLength)\n const cookieHeader = buildCookieString(cookieName, token, cookieOpts)\n\n return { token, cookieHeader }\n}\n\n/**\n * Validate a CSRF token without middleware\n * Useful for custom validation flows\n */\nexport async function validateCSRF(\n req: NextRequest,\n config: CSRFConfig = {}\n): Promise<{ valid: boolean; reason?: string }> {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const headerName = config.headerName || DEFAULT_CONFIG.headerName\n const fieldName = config.fieldName || DEFAULT_CONFIG.fieldName\n const cookieName = cookieOpts.name || '__csrf'\n\n const cookieToken = req.cookies.get(cookieName)?.value\n if (!cookieToken) {\n return { valid: false, reason: 'missing_cookie' }\n }\n\n const cookieValid = await verifyToken(cookieToken, secret)\n if (!cookieValid) {\n return { valid: false, reason: 'invalid_cookie' }\n }\n\n const requestToken = await extractToken(req, headerName, fieldName)\n if (!requestToken) {\n return { valid: false, reason: 'missing_token' }\n }\n\n if (!tokensMatch(cookieToken, requestToken)) {\n return { valid: false, reason: 'token_mismatch' }\n }\n\n return { valid: true }\n}\n","import type {\n ContentSecurityPolicy,\n StrictTransportSecurity,\n PermissionsPolicy,\n SecurityHeadersConfig,\n SecurityHeadersPreset,\n} from './types'\n\n/**\n * Build CSP header string from config\n */\nexport function buildCSP(policy: ContentSecurityPolicy): string {\n const directives: string[] = []\n\n const directiveMap: Record<string, string> = {\n defaultSrc: 'default-src',\n scriptSrc: 'script-src',\n styleSrc: 'style-src',\n imgSrc: 'img-src',\n fontSrc: 'font-src',\n connectSrc: 'connect-src',\n mediaSrc: 'media-src',\n objectSrc: 'object-src',\n frameSrc: 'frame-src',\n childSrc: 'child-src',\n workerSrc: 'worker-src',\n frameAncestors: 'frame-ancestors',\n formAction: 'form-action',\n baseUri: 'base-uri',\n manifestSrc: 'manifest-src',\n reportUri: 'report-uri',\n reportTo: 'report-to',\n }\n\n for (const [key, directive] of Object.entries(directiveMap)) {\n const value = policy[key as keyof ContentSecurityPolicy]\n if (value !== undefined && value !== false) {\n if (Array.isArray(value)) {\n directives.push(`${directive} ${value.join(' ')}`)\n } else if (typeof value === 'string') {\n directives.push(`${directive} ${value}`)\n }\n }\n }\n\n if (policy.upgradeInsecureRequests) {\n directives.push('upgrade-insecure-requests')\n }\n\n if (policy.blockAllMixedContent) {\n directives.push('block-all-mixed-content')\n }\n\n return directives.join('; ')\n}\n\n/**\n * Build HSTS header string\n */\nexport function buildHSTS(config: StrictTransportSecurity): string {\n let value = `max-age=${config.maxAge}`\n\n if (config.includeSubDomains) {\n value += '; includeSubDomains'\n }\n\n if (config.preload) {\n value += '; preload'\n }\n\n return value\n}\n\n/**\n * Build Permissions-Policy header string\n */\nexport function buildPermissionsPolicy(policy: PermissionsPolicy): string {\n const directives: string[] = []\n\n const featureMap: Record<string, string> = {\n accelerometer: 'accelerometer',\n ambientLightSensor: 'ambient-light-sensor',\n autoplay: 'autoplay',\n battery: 'battery',\n camera: 'camera',\n displayCapture: 'display-capture',\n documentDomain: 'document-domain',\n encryptedMedia: 'encrypted-media',\n fullscreen: 'fullscreen',\n geolocation: 'geolocation',\n gyroscope: 'gyroscope',\n magnetometer: 'magnetometer',\n microphone: 'microphone',\n midi: 'midi',\n payment: 'payment',\n pictureInPicture: 'picture-in-picture',\n publicKeyCredentialsGet: 'publickey-credentials-get',\n screenWakeLock: 'screen-wake-lock',\n syncXhr: 'sync-xhr',\n usb: 'usb',\n webShare: 'web-share',\n xrSpatialTracking: 'xr-spatial-tracking',\n }\n\n for (const [key, feature] of Object.entries(featureMap)) {\n const origins = policy[key as keyof PermissionsPolicy]\n if (origins !== undefined) {\n if (origins.length === 0) {\n directives.push(`${feature}=()`)\n } else {\n const formatted = origins.map((o) => (o === 'self' ? 'self' : `\"${o}\"`)).join(' ')\n directives.push(`${feature}=(${formatted})`)\n }\n }\n }\n\n return directives.join(', ')\n}\n\n/**\n * Preset: Strict security headers\n */\nexport const PRESET_STRICT: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\"],\n imgSrc: [\"'self'\", 'data:'],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n frameAncestors: [\"'none'\"],\n formAction: [\"'self'\"],\n baseUri: [\"'self'\"],\n upgradeInsecureRequests: true,\n },\n strictTransportSecurity: {\n maxAge: 31536000, // 1 year\n includeSubDomains: true,\n preload: true,\n },\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n xDnsPrefetchControl: 'off',\n xDownloadOptions: true,\n xPermittedCrossDomainPolicies: 'none',\n referrerPolicy: 'strict-origin-when-cross-origin',\n crossOriginOpenerPolicy: 'same-origin',\n crossOriginEmbedderPolicy: 'require-corp',\n crossOriginResourcePolicy: 'same-origin',\n permissionsPolicy: {\n camera: [],\n microphone: [],\n geolocation: [],\n payment: [],\n },\n originAgentCluster: true,\n}\n\n/**\n * Preset: Relaxed security headers (for development or less strict needs)\n */\nexport const PRESET_RELAXED: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\", \"'unsafe-inline'\", \"'unsafe-eval'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'blob:', 'https:'],\n fontSrc: [\"'self'\", 'https:', 'data:'],\n connectSrc: [\"'self'\", 'https:', 'wss:'],\n frameSrc: [\"'self'\"],\n },\n strictTransportSecurity: {\n maxAge: 86400, // 1 day\n includeSubDomains: false,\n },\n xFrameOptions: 'SAMEORIGIN',\n xContentTypeOptions: true,\n referrerPolicy: 'no-referrer-when-downgrade',\n}\n\n/**\n * Preset: API-focused security headers\n */\nexport const PRESET_API: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'none'\"],\n frameAncestors: [\"'none'\"],\n },\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n referrerPolicy: 'no-referrer',\n crossOriginResourcePolicy: 'same-origin',\n}\n\n/**\n * Get preset config by name\n */\nexport function getPreset(name: SecurityHeadersPreset): SecurityHeadersConfig {\n switch (name) {\n case 'strict':\n return PRESET_STRICT\n case 'relaxed':\n return PRESET_RELAXED\n case 'api':\n return PRESET_API\n default:\n return PRESET_STRICT\n }\n}\n\n/**\n * Build all headers from config\n */\nexport function buildHeaders(config: SecurityHeadersConfig): Headers {\n const headers = new Headers()\n\n // CSP\n if (config.contentSecurityPolicy) {\n const csp = buildCSP(config.contentSecurityPolicy)\n if (csp) headers.set('Content-Security-Policy', csp)\n }\n\n // HSTS\n if (config.strictTransportSecurity) {\n headers.set('Strict-Transport-Security', buildHSTS(config.strictTransportSecurity))\n }\n\n // X-Frame-Options\n if (config.xFrameOptions) {\n headers.set('X-Frame-Options', config.xFrameOptions)\n }\n\n // X-Content-Type-Options\n if (config.xContentTypeOptions) {\n headers.set('X-Content-Type-Options', 'nosniff')\n }\n\n // X-DNS-Prefetch-Control\n if (config.xDnsPrefetchControl) {\n headers.set('X-DNS-Prefetch-Control', config.xDnsPrefetchControl)\n }\n\n // X-Download-Options\n if (config.xDownloadOptions) {\n headers.set('X-Download-Options', 'noopen')\n }\n\n // X-Permitted-Cross-Domain-Policies\n if (config.xPermittedCrossDomainPolicies) {\n headers.set('X-Permitted-Cross-Domain-Policies', config.xPermittedCrossDomainPolicies)\n }\n\n // Referrer-Policy\n if (config.referrerPolicy) {\n const value = Array.isArray(config.referrerPolicy)\n ? config.referrerPolicy.join(', ')\n : config.referrerPolicy\n headers.set('Referrer-Policy', value)\n }\n\n // COOP\n if (config.crossOriginOpenerPolicy) {\n headers.set('Cross-Origin-Opener-Policy', config.crossOriginOpenerPolicy)\n }\n\n // COEP\n if (config.crossOriginEmbedderPolicy) {\n headers.set('Cross-Origin-Embedder-Policy', config.crossOriginEmbedderPolicy)\n }\n\n // CORP\n if (config.crossOriginResourcePolicy) {\n headers.set('Cross-Origin-Resource-Policy', config.crossOriginResourcePolicy)\n }\n\n // Permissions-Policy\n if (config.permissionsPolicy) {\n const pp = buildPermissionsPolicy(config.permissionsPolicy)\n if (pp) headers.set('Permissions-Policy', pp)\n }\n\n // Origin-Agent-Cluster\n if (config.originAgentCluster) {\n headers.set('Origin-Agent-Cluster', '?1')\n }\n\n return headers\n}\n","import type { NextRequest } from 'next/server'\nimport type { SecurityHeadersConfig, SecurityHeadersPreset } from './types'\nimport { buildHeaders, getPreset, PRESET_STRICT } from './builder'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\nexport interface WithSecurityHeadersOptions {\n /** Use a preset configuration */\n preset?: SecurityHeadersPreset\n\n /** Custom header configuration (merged with preset if provided) */\n config?: SecurityHeadersConfig\n\n /** Override response headers instead of merging */\n override?: boolean\n}\n\n/**\n * Merge two configs, with custom taking precedence\n */\nfunction mergeConfigs(\n base: SecurityHeadersConfig,\n custom: SecurityHeadersConfig\n): SecurityHeadersConfig {\n return {\n ...base,\n ...custom,\n // Deep merge CSP if both exist\n contentSecurityPolicy:\n custom.contentSecurityPolicy === false\n ? false\n : custom.contentSecurityPolicy\n ? base.contentSecurityPolicy\n ? { ...(base.contentSecurityPolicy as object), ...custom.contentSecurityPolicy }\n : custom.contentSecurityPolicy\n : base.contentSecurityPolicy,\n // Deep merge HSTS if both exist\n strictTransportSecurity:\n custom.strictTransportSecurity === false\n ? false\n : custom.strictTransportSecurity\n ? base.strictTransportSecurity\n ? { ...(base.strictTransportSecurity as object), ...custom.strictTransportSecurity }\n : custom.strictTransportSecurity\n : base.strictTransportSecurity,\n // Deep merge Permissions-Policy if both exist\n permissionsPolicy:\n custom.permissionsPolicy === false\n ? false\n : custom.permissionsPolicy\n ? base.permissionsPolicy\n ? { ...(base.permissionsPolicy as object), ...custom.permissionsPolicy }\n : custom.permissionsPolicy\n : base.permissionsPolicy,\n }\n}\n\n/**\n * Security headers middleware\n *\n * Adds security headers to responses. Use presets for quick setup\n * or provide custom configuration.\n *\n * @example\n * ```typescript\n * // Use strict preset\n * export const GET = withSecurityHeaders(handler, { preset: 'strict' })\n *\n * // Custom config\n * export const GET = withSecurityHeaders(handler, {\n * config: {\n * xFrameOptions: 'SAMEORIGIN',\n * referrerPolicy: 'no-referrer'\n * }\n * })\n * ```\n */\nexport function withSecurityHeaders(\n handler: RouteHandler,\n options: WithSecurityHeadersOptions = {}\n): RouteHandler {\n const { preset, config, override = false } = options\n\n // Get base config from preset or default to strict\n let baseConfig: SecurityHeadersConfig = preset ? getPreset(preset) : PRESET_STRICT\n\n // Merge with custom config if provided\n if (config) {\n baseConfig = mergeConfigs(baseConfig, config)\n }\n\n // Pre-build headers for performance\n const securityHeaders = buildHeaders(baseConfig)\n\n return async (req: NextRequest): Promise<Response> => {\n const response = await handler(req)\n\n // Clone response to modify headers\n const newHeaders = new Headers(response.headers)\n\n // Add security headers\n securityHeaders.forEach((value, key) => {\n if (override || !newHeaders.has(key)) {\n newHeaders.set(key, value)\n }\n })\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n })\n }\n}\n\n/**\n * Create headers object for use in responses\n * Useful when you want to add headers manually\n *\n * @example\n * ```typescript\n * const headers = createSecurityHeaders({ preset: 'api' })\n *\n * return Response.json(data, { headers })\n * ```\n */\nexport function createSecurityHeaders(\n options: WithSecurityHeadersOptions = {}\n): Headers {\n const { preset, config } = options\n\n let baseConfig: SecurityHeadersConfig = preset ? getPreset(preset) : PRESET_STRICT\n\n if (config) {\n baseConfig = mergeConfigs(baseConfig, config)\n }\n\n return buildHeaders(baseConfig)\n}\n\n/**\n * Create a headers object as a plain object (for Next.js headers())\n */\nexport function createSecurityHeadersObject(\n options: WithSecurityHeadersOptions = {}\n): Record<string, string> {\n const headers = createSecurityHeaders(options)\n const obj: Record<string, string> = {}\n\n headers.forEach((value, key) => {\n obj[key] = value\n })\n\n return obj\n}\n","import { webcrypto } from 'node:crypto'\nimport type { JWTPayload, JWTConfig, AuthError } from './types'\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\n/**\n * Base64URL decode\n */\nfunction base64UrlDecode(str: string): Uint8Array {\n // Add padding if needed\n const pad = str.length % 4\n if (pad) {\n str += '='.repeat(4 - pad)\n }\n\n // Replace URL-safe chars\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n\n const binary = atob(base64)\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 * Parse JWT without verification (for header inspection)\n */\nexport function decodeJWT(token: string): {\n header: Record<string, unknown>\n payload: JWTPayload\n signature: Uint8Array\n} | null {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return null\n\n const header = JSON.parse(decoder.decode(base64UrlDecode(parts[0])))\n const payload = JSON.parse(decoder.decode(base64UrlDecode(parts[1])))\n const signature = base64UrlDecode(parts[2])\n\n return { header, payload, signature }\n } catch {\n return null\n }\n}\n\n/**\n * Get crypto algorithm params from JWT algorithm\n */\nfunction getAlgorithmParams(alg: string): {\n name: string\n hash?: string\n namedCurve?: string\n} | null {\n switch (alg) {\n case 'HS256':\n return { name: 'HMAC', hash: 'SHA-256' }\n case 'HS384':\n return { name: 'HMAC', hash: 'SHA-384' }\n case 'HS512':\n return { name: 'HMAC', hash: 'SHA-512' }\n case 'RS256':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }\n case 'RS384':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-384' }\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' }\n case 'ES256':\n return { name: 'ECDSA', hash: 'SHA-256', namedCurve: 'P-256' }\n case 'ES384':\n return { name: 'ECDSA', hash: 'SHA-384', namedCurve: 'P-384' }\n case 'ES512':\n return { name: 'ECDSA', hash: 'SHA-512', namedCurve: 'P-521' }\n default:\n return null\n }\n}\n\n/**\n * Verify HMAC signature\n */\nasync function verifyHMAC(\n data: string,\n signature: Uint8Array,\n secret: string,\n hash: string\n): Promise<boolean> {\n const key = await webcrypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash },\n false,\n ['verify']\n )\n\n return webcrypto.subtle.verify('HMAC', key, signature, encoder.encode(data))\n}\n\n/**\n * Import PEM public key\n */\nasync function importPublicKey(\n pem: string,\n algorithm: { name: string; hash?: string; namedCurve?: string }\n): Promise<CryptoKey> {\n // Remove PEM headers and decode\n const pemContents = pem\n .replace(/-----BEGIN.*-----/, '')\n .replace(/-----END.*-----/, '')\n .replace(/\\s/g, '')\n\n const binaryDer = base64UrlDecode(pemContents.replace(/\\+/g, '-').replace(/\\//g, '_'))\n\n const keyUsages: KeyUsage[] = ['verify']\n\n if (algorithm.name === 'RSASSA-PKCS1-v1_5') {\n return webcrypto.subtle.importKey(\n 'spki',\n binaryDer,\n { name: algorithm.name, hash: algorithm.hash! },\n false,\n keyUsages\n )\n }\n\n if (algorithm.name === 'ECDSA') {\n return webcrypto.subtle.importKey(\n 'spki',\n binaryDer,\n { name: algorithm.name, namedCurve: algorithm.namedCurve! },\n false,\n keyUsages\n )\n }\n\n throw new Error(`Unsupported algorithm: ${algorithm.name}`)\n}\n\n/**\n * Verify RSA/ECDSA signature\n */\nasync function verifyAsymmetric(\n data: string,\n signature: Uint8Array,\n publicKey: string,\n algorithm: { name: string; hash?: string; namedCurve?: string }\n): Promise<boolean> {\n const key = await importPublicKey(publicKey, algorithm)\n\n const params = algorithm.name === 'ECDSA'\n ? { name: 'ECDSA', hash: algorithm.hash! } as EcdsaParams\n : algorithm.name\n\n return webcrypto.subtle.verify(params, key, signature, encoder.encode(data))\n}\n\n/**\n * Validate JWT claims\n */\nfunction validateClaims(\n payload: JWTPayload,\n config: JWTConfig\n): AuthError | null {\n const now = Math.floor(Date.now() / 1000)\n const tolerance = config.clockTolerance || 0\n\n // Check expiration\n if (payload.exp !== undefined && payload.exp < now - tolerance) {\n return {\n code: 'expired_token',\n message: 'Token has expired',\n status: 401,\n }\n }\n\n // Check not before\n if (payload.nbf !== undefined && payload.nbf > now + tolerance) {\n return {\n code: 'invalid_token',\n message: 'Token not yet valid',\n status: 401,\n }\n }\n\n // Check issuer\n if (config.issuer) {\n const issuers = Array.isArray(config.issuer) ? config.issuer : [config.issuer]\n if (!payload.iss || !issuers.includes(payload.iss)) {\n return {\n code: 'invalid_token',\n message: 'Invalid token issuer',\n status: 401,\n }\n }\n }\n\n // Check audience\n if (config.audience) {\n const audiences = Array.isArray(config.audience) ? config.audience : [config.audience]\n const tokenAudiences = Array.isArray(payload.aud)\n ? payload.aud\n : payload.aud\n ? [payload.aud]\n : []\n\n const hasValidAudience = audiences.some((aud) => tokenAudiences.includes(aud))\n if (!hasValidAudience) {\n return {\n code: 'invalid_token',\n message: 'Invalid token audience',\n status: 401,\n }\n }\n }\n\n return null\n}\n\n/**\n * Verify and decode JWT\n */\nexport async function verifyJWT(\n token: string,\n config: JWTConfig\n): Promise<{ payload: JWTPayload; error: null } | { payload: null; error: AuthError }> {\n // Decode token\n const decoded = decodeJWT(token)\n if (!decoded) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Malformed token',\n status: 401,\n },\n }\n }\n\n const { header, payload, signature } = decoded\n const alg = header.alg as string\n\n // Check algorithm\n const allowedAlgorithms = config.algorithms || ['HS256']\n if (!allowedAlgorithms.includes(alg)) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: `Algorithm ${alg} not allowed`,\n status: 401,\n },\n }\n }\n\n // Get algorithm params\n const algorithmParams = getAlgorithmParams(alg)\n if (!algorithmParams) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: `Unsupported algorithm: ${alg}`,\n status: 401,\n },\n }\n }\n\n // Verify signature\n const parts = token.split('.')\n const signedData = `${parts[0]}.${parts[1]}`\n let isValid = false\n\n try {\n if (algorithmParams.name === 'HMAC') {\n if (!config.secret) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Secret required for HMAC algorithms',\n status: 500,\n },\n }\n }\n isValid = await verifyHMAC(signedData, signature, config.secret, algorithmParams.hash!)\n } else {\n if (!config.publicKey) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Public key required for asymmetric algorithms',\n status: 500,\n },\n }\n }\n isValid = await verifyAsymmetric(signedData, signature, config.publicKey, algorithmParams)\n }\n } catch {\n isValid = false\n }\n\n if (!isValid) {\n return {\n payload: null,\n error: {\n code: 'invalid_signature',\n message: 'Invalid token signature',\n status: 401,\n },\n }\n }\n\n // Validate claims\n const claimsError = validateClaims(payload, config)\n if (claimsError) {\n return { payload: null, error: claimsError }\n }\n\n return { payload, error: null }\n}\n\n/**\n * Extract token from Authorization header\n */\nexport function extractBearerToken(authHeader: string | null): string | null {\n if (!authHeader) return null\n if (!authHeader.startsWith('Bearer ')) return null\n return authHeader.slice(7)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n AuthConfig,\n AuthUser,\n AuthError,\n JWTConfig,\n APIKeyConfig,\n SessionConfig,\n RBACConfig,\n} from './types'\nimport { verifyJWT, extractBearerToken } from './jwt'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\ntype AuthenticatedHandler = (\n req: NextRequest,\n ctx: { user: AuthUser; token?: string }\n) => Response | Promise<Response>\n\n/**\n * Default error response\n */\nfunction defaultErrorResponse(_req: NextRequest, error: AuthError): Response {\n return new Response(\n JSON.stringify({\n error: error.code,\n message: error.message,\n }),\n {\n status: error.status,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Extract token from request\n */\nasync function getTokenFromRequest(\n req: NextRequest,\n config?: JWTConfig\n): Promise<string | null> {\n // Custom extractor\n if (config?.getToken) {\n return config.getToken(req)\n }\n\n // Default: Authorization header\n return extractBearerToken(req.headers.get('authorization'))\n}\n\n/**\n * JWT Authentication middleware\n */\nexport function withJWT(\n handler: AuthenticatedHandler,\n config: JWTConfig\n): RouteHandler {\n const secret = config.secret || process.env.JWT_SECRET\n const effectiveConfig = { ...config, secret }\n\n return async (req: NextRequest): Promise<Response> => {\n const token = await getTokenFromRequest(req, effectiveConfig)\n\n if (!token) {\n return defaultErrorResponse(req, {\n code: 'missing_token',\n message: 'Authentication required',\n status: 401,\n })\n }\n\n const { payload, error } = await verifyJWT(token, effectiveConfig)\n\n if (error) {\n return defaultErrorResponse(req, error)\n }\n\n // Map payload to user\n const user: AuthUser = effectiveConfig.mapUser\n ? await effectiveConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n permissions: payload.permissions as string[] | undefined,\n }\n\n return handler(req, { user, token })\n }\n}\n\n/**\n * API Key Authentication middleware\n */\nexport function withAPIKey(\n handler: AuthenticatedHandler,\n config: APIKeyConfig\n): RouteHandler {\n const headerName = config.headerName || 'x-api-key'\n const queryParam = config.queryParam || 'api_key'\n\n return async (req: NextRequest): Promise<Response> => {\n // Try header first\n let apiKey = req.headers.get(headerName)\n\n // Try query param\n if (!apiKey) {\n const url = new URL(req.url)\n apiKey = url.searchParams.get(queryParam)\n }\n\n if (!apiKey) {\n return defaultErrorResponse(req, {\n code: 'missing_api_key',\n message: 'API key required',\n status: 401,\n })\n }\n\n const user = await config.validate(apiKey, req)\n\n if (!user) {\n return defaultErrorResponse(req, {\n code: 'invalid_api_key',\n message: 'Invalid API key',\n status: 401,\n })\n }\n\n return handler(req, { user })\n }\n}\n\n/**\n * Session/Cookie Authentication middleware\n */\nexport function withSession(\n handler: AuthenticatedHandler,\n config: SessionConfig\n): RouteHandler {\n const cookieName = config.cookieName || 'session'\n\n return async (req: NextRequest): Promise<Response> => {\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (!sessionId) {\n return defaultErrorResponse(req, {\n code: 'missing_session',\n message: 'Session required',\n status: 401,\n })\n }\n\n const user = await config.validate(sessionId, req)\n\n if (!user) {\n return defaultErrorResponse(req, {\n code: 'invalid_session',\n message: 'Invalid or expired session',\n status: 401,\n })\n }\n\n return handler(req, { user })\n }\n}\n\n/**\n * Role-based access control middleware\n * Must be used after authentication middleware\n */\nexport function withRoles(\n handler: AuthenticatedHandler,\n config: RBACConfig\n): (req: NextRequest, ctx: { user: AuthUser; token?: string }) => Promise<Response> {\n return async (\n req: NextRequest,\n ctx: { user: AuthUser; token?: string }\n ): Promise<Response> => {\n const { user } = ctx\n\n // Get user roles\n const userRoles = config.getUserRoles\n ? config.getUserRoles(user)\n : user.roles || []\n\n // Check required roles (any match)\n if (config.roles && config.roles.length > 0) {\n const hasRole = config.roles.some((role) => userRoles.includes(role))\n if (!hasRole) {\n return defaultErrorResponse(req, {\n code: 'insufficient_roles',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n // Get user permissions\n const userPermissions = config.getUserPermissions\n ? config.getUserPermissions(user)\n : user.permissions || []\n\n // Check required permissions (all required)\n if (config.permissions && config.permissions.length > 0) {\n const hasAllPermissions = config.permissions.every((perm) =>\n userPermissions.includes(perm)\n )\n if (!hasAllPermissions) {\n return defaultErrorResponse(req, {\n code: 'insufficient_permissions',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n // Custom authorization\n if (config.authorize) {\n const authorized = await config.authorize(user, req)\n if (!authorized) {\n return defaultErrorResponse(req, {\n code: 'unauthorized',\n message: 'Unauthorized',\n status: 403,\n })\n }\n }\n\n return handler(req, ctx)\n }\n}\n\n/**\n * Combined auth middleware with multiple strategies\n */\nexport function withAuth(\n handler: AuthenticatedHandler,\n config: AuthConfig\n): RouteHandler {\n const onError = config.onError || defaultErrorResponse\n\n return async (req: NextRequest): Promise<Response> => {\n let user: AuthUser | null = null\n let token: string | undefined\n\n // Try JWT auth\n if (config.jwt) {\n const secret = config.jwt.secret || process.env.JWT_SECRET\n const jwtConfig = { ...config.jwt, secret }\n const jwtToken = await getTokenFromRequest(req, jwtConfig)\n\n if (jwtToken) {\n const { payload, error } = await verifyJWT(jwtToken, jwtConfig)\n if (!error && payload) {\n user = jwtConfig.mapUser\n ? await jwtConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n }\n token = jwtToken\n }\n }\n }\n\n // Try API Key auth\n if (!user && config.apiKey) {\n const headerName = config.apiKey.headerName || 'x-api-key'\n const queryParam = config.apiKey.queryParam || 'api_key'\n\n let apiKey = req.headers.get(headerName)\n if (!apiKey) {\n const url = new URL(req.url)\n apiKey = url.searchParams.get(queryParam)\n }\n\n if (apiKey) {\n const apiUser = await config.apiKey.validate(apiKey, req)\n if (apiUser) {\n user = apiUser\n }\n }\n }\n\n // Try Session auth\n if (!user && config.session) {\n const cookieName = config.session.cookieName || 'session'\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (sessionId) {\n const sessionUser = await config.session.validate(sessionId, req)\n if (sessionUser) {\n user = sessionUser\n }\n }\n }\n\n // No authentication found\n if (!user) {\n return onError(req, {\n code: 'unauthorized',\n message: 'Authentication required',\n status: 401,\n })\n }\n\n // RBAC check\n if (config.rbac) {\n const userRoles = config.rbac.getUserRoles\n ? config.rbac.getUserRoles(user)\n : user.roles || []\n\n if (config.rbac.roles && config.rbac.roles.length > 0) {\n const hasRole = config.rbac.roles.some((role) => userRoles.includes(role))\n if (!hasRole) {\n return onError(req, {\n code: 'insufficient_roles',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n const userPermissions = config.rbac.getUserPermissions\n ? config.rbac.getUserPermissions(user)\n : user.permissions || []\n\n if (config.rbac.permissions && config.rbac.permissions.length > 0) {\n const hasAllPermissions = config.rbac.permissions.every((perm) =>\n userPermissions.includes(perm)\n )\n if (!hasAllPermissions) {\n return onError(req, {\n code: 'insufficient_permissions',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n if (config.rbac.authorize) {\n const authorized = await config.rbac.authorize(user, req)\n if (!authorized) {\n return onError(req, {\n code: 'unauthorized',\n message: 'Unauthorized',\n status: 403,\n })\n }\n }\n }\n\n // Success callback\n if (config.onSuccess) {\n await config.onSuccess(req, user)\n }\n\n return handler(req, { user, token })\n }\n}\n\n/**\n * Optional auth - doesn't fail if no auth present\n */\nexport function withOptionalAuth(\n handler: (\n req: NextRequest,\n ctx: { user: AuthUser | null; token?: string }\n ) => Response | Promise<Response>,\n config: Omit<AuthConfig, 'rbac'>\n): RouteHandler {\n return async (req: NextRequest): Promise<Response> => {\n let user: AuthUser | null = null\n let token: string | undefined\n\n // Try JWT auth\n if (config.jwt) {\n const secret = config.jwt.secret || process.env.JWT_SECRET\n const jwtConfig = { ...config.jwt, secret }\n const jwtToken = await getTokenFromRequest(req, jwtConfig)\n\n if (jwtToken) {\n const { payload, error } = await verifyJWT(jwtToken, jwtConfig)\n if (!error && payload) {\n user = jwtConfig.mapUser\n ? await jwtConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n }\n token = jwtToken\n }\n }\n }\n\n // Try API Key auth\n if (!user && config.apiKey) {\n const headerName = config.apiKey.headerName || 'x-api-key'\n let apiKey = req.headers.get(headerName)\n\n if (apiKey) {\n const apiUser = await config.apiKey.validate(apiKey, req)\n if (apiUser) user = apiUser\n }\n }\n\n // Try Session auth\n if (!user && config.session) {\n const cookieName = config.session.cookieName || 'session'\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (sessionId) {\n const sessionUser = await config.session.validate(sessionId, req)\n if (sessionUser) user = sessionUser\n }\n }\n\n return handler(req, { user, token })\n }\n}\n","import type { Schema, CustomSchema, FieldRule, ValidationError, ValidationResult } from './types'\n\n/**\n * Check if a schema is a Zod-like schema (has safeParse method)\n */\nexport function isZodSchema(schema: unknown): schema is Schema {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n 'safeParse' in schema &&\n typeof (schema as Schema).safeParse === 'function'\n )\n}\n\n/**\n * Check if a schema is a custom schema (plain object with field rules)\n */\nexport function isCustomSchema(schema: unknown): schema is CustomSchema {\n if (typeof schema !== 'object' || schema === null) return false\n if ('safeParse' in schema) return false\n\n const entries = Object.entries(schema)\n if (entries.length === 0) return false\n\n return entries.every(([_, rule]) => {\n return typeof rule === 'object' && rule !== null && 'type' in rule\n })\n}\n\n/**\n * Email regex pattern (RFC 5322 simplified)\n */\nconst EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n/**\n * URL regex pattern (supports domain names, localhost, and IP addresses)\n */\nconst URL_PATTERN = /^https?:\\/\\/(?:(?:www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}|localhost|(?:\\d{1,3}\\.){3}\\d{1,3})(?::\\d{1,5})?(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/\n\n/**\n * UUID regex pattern (v4)\n */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\n/**\n * ISO date pattern\n */\nconst DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?(?:Z|[+-]\\d{2}:?\\d{2})?)?$/\n\n/**\n * Validate a single field with a rule\n */\nexport function validateField(value: unknown, rule: FieldRule, fieldName: string): ValidationError | null {\n // Handle required\n if (value === undefined || value === null || value === '') {\n if (rule.required) {\n return {\n field: fieldName,\n code: 'required',\n message: rule.message || `${fieldName} is required`,\n received: value,\n }\n }\n return null // Optional field with no value\n }\n\n // Type validation\n switch (rule.type) {\n case 'string':\n if (typeof value !== 'string') {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a string`,\n expected: 'string',\n received: typeof value,\n }\n }\n // String length validation\n if (rule.minLength !== undefined && value.length < rule.minLength) {\n return {\n field: fieldName,\n code: 'too_short',\n message: rule.message || `${fieldName} must be at least ${rule.minLength} characters`,\n received: value.length,\n }\n }\n if (rule.maxLength !== undefined && value.length > rule.maxLength) {\n return {\n field: fieldName,\n code: 'too_long',\n message: rule.message || `${fieldName} must be at most ${rule.maxLength} characters`,\n received: value.length,\n }\n }\n // Pattern validation\n if (rule.pattern && !rule.pattern.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_pattern',\n message: rule.message || `${fieldName} has invalid format`,\n received: value,\n }\n }\n break\n\n case 'number':\n const num = typeof value === 'number' ? value : Number(value)\n if (isNaN(num)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a number`,\n expected: 'number',\n received: typeof value,\n }\n }\n if (rule.integer && !Number.isInteger(num)) {\n return {\n field: fieldName,\n code: 'invalid_integer',\n message: rule.message || `${fieldName} must be an integer`,\n received: num,\n }\n }\n if (rule.min !== undefined && num < rule.min) {\n return {\n field: fieldName,\n code: 'too_small',\n message: rule.message || `${fieldName} must be at least ${rule.min}`,\n received: num,\n }\n }\n if (rule.max !== undefined && num > rule.max) {\n return {\n field: fieldName,\n code: 'too_large',\n message: rule.message || `${fieldName} must be at most ${rule.max}`,\n received: num,\n }\n }\n break\n\n case 'boolean':\n if (typeof value !== 'boolean' && value !== 'true' && value !== 'false') {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a boolean`,\n expected: 'boolean',\n received: typeof value,\n }\n }\n break\n\n case 'email':\n if (typeof value !== 'string' || !EMAIL_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_email',\n message: rule.message || `${fieldName} must be a valid email address`,\n received: value,\n }\n }\n break\n\n case 'url':\n if (typeof value !== 'string' || !URL_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_url',\n message: rule.message || `${fieldName} must be a valid URL`,\n received: value,\n }\n }\n break\n\n case 'uuid':\n if (typeof value !== 'string' || !UUID_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_uuid',\n message: rule.message || `${fieldName} must be a valid UUID`,\n received: value,\n }\n }\n break\n\n case 'date':\n if (typeof value !== 'string' || !DATE_PATTERN.test(value)) {\n const parsed = new Date(value as string)\n if (isNaN(parsed.getTime())) {\n return {\n field: fieldName,\n code: 'invalid_date',\n message: rule.message || `${fieldName} must be a valid date`,\n received: value,\n }\n }\n }\n break\n\n case 'array':\n if (!Array.isArray(value)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be an array`,\n expected: 'array',\n received: typeof value,\n }\n }\n if (rule.minItems !== undefined && value.length < rule.minItems) {\n return {\n field: fieldName,\n code: 'too_few_items',\n message: rule.message || `${fieldName} must have at least ${rule.minItems} items`,\n received: value.length,\n }\n }\n if (rule.maxItems !== undefined && value.length > rule.maxItems) {\n return {\n field: fieldName,\n code: 'too_many_items',\n message: rule.message || `${fieldName} must have at most ${rule.maxItems} items`,\n received: value.length,\n }\n }\n // Validate items if rule provided\n if (rule.items) {\n for (let i = 0; i < value.length; i++) {\n const itemError = validateField(value[i], rule.items, `${fieldName}[${i}]`)\n if (itemError) return itemError\n }\n }\n break\n\n case 'object':\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be an object`,\n expected: 'object',\n received: Array.isArray(value) ? 'array' : typeof value,\n }\n }\n break\n }\n\n // Custom validation\n if (rule.custom) {\n const result = rule.custom(value)\n if (result !== true) {\n return {\n field: fieldName,\n code: 'custom_validation',\n message: typeof result === 'string' ? result : rule.message || `${fieldName} failed validation`,\n received: value,\n }\n }\n }\n\n return null\n}\n\n/**\n * Validate data against a custom schema\n */\nexport function validateCustomSchema<T>(data: unknown, schema: CustomSchema): ValidationResult<T> {\n if (typeof data !== 'object' || data === null) {\n return {\n success: false,\n errors: [{\n field: '_root',\n code: 'invalid_type',\n message: 'Expected an object',\n received: data,\n }],\n }\n }\n\n const errors: ValidationError[] = []\n const record = data as Record<string, unknown>\n\n for (const [fieldName, rule] of Object.entries(schema)) {\n const error = validateField(record[fieldName], rule, fieldName)\n if (error) {\n errors.push(error)\n }\n }\n\n if (errors.length > 0) {\n return { success: false, errors }\n }\n\n return { success: true, data: data as T }\n}\n\n/**\n * Validate data against a Zod schema\n */\nexport function validateZodSchema<T>(data: unknown, schema: Schema<T>): ValidationResult<T> {\n const result = schema.safeParse(data)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n const errors: ValidationError[] = result.error.issues.map(issue => ({\n field: issue.path.join('.') || '_root',\n code: issue.code,\n message: issue.message,\n path: issue.path.map(String),\n }))\n\n return { success: false, errors }\n}\n\n/**\n * Deep get value from object by path\n */\nexport function getByPath(obj: unknown, path: string): unknown {\n if (typeof obj !== 'object' || obj === null) return undefined\n\n const parts = path.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (typeof current !== 'object' || current === null) return undefined\n current = (current as Record<string, unknown>)[part]\n }\n\n return current\n}\n\n/**\n * Deep set value in object by path\n */\nexport function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.')\n let current = obj\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (!(part in current) || typeof current[part] !== 'object') {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n\n current[parts[parts.length - 1]] = value\n}\n\n/**\n * Walk through object and apply function to all string values\n */\nexport function walkObject(\n obj: unknown,\n fn: (value: string, path: string) => string,\n path = ''\n): unknown {\n if (typeof obj === 'string') {\n return fn(obj, path)\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, i) => walkObject(item, fn, `${path}[${i}]`))\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n const newPath = path ? `${path}.${key}` : key\n result[key] = walkObject(value, fn, newPath)\n }\n return result\n }\n\n return obj\n}\n\n/**\n * Parse query string to object\n */\nexport function parseQueryString(url: string): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n\n try {\n const urlObj = new URL(url)\n for (const [key, value] of urlObj.searchParams.entries()) {\n if (key in result) {\n const existing = result[key]\n if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n result[key] = [existing, value]\n }\n } else {\n result[key] = value\n }\n }\n } catch {\n // Invalid URL, return empty\n }\n\n return result\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n Schema,\n CustomSchema,\n ValidationResult,\n ValidationError,\n ValidatedContext,\n} from '../types'\nimport { isZodSchema, isCustomSchema, validateCustomSchema, validateZodSchema, parseQueryString } from '../utils'\n\n/**\n * Validate data against a schema (Zod or custom)\n */\nexport function validate<T>(\n data: unknown,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n if (isZodSchema(schema)) {\n return validateZodSchema(data, schema)\n }\n\n if (isCustomSchema(schema)) {\n return validateCustomSchema<T>(data, schema)\n }\n\n // Unknown schema type\n return {\n success: false,\n errors: [{\n field: '_schema',\n code: 'invalid_schema',\n message: 'Invalid schema provided',\n }],\n }\n}\n\n/**\n * Extract and validate request body\n */\nexport async function validateBody<T>(\n request: NextRequest,\n schema: Schema<T> | CustomSchema\n): Promise<ValidationResult<T>> {\n let body: unknown\n\n try {\n const contentType = request.headers.get('content-type') || ''\n\n if (contentType.includes('application/json')) {\n body = await request.json()\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await request.text()\n body = Object.fromEntries(new URLSearchParams(text))\n } else if (contentType.includes('multipart/form-data')) {\n const formData = await request.formData()\n const obj: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n // Skip File objects for validation, only include strings\n if (typeof value === 'string') {\n obj[key] = value\n }\n })\n body = obj\n } else {\n // Try JSON as fallback\n try {\n body = await request.json()\n } catch {\n body = {}\n }\n }\n } catch (error) {\n return {\n success: false,\n errors: [{\n field: '_body',\n code: 'parse_error',\n message: 'Failed to parse request body',\n }],\n }\n }\n\n return validate<T>(body, schema)\n}\n\n/**\n * Extract and validate query parameters\n */\nexport function validateQuery<T>(\n request: NextRequest,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n const query = parseQueryString(request.url)\n return validate<T>(query, schema)\n}\n\n/**\n * Validate path parameters (from URL pattern)\n */\nexport function validateParams<T>(\n params: Record<string, string | string[]>,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n return validate<T>(params, schema)\n}\n\n/**\n * Combined request validation\n */\nexport async function validateRequest<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n request: NextRequest,\n config: {\n body?: Schema<TBody> | CustomSchema\n query?: Schema<TQuery> | CustomSchema\n params?: Schema<TParams> | CustomSchema\n routeParams?: Record<string, string | string[]>\n }\n): Promise<{\n success: boolean\n data?: ValidatedContext<TBody, TQuery, TParams>\n errors?: ValidationError[]\n}> {\n const allErrors: ValidationError[] = []\n const data: Partial<ValidatedContext<TBody, TQuery, TParams>> = {}\n\n // Validate body\n if (config.body) {\n const bodyResult = await validateBody<TBody>(request, config.body)\n if (!bodyResult.success) {\n allErrors.push(...(bodyResult.errors || []).map(e => ({\n ...e,\n field: `body.${e.field}`.replace('body._root', 'body'),\n })))\n } else {\n data.body = bodyResult.data\n }\n } else {\n data.body = {} as TBody\n }\n\n // Validate query\n if (config.query) {\n const queryResult = validateQuery<TQuery>(request, config.query)\n if (!queryResult.success) {\n allErrors.push(...(queryResult.errors || []).map(e => ({\n ...e,\n field: `query.${e.field}`.replace('query._root', 'query'),\n })))\n } else {\n data.query = queryResult.data\n }\n } else {\n data.query = {} as TQuery\n }\n\n // Validate params\n if (config.params && config.routeParams) {\n const paramsResult = validateParams<TParams>(config.routeParams, config.params)\n if (!paramsResult.success) {\n allErrors.push(...(paramsResult.errors || []).map(e => ({\n ...e,\n field: `params.${e.field}`.replace('params._root', 'params'),\n })))\n } else {\n data.params = paramsResult.data\n }\n } else {\n data.params = {} as TParams\n }\n\n if (allErrors.length > 0) {\n return { success: false, errors: allErrors }\n }\n\n return {\n success: true,\n data: data as ValidatedContext<TBody, TQuery, TParams>,\n }\n}\n\n/**\n * Default validation error response\n */\nexport function defaultValidationErrorResponse(\n errors: ValidationError[]\n): Response {\n return new Response(\n JSON.stringify({\n error: 'validation_error',\n message: 'Request validation failed',\n details: errors.map(e => ({\n field: e.field,\n code: e.code,\n message: e.message,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Create a validation function for a schema\n */\nexport function createValidator<T>(\n schema: Schema<T> | CustomSchema\n): (data: unknown) => ValidationResult<T> {\n return (data: unknown) => validate<T>(data, schema)\n}\n\n/**\n * Check if all validation results are successful\n */\nexport function allValid(...results: ValidationResult[]): boolean {\n return results.every(r => r.success)\n}\n\n/**\n * Merge validation errors from multiple results\n */\nexport function mergeErrors(...results: ValidationResult[]): ValidationError[] {\n const errors: ValidationError[] = []\n for (const result of results) {\n if (result.errors) {\n errors.push(...result.errors)\n }\n }\n return errors\n}\n","import type { NextRequest } from 'next/server'\nimport type { ContentTypeConfig } from '../types'\n\n/**\n * Common MIME types\n */\nexport const MIME_TYPES = {\n // Text\n TEXT_PLAIN: 'text/plain',\n TEXT_HTML: 'text/html',\n TEXT_CSS: 'text/css',\n TEXT_JAVASCRIPT: 'text/javascript',\n\n // Application\n JSON: 'application/json',\n FORM_URLENCODED: 'application/x-www-form-urlencoded',\n MULTIPART_FORM: 'multipart/form-data',\n XML: 'application/xml',\n PDF: 'application/pdf',\n ZIP: 'application/zip',\n GZIP: 'application/gzip',\n OCTET_STREAM: 'application/octet-stream',\n\n // Image\n IMAGE_PNG: 'image/png',\n IMAGE_JPEG: 'image/jpeg',\n IMAGE_GIF: 'image/gif',\n IMAGE_WEBP: 'image/webp',\n IMAGE_SVG: 'image/svg+xml',\n\n // Audio\n AUDIO_MP3: 'audio/mpeg',\n AUDIO_WAV: 'audio/wav',\n AUDIO_OGG: 'audio/ogg',\n\n // Video\n VIDEO_MP4: 'video/mp4',\n VIDEO_WEBM: 'video/webm',\n} as const\n\n/**\n * Parse Content-Type header\n */\nexport function parseContentType(header: string | null): {\n type: string\n subtype: string\n mediaType: string\n charset?: string\n boundary?: string\n parameters: Record<string, string>\n} {\n if (!header) {\n return {\n type: '',\n subtype: '',\n mediaType: '',\n parameters: {},\n }\n }\n\n // Split by semicolon to separate media type from parameters\n const parts = header.split(';').map(p => p.trim())\n const mediaType = parts[0].toLowerCase()\n\n // Split media type into type/subtype\n const [type = '', subtype = ''] = mediaType.split('/')\n\n // Parse parameters\n const parameters: Record<string, string> = {}\n for (let i = 1; i < parts.length; i++) {\n const [key, value] = parts[i].split('=').map(p => p.trim())\n if (key && value) {\n // Remove quotes if present\n parameters[key.toLowerCase()] = value.replace(/^[\"']|[\"']$/g, '')\n }\n }\n\n return {\n type,\n subtype,\n mediaType,\n charset: parameters['charset'],\n boundary: parameters['boundary'],\n parameters,\n }\n}\n\n/**\n * Check if Content-Type matches allowed types\n */\nexport function isAllowedContentType(\n contentType: string | null,\n allowedTypes: string[],\n strict = false\n): boolean {\n if (!contentType) {\n return !strict\n }\n\n const { mediaType } = parseContentType(contentType)\n\n return allowedTypes.some(allowed => {\n const normalizedAllowed = allowed.toLowerCase().trim()\n\n // Exact match\n if (mediaType === normalizedAllowed) {\n return true\n }\n\n // Wildcard match (e.g., 'application/*' matches 'application/json')\n if (normalizedAllowed.endsWith('/*')) {\n const prefix = normalizedAllowed.slice(0, -2)\n return mediaType.startsWith(prefix + '/')\n }\n\n // Type-only match (e.g., 'application' matches 'application/json')\n if (!normalizedAllowed.includes('/')) {\n const { type } = parseContentType(contentType)\n return type === normalizedAllowed\n }\n\n return false\n })\n}\n\n/**\n * Validate Content-Type header\n */\nexport function validateContentType(\n request: NextRequest,\n config: ContentTypeConfig\n): { valid: boolean; contentType: string | null; reason?: string } {\n const contentType = request.headers.get('content-type')\n const { allowed, strict = false, charset } = config\n\n // Check if Content-Type is required but missing\n if (strict && !contentType) {\n return {\n valid: false,\n contentType: null,\n reason: 'Content-Type header is required',\n }\n }\n\n // Check if Content-Type is allowed\n if (contentType && !isAllowedContentType(contentType, allowed, strict)) {\n return {\n valid: false,\n contentType,\n reason: `Content-Type '${contentType}' is not allowed`,\n }\n }\n\n // Check charset if specified\n if (charset && contentType) {\n const parsed = parseContentType(contentType)\n if (parsed.charset && parsed.charset.toLowerCase() !== charset.toLowerCase()) {\n return {\n valid: false,\n contentType,\n reason: `Charset '${parsed.charset}' is not allowed, expected '${charset}'`,\n }\n }\n }\n\n return { valid: true, contentType }\n}\n\n/**\n * Default Content-Type validation error response\n */\nexport function defaultContentTypeErrorResponse(\n contentType: string | null,\n reason: string\n): Response {\n return new Response(\n JSON.stringify({\n error: 'invalid_content_type',\n message: reason,\n received: contentType,\n }),\n {\n status: 415, // Unsupported Media Type\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Check if request has JSON content type\n */\nexport function isJsonRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.JSON]\n )\n}\n\n/**\n * Check if request has form content type\n */\nexport function isFormRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.FORM_URLENCODED, MIME_TYPES.MULTIPART_FORM]\n )\n}\n\n/**\n * Check if request has multipart content type\n */\nexport function isMultipartRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.MULTIPART_FORM]\n )\n}\n\n/**\n * Get boundary from multipart Content-Type\n */\nexport function getMultipartBoundary(request: NextRequest): string | null {\n const contentType = request.headers.get('content-type')\n if (!contentType) return null\n\n const { boundary } = parseContentType(contentType)\n return boundary || null\n}\n","import type { PathValidationConfig, PathValidationResult } from '../types'\n\n/**\n * Dangerous path patterns\n */\nconst DANGEROUS_PATTERNS = [\n // Unix path traversal\n /\\.\\.\\//g,\n /\\.\\./g,\n // Windows path traversal\n /\\.\\.\\\\/g,\n // Null byte (can truncate paths in some systems)\n /%00/g,\n /\\0/g,\n // URL encoded traversal\n /%2e%2e%2f/gi, // ../\n /%2e%2e\\//gi, // ../\n /%2e%2e%5c/gi, // ..\\\n /%2e%2e\\\\/gi, // ..\\\n // Double URL encoding\n /%252e%252e%252f/gi,\n /%252e%252e%255c/gi,\n // Unicode encoding\n /\\.%u002e\\//gi,\n /%u002e%u002e%u002f/gi,\n // Overlong UTF-8 encoding\n /%c0%ae%c0%ae%c0%af/gi,\n /%c1%9c/gi, // Backslash variant\n]\n\n/**\n * Default blocked extensions\n */\nconst DEFAULT_BLOCKED_EXTENSIONS = [\n '.exe', '.dll', '.so', '.dylib', // Executables\n '.sh', '.bash', '.bat', '.cmd', '.ps1', // Scripts\n '.php', '.asp', '.aspx', '.jsp', '.cgi', // Server scripts\n '.htaccess', '.htpasswd', // Apache config\n '.env', '.git', '.svn', // Config/VCS\n]\n\n/**\n * Normalize path separators\n */\nfunction normalizePathSeparators(path: string): string {\n return path.replace(/\\\\/g, '/')\n}\n\n/**\n * URL decode a path (handles double encoding)\n */\nfunction decodePathComponent(path: string): string {\n let result = path\n let previous = ''\n\n // Keep decoding until no more changes (handles double encoding)\n while (result !== previous) {\n previous = result\n try {\n result = decodeURIComponent(result)\n } catch {\n break\n }\n }\n\n return result\n}\n\n/**\n * Check if path contains traversal patterns\n */\nexport function hasPathTraversal(path: string): boolean {\n if (!path || typeof path !== 'string') return false\n\n // Normalize and decode\n const normalized = normalizePathSeparators(decodePathComponent(path))\n\n // Check for dangerous patterns\n for (const pattern of DANGEROUS_PATTERNS) {\n pattern.lastIndex = 0\n if (pattern.test(normalized)) {\n return true\n }\n }\n\n // Check for .. sequences (already handled by patterns but double check)\n if (normalized.includes('..')) {\n return true\n }\n\n return false\n}\n\n/**\n * Validate and sanitize a path\n */\nexport function validatePath(\n path: string,\n config: PathValidationConfig = {}\n): PathValidationResult {\n if (!path || typeof path !== 'string') {\n return { valid: false, reason: 'Path is empty or not a string' }\n }\n\n const {\n allowAbsolute = false,\n allowedPrefixes = [],\n allowedExtensions,\n blockedExtensions = DEFAULT_BLOCKED_EXTENSIONS,\n maxDepth = 10,\n maxLength = 255,\n normalize = true,\n } = config\n\n // Check length\n if (path.length > maxLength) {\n return { valid: false, reason: `Path exceeds maximum length of ${maxLength}` }\n }\n\n // Decode and normalize\n let normalized = decodePathComponent(path)\n if (normalize) {\n normalized = normalizePathSeparators(normalized)\n }\n\n // Check for null bytes\n if (normalized.includes('\\0') || path.includes('%00')) {\n return { valid: false, reason: 'Path contains null bytes' }\n }\n\n // Check for path traversal\n if (hasPathTraversal(path)) {\n return { valid: false, reason: 'Path contains traversal sequences' }\n }\n\n // Check absolute path\n const isAbsolute = normalized.startsWith('/') ||\n /^[a-zA-Z]:/.test(normalized) || // Windows drive letter\n normalized.startsWith('\\\\\\\\') // UNC path\n\n if (isAbsolute && !allowAbsolute) {\n return { valid: false, reason: 'Absolute paths are not allowed' }\n }\n\n // Check allowed prefixes\n if (allowedPrefixes.length > 0) {\n const hasValidPrefix = allowedPrefixes.some(prefix => {\n const normalizedPrefix = normalizePathSeparators(prefix)\n return normalized.startsWith(normalizedPrefix)\n })\n\n if (!hasValidPrefix) {\n return { valid: false, reason: 'Path does not start with an allowed prefix' }\n }\n }\n\n // Check path depth\n const segments = normalized.split('/').filter(s => s && s !== '.')\n if (segments.length > maxDepth) {\n return { valid: false, reason: `Path depth exceeds maximum of ${maxDepth}` }\n }\n\n // Get extension\n const lastSegment = segments[segments.length - 1] || ''\n const dotIndex = lastSegment.lastIndexOf('.')\n const extension = dotIndex > 0 ? lastSegment.slice(dotIndex).toLowerCase() : ''\n\n // Check blocked extensions\n if (extension && blockedExtensions.length > 0) {\n if (blockedExtensions.map(e => e.toLowerCase()).includes(extension)) {\n return { valid: false, reason: `Extension ${extension} is not allowed` }\n }\n }\n\n // Check allowed extensions\n if (extension && allowedExtensions && allowedExtensions.length > 0) {\n if (!allowedExtensions.map(e => e.toLowerCase()).includes(extension)) {\n return { valid: false, reason: `Extension ${extension} is not in allowed list` }\n }\n }\n\n // Normalize double slashes\n const sanitized = normalized.replace(/\\/+/g, '/')\n\n return { valid: true, sanitized }\n}\n\n/**\n * Sanitize a path by removing dangerous elements\n */\nexport function sanitizePath(\n path: string,\n config: PathValidationConfig = {}\n): string {\n if (!path || typeof path !== 'string') return ''\n\n const { normalize = true, maxLength = 255 } = config\n\n // Decode\n let result = decodePathComponent(path)\n\n // Normalize separators\n if (normalize) {\n result = normalizePathSeparators(result)\n }\n\n // Remove null bytes\n result = result.replace(/\\0/g, '').replace(/%00/g, '')\n\n // Remove traversal sequences\n result = result.replace(/\\.\\.\\//g, '').replace(/\\.\\.\\\\/g, '')\n\n // Remove leading slashes if not allowed absolute\n if (!config.allowAbsolute) {\n result = result.replace(/^\\/+/, '')\n result = result.replace(/^[a-zA-Z]:/, '')\n result = result.replace(/^\\\\\\\\/, '')\n }\n\n // Remove double slashes\n result = result.replace(/\\/+/g, '/')\n\n // Remove trailing slashes\n result = result.replace(/\\/+$/, '')\n\n // Limit length\n if (result.length > maxLength) {\n result = result.slice(0, maxLength)\n }\n\n return result\n}\n\n/**\n * Check if a path is within a base directory (safe containment)\n */\nexport function isPathContained(path: string, baseDir: string): boolean {\n if (!path || !baseDir) return false\n\n // Normalize both paths\n const normalizedPath = normalizePathSeparators(decodePathComponent(path))\n const normalizedBase = normalizePathSeparators(baseDir)\n\n // Resolve the path (simulate what a file system would do)\n const resolvedPath = resolvePath(normalizedPath, normalizedBase)\n\n // Check if resolved path starts with base directory\n return resolvedPath.startsWith(normalizedBase.replace(/\\/$/, '') + '/')\n}\n\n/**\n * Simple path resolver (simulates path.resolve)\n */\nfunction resolvePath(path: string, base: string): string {\n // Combine base and path\n let combined: string\n if (path.startsWith('/')) {\n combined = path\n } else {\n combined = `${base.replace(/\\/$/, '')}/${path}`\n }\n\n // Resolve . and ..\n const segments: string[] = []\n for (const segment of combined.split('/')) {\n if (segment === '' || segment === '.') {\n continue\n }\n if (segment === '..') {\n segments.pop()\n } else {\n segments.push(segment)\n }\n }\n\n return '/' + segments.join('/')\n}\n\n/**\n * Get the file extension from a path\n */\nexport function getExtension(path: string): string {\n if (!path || typeof path !== 'string') return ''\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/')\n const filename = segments[segments.length - 1] || ''\n\n const dotIndex = filename.lastIndexOf('.')\n if (dotIndex <= 0) return '' // No extension or hidden file\n\n return filename.slice(dotIndex).toLowerCase()\n}\n\n/**\n * Get the filename from a path\n */\nexport function getFilename(path: string): string {\n if (!path || typeof path !== 'string') return ''\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/')\n\n return segments[segments.length - 1] || ''\n}\n\n/**\n * Sanitize a filename (remove dangerous characters)\n */\nexport function sanitizeFilename(filename: string): string {\n if (typeof filename !== 'string') return 'file'\n if (!filename) return 'file'\n\n let result = filename\n\n // Remove path separators\n result = result.replace(/[/\\\\]/g, '')\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n // Remove control characters\n result = result.replace(/[\\x00-\\x1f\\x7f]/g, '')\n\n // Remove dangerous characters for file systems\n result = result.replace(/[<>:\"|?*]/g, '')\n\n // Remove leading/trailing dots and spaces\n result = result.replace(/^[.\\s]+|[.\\s]+$/g, '')\n\n // Limit length (common file system limit)\n if (result.length > 255) {\n const ext = getExtension(result)\n const name = result.slice(0, 255 - ext.length)\n result = name + ext\n }\n\n return result || 'file'\n}\n\n/**\n * Check if path is a hidden file (starts with dot)\n */\nexport function isHiddenPath(path: string): boolean {\n if (!path) return false\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/').filter(Boolean)\n\n return segments.some(segment => segment.startsWith('.'))\n}\n","import type { NextRequest } from 'next/server'\nimport type { FileValidationConfig, FileValidationError, FileInfo, MagicNumber } from '../types'\nimport { sanitizeFilename, getExtension } from '../sanitizers/path'\n\n/**\n * Known magic numbers for file type validation\n */\nconst MAGIC_NUMBERS: MagicNumber[] = [\n // Images\n { type: 'image/jpeg', extension: '.jpg', signature: [0xFF, 0xD8, 0xFF] },\n { type: 'image/png', extension: '.png', signature: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] },\n { type: 'image/gif', extension: '.gif', signature: [0x47, 0x49, 0x46, 0x38] }, // GIF87a or GIF89a\n { type: 'image/webp', extension: '.webp', signature: [0x52, 0x49, 0x46, 0x46], offset: 0 }, // RIFF\n { type: 'image/bmp', extension: '.bmp', signature: [0x42, 0x4D] },\n { type: 'image/tiff', extension: '.tiff', signature: [0x49, 0x49, 0x2A, 0x00] }, // Little endian\n { type: 'image/tiff', extension: '.tiff', signature: [0x4D, 0x4D, 0x00, 0x2A] }, // Big endian\n { type: 'image/x-icon', extension: '.ico', signature: [0x00, 0x00, 0x01, 0x00] },\n { type: 'image/svg+xml', extension: '.svg', signature: [0x3C, 0x3F, 0x78, 0x6D, 0x6C] }, // <?xml\n\n // Documents\n { type: 'application/pdf', extension: '.pdf', signature: [0x25, 0x50, 0x44, 0x46] }, // %PDF\n { type: 'application/zip', extension: '.zip', signature: [0x50, 0x4B, 0x03, 0x04] }, // PK\n { type: 'application/gzip', extension: '.gz', signature: [0x1F, 0x8B] },\n { type: 'application/x-rar-compressed', extension: '.rar', signature: [0x52, 0x61, 0x72, 0x21] },\n { type: 'application/x-7z-compressed', extension: '.7z', signature: [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C] },\n\n // Microsoft Office (new format - zip based)\n { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', extension: '.xlsx', signature: [0x50, 0x4B, 0x03, 0x04] },\n { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extension: '.docx', signature: [0x50, 0x4B, 0x03, 0x04] },\n { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', extension: '.pptx', signature: [0x50, 0x4B, 0x03, 0x04] },\n\n // Microsoft Office (old format)\n { type: 'application/msword', extension: '.doc', signature: [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1] },\n { type: 'application/vnd.ms-excel', extension: '.xls', signature: [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1] },\n\n // Audio\n { type: 'audio/mpeg', extension: '.mp3', signature: [0xFF, 0xFB] }, // MP3 frame sync\n { type: 'audio/mpeg', extension: '.mp3', signature: [0x49, 0x44, 0x33] }, // ID3\n { type: 'audio/wav', extension: '.wav', signature: [0x52, 0x49, 0x46, 0x46] }, // RIFF\n { type: 'audio/ogg', extension: '.ogg', signature: [0x4F, 0x67, 0x67, 0x53] },\n { type: 'audio/flac', extension: '.flac', signature: [0x66, 0x4C, 0x61, 0x43] },\n\n // Video\n { type: 'video/mp4', extension: '.mp4', signature: [0x00, 0x00, 0x00], offset: 0 }, // Partial match\n { type: 'video/webm', extension: '.webm', signature: [0x1A, 0x45, 0xDF, 0xA3] },\n { type: 'video/avi', extension: '.avi', signature: [0x52, 0x49, 0x46, 0x46] }, // RIFF\n { type: 'video/quicktime', extension: '.mov', signature: [0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70] },\n\n // Web\n { type: 'application/wasm', extension: '.wasm', signature: [0x00, 0x61, 0x73, 0x6D] }, // \\0asm\n\n // Fonts\n { type: 'font/woff', extension: '.woff', signature: [0x77, 0x4F, 0x46, 0x46] },\n { type: 'font/woff2', extension: '.woff2', signature: [0x77, 0x4F, 0x46, 0x32] },\n]\n\n/**\n * Default file size limits\n */\nexport const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB\nexport const DEFAULT_MAX_FILES = 10\n\n/**\n * Dangerous file extensions to block by default\n */\nexport const DANGEROUS_EXTENSIONS = [\n '.exe', '.dll', '.so', '.dylib', '.bin',\n '.sh', '.bash', '.bat', '.cmd', '.ps1', '.vbs',\n '.php', '.asp', '.aspx', '.jsp', '.cgi', '.pl',\n '.py', '.rb', '.jar', '.class',\n '.msi', '.dmg', '.pkg', '.deb', '.rpm',\n '.scr', '.pif', '.com', '.hta',\n]\n\n/**\n * Check magic number signature\n */\nexport function checkMagicNumber(bytes: Uint8Array, magicNumber: MagicNumber): boolean {\n const offset = magicNumber.offset || 0\n const signature = magicNumber.signature\n\n if (bytes.length < offset + signature.length) {\n return false\n }\n\n for (let i = 0; i < signature.length; i++) {\n if (bytes[offset + i] !== signature[i]) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Detect file type from magic number\n */\nexport function detectFileType(bytes: Uint8Array): { type: string; extension: string } | null {\n for (const magic of MAGIC_NUMBERS) {\n if (checkMagicNumber(bytes, magic)) {\n return { type: magic.type, extension: magic.extension }\n }\n }\n return null\n}\n\n/**\n * Validate a single file\n */\nexport async function validateFile(\n file: File,\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; info: FileInfo; errors: FileValidationError[] }> {\n const {\n maxSize = DEFAULT_MAX_FILE_SIZE,\n minSize = 0,\n allowedTypes = [],\n blockedTypes = [],\n allowedExtensions = [],\n blockedExtensions = DANGEROUS_EXTENSIONS,\n validateMagicNumbers = true,\n sanitizeFilename: doSanitize = true,\n } = config\n\n const errors: FileValidationError[] = []\n const extension = getExtension(file.name)\n\n const info: FileInfo = {\n filename: doSanitize ? sanitizeFilename(file.name) : file.name,\n size: file.size,\n type: file.type,\n extension,\n }\n\n // Check size\n if (file.size > maxSize) {\n errors.push({\n filename: file.name,\n code: 'size_exceeded',\n message: `File size (${formatBytes(file.size)}) exceeds maximum allowed (${formatBytes(maxSize)})`,\n details: { size: file.size, maxSize },\n })\n }\n\n if (file.size < minSize) {\n errors.push({\n filename: file.name,\n code: 'size_too_small',\n message: `File size (${formatBytes(file.size)}) is below minimum required (${formatBytes(minSize)})`,\n details: { size: file.size, minSize },\n })\n }\n\n // Check extension\n if (blockedExtensions.length > 0 && extension) {\n if (blockedExtensions.map(e => e.toLowerCase()).includes(extension.toLowerCase())) {\n errors.push({\n filename: file.name,\n code: 'extension_not_allowed',\n message: `File extension '${extension}' is not allowed`,\n details: { extension, blockedExtensions },\n })\n }\n }\n\n if (allowedExtensions.length > 0 && extension) {\n if (!allowedExtensions.map(e => e.toLowerCase()).includes(extension.toLowerCase())) {\n errors.push({\n filename: file.name,\n code: 'extension_not_allowed',\n message: `File extension '${extension}' is not in allowed list`,\n details: { extension, allowedExtensions },\n })\n }\n }\n\n // Check MIME type\n if (blockedTypes.length > 0 && file.type) {\n if (blockedTypes.includes(file.type)) {\n errors.push({\n filename: file.name,\n code: 'type_not_allowed',\n message: `File type '${file.type}' is not allowed`,\n details: { type: file.type, blockedTypes },\n })\n }\n }\n\n if (allowedTypes.length > 0) {\n if (!allowedTypes.includes(file.type)) {\n errors.push({\n filename: file.name,\n code: 'type_not_allowed',\n message: `File type '${file.type}' is not in allowed list`,\n details: { type: file.type, allowedTypes },\n })\n }\n }\n\n // Validate magic numbers\n if (validateMagicNumbers && errors.length === 0) {\n try {\n const buffer = await file.arrayBuffer()\n const bytes = new Uint8Array(buffer.slice(0, 32)) // Read first 32 bytes\n const detected = detectFileType(bytes)\n\n if (detected) {\n // Check if detected type matches claimed type\n if (file.type && detected.type !== file.type) {\n // Allow some flexibility for similar types\n const isSimilar =\n (detected.type.startsWith('image/') && file.type.startsWith('image/')) ||\n (detected.type.startsWith('audio/') && file.type.startsWith('audio/')) ||\n (detected.type.startsWith('video/') && file.type.startsWith('video/'))\n\n if (!isSimilar) {\n errors.push({\n filename: file.name,\n code: 'invalid_content',\n message: `File content doesn't match declared type (claimed: ${file.type}, detected: ${detected.type})`,\n details: { claimed: file.type, detected: detected.type },\n })\n }\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n\n return {\n valid: errors.length === 0,\n info,\n errors,\n }\n}\n\n/**\n * Validate multiple files\n */\nexport async function validateFiles(\n files: File[],\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; infos: FileInfo[]; errors: FileValidationError[] }> {\n const { maxFiles = DEFAULT_MAX_FILES } = config\n\n const allErrors: FileValidationError[] = []\n const infos: FileInfo[] = []\n\n // Check total file count\n if (files.length > maxFiles) {\n allErrors.push({\n filename: '',\n code: 'too_many_files',\n message: `Too many files (${files.length}), maximum allowed is ${maxFiles}`,\n details: { count: files.length, maxFiles },\n })\n }\n\n // Validate each file\n for (const file of files) {\n const result = await validateFile(file, config)\n infos.push(result.info)\n allErrors.push(...result.errors)\n }\n\n return {\n valid: allErrors.length === 0,\n infos,\n errors: allErrors,\n }\n}\n\n/**\n * Extract files from FormData\n */\nexport function extractFilesFromFormData(formData: FormData): Map<string, File[]> {\n const files = new Map<string, File[]>()\n\n formData.forEach((value, key) => {\n if (value instanceof File) {\n const existing = files.get(key) || []\n existing.push(value)\n files.set(key, existing)\n }\n })\n\n return files\n}\n\n/**\n * Validate files from a request\n */\nexport async function validateFilesFromRequest(\n request: NextRequest,\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; files: Map<string, FileInfo[]>; errors: FileValidationError[] }> {\n const contentType = request.headers.get('content-type') || ''\n\n if (!contentType.includes('multipart/form-data')) {\n return { valid: true, files: new Map(), errors: [] }\n }\n\n try {\n const formData = await request.formData()\n const fileMap = extractFilesFromFormData(formData)\n\n const allInfos = new Map<string, FileInfo[]>()\n const allErrors: FileValidationError[] = []\n\n let totalFileCount = 0\n\n for (const [field, files] of fileMap.entries()) {\n totalFileCount += files.length\n const result = await validateFiles(files, { ...config, maxFiles: Infinity }) // Check max later\n\n allInfos.set(field, result.infos)\n allErrors.push(...result.errors.map(e => ({ ...e, field })))\n }\n\n // Check total file count across all fields\n const maxFiles = config.maxFiles ?? DEFAULT_MAX_FILES\n if (totalFileCount > maxFiles) {\n allErrors.push({\n filename: '',\n code: 'too_many_files',\n message: `Total file count (${totalFileCount}) exceeds maximum (${maxFiles})`,\n details: { count: totalFileCount, maxFiles },\n })\n }\n\n return {\n valid: allErrors.length === 0,\n files: allInfos,\n errors: allErrors,\n }\n } catch {\n return {\n valid: false,\n files: new Map(),\n errors: [{\n filename: '',\n code: 'invalid_content',\n message: 'Failed to parse multipart form data',\n }],\n }\n }\n}\n\n/**\n * Default file validation error response\n */\nexport function defaultFileErrorResponse(errors: FileValidationError[]): Response {\n return new Response(\n JSON.stringify({\n error: 'file_validation_error',\n message: 'File validation failed',\n details: errors.map(e => ({\n filename: e.filename,\n field: e.field,\n code: e.code,\n message: e.message,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Format bytes to human readable string\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B'\n\n const units = ['B', 'KB', 'MB', 'GB']\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${units[i]}`\n}\n","import type { SanitizeConfig } from '../types'\n\n/**\n * Default allowed tags for 'allow-safe' mode\n */\nconst DEFAULT_ALLOWED_TAGS = [\n 'a', 'abbr', 'b', 'blockquote', 'br', 'code', 'del', 'em', 'h1', 'h2', 'h3',\n 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'li', 'mark', 'ol', 'p', 'pre', 'q',\n 's', 'small', 'span', 'strong', 'sub', 'sup', 'u', 'ul',\n]\n\n/**\n * Default allowed attributes per tag\n */\nconst DEFAULT_ALLOWED_ATTRIBUTES: Record<string, string[]> = {\n a: ['href', 'title', 'target', 'rel'],\n img: ['src', 'alt', 'title', 'width', 'height'],\n abbr: ['title'],\n q: ['cite'],\n blockquote: ['cite'],\n}\n\n/**\n * Safe protocols for URLs\n */\nconst DEFAULT_SAFE_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:']\n\n/**\n * Dangerous patterns to detect\n */\nconst DANGEROUS_PATTERNS = [\n // Event handlers\n /\\bon\\w+\\s*=/gi,\n // JavaScript protocol\n /javascript\\s*:/gi,\n // VBScript protocol\n /vbscript\\s*:/gi,\n // Data URI with scripts\n /data\\s*:[^,]*(?:text\\/html|application\\/javascript|text\\/javascript)/gi,\n // Expression in CSS\n /expression\\s*\\(/gi,\n // Binding in CSS (Firefox)\n /-moz-binding\\s*:/gi,\n // Behavior in CSS (IE)\n /behavior\\s*:/gi,\n // Import in CSS\n /@import/gi,\n // Script tags\n /<\\s*script/gi,\n // Style tags with expressions\n /<\\s*style[^>]*>[^<]*expression/gi,\n // SVG with scripts\n /<\\s*svg[^>]*onload/gi,\n // Object/embed/applet tags\n /<\\s*(object|embed|applet)/gi,\n // Base tag (can redirect resources)\n /<\\s*base/gi,\n // Meta refresh\n /<\\s*meta[^>]*http-equiv\\s*=\\s*[\"']?refresh/gi,\n // Form action hijacking\n /<\\s*form[^>]*action\\s*=\\s*[\"']?javascript/gi,\n // Link tag with import\n /<\\s*link[^>]*rel\\s*=\\s*[\"']?import/gi,\n]\n\n/**\n * HTML entities map\n */\nconst HTML_ENTITIES: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#x27;',\n '/': '&#x2F;',\n '`': '&#x60;',\n '=': '&#x3D;',\n}\n\n/**\n * Escape HTML special characters\n */\nexport function escapeHtml(str: string): string {\n return str.replace(/[&<>\"'`=/]/g, char => HTML_ENTITIES[char] || char)\n}\n\n/**\n * Unescape HTML entities\n */\nexport function unescapeHtml(str: string): string {\n const entityMap: Record<string, string> = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#x27;': \"'\",\n '&#x2F;': '/',\n '&#x60;': '`',\n '&#x3D;': '=',\n '&#39;': \"'\",\n '&#47;': '/',\n }\n\n return str.replace(/&(?:amp|lt|gt|quot|#x27|#x2F|#x60|#x3D|#39|#47);/gi, entity => {\n return entityMap[entity.toLowerCase()] || entity\n })\n}\n\n/**\n * Strip all HTML tags\n */\nexport function stripHtml(str: string): string {\n // Remove script and style content completely\n let result = str.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n result = result.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n\n // Remove all HTML tags\n result = result.replace(/<[^>]*>/g, '')\n\n // Decode entities\n result = unescapeHtml(result)\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n return result.trim()\n}\n\n/**\n * Check if a URL is safe\n */\nexport function isSafeUrl(url: string, allowedProtocols: string[] = DEFAULT_SAFE_PROTOCOLS): boolean {\n if (!url) return true\n\n // Normalize\n const trimmed = url.trim().toLowerCase()\n\n // Check for dangerous protocols\n if (trimmed.startsWith('javascript:')) return false\n if (trimmed.startsWith('vbscript:')) return false\n\n // Allow data:image URLs (commonly used for base64 images)\n if (trimmed.startsWith('data:image/')) return true\n\n // Block other data URLs\n if (trimmed.startsWith('data:')) return false\n\n // Check if protocol is allowed\n try {\n const parsed = new URL(url, 'https://example.com')\n if (parsed.protocol && !allowedProtocols.includes(parsed.protocol)) {\n // Allow relative URLs\n if (!url.includes(':')) return true\n return false\n }\n } catch {\n // Relative URL, allow\n return true\n }\n\n return true\n}\n\n/**\n * Sanitize HTML with allowed tags\n */\nexport function sanitizeHtml(\n str: string,\n allowedTags: string[] = DEFAULT_ALLOWED_TAGS,\n allowedAttributes: Record<string, string[]> = DEFAULT_ALLOWED_ATTRIBUTES,\n allowedProtocols: string[] = DEFAULT_SAFE_PROTOCOLS\n): string {\n // Remove null bytes first\n let result = str.replace(/\\0/g, '')\n\n // Remove script and style content completely\n result = result.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n result = result.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n\n // Remove comments\n result = result.replace(/<!--[\\s\\S]*?-->/g, '')\n\n // Process tags\n result = result.replace(/<\\/?([a-z][a-z0-9]*)\\b([^>]*)>/gi, (match, tagName, attributes) => {\n const lowerTag = tagName.toLowerCase()\n const isClosing = match.startsWith('</')\n\n // Check if tag is allowed\n if (!allowedTags.includes(lowerTag)) {\n return ''\n }\n\n if (isClosing) {\n return `</${lowerTag}>`\n }\n\n // Process attributes\n const allowedAttrs = allowedAttributes[lowerTag] || []\n const safeAttrs: string[] = []\n\n // Parse attributes\n const attrRegex = /([a-z][a-z0-9-]*)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*))/gi\n let attrMatch\n\n while ((attrMatch = attrRegex.exec(attributes)) !== null) {\n const attrName = attrMatch[1].toLowerCase()\n const attrValue = attrMatch[2] || attrMatch[3] || attrMatch[4] || ''\n\n // Check if attribute is allowed\n if (!allowedAttrs.includes(attrName)) continue\n\n // Check for dangerous patterns in value\n if (DANGEROUS_PATTERNS.some(pattern => pattern.test(attrValue))) continue\n\n // Check URL attributes\n if (['href', 'src', 'action', 'formaction'].includes(attrName)) {\n if (!isSafeUrl(attrValue, allowedProtocols)) continue\n }\n\n // Escape attribute value\n const safeValue = escapeHtml(attrValue)\n safeAttrs.push(`${attrName}=\"${safeValue}\"`)\n }\n\n const attrStr = safeAttrs.length > 0 ? ' ' + safeAttrs.join(' ') : ''\n return `<${lowerTag}${attrStr}>`\n })\n\n // Final check for any remaining dangerous patterns\n for (const pattern of DANGEROUS_PATTERNS) {\n result = result.replace(pattern, '')\n }\n\n return result\n}\n\n/**\n * Detect if string contains potential XSS\n */\nexport function detectXSS(str: string): boolean {\n if (!str || typeof str !== 'string') return false\n\n // Normalize\n const normalized = str\n .replace(/\\\\x([0-9a-f]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/\\\\u([0-9a-f]{4})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#x([0-9a-f]+);?/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#(\\d+);?/gi, (_, dec) => String.fromCharCode(parseInt(dec, 10)))\n\n // Reset lastIndex for global regexes before testing\n for (const pattern of DANGEROUS_PATTERNS) {\n pattern.lastIndex = 0\n if (pattern.test(normalized)) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Main sanitize function\n */\nexport function sanitize(input: string, config: SanitizeConfig = {}): string {\n if (!input || typeof input !== 'string') return ''\n\n const {\n mode = 'escape',\n allowedTags = DEFAULT_ALLOWED_TAGS,\n allowedAttributes = DEFAULT_ALLOWED_ATTRIBUTES,\n allowedProtocols = DEFAULT_SAFE_PROTOCOLS,\n maxLength,\n stripNull = true,\n } = config\n\n let result = input\n\n // Strip null bytes\n if (stripNull) {\n result = result.replace(/\\0/g, '')\n }\n\n // Apply sanitization based on mode\n switch (mode) {\n case 'escape':\n result = escapeHtml(result)\n break\n\n case 'strip':\n result = stripHtml(result)\n break\n\n case 'allow-safe':\n result = sanitizeHtml(result, allowedTags, allowedAttributes, allowedProtocols)\n break\n }\n\n // Apply max length\n if (maxLength !== undefined && result.length > maxLength) {\n result = result.slice(0, maxLength)\n }\n\n return result\n}\n\n/**\n * Sanitize object values recursively\n */\nexport function sanitizeObject<T>(obj: T, config: SanitizeConfig = {}): T {\n if (typeof obj === 'string') {\n return sanitize(obj, config) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => sanitizeObject(item, config)) as T\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = sanitizeObject(value, config)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Sanitize specific fields in an object\n */\nexport function sanitizeFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[],\n config: SanitizeConfig = {}\n): T {\n const result = { ...obj }\n\n for (const field of fields) {\n if (field in result && typeof result[field] === 'string') {\n (result as Record<string, unknown>)[field] = sanitize(result[field] as string, config)\n }\n }\n\n return result\n}\n","import type { SQLDetection } from '../types'\n\n/**\n * SQL injection patterns with severity levels\n */\ninterface SQLPattern {\n pattern: RegExp\n name: string\n severity: 'low' | 'medium' | 'high'\n}\n\n/**\n * Common SQL injection patterns\n */\nconst SQL_PATTERNS: SQLPattern[] = [\n // High severity - Definite attacks\n {\n pattern: /'\\s*OR\\s+'?\\d+'?\\s*=\\s*'?\\d+'?/gi,\n name: \"OR '1'='1' attack\",\n severity: 'high',\n },\n {\n pattern: /'\\s*OR\\s+'[^']*'\\s*=\\s*'[^']*'/gi,\n name: \"OR 'x'='x' attack\",\n severity: 'high',\n },\n {\n pattern: /;\\s*DROP\\s+(TABLE|DATABASE|INDEX|VIEW)/gi,\n name: 'DROP statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*DELETE\\s+FROM/gi,\n name: 'DELETE statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*TRUNCATE\\s+/gi,\n name: 'TRUNCATE statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*INSERT\\s+INTO/gi,\n name: 'INSERT statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*UPDATE\\s+\\w+\\s+SET/gi,\n name: 'UPDATE statement',\n severity: 'high',\n },\n {\n pattern: /UNION\\s+(ALL\\s+)?SELECT/gi,\n name: 'UNION SELECT attack',\n severity: 'high',\n },\n {\n pattern: /EXEC(\\s+|\\()+(sp_|xp_)/gi,\n name: 'SQL Server stored procedure',\n severity: 'high',\n },\n {\n pattern: /EXECUTE\\s+IMMEDIATE/gi,\n name: 'Oracle EXECUTE IMMEDIATE',\n severity: 'high',\n },\n {\n pattern: /INTO\\s+(OUT|DUMP)FILE/gi,\n name: 'MySQL file write',\n severity: 'high',\n },\n {\n pattern: /LOAD_FILE\\s*\\(/gi,\n name: 'MySQL file read',\n severity: 'high',\n },\n {\n pattern: /BENCHMARK\\s*\\(\\s*\\d+\\s*,/gi,\n name: 'MySQL BENCHMARK DoS',\n severity: 'high',\n },\n {\n pattern: /SLEEP\\s*\\(\\s*\\d+\\s*\\)/gi,\n name: 'SQL SLEEP time-based attack',\n severity: 'high',\n },\n {\n pattern: /WAITFOR\\s+DELAY/gi,\n name: 'SQL Server WAITFOR DELAY',\n severity: 'high',\n },\n {\n pattern: /PG_SLEEP\\s*\\(/gi,\n name: 'PostgreSQL pg_sleep',\n severity: 'high',\n },\n\n // Medium severity - Likely attacks\n {\n pattern: /'\\s*--/g,\n name: 'SQL comment injection',\n severity: 'medium',\n },\n {\n pattern: /'\\s*#/g,\n name: 'MySQL comment injection',\n severity: 'medium',\n },\n {\n pattern: /\\/\\*[\\s\\S]*?\\*\\//g,\n name: 'Block comment',\n severity: 'medium',\n },\n {\n pattern: /'\\s*;\\s*$/g,\n name: 'Statement terminator',\n severity: 'medium',\n },\n {\n pattern: /HAVING\\s+\\d+\\s*=\\s*\\d+/gi,\n name: 'HAVING clause injection',\n severity: 'medium',\n },\n {\n pattern: /GROUP\\s+BY\\s+\\d+/gi,\n name: 'GROUP BY injection',\n severity: 'medium',\n },\n {\n pattern: /ORDER\\s+BY\\s+\\d+/gi,\n name: 'ORDER BY injection',\n severity: 'medium',\n },\n {\n pattern: /CONCAT\\s*\\(/gi,\n name: 'CONCAT function',\n severity: 'medium',\n },\n {\n pattern: /CHAR\\s*\\(\\s*\\d+\\s*\\)/gi,\n name: 'CHAR function bypass',\n severity: 'medium',\n },\n {\n pattern: /0x[0-9a-f]{2,}/gi,\n name: 'Hex encoded value',\n severity: 'medium',\n },\n {\n pattern: /CONVERT\\s*\\(/gi,\n name: 'CONVERT function',\n severity: 'medium',\n },\n {\n pattern: /CAST\\s*\\(/gi,\n name: 'CAST function',\n severity: 'medium',\n },\n\n // Low severity - Suspicious but may be false positives\n {\n pattern: /'\\s*AND\\s+'?\\d+'?\\s*=\\s*'?\\d+'?/gi,\n name: \"AND '1'='1' pattern\",\n severity: 'low',\n },\n {\n pattern: /'\\s*AND\\s+'[^']*'\\s*=\\s*'[^']*'/gi,\n name: \"AND 'x'='x' pattern\",\n severity: 'low',\n },\n {\n pattern: /SELECT\\s+[\\w\\s,*]+\\s+FROM/gi,\n name: 'SELECT statement',\n severity: 'low',\n },\n {\n pattern: /'\\s*\\+\\s*'/g,\n name: 'String concatenation',\n severity: 'low',\n },\n {\n pattern: /'\\s*\\|\\|\\s*'/g,\n name: 'Oracle string concatenation',\n severity: 'low',\n },\n]\n\n/**\n * Additional encoded patterns (URL, hex, unicode)\n * Note: These match on the NORMALIZED (decoded) input\n */\nconst ENCODED_PATTERNS: SQLPattern[] = [\n {\n pattern: /%27\\s*%4f%52\\s*%27/gi, // URL encoded ' OR '\n name: 'URL encoded OR injection',\n severity: 'high',\n },\n {\n pattern: /%27\\s*%2d%2d/gi, // URL encoded ' --\n name: 'URL encoded comment injection',\n severity: 'medium',\n },\n {\n pattern: /\\0|%00/g, // Null byte (decoded or encoded)\n name: 'Null byte injection',\n severity: 'high',\n },\n {\n pattern: /\\\\x27/gi, // Hex escape\n name: 'Hex escaped quote',\n severity: 'medium',\n },\n {\n pattern: /\\\\u0027/gi, // Unicode escape\n name: 'Unicode escaped quote',\n severity: 'medium',\n },\n]\n\n/**\n * Normalize input by decoding common encodings\n */\nfunction normalizeInput(input: string): string {\n let result = input\n\n // URL decode\n try {\n result = decodeURIComponent(result)\n } catch {\n // Ignore decode errors\n }\n\n // HTML entity decode\n result = result\n .replace(/&#x([0-9a-f]+);?/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#(\\d+);?/gi, (_, dec) => String.fromCharCode(parseInt(dec, 10)))\n .replace(/&quot;/gi, '\"')\n .replace(/&apos;/gi, \"'\")\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&amp;/gi, '&')\n\n // Hex escape decode\n result = result.replace(/\\\\x([0-9a-f]{2})/gi, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n )\n\n // Unicode escape decode\n result = result.replace(/\\\\u([0-9a-f]{4})/gi, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n )\n\n return result\n}\n\n/**\n * Detect SQL injection in a string\n */\nexport function detectSQLInjection(\n input: string,\n options: {\n customPatterns?: RegExp[]\n checkEncoded?: boolean\n minSeverity?: 'low' | 'medium' | 'high'\n } = {}\n): SQLDetection[] {\n if (!input || typeof input !== 'string') return []\n\n const {\n customPatterns = [],\n checkEncoded = true,\n minSeverity = 'low',\n } = options\n\n const severityOrder = { low: 0, medium: 1, high: 2 }\n const minSeverityLevel = severityOrder[minSeverity]\n\n const detections: SQLDetection[] = []\n const seenPatterns = new Set<string>()\n\n // Normalize input for encoded pattern detection\n const normalizedInput = checkEncoded ? normalizeInput(input) : input\n\n // Check all patterns\n const allPatterns = [\n ...SQL_PATTERNS,\n ...(checkEncoded ? ENCODED_PATTERNS : []),\n ...customPatterns.map(p => ({ pattern: p, name: 'Custom pattern', severity: 'high' as const })),\n ]\n\n for (const { pattern, name, severity } of allPatterns) {\n if (severityOrder[severity] < minSeverityLevel) continue\n\n // Reset regex state\n pattern.lastIndex = 0\n\n const testInput = checkEncoded ? normalizedInput : input\n if (pattern.test(testInput)) {\n const key = `${name}:${severity}`\n if (!seenPatterns.has(key)) {\n seenPatterns.add(key)\n detections.push({\n field: '', // Will be set by caller\n value: input,\n pattern: name,\n severity,\n })\n }\n }\n }\n\n return detections\n}\n\n/**\n * Check if string contains SQL injection (boolean check)\n */\nexport function hasSQLInjection(\n input: string,\n minSeverity: 'low' | 'medium' | 'high' = 'medium'\n): boolean {\n return detectSQLInjection(input, { minSeverity }).length > 0\n}\n\n/**\n * Sanitize input to prevent SQL injection\n * NOTE: This should NOT be a replacement for parameterized queries!\n */\nexport function sanitizeSQLInput(input: string): string {\n if (!input || typeof input !== 'string') return ''\n\n let result = input\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n // Escape single quotes\n result = result.replace(/'/g, \"''\")\n\n // Remove dangerous characters\n result = result.replace(/;/g, '')\n result = result.replace(/--/g, '')\n result = result.replace(/\\/\\*/g, '')\n result = result.replace(/\\*\\//g, '')\n\n // Remove hex encoded values\n result = result.replace(/0x[0-9a-f]+/gi, '')\n\n return result\n}\n\n/**\n * Detect SQL injection in object fields\n */\nexport function detectSQLInjectionInObject(\n obj: unknown,\n options: {\n fields?: string[]\n deep?: boolean\n customPatterns?: RegExp[]\n minSeverity?: 'low' | 'medium' | 'high'\n } = {}\n): SQLDetection[] {\n const { fields, deep = true, customPatterns, minSeverity } = options\n const detections: SQLDetection[] = []\n\n function walk(value: unknown, path: string): void {\n if (typeof value === 'string') {\n // If fields specified, only check those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) return\n }\n\n const detected = detectSQLInjection(value, { customPatterns, minSeverity })\n for (const d of detected) {\n detections.push({ ...d, field: path })\n }\n } else if (deep && Array.isArray(value)) {\n value.forEach((item, i) => walk(item, `${path}[${i}]`))\n } else if (deep && typeof value === 'object' && value !== null) {\n for (const [key, val] of Object.entries(value)) {\n walk(val, path ? `${path}.${key}` : key)\n }\n }\n }\n\n walk(obj, '')\n return detections\n}\n\n/**\n * Check if value is in allowlist (safe values)\n */\nexport function isAllowedValue(value: string, allowList: string[]): boolean {\n if (!allowList || allowList.length === 0) return false\n return allowList.includes(value)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n ValidationConfig,\n ValidatedContext,\n ValidationError,\n SanitizationMiddlewareConfig,\n SanitizationChange,\n SQLProtectionConfig,\n ContentTypeConfig,\n FileValidationConfig,\n FileInfo,\n Schema,\n CustomSchema,\n} from './types'\nimport { validateRequest, defaultValidationErrorResponse } from './validators/schema'\nimport { validateContentType, defaultContentTypeErrorResponse } from './validators/content-type'\nimport { validateFilesFromRequest, defaultFileErrorResponse } from './validators/file'\nimport { sanitize, detectXSS } from './sanitizers/xss'\nimport { detectSQLInjectionInObject } from './sanitizers/sql'\nimport { walkObject } from './utils'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\n/**\n * Validation middleware\n * Validates request body, query, and params against schemas\n */\nexport function withValidation<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n handler: (\n req: NextRequest,\n ctx: { validated: ValidatedContext<TBody, TQuery, TParams> }\n ) => Response | Promise<Response>,\n config: ValidationConfig<TBody, TQuery, TParams> & {\n routeParams?: Record<string, string | string[]>\n }\n): RouteHandler {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n\n return async (req: NextRequest): Promise<Response> => {\n const result = await validateRequest<TBody, TQuery, TParams>(req, {\n body: config.body as Schema<TBody> | CustomSchema | undefined,\n query: config.query as Schema<TQuery> | CustomSchema | undefined,\n params: config.params as Schema<TParams> | CustomSchema | undefined,\n routeParams: config.routeParams,\n })\n\n if (!result.success) {\n return onError(req, result.errors || [])\n }\n\n return handler(req, { validated: result.data! })\n }\n}\n\n/**\n * XSS Sanitization middleware\n * Sanitizes string values in request body\n */\nexport function withSanitization(\n handler: (\n req: NextRequest,\n ctx: { sanitized: unknown; changes: SanitizationChange[] }\n ) => Response | Promise<Response>,\n config: SanitizationMiddlewareConfig = {}\n): RouteHandler {\n const {\n fields,\n mode = 'escape',\n allowedTags,\n skip,\n onSanitized,\n } = config\n\n return async (req: NextRequest): Promise<Response> => {\n // Check skip condition\n if (skip && await skip(req)) {\n return handler(req, { sanitized: null, changes: [] })\n }\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return handler(req, { sanitized: null, changes: [] })\n }\n\n const changes: SanitizationChange[] = []\n\n const sanitized = walkObject(body, (value, path) => {\n // If specific fields are specified, only sanitize those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) {\n return value\n }\n }\n\n const cleaned = sanitize(value, { mode, allowedTags })\n\n if (cleaned !== value) {\n changes.push({\n field: path,\n original: value,\n sanitized: cleaned,\n })\n }\n\n return cleaned\n }, '')\n\n // Callback for tracking\n if (onSanitized && changes.length > 0) {\n onSanitized(req, changes)\n }\n\n return handler(req, { sanitized, changes })\n }\n}\n\n/**\n * XSS Detection middleware\n * Blocks requests with potential XSS payloads in body and query parameters\n */\nexport function withXSSProtection(\n handler: RouteHandler,\n config: {\n fields?: string[]\n deep?: boolean\n checkQuery?: boolean\n onDetection?: (req: NextRequest, field: string, value: string) => Response | void | Promise<Response | void>\n } = {}\n): RouteHandler {\n const { fields, onDetection, checkQuery = true } = config\n\n return async (req: NextRequest): Promise<Response> => {\n const detections: { field: string; value: string }[] = []\n\n // Check query parameters for XSS\n if (checkQuery) {\n const url = new URL(req.url)\n for (const [key, value] of url.searchParams.entries()) {\n if (detectXSS(value)) {\n detections.push({ field: `query.${key}`, value })\n }\n }\n }\n\n // Check body\n let body: unknown\n try {\n body = await req.json()\n } catch {\n // No body or invalid JSON, skip body check\n body = null\n }\n\n if (body) {\n walkObject(body, (value, path) => {\n // If specific fields are specified, only check those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) {\n return value\n }\n }\n\n if (detectXSS(value)) {\n detections.push({ field: path, value })\n }\n\n return value\n }, '')\n }\n\n if (detections.length > 0) {\n if (onDetection) {\n for (const { field, value } of detections) {\n const result = await onDetection(req, field, value)\n if (result instanceof Response) {\n return result\n }\n }\n }\n\n // Default: block request\n return new Response(\n JSON.stringify({\n error: 'xss_detected',\n message: 'Potentially malicious content detected',\n fields: detections.map(d => d.field),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n\n return handler(req)\n }\n}\n\n/**\n * SQL Injection Protection middleware\n */\nexport function withSQLProtection(\n handler: RouteHandler,\n config: SQLProtectionConfig = {}\n): RouteHandler {\n const {\n fields,\n deep = true,\n mode = 'block',\n customPatterns,\n allowList = [],\n onDetection,\n } = config\n\n return async (req: NextRequest): Promise<Response> => {\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return handler(req)\n }\n\n const detections = detectSQLInjectionInObject(body, {\n fields,\n deep,\n customPatterns,\n minSeverity: mode === 'detect' ? 'low' : 'medium',\n })\n\n // Filter out allowed values\n const filtered = detections.filter(d => !allowList.includes(d.value))\n\n if (filtered.length > 0) {\n if (onDetection) {\n const result = await onDetection(req, filtered)\n if (result instanceof Response) {\n return result\n }\n }\n\n if (mode === 'block') {\n return new Response(\n JSON.stringify({\n error: 'sql_injection_detected',\n message: 'Potentially malicious SQL detected',\n detections: filtered.map(d => ({\n field: d.field,\n pattern: d.pattern,\n severity: d.severity,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n }\n\n return handler(req)\n }\n}\n\n/**\n * Content-Type validation middleware\n */\nexport function withContentType(\n handler: RouteHandler,\n config: ContentTypeConfig\n): RouteHandler {\n const onInvalid = config.onInvalid || ((_, contentType) =>\n defaultContentTypeErrorResponse(contentType, `Content-Type '${contentType}' is not allowed`)\n )\n\n return async (req: NextRequest): Promise<Response> => {\n const result = validateContentType(req, config)\n\n if (!result.valid) {\n return onInvalid(req, result.contentType)\n }\n\n return handler(req)\n }\n}\n\n/**\n * File upload validation middleware\n */\nexport function withFileValidation(\n handler: (\n req: NextRequest,\n ctx: { files: Map<string, FileInfo[]> }\n ) => Response | Promise<Response>,\n config: FileValidationConfig = {}\n): RouteHandler {\n const onInvalid = config.onInvalid || ((_, errors) => defaultFileErrorResponse(errors))\n\n return async (req: NextRequest): Promise<Response> => {\n const result = await validateFilesFromRequest(req, config)\n\n if (!result.valid) {\n return onInvalid(req, result.errors)\n }\n\n return handler(req, { files: result.files })\n }\n}\n\n/**\n * Combined validation middleware\n * Combines schema validation, sanitization, and protection\n */\nexport function withSecureValidation<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n handler: (\n req: NextRequest,\n ctx: {\n validated: ValidatedContext<TBody, TQuery, TParams>\n files?: Map<string, FileInfo[]>\n }\n ) => Response | Promise<Response>,\n config: {\n schema?: ValidationConfig<TBody, TQuery, TParams>\n routeParams?: Record<string, string | string[]>\n contentType?: ContentTypeConfig\n files?: FileValidationConfig\n sanitize?: SanitizationMiddlewareConfig\n xss?: { enabled: boolean; fields?: string[] }\n sql?: SQLProtectionConfig\n onError?: (req: NextRequest, errors: ValidationError[]) => Response | Promise<Response>\n }\n): RouteHandler {\n return async (req: NextRequest): Promise<Response> => {\n const allErrors: ValidationError[] = []\n\n // 1. Content-Type validation\n if (config.contentType) {\n const ctResult = validateContentType(req, config.contentType)\n if (!ctResult.valid) {\n allErrors.push({\n field: 'Content-Type',\n code: 'invalid_content_type',\n message: ctResult.reason || 'Invalid Content-Type',\n })\n }\n }\n\n // 2. File validation (if multipart)\n let files: Map<string, FileInfo[]> | undefined\n if (config.files) {\n const fileResult = await validateFilesFromRequest(req, config.files)\n if (!fileResult.valid) {\n allErrors.push(...fileResult.errors.map(e => ({\n field: e.field || e.filename,\n code: e.code,\n message: e.message,\n })))\n } else {\n files = fileResult.files\n }\n }\n\n // Early return on content errors\n if (allErrors.length > 0) {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n return onError(req, allErrors)\n }\n\n // 3. Schema validation\n let validated: ValidatedContext<TBody, TQuery, TParams> | undefined\n if (config.schema) {\n const schemaResult = await validateRequest<TBody, TQuery, TParams>(req, {\n body: config.schema.body as Schema<TBody> | CustomSchema | undefined,\n query: config.schema.query as Schema<TQuery> | CustomSchema | undefined,\n params: config.schema.params as Schema<TParams> | CustomSchema | undefined,\n routeParams: config.routeParams,\n })\n\n if (!schemaResult.success) {\n allErrors.push(...(schemaResult.errors || []))\n } else {\n validated = schemaResult.data\n }\n } else {\n validated = {\n body: {} as TBody,\n query: {} as TQuery,\n params: {} as TParams,\n }\n }\n\n // 4. SQL injection detection\n if (config.sql && validated?.body) {\n const sqlDetections = detectSQLInjectionInObject(validated.body, {\n fields: config.sql.fields,\n deep: config.sql.deep,\n customPatterns: config.sql.customPatterns,\n })\n\n if (sqlDetections.length > 0 && config.sql.mode !== 'detect') {\n allErrors.push(...sqlDetections.map(d => ({\n field: d.field,\n code: 'sql_injection',\n message: `Potential SQL injection detected: ${d.pattern}`,\n })))\n }\n }\n\n // 5. XSS detection\n if (config.xss?.enabled && validated?.body) {\n walkObject(validated.body, (value, path) => {\n if (config.xss?.fields && config.xss.fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!config.xss.fields.includes(fieldName)) {\n return value\n }\n }\n\n if (detectXSS(value)) {\n allErrors.push({\n field: path,\n code: 'xss_detected',\n message: 'Potentially malicious content detected',\n })\n }\n\n return value\n }, '')\n }\n\n // Return errors\n if (allErrors.length > 0) {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n return onError(req, allErrors)\n }\n\n return handler(req, { validated: validated!, files })\n }\n}\n","import type { LogStore, AuditLogEntry, LogQueryOptions, MemoryStoreOptions, SecurityEventType } from '../types'\n\n/**\n * In-memory log store with LRU eviction\n * Useful for development and testing\n */\nexport class MemoryStore implements LogStore {\n private entries: AuditLogEntry[] = []\n private readonly maxEntries: number\n private readonly ttl: number\n\n constructor(options: MemoryStoreOptions = {}) {\n this.maxEntries = options.maxEntries || 1000\n this.ttl = options.ttl || 0 // 0 = no TTL\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n // Add entry\n this.entries.push(entry)\n\n // Evict old entries if over limit\n if (this.entries.length > this.maxEntries) {\n this.entries = this.entries.slice(-this.maxEntries)\n }\n\n // Clean expired entries if TTL is set\n if (this.ttl > 0) {\n this.cleanExpired()\n }\n }\n\n async query(options: LogQueryOptions = {}): Promise<AuditLogEntry[]> {\n let result = [...this.entries]\n\n // Filter by level\n if (options.level) {\n const levels = Array.isArray(options.level) ? options.level : [options.level]\n result = result.filter(e => levels.includes(e.level))\n }\n\n // Filter by type\n if (options.type) {\n result = result.filter(e => e.type === options.type)\n }\n\n // Filter by event type (for security events)\n if (options.event) {\n const events = Array.isArray(options.event) ? options.event : [options.event]\n result = result.filter(e =>\n e.type === 'security' && events.includes((e as { event: SecurityEventType }).event)\n )\n }\n\n // Filter by time range\n if (options.startTime) {\n result = result.filter(e => e.timestamp >= options.startTime!)\n }\n if (options.endTime) {\n result = result.filter(e => e.timestamp <= options.endTime!)\n }\n\n // Filter by IP\n if (options.ip) {\n result = result.filter(e => {\n if (e.type === 'request') return e.request.ip === options.ip\n if (e.type === 'security') return e.source.ip === options.ip\n return false\n })\n }\n\n // Filter by user ID\n if (options.userId) {\n result = result.filter(e => {\n if (e.type === 'request') return e.user?.id === options.userId\n if (e.type === 'security') return e.source.userId === options.userId\n return false\n })\n }\n\n // Apply offset\n if (options.offset) {\n result = result.slice(options.offset)\n }\n\n // Apply limit\n if (options.limit) {\n result = result.slice(0, options.limit)\n }\n\n return result\n }\n\n async flush(): Promise<void> {\n // No-op for memory store\n }\n\n async close(): Promise<void> {\n this.entries = []\n }\n\n /**\n * Get all entries (for testing)\n */\n getEntries(): AuditLogEntry[] {\n return [...this.entries]\n }\n\n /**\n * Clear all entries\n */\n clear(): void {\n this.entries = []\n }\n\n /**\n * Get entry count\n */\n size(): number {\n return this.entries.length\n }\n\n /**\n * Clean expired entries\n */\n private cleanExpired(): void {\n if (this.ttl <= 0) return\n\n const now = Date.now()\n this.entries = this.entries.filter(e => {\n const age = now - e.timestamp.getTime()\n return age < this.ttl\n })\n }\n}\n\n/**\n * Create a memory store\n */\nexport function createMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n return new MemoryStore(options)\n}\n","import type { LogStore, AuditLogEntry, ConsoleStoreOptions, LogLevel } from '../types'\n\n/**\n * ANSI color codes\n */\nconst COLORS = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // Log levels\n debug: '\\x1b[36m', // Cyan\n info: '\\x1b[32m', // Green\n warn: '\\x1b[33m', // Yellow\n error: '\\x1b[31m', // Red\n critical: '\\x1b[35m', // Magenta\n\n // Security severity\n low: '\\x1b[36m', // Cyan\n medium: '\\x1b[33m', // Yellow\n high: '\\x1b[31m', // Red\n\n // Other\n timestamp: '\\x1b[90m', // Gray\n method: '\\x1b[34m', // Blue\n status2xx: '\\x1b[32m', // Green\n status3xx: '\\x1b[36m', // Cyan\n status4xx: '\\x1b[33m', // Yellow\n status5xx: '\\x1b[31m', // Red\n}\n\n/**\n * Log level priority\n */\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n critical: 4,\n}\n\n/**\n * Console log store\n * Outputs formatted logs to console\n */\nexport class ConsoleStore implements LogStore {\n private readonly colorize: boolean\n private readonly showTimestamp: boolean\n private readonly pretty: boolean\n private readonly minLevel: LogLevel\n\n constructor(options: ConsoleStoreOptions = {}) {\n this.colorize = options.colorize ?? (process.env.NODE_ENV !== 'production')\n this.showTimestamp = options.timestamp ?? true\n this.pretty = options.pretty ?? false\n this.minLevel = options.level || 'info'\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n // Check log level\n if (LEVEL_PRIORITY[entry.level] < LEVEL_PRIORITY[this.minLevel]) {\n return\n }\n\n const output = this.pretty\n ? this.formatPretty(entry)\n : this.formatCompact(entry)\n\n // Use appropriate console method\n switch (entry.level) {\n case 'debug':\n console.debug(output)\n break\n case 'info':\n console.info(output)\n break\n case 'warn':\n console.warn(output)\n break\n case 'error':\n case 'critical':\n console.error(output)\n break\n default:\n console.log(output)\n }\n }\n\n async flush(): Promise<void> {\n // No-op for console\n }\n\n async close(): Promise<void> {\n // No-op for console\n }\n\n /**\n * Format entry in compact single-line format\n */\n private formatCompact(entry: AuditLogEntry): string {\n const parts: string[] = []\n\n // Timestamp\n if (this.showTimestamp) {\n const ts = entry.timestamp.toISOString()\n parts.push(this.color(ts, 'timestamp'))\n }\n\n // Level\n parts.push(this.colorLevel(entry.level))\n\n if (entry.type === 'request') {\n // Request log\n const req = entry.request\n const res = entry.response\n\n // Method and path\n parts.push(this.color(req.method, 'method'))\n parts.push(req.path)\n\n // Status and duration\n if (res) {\n parts.push(this.colorStatus(res.status))\n parts.push(this.color(`${res.duration}ms`, 'dim'))\n }\n\n // IP\n if (req.ip) {\n parts.push(this.color(`[${req.ip}]`, 'dim'))\n }\n\n // User\n if (entry.user?.id) {\n parts.push(this.color(`user:${entry.user.id}`, 'dim'))\n }\n\n // Error\n if (entry.error) {\n parts.push(this.color(`ERROR: ${entry.error.message}`, 'error'))\n }\n } else if (entry.type === 'security') {\n // Security event\n parts.push(this.colorSeverity(entry.severity))\n parts.push(entry.event)\n\n if (entry.source.ip) {\n parts.push(this.color(`[${entry.source.ip}]`, 'dim'))\n }\n\n if (entry.source.userId) {\n parts.push(this.color(`user:${entry.source.userId}`, 'dim'))\n }\n\n parts.push(entry.message)\n }\n\n return parts.join(' ')\n }\n\n /**\n * Format entry in pretty multi-line format\n */\n private formatPretty(entry: AuditLogEntry): string {\n const lines: string[] = []\n\n // Header\n const header = [\n this.color(entry.timestamp.toISOString(), 'timestamp'),\n this.colorLevel(entry.level),\n `[${entry.type.toUpperCase()}]`,\n ].join(' ')\n\n lines.push(header)\n\n if (entry.type === 'request') {\n const req = entry.request\n const res = entry.response\n\n // Request line\n lines.push(` ${this.color(req.method, 'method')} ${req.url}`)\n\n // Request details\n if (req.ip) lines.push(` IP: ${req.ip}`)\n if (req.userAgent) lines.push(` UA: ${req.userAgent}`)\n\n // Response\n if (res) {\n lines.push(` Status: ${this.colorStatus(res.status)} (${res.duration}ms)`)\n }\n\n // User\n if (entry.user) {\n lines.push(` User: ${JSON.stringify(entry.user)}`)\n }\n\n // Error\n if (entry.error) {\n lines.push(` ${this.color('Error:', 'error')} ${entry.error.message}`)\n if (entry.error.stack) {\n lines.push(` ${this.color(entry.error.stack, 'dim')}`)\n }\n }\n } else if (entry.type === 'security') {\n lines.push(` Event: ${entry.event}`)\n lines.push(` Severity: ${this.colorSeverity(entry.severity)}`)\n lines.push(` Message: ${entry.message}`)\n\n if (entry.source.ip) lines.push(` Source IP: ${entry.source.ip}`)\n if (entry.source.userId) lines.push(` Source User: ${entry.source.userId}`)\n\n if (entry.target) {\n lines.push(` Target: ${JSON.stringify(entry.target)}`)\n }\n\n if (entry.details) {\n lines.push(` Details: ${JSON.stringify(entry.details)}`)\n }\n }\n\n // Metadata\n if (entry.metadata && Object.keys(entry.metadata).length > 0) {\n lines.push(` Metadata: ${JSON.stringify(entry.metadata)}`)\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Apply color if enabled\n */\n private color(text: string, colorName: keyof typeof COLORS): string {\n if (!this.colorize) return text\n return `${COLORS[colorName]}${text}${COLORS.reset}`\n }\n\n /**\n * Color log level\n */\n private colorLevel(level: LogLevel): string {\n const text = level.toUpperCase().padEnd(8)\n if (!this.colorize) return `[${text}]`\n return `[${COLORS[level]}${text}${COLORS.reset}]`\n }\n\n /**\n * Color HTTP status\n */\n private colorStatus(status: number): string {\n const text = status.toString()\n if (!this.colorize) return text\n\n if (status >= 500) return `${COLORS.status5xx}${text}${COLORS.reset}`\n if (status >= 400) return `${COLORS.status4xx}${text}${COLORS.reset}`\n if (status >= 300) return `${COLORS.status3xx}${text}${COLORS.reset}`\n return `${COLORS.status2xx}${text}${COLORS.reset}`\n }\n\n /**\n * Color severity\n */\n private colorSeverity(severity: 'low' | 'medium' | 'high' | 'critical'): string {\n const text = `[${severity.toUpperCase()}]`\n if (!this.colorize) return text\n\n const colorKey = severity === 'critical' ? 'critical' : severity\n return `${COLORS[colorKey]}${text}${COLORS.reset}`\n }\n}\n\n/**\n * Create a console store\n */\nexport function createConsoleStore(options?: ConsoleStoreOptions): ConsoleStore {\n return new ConsoleStore(options)\n}\n","import type { LogStore, AuditLogEntry, ExternalStoreOptions } from '../types'\n\n/**\n * External HTTP log store\n * Sends logs to external services (Datadog, Sentry, custom endpoints)\n */\nexport class ExternalStore implements LogStore {\n private readonly endpoint: string\n private readonly headers: Record<string, string>\n private readonly batchSize: number\n private readonly flushInterval: number\n private readonly retryAttempts: number\n private readonly timeout: number\n\n private buffer: AuditLogEntry[] = []\n private flushTimer: ReturnType<typeof setInterval> | null = null\n private isFlushing = false\n\n constructor(options: ExternalStoreOptions) {\n this.endpoint = options.endpoint\n this.headers = {\n 'Content-Type': 'application/json',\n ...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}),\n ...options.headers,\n }\n this.batchSize = options.batchSize || 100\n this.flushInterval = options.flushInterval || 5000 // 5 seconds\n this.retryAttempts = options.retryAttempts || 3\n this.timeout = options.timeout || 10000 // 10 seconds\n\n // Start auto-flush timer\n if (this.flushInterval > 0) {\n this.flushTimer = setInterval(() => this.flush(), this.flushInterval)\n }\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n this.buffer.push(entry)\n\n // Flush if batch size reached\n if (this.buffer.length >= this.batchSize) {\n await this.flush()\n }\n }\n\n async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) return\n\n this.isFlushing = true\n const entries = [...this.buffer]\n this.buffer = []\n\n try {\n await this.send(entries)\n } catch (error) {\n // Put entries back in buffer on failure\n this.buffer = [...entries, ...this.buffer]\n console.error('[ExternalStore] Failed to flush logs:', error)\n } finally {\n this.isFlushing = false\n }\n }\n\n async close(): Promise<void> {\n // Clear timer\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n\n // Final flush\n await this.flush()\n }\n\n /**\n * Send entries to external endpoint\n */\n private async send(entries: AuditLogEntry[]): Promise<void> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < this.retryAttempts; attempt++) {\n try {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.timeout)\n\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({\n logs: entries.map(e => this.serialize(e)),\n timestamp: new Date().toISOString(),\n count: entries.length,\n }),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n return // Success\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // Wait before retry (exponential backoff)\n if (attempt < this.retryAttempts - 1) {\n await this.sleep(Math.pow(2, attempt) * 1000)\n }\n }\n }\n\n throw lastError || new Error('Failed to send logs')\n }\n\n /**\n * Serialize entry for transmission\n */\n private serialize(entry: AuditLogEntry): Record<string, unknown> {\n return {\n ...entry,\n timestamp: entry.timestamp.toISOString(),\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n /**\n * Get buffer size (for monitoring)\n */\n getBufferSize(): number {\n return this.buffer.length\n }\n}\n\n/**\n * Create an external store\n */\nexport function createExternalStore(options: ExternalStoreOptions): ExternalStore {\n return new ExternalStore(options)\n}\n\n/**\n * Create a Datadog store\n */\nexport function createDatadogStore(options: {\n apiKey: string\n site?: 'datadoghq.com' | 'datadoghq.eu' | 'us3.datadoghq.com' | 'us5.datadoghq.com'\n service?: string\n source?: string\n tags?: string[]\n batchSize?: number\n flushInterval?: number\n}): ExternalStore {\n const site = options.site || 'datadoghq.com'\n const endpoint = `https://http-intake.logs.${site}/api/v2/logs`\n\n return new ExternalStore({\n endpoint,\n headers: {\n 'DD-API-KEY': options.apiKey,\n 'Content-Type': 'application/json',\n },\n batchSize: options.batchSize || 100,\n flushInterval: options.flushInterval || 5000,\n })\n}\n\n/**\n * Create a multi-store that writes to multiple stores\n */\nexport class MultiStore implements LogStore {\n private stores: LogStore[]\n\n constructor(stores: LogStore[]) {\n this.stores = stores\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n await Promise.all(this.stores.map(store => store.write(entry)))\n }\n\n async query(options: Parameters<NonNullable<LogStore['query']>>[0]): Promise<AuditLogEntry[]> {\n // Query from first store that supports it\n for (const store of this.stores) {\n if (store.query) {\n return store.query(options)\n }\n }\n return []\n }\n\n async flush(): Promise<void> {\n await Promise.all(this.stores.map(store => store.flush?.()))\n }\n\n async close(): Promise<void> {\n await Promise.all(this.stores.map(store => store.close?.()))\n }\n}\n\n/**\n * Create a multi-store\n */\nexport function createMultiStore(stores: LogStore[]): MultiStore {\n return new MultiStore(stores)\n}\n","import type { LogFormatter, AuditLogEntry } from './types'\n\n/**\n * JSON formatter - outputs logs as JSON strings\n */\nexport class JSONFormatter implements LogFormatter {\n private readonly pretty: boolean\n private readonly includeTimestamp: boolean\n\n constructor(options: { pretty?: boolean; includeTimestamp?: boolean } = {}) {\n this.pretty = options.pretty ?? false\n this.includeTimestamp = options.includeTimestamp ?? true\n }\n\n format(entry: AuditLogEntry): string {\n const output = {\n ...entry,\n timestamp: this.includeTimestamp ? entry.timestamp.toISOString() : undefined,\n }\n\n return this.pretty\n ? JSON.stringify(output, null, 2)\n : JSON.stringify(output)\n }\n}\n\n/**\n * Text formatter - outputs logs as human-readable text\n */\nexport class TextFormatter implements LogFormatter {\n private readonly template: string\n private readonly dateFormat: 'iso' | 'utc' | 'local'\n\n constructor(options: {\n template?: string\n dateFormat?: 'iso' | 'utc' | 'local'\n } = {}) {\n this.template = options.template || '{timestamp} [{level}] {message}'\n this.dateFormat = options.dateFormat || 'iso'\n }\n\n format(entry: AuditLogEntry): string {\n let output = this.template\n\n // Replace placeholders\n output = output.replace('{timestamp}', this.formatDate(entry.timestamp))\n output = output.replace('{level}', entry.level.toUpperCase().padEnd(8))\n output = output.replace('{message}', entry.message)\n output = output.replace('{type}', entry.type)\n output = output.replace('{id}', entry.id)\n\n if (entry.category) {\n output = output.replace('{category}', entry.category)\n }\n\n // Request-specific\n if (entry.type === 'request') {\n output = output.replace('{method}', entry.request.method)\n output = output.replace('{path}', entry.request.path)\n output = output.replace('{url}', entry.request.url)\n output = output.replace('{ip}', entry.request.ip || '-')\n output = output.replace('{status}', entry.response?.status?.toString() || '-')\n output = output.replace('{duration}', entry.response?.duration?.toString() || '-')\n }\n\n // Security-specific\n if (entry.type === 'security') {\n output = output.replace('{event}', entry.event)\n output = output.replace('{severity}', entry.severity)\n }\n\n return output\n }\n\n private formatDate(date: Date): string {\n switch (this.dateFormat) {\n case 'utc':\n return date.toUTCString()\n case 'local':\n return date.toLocaleString()\n case 'iso':\n default:\n return date.toISOString()\n }\n }\n}\n\n/**\n * CLF (Common Log Format) formatter\n * Apache/Nginx style: host ident authuser date request status bytes\n */\nexport class CLFFormatter implements LogFormatter {\n format(entry: AuditLogEntry): string {\n if (entry.type !== 'request') {\n // Fall back to simple format for non-request entries\n return `[${entry.timestamp.toISOString()}] ${entry.level.toUpperCase()} ${entry.message}`\n }\n\n const req = entry.request\n const res = entry.response\n\n const host = req.ip || '-'\n const ident = '-'\n const authuser = entry.user?.id || '-'\n const date = this.formatCLFDate(entry.timestamp)\n const request = `${req.method} ${req.path} HTTP/1.1`\n const status = res?.status || 0\n const bytes = res?.contentLength || 0\n\n return `${host} ${ident} ${authuser} [${date}] \"${request}\" ${status} ${bytes}`\n }\n\n private formatCLFDate(date: Date): string {\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n\n const day = date.getDate().toString().padStart(2, '0')\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n const hours = date.getHours().toString().padStart(2, '0')\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n\n const offset = -date.getTimezoneOffset()\n const offsetSign = offset >= 0 ? '+' : '-'\n const offsetHours = Math.floor(Math.abs(offset) / 60).toString().padStart(2, '0')\n const offsetMins = (Math.abs(offset) % 60).toString().padStart(2, '0')\n\n return `${day}/${month}/${year}:${hours}:${minutes}:${seconds} ${offsetSign}${offsetHours}${offsetMins}`\n }\n}\n\n/**\n * Structured formatter for ELK/Splunk\n * Outputs key=value pairs\n */\nexport class StructuredFormatter implements LogFormatter {\n private readonly delimiter: string\n private readonly kvSeparator: string\n\n constructor(options: { delimiter?: string; kvSeparator?: string } = {}) {\n this.delimiter = options.delimiter || ' '\n this.kvSeparator = options.kvSeparator || '='\n }\n\n format(entry: AuditLogEntry): string {\n const pairs: string[] = []\n\n pairs.push(this.pair('timestamp', entry.timestamp.toISOString()))\n pairs.push(this.pair('level', entry.level))\n pairs.push(this.pair('type', entry.type))\n pairs.push(this.pair('id', entry.id))\n pairs.push(this.pair('message', this.escape(entry.message)))\n\n if (entry.category) {\n pairs.push(this.pair('category', entry.category))\n }\n\n if (entry.type === 'request') {\n pairs.push(this.pair('method', entry.request.method))\n pairs.push(this.pair('path', entry.request.path))\n if (entry.request.ip) pairs.push(this.pair('ip', entry.request.ip))\n if (entry.response) {\n pairs.push(this.pair('status', entry.response.status.toString()))\n pairs.push(this.pair('duration_ms', entry.response.duration.toString()))\n }\n if (entry.user?.id) pairs.push(this.pair('user_id', entry.user.id))\n if (entry.error) {\n pairs.push(this.pair('error', this.escape(entry.error.message)))\n }\n }\n\n if (entry.type === 'security') {\n pairs.push(this.pair('event', entry.event))\n pairs.push(this.pair('severity', entry.severity))\n if (entry.source.ip) pairs.push(this.pair('source_ip', entry.source.ip))\n if (entry.source.userId) pairs.push(this.pair('source_user', entry.source.userId))\n }\n\n return pairs.join(this.delimiter)\n }\n\n private pair(key: string, value: string): string {\n return `${key}${this.kvSeparator}${value}`\n }\n\n private escape(value: string): string {\n // Escape quotes and wrap in quotes if contains spaces\n if (value.includes(' ') || value.includes('\"')) {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`\n }\n return value\n }\n}\n\n/**\n * Create a JSON formatter\n */\nexport function createJSONFormatter(options?: { pretty?: boolean }): JSONFormatter {\n return new JSONFormatter(options)\n}\n\n/**\n * Create a text formatter\n */\nexport function createTextFormatter(options?: {\n template?: string\n dateFormat?: 'iso' | 'utc' | 'local'\n}): TextFormatter {\n return new TextFormatter(options)\n}\n\n/**\n * Create a CLF formatter\n */\nexport function createCLFFormatter(): CLFFormatter {\n return new CLFFormatter()\n}\n\n/**\n * Create a structured formatter\n */\nexport function createStructuredFormatter(options?: {\n delimiter?: string\n kvSeparator?: string\n}): StructuredFormatter {\n return new StructuredFormatter(options)\n}\n","import type { PIIConfig } from './types'\n\n/**\n * Default PII fields to redact\n */\nexport const DEFAULT_PII_FIELDS = [\n // Authentication\n 'password',\n 'passwd',\n 'secret',\n 'token',\n 'api_key',\n 'apiKey',\n 'api-key',\n 'access_token',\n 'accessToken',\n 'refresh_token',\n 'refreshToken',\n 'authorization',\n 'auth',\n\n // Personal information\n 'ssn',\n 'social_security',\n 'socialSecurity',\n 'credit_card',\n 'creditCard',\n 'card_number',\n 'cardNumber',\n 'cvv',\n 'cvc',\n 'pin',\n\n // Contact\n 'email',\n 'phone',\n 'phone_number',\n 'phoneNumber',\n 'mobile',\n 'address',\n 'street',\n 'zip',\n 'zipcode',\n 'postal_code',\n 'postalCode',\n\n // Identity\n 'date_of_birth',\n 'dateOfBirth',\n 'dob',\n 'birth_date',\n 'birthDate',\n 'passport',\n 'license',\n 'national_id',\n 'nationalId',\n]\n\n/**\n * Mask a value with asterisks\n */\nexport function mask(\n value: string,\n options: {\n char?: string\n preserveLength?: boolean\n showFirst?: number\n showLast?: number\n } = {}\n): string {\n const {\n char = '*',\n preserveLength = false,\n showFirst = 0,\n showLast = 0,\n } = options\n\n if (!value) return value\n\n const len = value.length\n\n if (preserveLength) {\n const first = value.slice(0, showFirst)\n const last = value.slice(-showLast || len)\n const middle = char.repeat(Math.max(0, len - showFirst - showLast))\n return first + middle + (showLast > 0 ? last : '')\n }\n\n // Default: show first/last chars with fixed mask\n const maskLen = 8\n const first = showFirst > 0 ? value.slice(0, showFirst) : ''\n const last = showLast > 0 ? value.slice(-showLast) : ''\n\n return first + char.repeat(maskLen) + last\n}\n\n/**\n * Simple hash function for Edge Runtime compatibility\n * Uses a fast, deterministic string hash (not cryptographic)\n */\nexport function hash(value: string, salt = ''): string {\n const str = salt + value\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32bit integer\n }\n // Convert to hex and ensure positive, pad to 16 chars\n const hex = Math.abs(hash).toString(16).padStart(8, '0')\n return hex + hex.slice(0, 8) // Return 16 char string\n}\n\n/**\n * Redact a single value\n */\nexport function redactValue(\n value: unknown,\n field: string,\n config: PIIConfig\n): unknown {\n if (typeof value !== 'string') return value\n if (!value) return value\n\n // Check if field should be redacted\n const shouldRedact = config.fields.some(f => {\n const fieldLower = field.toLowerCase()\n const fLower = f.toLowerCase()\n return fieldLower === fLower ||\n fieldLower.endsWith('.' + fLower) ||\n fieldLower.includes('[' + fLower + ']')\n })\n\n if (!shouldRedact) return value\n\n // Apply custom redactor if provided\n if (config.customRedactor) {\n return config.customRedactor(value, field)\n }\n\n // Apply redaction based on mode\n switch (config.mode) {\n case 'mask':\n return mask(value, {\n char: config.maskChar || '*',\n preserveLength: config.preserveLength,\n showFirst: 2,\n showLast: 2,\n })\n\n case 'hash':\n return `[HASH:${hash(value)}]`\n\n case 'remove':\n return '[REDACTED]'\n\n default:\n return '[REDACTED]'\n }\n}\n\n/**\n * Redact PII from an object recursively\n */\nexport function redactObject<T>(obj: T, config: PIIConfig, path = ''): T {\n if (typeof obj === 'string') {\n return redactValue(obj, path, config) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, i) => redactObject(item, config, `${path}[${i}]`)) as T\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n const newPath = path ? `${path}.${key}` : key\n result[key] = redactObject(value, config, newPath)\n }\n\n return result as T\n }\n\n return obj\n}\n\n/**\n * Create a redactor function with preset config\n */\nexport function createRedactor(config: Partial<PIIConfig> = {}): <T>(obj: T) => T {\n const fullConfig: PIIConfig = {\n fields: config.fields || DEFAULT_PII_FIELDS,\n mode: config.mode || 'mask',\n maskChar: config.maskChar || '*',\n preserveLength: config.preserveLength || false,\n customRedactor: config.customRedactor,\n }\n\n return <T>(obj: T) => redactObject(obj, fullConfig)\n}\n\n/**\n * Redact sensitive headers\n */\nexport function redactHeaders(\n headers: Record<string, string>,\n sensitiveHeaders: string[] = ['authorization', 'cookie', 'x-api-key', 'x-auth-token']\n): Record<string, string> {\n const result: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n const keyLower = key.toLowerCase()\n if (sensitiveHeaders.some(h => keyLower === h.toLowerCase())) {\n result[key] = '[REDACTED]'\n } else {\n result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Redact query parameters\n */\nexport function redactQuery(\n query: Record<string, string>,\n sensitiveParams: string[] = ['token', 'key', 'secret', 'password', 'auth']\n): Record<string, string> {\n const result: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(query)) {\n const keyLower = key.toLowerCase()\n if (sensitiveParams.some(p => keyLower.includes(p.toLowerCase()))) {\n result[key] = '[REDACTED]'\n } else {\n result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Redact email (show only domain)\n */\nexport function redactEmail(email: string): string {\n if (!email || !email.includes('@')) return mask(email)\n\n const [, domain] = email.split('@')\n return `****@${domain}`\n}\n\n/**\n * Redact credit card number (show last 4 digits)\n */\nexport function redactCreditCard(cardNumber: string): string {\n const cleaned = cardNumber.replace(/\\D/g, '')\n if (cleaned.length < 4) return mask(cardNumber)\n\n return '**** **** **** ' + cleaned.slice(-4)\n}\n\n/**\n * Redact phone number\n */\nexport function redactPhone(phone: string): string {\n const cleaned = phone.replace(/\\D/g, '')\n if (cleaned.length < 4) return mask(phone)\n\n return mask(phone, { preserveLength: true, showLast: 4 })\n}\n\n/**\n * Redact IP address (show only first two octets for IPv4)\n */\nexport function redactIP(ip: string): string {\n if (ip.includes(':')) {\n // IPv6 - show first segment\n const parts = ip.split(':')\n return parts[0] + ':****:****:****'\n }\n\n // IPv4 - show first two octets\n const parts = ip.split('.')\n if (parts.length !== 4) return mask(ip)\n\n return `${parts[0]}.${parts[1]}.*.*`\n}\n","import type {\n SecurityEventEntry,\n SecurityEventType,\n SecurityEventConfig,\n LogStore,\n LogLevel,\n} from './types'\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n return `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Map severity to log level\n */\nfunction severityToLevel(severity: 'low' | 'medium' | 'high' | 'critical'): LogLevel {\n switch (severity) {\n case 'low': return 'info'\n case 'medium': return 'warn'\n case 'high': return 'error'\n case 'critical': return 'critical'\n }\n}\n\n/**\n * Security event tracker\n */\nexport class SecurityEventTracker {\n private store: LogStore\n private defaultSeverity: 'low' | 'medium' | 'high' | 'critical'\n private onEvent?: (event: SecurityEventEntry) => void | Promise<void>\n\n constructor(config: SecurityEventConfig) {\n this.store = config.store\n this.defaultSeverity = config.defaultSeverity || 'medium'\n this.onEvent = config.onEvent\n }\n\n /**\n * Track a security event\n */\n async track(options: {\n event: SecurityEventType\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n userId?: string\n }\n details?: Record<string, unknown>\n mitigated?: boolean\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n const severity = options.severity || this.defaultSeverity\n\n const entry: SecurityEventEntry = {\n id: generateId(),\n timestamp: new Date(),\n type: 'security',\n level: severityToLevel(severity),\n message: options.message,\n event: options.event,\n severity,\n source: options.source || {},\n target: options.target,\n details: options.details,\n mitigated: options.mitigated,\n metadata: options.metadata,\n }\n\n // Write to store\n await this.store.write(entry)\n\n // Call event handler\n if (this.onEvent) {\n await this.onEvent(entry)\n }\n\n return entry\n }\n\n // Convenience methods for common events\n\n /**\n * Track failed authentication\n */\n async authFailed(options: {\n ip?: string\n userAgent?: string\n email?: string\n reason?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.failed',\n message: options.reason || 'Authentication failed',\n severity: 'medium',\n source: {\n ip: options.ip,\n userAgent: options.userAgent,\n },\n details: {\n attemptedEmail: options.email,\n reason: options.reason,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track successful login\n */\n async authLogin(options: {\n userId: string\n ip?: string\n userAgent?: string\n method?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.login',\n message: `User ${options.userId} logged in`,\n severity: 'low',\n source: {\n ip: options.ip,\n userAgent: options.userAgent,\n userId: options.userId,\n },\n details: {\n method: options.method || 'credentials',\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track logout\n */\n async authLogout(options: {\n userId: string\n ip?: string\n reason?: 'user' | 'timeout' | 'forced'\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.logout',\n message: `User ${options.userId} logged out`,\n severity: 'low',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n details: {\n reason: options.reason || 'user',\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track permission denied\n */\n async permissionDenied(options: {\n userId?: string\n ip?: string\n resource: string\n action: string\n requiredRole?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.permission_denied',\n message: `Permission denied for ${options.action} on ${options.resource}`,\n severity: 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.resource,\n action: options.action,\n },\n details: {\n requiredRole: options.requiredRole,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track rate limit exceeded\n */\n async rateLimitExceeded(options: {\n ip?: string\n userId?: string\n endpoint: string\n limit: number\n window: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ratelimit.exceeded',\n message: `Rate limit exceeded for ${options.endpoint}`,\n severity: 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n limit: options.limit,\n window: options.window,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track CSRF validation failure\n */\n async csrfInvalid(options: {\n ip?: string\n userId?: string\n endpoint: string\n reason?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'csrf.invalid',\n message: `CSRF validation failed for ${options.endpoint}`,\n severity: 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n reason: options.reason,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track XSS detection\n */\n async xssDetected(options: {\n ip?: string\n userId?: string\n field: string\n payload?: string\n endpoint: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'xss.detected',\n message: `XSS payload detected in ${options.field}`,\n severity: 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n field: options.field,\n payload: options.payload?.slice(0, 100), // Truncate\n },\n mitigated: true,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track SQL injection detection\n */\n async sqliDetected(options: {\n ip?: string\n userId?: string\n field: string\n pattern: string\n severity?: 'low' | 'medium' | 'high'\n endpoint: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'sqli.detected',\n message: `SQL injection attempt detected in ${options.field}`,\n severity: options.severity || 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n field: options.field,\n pattern: options.pattern,\n },\n mitigated: true,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track IP block\n */\n async ipBlocked(options: {\n ip: string\n reason: string\n duration?: number\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ip.blocked',\n message: `IP ${options.ip} blocked: ${options.reason}`,\n severity: 'high',\n source: {\n ip: options.ip,\n },\n details: {\n reason: options.reason,\n duration: options.duration,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track suspicious activity\n */\n async suspicious(options: {\n ip?: string\n userId?: string\n activity: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ip.suspicious',\n message: options.activity,\n severity: options.severity || 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n details: options.details,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track custom event\n */\n async custom(options: {\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n }\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'custom',\n ...options,\n })\n }\n}\n\n/**\n * Create a security event tracker\n */\nexport function createSecurityTracker(config: SecurityEventConfig): SecurityEventTracker {\n return new SecurityEventTracker(config)\n}\n\n/**\n * Standalone function to track security events\n */\nexport async function trackSecurityEvent(\n store: LogStore,\n options: {\n event: SecurityEventType\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n userId?: string\n }\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }\n): Promise<SecurityEventEntry> {\n const tracker = new SecurityEventTracker({ store })\n return tracker.track(options)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n AuditConfig,\n RequestLogEntry,\n LogLevel,\n PIIConfig,\n} from './types'\nimport { redactObject, redactHeaders, redactQuery, DEFAULT_PII_FIELDS } from './redaction'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\n/**\n * Generate unique request ID\n */\nfunction generateRequestId(): string {\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string | undefined {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n undefined\n )\n}\n\n/**\n * Convert headers to record\n */\nfunction headersToRecord(headers: Headers, includeHeaders?: boolean | string[]): Record<string, string> {\n if (!includeHeaders) return {}\n\n const result: Record<string, string> = {}\n\n if (includeHeaders === true) {\n headers.forEach((value, key) => {\n result[key] = value\n })\n } else if (Array.isArray(includeHeaders)) {\n for (const key of includeHeaders) {\n const value = headers.get(key)\n if (value) result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Parse query parameters from URL\n */\nfunction parseQuery(url: string): Record<string, string> {\n const result: Record<string, string> = {}\n\n try {\n const urlObj = new URL(url)\n urlObj.searchParams.forEach((value, key) => {\n result[key] = value\n })\n } catch {\n // Invalid URL\n }\n\n return result\n}\n\n/**\n * Determine log level from status code\n */\nfunction statusToLevel(status: number): LogLevel {\n if (status >= 500) return 'error'\n if (status >= 400) return 'warn'\n return 'info'\n}\n\n/**\n * Should skip logging for this request\n */\nfunction shouldSkip(\n req: NextRequest,\n status: number,\n exclude?: AuditConfig['exclude']\n): boolean {\n if (!exclude) return false\n\n const url = new URL(req.url)\n\n // Check path\n if (exclude.paths?.length) {\n const matchesPath = exclude.paths.some(pattern => {\n if (pattern.includes('*')) {\n const regex = new RegExp('^' + pattern.replace(/\\*/g, '.*') + '$')\n return regex.test(url.pathname)\n }\n return url.pathname === pattern || url.pathname.startsWith(pattern)\n })\n if (matchesPath) return true\n }\n\n // Check method\n if (exclude.methods?.includes(req.method)) {\n return true\n }\n\n // Check status code\n if (exclude.statusCodes?.includes(status)) {\n return true\n }\n\n return false\n}\n\n/**\n * Audit logging middleware\n */\nexport function withAuditLog(\n handler: RouteHandler,\n config: AuditConfig\n): RouteHandler {\n const {\n enabled = true,\n store,\n include = {},\n exclude,\n pii,\n getUser,\n requestIdHeader = 'x-request-id',\n generateRequestId: customGenerateId,\n onError,\n skip,\n } = config\n\n // Default include settings\n const includeSettings = {\n ip: include.ip ?? true,\n userAgent: include.userAgent ?? true,\n headers: include.headers ?? false,\n query: include.query ?? true,\n body: include.body ?? false,\n response: include.response ?? true,\n responseBody: include.responseBody ?? false,\n duration: include.duration ?? true,\n user: include.user ?? true,\n }\n\n // PII config\n const piiConfig: PIIConfig = pii || {\n fields: DEFAULT_PII_FIELDS,\n mode: 'mask',\n }\n\n return async (req: NextRequest): Promise<Response> => {\n // Check if logging is enabled\n if (!enabled) {\n return handler(req)\n }\n\n // Check skip condition\n if (skip && await skip(req)) {\n return handler(req)\n }\n\n const startTime = Date.now()\n const requestId = req.headers.get(requestIdHeader) ||\n (customGenerateId ? customGenerateId() : generateRequestId())\n\n const url = new URL(req.url)\n\n // Build request info\n let requestInfo: RequestLogEntry['request'] = {\n id: requestId,\n method: req.method,\n url: req.url,\n path: url.pathname,\n }\n\n if (includeSettings.ip) {\n requestInfo.ip = getClientIP(req)\n }\n\n if (includeSettings.userAgent) {\n requestInfo.userAgent = req.headers.get('user-agent') || undefined\n }\n\n if (includeSettings.headers) {\n let headers = headersToRecord(req.headers, includeSettings.headers)\n headers = redactHeaders(headers)\n requestInfo.headers = headers\n }\n\n if (includeSettings.query) {\n let query = parseQuery(req.url)\n query = redactQuery(query)\n requestInfo.query = query\n }\n\n requestInfo.contentType = req.headers.get('content-type') || undefined\n requestInfo.contentLength = parseInt(req.headers.get('content-length') || '0', 10) || undefined\n\n // Get user if configured\n let user: RequestLogEntry['user']\n if (includeSettings.user && getUser) {\n try {\n user = await getUser(req) || undefined\n } catch {\n // Ignore user extraction errors\n }\n }\n\n // Execute handler\n let response: Response\n let error: Error | undefined\n\n try {\n response = await handler(req)\n } catch (err) {\n error = err instanceof Error ? err : new Error(String(err))\n // Re-throw to let error propagate\n throw err\n } finally {\n const duration = Date.now() - startTime\n const status = response!?.status || 500\n\n // Check if we should skip this request\n if (!shouldSkip(req, status, exclude)) {\n // Build log entry\n const entry: RequestLogEntry = {\n id: requestId,\n timestamp: new Date(),\n type: 'request',\n level: error ? 'error' : statusToLevel(status),\n message: `${req.method} ${url.pathname} ${status} ${duration}ms`,\n request: requestInfo,\n user,\n }\n\n // Add response info\n if (includeSettings.response && response!) {\n entry.response = {\n status: response.status,\n duration,\n }\n\n if (includeSettings.headers) {\n entry.response.headers = headersToRecord(response.headers, includeSettings.headers)\n }\n }\n\n // Add error info\n if (error) {\n entry.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n }\n\n // Redact PII\n const redactedEntry = redactObject(entry, piiConfig)\n\n // Write to store\n try {\n await store.write(redactedEntry)\n } catch (writeError) {\n if (onError) {\n onError(writeError instanceof Error ? writeError : new Error(String(writeError)), entry)\n } else {\n console.error('[AuditLog] Failed to write log:', writeError)\n }\n }\n }\n }\n\n return response!\n }\n}\n\n/**\n * Create audit middleware with default console logging\n */\nexport function createAuditMiddleware(\n config: Partial<AuditConfig> & { store: AuditConfig['store'] }\n): (handler: RouteHandler) => RouteHandler {\n return (handler: RouteHandler) => withAuditLog(handler, config as AuditConfig)\n}\n\n/**\n * Request logger that adds request ID to response headers\n */\nexport function withRequestId(\n handler: RouteHandler,\n options: {\n headerName?: string\n generateId?: () => string\n } = {}\n): RouteHandler {\n const { headerName = 'x-request-id', generateId = generateRequestId } = options\n\n return async (req: NextRequest): Promise<Response> => {\n const requestId = req.headers.get(headerName) || generateId()\n\n const response = await handler(req)\n\n // Clone response to add header\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n newResponse.headers.set(headerName, requestId)\n\n return newResponse\n }\n}\n\n/**\n * Simple request timing middleware\n */\nexport function withTiming(\n handler: RouteHandler,\n options: {\n headerName?: string\n log?: boolean\n } = {}\n): RouteHandler {\n const { headerName = 'x-response-time', log = false } = options\n\n return async (req: NextRequest): Promise<Response> => {\n const start = Date.now()\n\n const response = await handler(req)\n\n const duration = Date.now() - start\n\n // Clone response to add header\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n newResponse.headers.set(headerName, `${duration}ms`)\n\n if (log) {\n const url = new URL(req.url)\n console.log(`${req.method} ${url.pathname} ${response.status} ${duration}ms`)\n }\n\n return newResponse\n }\n}\n","/**\n * next-secure\n *\n * Production-ready security middleware for Next.js 13+ App Router.\n *\n * @example\n * ```typescript\n * import { withRateLimit, withAuth, secure } from 'next-secure'\n *\n * // Simple rate limiting\n * export const GET = withRateLimit(\n * async (req) => Response.json({ ok: true }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // Builder pattern\n * export const POST = secure()\n * .rateLimit({ limit: 10, window: '1m' })\n * .auth({ roles: ['admin'] })\n * .handle(async (req, ctx) => {\n * return Response.json({ user: ctx.user })\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// Core\n// =============================================================================\n\nexport type {\n NextRequest,\n SecureContext,\n SecureHandler,\n Middleware,\n ErrorResponse,\n RateLimitInfo,\n Duration,\n RateLimitAlgorithm,\n RateLimitIdentifier,\n} from './core/types'\n\nexport {\n SecureError,\n RateLimitError,\n AuthenticationError,\n AuthorizationError,\n ValidationError,\n CsrfError,\n ConfigurationError,\n isSecureError,\n toSecureError,\n} from './core/errors'\n\n// =============================================================================\n// Rate Limiting\n// =============================================================================\n\nexport {\n withRateLimit,\n createRateLimiter,\n checkRateLimit,\n resetRateLimit,\n getRateLimitStatus,\n clearAllRateLimits,\n} from './middleware/rate-limit'\n\nexport type {\n RateLimitConfig,\n RateLimitStore,\n MemoryStoreOptions,\n RedisStoreOptions,\n UpstashStoreOptions,\n} from './middleware/rate-limit'\n\nexport {\n MemoryStore,\n createMemoryStore,\n getGlobalMemoryStore,\n} from './middleware/rate-limit'\n\n// =============================================================================\n// CSRF Protection\n// =============================================================================\n\nexport {\n withCSRF,\n generateCSRF,\n validateCSRF,\n createToken as createCSRFToken,\n verifyToken as verifyCSRFToken,\n tokensMatch,\n} from './middleware/csrf'\n\nexport type {\n CSRFConfig,\n CSRFCookieOptions,\n CSRFToken,\n} from './middleware/csrf'\n\n// =============================================================================\n// Security Headers\n// =============================================================================\n\nexport {\n withSecurityHeaders,\n createSecurityHeaders,\n createSecurityHeadersObject,\n buildCSP,\n buildHSTS,\n buildPermissionsPolicy,\n getPreset,\n PRESET_STRICT,\n PRESET_RELAXED,\n PRESET_API,\n} from './middleware/headers'\n\nexport type {\n ContentSecurityPolicy,\n StrictTransportSecurity,\n PermissionsPolicy,\n SecurityHeadersConfig,\n SecurityHeadersPreset,\n XFrameOptions,\n ReferrerPolicy,\n} from './middleware/headers'\n\n// =============================================================================\n// Authentication\n// =============================================================================\n\nexport {\n withJWT,\n withAPIKey,\n withSession,\n withAuth,\n withRoles,\n withOptionalAuth,\n verifyJWT,\n decodeJWT,\n extractBearerToken,\n} from './middleware/auth'\n\nexport type {\n AuthUser,\n AuthConfig,\n AuthError,\n AuthErrorCode,\n JWTConfig,\n JWTPayload,\n APIKeyConfig,\n SessionConfig,\n RBACConfig,\n} from './middleware/auth'\n\n// =============================================================================\n// Input Validation\n// =============================================================================\n\nexport {\n // Middleware\n withValidation,\n withSanitization,\n withXSSProtection,\n withSQLProtection,\n withContentType,\n withFileValidation,\n withSecureValidation,\n // Schema validation\n validate,\n validateBody,\n validateQuery,\n validateRequest,\n createValidator,\n // XSS\n sanitize,\n sanitizeObject,\n sanitizeFields,\n escapeHtml,\n stripHtml,\n detectXSS,\n // SQL\n detectSQLInjection,\n hasSQLInjection,\n sanitizeSQLInput,\n // Path\n validatePath,\n sanitizePath,\n hasPathTraversal,\n sanitizeFilename,\n // Content-Type\n validateContentType,\n isJsonRequest,\n isFormRequest,\n MIME_TYPES,\n // File\n validateFile,\n validateFiles,\n detectFileType,\n DANGEROUS_EXTENSIONS,\n} from './middleware/validation'\n\nexport type {\n ValidationError as InputValidationError,\n ValidationResult,\n ValidationConfig,\n ValidatedContext,\n SanitizeConfig,\n SanitizeMode,\n SQLDetection,\n SQLProtectionConfig,\n PathValidationConfig,\n PathValidationResult,\n ContentTypeConfig,\n FileValidationConfig,\n FileValidationError,\n FileInfo,\n FieldRule,\n FieldType,\n CustomSchema,\n} from './middleware/validation'\n\n// =============================================================================\n// Audit Logging\n// =============================================================================\n\nexport {\n // Middleware\n withAuditLog,\n createAuditMiddleware,\n withRequestId,\n withTiming,\n // Stores\n MemoryStore as AuditMemoryStore,\n createMemoryStore as createAuditMemoryStore,\n ConsoleStore,\n createConsoleStore,\n ExternalStore,\n createExternalStore,\n createDatadogStore,\n MultiStore,\n createMultiStore,\n // Formatters\n JSONFormatter,\n TextFormatter,\n CLFFormatter,\n StructuredFormatter,\n createJSONFormatter,\n createTextFormatter,\n createCLFFormatter,\n createStructuredFormatter,\n // Redaction\n DEFAULT_PII_FIELDS,\n mask,\n redactObject,\n createRedactor,\n redactHeaders,\n redactQuery,\n redactEmail,\n redactCreditCard,\n redactPhone,\n redactIP,\n // Security Events\n SecurityEventTracker,\n createSecurityTracker,\n trackSecurityEvent,\n} from './middleware/audit'\n\nexport type {\n LogLevel,\n SecurityEventType,\n LogEntry,\n RequestLogEntry,\n SecurityEventEntry,\n AuditLogEntry,\n LogStore,\n LogQueryOptions,\n LogFormatter,\n PIIConfig,\n AuditConfig,\n SecurityEventConfig,\n ConsoleStoreOptions,\n MemoryStoreOptions as AuditMemoryStoreOptions,\n ExternalStoreOptions,\n} from './middleware/audit'\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nexport {\n parseDuration,\n formatDuration,\n nowInSeconds,\n nowInMs,\n sleep,\n} from './utils/time'\n\nexport {\n getClientIp,\n normalizeIp,\n isValidIp,\n isPrivateIp,\n isLocalhost,\n anonymizeIp,\n getGeoInfo,\n} from './utils/ip'\n\n// =============================================================================\n// Version\n// =============================================================================\n\n/**\n * Package version\n */\nexport const VERSION = '0.6.0'\n"]}
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/utils/time.ts","../src/utils/ip.ts","../src/middleware/rate-limit/stores/memory.ts","../src/middleware/rate-limit/algorithms/sliding-window.ts","../src/middleware/rate-limit/algorithms/fixed-window.ts","../src/middleware/rate-limit/algorithms/token-bucket.ts","../src/middleware/rate-limit/middleware.ts","../src/middleware/csrf/token.ts","../src/middleware/csrf/middleware.ts","../src/middleware/headers/builder.ts","../src/middleware/headers/middleware.ts","../src/middleware/auth/jwt.ts","../src/middleware/auth/middleware.ts","../src/middleware/validation/utils.ts","../src/middleware/validation/validators/schema.ts","../src/middleware/validation/validators/content-type.ts","../src/middleware/validation/sanitizers/path.ts","../src/middleware/validation/validators/file.ts","../src/middleware/validation/sanitizers/xss.ts","../src/middleware/validation/sanitizers/sql.ts","../src/middleware/validation/middleware.ts","../src/middleware/audit/stores/memory.ts","../src/middleware/audit/stores/console.ts","../src/middleware/audit/stores/external.ts","../src/middleware/audit/formatters.ts","../src/middleware/audit/redaction.ts","../src/middleware/audit/events.ts","../src/middleware/audit/middleware.ts","../src/middleware/bot/user-agent.ts","../src/middleware/bot/honeypot.ts","../src/middleware/bot/behavior.ts","../src/middleware/bot/captcha.ts","../src/middleware/bot/middleware.ts","../src/index.ts"],"names":["shouldSkip","response","info","webcrypto","DEFAULT_CONFIG","encoder","hash","defaultErrorResponse","DANGEROUS_PATTERNS","MemoryStore","createMemoryStore","first","last","parts","generateId","validate","getClientIP","getIdentifier","hasBody","getRequestBody"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Custom error classes for next-secure\n */\n\n/**\n * Base error class for all next-secure errors\n */\nexport class SecureError extends Error {\n /**\n * HTTP status code\n */\n public readonly statusCode: number\n\n /**\n * Error code for programmatic handling\n */\n public readonly code: string\n\n /**\n * Additional error details\n */\n public readonly details?: Record<string, unknown>\n\n constructor(\n message: string,\n options: {\n statusCode?: number\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, { cause: options.cause })\n this.name = 'SecureError'\n this.statusCode = options.statusCode ?? 500\n this.code = options.code ?? 'SECURE_ERROR'\n this.details = options.details\n\n // Maintains proper stack trace for where error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n }\n\n /**\n * Convert error to JSON response\n */\n toJSON(): Record<string, unknown> {\n return {\n error: this.name,\n message: this.message,\n code: this.code,\n ...(this.details && { details: this.details }),\n }\n }\n\n /**\n * Create a Response object from this error\n */\n toResponse(headers?: HeadersInit): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n status: this.statusCode,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n })\n }\n}\n\n/**\n * Rate limit exceeded error\n */\nexport class RateLimitError extends SecureError {\n /**\n * Seconds until rate limit resets\n */\n public readonly retryAfter: number\n\n /**\n * Unix timestamp when limit resets\n */\n public readonly resetAt: number\n\n constructor(\n options: {\n retryAfter: number\n resetAt: number\n message?: string\n details?: Record<string, unknown>\n }\n ) {\n super(options.message ?? 'Too Many Requests', {\n statusCode: 429,\n code: 'RATE_LIMIT_EXCEEDED',\n details: options.details,\n })\n this.name = 'RateLimitError'\n this.retryAfter = options.retryAfter\n this.resetAt = options.resetAt\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n retryAfter: this.retryAfter,\n }\n }\n\n override toResponse(headers?: HeadersInit): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n status: this.statusCode,\n headers: {\n 'Content-Type': 'application/json',\n 'Retry-After': String(this.retryAfter),\n ...headers,\n },\n })\n }\n}\n\n/**\n * Authentication error\n */\nexport class AuthenticationError extends SecureError {\n constructor(\n message = 'Authentication required',\n options: {\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 401,\n code: options.code ?? 'AUTHENTICATION_REQUIRED',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'AuthenticationError'\n }\n}\n\n/**\n * Authorization error (authenticated but not permitted)\n */\nexport class AuthorizationError extends SecureError {\n constructor(\n message = 'Access denied',\n options: {\n code?: string\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 403,\n code: options.code ?? 'ACCESS_DENIED',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'AuthorizationError'\n }\n}\n\n/**\n * Validation error\n */\nexport class ValidationError extends SecureError {\n /**\n * Field-level validation errors\n */\n public readonly errors: Array<{\n field: string\n message: string\n code?: string\n }>\n\n constructor(\n errors: Array<{ field: string; message: string; code?: string }>,\n message = 'Validation failed'\n ) {\n super(message, {\n statusCode: 400,\n code: 'VALIDATION_ERROR',\n details: { errors },\n })\n this.name = 'ValidationError'\n this.errors = errors\n }\n\n override toJSON(): Record<string, unknown> {\n return {\n ...super.toJSON(),\n errors: this.errors,\n }\n }\n}\n\n/**\n * CSRF token error\n */\nexport class CsrfError extends SecureError {\n constructor(\n message = 'Invalid or missing CSRF token',\n options: {\n details?: Record<string, unknown>\n } = {}\n ) {\n super(message, {\n statusCode: 403,\n code: 'CSRF_TOKEN_INVALID',\n details: options.details,\n })\n this.name = 'CsrfError'\n }\n}\n\n/**\n * Configuration error\n */\nexport class ConfigurationError extends SecureError {\n constructor(\n message: string,\n options: {\n details?: Record<string, unknown>\n cause?: Error\n } = {}\n ) {\n super(message, {\n statusCode: 500,\n code: 'CONFIGURATION_ERROR',\n details: options.details,\n cause: options.cause,\n })\n this.name = 'ConfigurationError'\n }\n}\n\n/**\n * Check if an error is a SecureError\n */\nexport function isSecureError(error: unknown): error is SecureError {\n return error instanceof SecureError\n}\n\n/**\n * Convert unknown error to SecureError\n */\nexport function toSecureError(error: unknown): SecureError {\n if (error instanceof SecureError) {\n return error\n }\n\n if (error instanceof Error) {\n return new SecureError(error.message, {\n cause: error,\n })\n }\n\n return new SecureError(String(error))\n}\n","/**\n * Time parsing and manipulation utilities\n */\n\nimport type { Duration } from '../core/types'\n\n/**\n * Time unit multipliers in milliseconds\n */\nconst TIME_UNITS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n}\n\n/**\n * Extended time unit names\n */\nconst TIME_UNIT_ALIASES: Record<string, string> = {\n millisecond: 'ms',\n milliseconds: 'ms',\n second: 's',\n seconds: 's',\n sec: 's',\n secs: 's',\n minute: 'm',\n minutes: 'm',\n min: 'm',\n mins: 'm',\n hour: 'h',\n hours: 'h',\n hr: 'h',\n hrs: 'h',\n day: 'd',\n days: 'd',\n}\n\n/**\n * Parse a duration string or number to milliseconds\n *\n * @example\n * ```typescript\n * parseDuration('15m') // 900000 (15 minutes)\n * parseDuration('1h') // 3600000 (1 hour)\n * parseDuration('30s') // 30000 (30 seconds)\n * parseDuration('1d') // 86400000 (1 day)\n * parseDuration(60000) // 60000 (already in ms)\n * parseDuration('2 hours') // 7200000 (2 hours)\n * parseDuration('1h 30m') // 5400000 (1.5 hours)\n * ```\n *\n * @param duration - Duration string (e.g., '15m', '1h', '30s') or number in milliseconds\n * @returns Duration in milliseconds\n * @throws Error if the duration format is invalid\n */\nexport function parseDuration(duration: Duration | string): number {\n // If it's already a number, return as-is\n if (typeof duration === 'number') {\n if (duration < 0) {\n throw new Error(`Invalid duration: ${duration}. Duration must be non-negative.`)\n }\n return duration\n }\n\n // Trim and lowercase the string\n const input = duration.trim().toLowerCase()\n\n if (!input) {\n throw new Error('Invalid duration: empty string')\n }\n\n // Try to parse as a simple number (assume milliseconds)\n const numericValue = Number(input)\n if (!isNaN(numericValue)) {\n if (numericValue < 0) {\n throw new Error(`Invalid duration: ${duration}. Duration must be non-negative.`)\n }\n return numericValue\n }\n\n // Handle compound durations like \"1h 30m\" or \"1h30m\"\n let totalMs = 0\n const regex = /(\\d+(?:\\.\\d+)?)\\s*([a-z]+)/g\n let match: RegExpExecArray | null\n let hasMatch = false\n\n while ((match = regex.exec(input)) !== null) {\n hasMatch = true\n const value = parseFloat(match[1])\n let unit = match[2]\n\n // Resolve unit aliases\n if (unit in TIME_UNIT_ALIASES) {\n unit = TIME_UNIT_ALIASES[unit]\n }\n\n // Get multiplier\n const multiplier = TIME_UNITS[unit]\n if (multiplier === undefined) {\n throw new Error(\n `Invalid duration unit: \"${unit}\" in \"${duration}\". ` +\n `Valid units: s, m, h, d (or seconds, minutes, hours, days)`\n )\n }\n\n totalMs += value * multiplier\n }\n\n if (!hasMatch) {\n throw new Error(\n `Invalid duration format: \"${duration}\". ` +\n `Expected format like \"15m\", \"1h\", \"30s\", \"1d\", or \"1h 30m\"`\n )\n }\n\n return Math.floor(totalMs)\n}\n\n/**\n * Format milliseconds to a human-readable duration string\n *\n * @example\n * ```typescript\n * formatDuration(900000) // \"15m\"\n * formatDuration(3600000) // \"1h\"\n * formatDuration(5400000) // \"1h 30m\"\n * formatDuration(86400000) // \"1d\"\n * formatDuration(90061000) // \"1d 1h 1m 1s\"\n * ```\n *\n * @param ms - Duration in milliseconds\n * @param options - Formatting options\n * @returns Human-readable duration string\n */\nexport function formatDuration(\n ms: number,\n options: {\n /**\n * Use long unit names (e.g., \"minutes\" instead of \"m\")\n */\n long?: boolean\n /**\n * Maximum number of units to include\n */\n maxUnits?: number\n /**\n * Separator between units\n */\n separator?: string\n } = {}\n): string {\n const { long = false, maxUnits = 4, separator = ' ' } = options\n\n if (ms < 0) {\n return `-${formatDuration(-ms, options)}`\n }\n\n if (ms === 0) {\n return long ? '0 seconds' : '0s'\n }\n\n const units: Array<{ value: number; short: string; long: string; longPlural: string }> = [\n { value: 86400000, short: 'd', long: 'day', longPlural: 'days' },\n { value: 3600000, short: 'h', long: 'hour', longPlural: 'hours' },\n { value: 60000, short: 'm', long: 'minute', longPlural: 'minutes' },\n { value: 1000, short: 's', long: 'second', longPlural: 'seconds' },\n { value: 1, short: 'ms', long: 'millisecond', longPlural: 'milliseconds' },\n ]\n\n const parts: string[] = []\n let remaining = ms\n\n for (const unit of units) {\n if (parts.length >= maxUnits) break\n if (remaining >= unit.value) {\n const count = Math.floor(remaining / unit.value)\n remaining = remaining % unit.value\n\n if (long) {\n parts.push(`${count} ${count === 1 ? unit.long : unit.longPlural}`)\n } else {\n parts.push(`${count}${unit.short}`)\n }\n }\n }\n\n return parts.join(separator)\n}\n\n/**\n * Get the current timestamp in seconds (Unix timestamp)\n */\nexport function nowInSeconds(): number {\n return Math.floor(Date.now() / 1000)\n}\n\n/**\n * Get the current timestamp in milliseconds\n */\nexport function nowInMs(): number {\n return Date.now()\n}\n\n/**\n * Calculate reset time for a fixed window\n *\n * @param windowMs - Window size in milliseconds\n * @returns Unix timestamp (seconds) when the window resets\n */\nexport function getWindowReset(windowMs: number): number {\n const now = Date.now()\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n return Math.floor(windowEnd / 1000)\n}\n\n/**\n * Get the start of the current window\n *\n * @param windowMs - Window size in milliseconds\n * @returns Timestamp (ms) of window start\n */\nexport function getWindowStart(windowMs: number): number {\n return Math.floor(Date.now() / windowMs) * windowMs\n}\n\n/**\n * Sleep for a specified duration\n *\n * @param duration - Duration to sleep\n * @returns Promise that resolves after the duration\n */\nexport function sleep(duration: Duration | string): Promise<void> {\n const ms = parseDuration(duration)\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Check if a timestamp has expired\n *\n * @param timestampMs - Timestamp in milliseconds\n * @param ttlMs - Time-to-live in milliseconds\n * @returns true if expired\n */\nexport function isExpired(timestampMs: number, ttlMs: number): boolean {\n return Date.now() > timestampMs + ttlMs\n}\n\n/**\n * Calculate time until expiration\n *\n * @param expiresAt - Expiration timestamp in milliseconds\n * @returns Milliseconds until expiration (0 if already expired)\n */\nexport function timeUntilExpiry(expiresAt: number): number {\n return Math.max(0, expiresAt - Date.now())\n}\n\n/**\n * Convert seconds to milliseconds\n */\nexport function secondsToMs(seconds: number): number {\n return seconds * 1000\n}\n\n/**\n * Convert milliseconds to seconds\n */\nexport function msToSeconds(ms: number): number {\n return Math.floor(ms / 1000)\n}\n","/**\n * IP address extraction and validation utilities\n */\n\nimport type { NextRequest } from '../core/types'\n\n/**\n * Headers to check for client IP (in order of priority)\n */\nconst IP_HEADERS = [\n // Cloudflare\n 'cf-connecting-ip',\n // Vercel\n 'x-real-ip',\n // Standard forwarded header (RFC 7239)\n 'x-forwarded-for',\n // AWS ELB\n 'x-client-ip',\n // Azure\n 'client-ip',\n // Fastly\n 'fastly-client-ip',\n // Akamai\n 'true-client-ip',\n // Google Cloud\n 'x-appengine-user-ip',\n // Fly.io\n 'fly-client-ip',\n] as const\n\n/**\n * Localhost/private IP patterns\n */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // IPv4 loopback\n /^10\\./, // Private class A\n /^172\\.(1[6-9]|2[0-9]|3[01])\\./, // Private class B\n /^192\\.168\\./, // Private class C\n /^::1$/, // IPv6 loopback\n /^fe80:/i, // IPv6 link-local\n /^fc00:/i, // IPv6 unique local\n /^fd[0-9a-f]{2}:/i, // IPv6 unique local\n]\n\n/**\n * IPv4 validation regex\n */\nconst IPV4_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/\n\n/**\n * IPv6 validation regex (simplified)\n */\nconst IPV6_REGEX = /^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$|^::1$|^::$|^(?:[a-fA-F0-9]{1,4}:)*:(?:[a-fA-F0-9]{1,4}:)*[a-fA-F0-9]{1,4}$/\n\n/**\n * Options for IP extraction\n */\nexport interface GetIpOptions {\n /**\n * Trust proxy headers (default: true)\n * Set to false in direct-to-client setups\n */\n trustProxy?: boolean\n\n /**\n * Additional headers to check (checked first)\n */\n customHeaders?: string[]\n\n /**\n * Fallback IP when none found\n */\n fallback?: string\n}\n\n/**\n * Extract client IP address from request\n *\n * @example\n * ```typescript\n * // Basic usage\n * const ip = getClientIp(request)\n *\n * // With options\n * const ip = getClientIp(request, {\n * trustProxy: true,\n * customHeaders: ['my-custom-ip-header'],\n * fallback: '0.0.0.0'\n * })\n * ```\n *\n * @param request - Next.js request object\n * @param options - Extraction options\n * @returns Client IP address or fallback\n */\nexport function getClientIp(request: NextRequest, options: GetIpOptions = {}): string {\n const { trustProxy = true, customHeaders = [], fallback = '127.0.0.1' } = options\n\n // First, check if Next.js has already extracted the IP\n if (request.ip) {\n return normalizeIp(request.ip)\n }\n\n if (!trustProxy) {\n return fallback\n }\n\n // Check custom headers first\n for (const header of customHeaders) {\n const value = request.headers.get(header)\n if (value) {\n const ip = parseIpFromHeader(value)\n if (ip) return ip\n }\n }\n\n // Check standard headers\n for (const header of IP_HEADERS) {\n const value = request.headers.get(header)\n if (value) {\n const ip = parseIpFromHeader(value)\n if (ip) return ip\n }\n }\n\n return fallback\n}\n\n/**\n * Parse IP from header value\n * Handles comma-separated lists (x-forwarded-for)\n */\nfunction parseIpFromHeader(headerValue: string): string | null {\n // x-forwarded-for can have multiple IPs: \"client, proxy1, proxy2\"\n // The first one is the client IP\n const ips = headerValue.split(',').map((ip) => ip.trim())\n\n for (const ip of ips) {\n const normalized = normalizeIp(ip)\n if (isValidIp(normalized)) {\n return normalized\n }\n }\n\n return null\n}\n\n/**\n * Normalize an IP address\n * - Removes IPv6 brackets\n * - Removes port numbers\n * - Trims whitespace\n */\nexport function normalizeIp(ip: string): string {\n let normalized = ip.trim()\n\n // Remove IPv6 brackets: [::1] -> ::1\n if (normalized.startsWith('[') && normalized.includes(']')) {\n normalized = normalized.slice(1, normalized.indexOf(']'))\n }\n\n // Remove port: 192.168.1.1:8080 -> 192.168.1.1\n // For IPv4 with port\n if (normalized.includes(':') && !normalized.includes('::')) {\n const lastColon = normalized.lastIndexOf(':')\n const potentialPort = normalized.slice(lastColon + 1)\n if (/^\\d+$/.test(potentialPort)) {\n normalized = normalized.slice(0, lastColon)\n }\n }\n\n // Handle IPv4-mapped IPv6: ::ffff:192.168.1.1 -> 192.168.1.1\n if (normalized.toLowerCase().startsWith('::ffff:')) {\n const ipv4Part = normalized.slice(7)\n if (isValidIpv4(ipv4Part)) {\n return ipv4Part\n }\n }\n\n return normalized\n}\n\n/**\n * Check if an IP address is valid\n */\nexport function isValidIp(ip: string): boolean {\n return isValidIpv4(ip) || isValidIpv6(ip)\n}\n\n/**\n * Check if an IPv4 address is valid\n */\nexport function isValidIpv4(ip: string): boolean {\n return IPV4_REGEX.test(ip)\n}\n\n/**\n * Check if an IPv6 address is valid\n */\nexport function isValidIpv6(ip: string): boolean {\n return IPV6_REGEX.test(ip) || ip === '::1' || ip === '::'\n}\n\n/**\n * Check if an IP is a private/local address\n */\nexport function isPrivateIp(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip))\n}\n\n/**\n * Check if an IP is localhost\n */\nexport function isLocalhost(ip: string): boolean {\n return ip === '127.0.0.1' || ip === '::1' || ip === 'localhost'\n}\n\n/**\n * Create a rate limit key from IP\n * Normalizes and optionally hashes the IP\n */\nexport function createIpKey(\n ip: string,\n options: {\n prefix?: string\n hash?: boolean\n } = {}\n): string {\n const { prefix = 'rl', hash = false } = options\n const normalizedIp = normalizeIp(ip)\n\n if (hash) {\n // Simple hash for privacy (not cryptographic)\n const hashCode = simpleHash(normalizedIp)\n return `${prefix}:ip:${hashCode}`\n }\n\n return `${prefix}:ip:${normalizedIp}`\n}\n\n/**\n * Simple non-cryptographic hash (for key generation)\n */\nfunction simpleHash(str: string): string {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Anonymize an IP address (for logging)\n * IPv4: 192.168.1.100 -> 192.168.1.xxx\n * IPv6: 2001:db8::1 -> 2001:db8::xxx\n */\nexport function anonymizeIp(ip: string): string {\n const normalized = normalizeIp(ip)\n\n if (isValidIpv4(normalized)) {\n const parts = normalized.split('.')\n parts[3] = 'xxx'\n return parts.join('.')\n }\n\n if (isValidIpv6(normalized)) {\n const parts = normalized.split(':')\n if (parts.length > 0) {\n parts[parts.length - 1] = 'xxxx'\n }\n return parts.join(':')\n }\n\n return 'xxx.xxx.xxx.xxx'\n}\n\n/**\n * Get geolocation info from request (if available)\n * Works with Vercel Edge and Cloudflare\n */\nexport function getGeoInfo(request: NextRequest): {\n country?: string\n city?: string\n region?: string\n latitude?: string\n longitude?: string\n} {\n // Vercel provides geo info on the request\n if (request.geo) {\n return {\n country: request.geo.country,\n city: request.geo.city,\n region: request.geo.region,\n latitude: request.geo.latitude,\n longitude: request.geo.longitude,\n }\n }\n\n // Cloudflare headers\n return {\n country: request.headers.get('cf-ipcountry') ?? undefined,\n city: request.headers.get('cf-ipcity') ?? undefined,\n region: request.headers.get('cf-region') ?? undefined,\n latitude: request.headers.get('cf-iplat') ?? undefined,\n longitude: request.headers.get('cf-iplong') ?? undefined,\n }\n}\n","/**\n * In-memory rate limit store\n *\n * Suitable for:\n * - Development\n * - Single-instance deployments\n * - Testing\n *\n * Not suitable for:\n * - Multi-instance/distributed deployments (use Redis/Upstash)\n * - Serverless (data lost between invocations)\n */\n\nimport type { RateLimitStore, MemoryStoreOptions } from '../types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Entry stored in memory\n */\ninterface MemoryEntry {\n count: number\n reset: number // Unix timestamp (seconds)\n createdAt: number // Timestamp (ms)\n}\n\n/**\n * LRU-style memory store for rate limiting\n *\n * Features:\n * - Automatic cleanup of expired entries\n * - LRU eviction when max keys exceeded\n * - Zero dependencies\n * - Edge Runtime compatible\n *\n * @example\n * ```typescript\n * import { MemoryStore } from 'next-secure/rate-limit'\n *\n * const store = new MemoryStore({\n * cleanupInterval: 60000, // 1 minute\n * maxKeys: 10000\n * })\n * ```\n */\nexport class MemoryStore implements RateLimitStore {\n public readonly name = 'memory'\n\n private store: Map<string, MemoryEntry>\n private cleanupTimer: ReturnType<typeof setInterval> | null = null\n private readonly maxKeys: number\n private readonly cleanupInterval: number\n\n constructor(options: MemoryStoreOptions = {}) {\n const { cleanupInterval = 60000, maxKeys = 10000 } = options\n\n this.store = new Map()\n this.maxKeys = maxKeys\n this.cleanupInterval = cleanupInterval\n\n // Start cleanup timer (only in long-running environments)\n if (typeof setInterval !== 'undefined' && cleanupInterval > 0) {\n this.startCleanupTimer()\n }\n }\n\n /**\n * Increment the counter for a key\n *\n * Note: The key should already include window information if needed.\n * This store is algorithm-agnostic - algorithms handle windowing logic.\n */\n async increment(\n key: string,\n windowMs: number\n ): Promise<{ count: number; reset: number }> {\n const now = Date.now()\n const defaultReset = msToSeconds(now + windowMs)\n\n const existing = this.store.get(key)\n\n if (existing) {\n // Increment existing entry\n existing.count++\n // Move to end (LRU update)\n this.store.delete(key)\n this.store.set(key, existing)\n return { count: existing.count, reset: existing.reset }\n }\n\n // New entry\n const entry: MemoryEntry = {\n count: 1,\n reset: defaultReset,\n createdAt: now,\n }\n\n // Check if we need to evict\n if (this.store.size >= this.maxKeys) {\n this.evictOldest()\n }\n\n this.store.set(key, entry)\n return { count: 1, reset: defaultReset }\n }\n\n /**\n * Get the current count for a key\n */\n async get(key: string): Promise<{ count: number; reset: number } | null> {\n const entry = this.store.get(key)\n\n if (!entry) {\n return null\n }\n\n // Check if expired\n const now = Math.floor(Date.now() / 1000)\n if (entry.reset <= now) {\n this.store.delete(key)\n return null\n }\n\n return { count: entry.count, reset: entry.reset }\n }\n\n /**\n * Reset the counter for a key\n */\n async reset(key: string): Promise<void> {\n this.store.delete(key)\n }\n\n /**\n * Check if the store is healthy\n */\n async isHealthy(): Promise<boolean> {\n return true\n }\n\n /**\n * Cleanup expired entries\n */\n async cleanup(): Promise<void> {\n const now = Math.floor(Date.now() / 1000)\n const keysToDelete: string[] = []\n\n for (const [key, entry] of this.store) {\n if (entry.reset <= now) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.store.delete(key)\n }\n }\n\n /**\n * Close the store (stop cleanup timer)\n */\n async close(): Promise<void> {\n this.stopCleanupTimer()\n this.store.clear()\n }\n\n /**\n * Get the current size of the store\n */\n get size(): number {\n return this.store.size\n }\n\n /**\n * Clear all entries\n */\n clear(): void {\n this.store.clear()\n }\n\n /**\n * Start the cleanup timer\n */\n private startCleanupTimer(): void {\n if (this.cleanupTimer) return\n\n this.cleanupTimer = setInterval(() => {\n void this.cleanup()\n }, this.cleanupInterval)\n\n // Unref to not keep the process alive\n if (typeof this.cleanupTimer === 'object' && 'unref' in this.cleanupTimer) {\n (this.cleanupTimer as NodeJS.Timeout).unref()\n }\n }\n\n /**\n * Stop the cleanup timer\n */\n private stopCleanupTimer(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer)\n this.cleanupTimer = null\n }\n }\n\n /**\n * Evict oldest entries when max keys exceeded\n */\n private evictOldest(): void {\n // Map maintains insertion order, so first key is oldest\n const keysToDelete = Math.ceil(this.maxKeys * 0.1) // Delete 10%\n\n let deleted = 0\n for (const key of this.store.keys()) {\n if (deleted >= keysToDelete) break\n this.store.delete(key)\n deleted++\n }\n }\n}\n\n/**\n * Create a memory store with default options\n */\nexport function createMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n return new MemoryStore(options)\n}\n\n/**\n * Global memory store instance (singleton)\n * Useful for serverless environments where you want to reuse across requests\n */\nlet globalStore: MemoryStore | null = null\n\n/**\n * Get or create the global memory store\n */\nexport function getGlobalMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n if (!globalStore) {\n globalStore = new MemoryStore(options)\n }\n return globalStore\n}\n\n/**\n * Reset the global memory store (useful for testing)\n */\nexport function resetGlobalMemoryStore(): void {\n if (globalStore) {\n void globalStore.close()\n globalStore = null\n }\n}\n","/**\n * Sliding Window Rate Limiting Algorithm\n *\n * This algorithm provides a smoother rate limiting experience compared to fixed windows.\n * It uses a weighted calculation based on the previous and current window counts.\n *\n * How it works:\n * 1. Divide time into fixed windows (e.g., 1 minute each)\n * 2. Track request counts for current and previous windows\n * 3. Calculate weighted count based on position within current window\n *\n * Example (100 req/min limit):\n * - Previous window: 80 requests\n * - Current window: 30 requests\n * - 30 seconds into current window (50% through)\n * - Weighted count = 30 + (80 * 0.5) = 70\n * - Since 70 < 100, request is allowed\n *\n * Pros:\n * - Smoother than fixed window\n * - Prevents burst attacks at window boundaries\n * - Memory efficient (only stores 2 counters per key)\n *\n * Cons:\n * - Slightly more complex than fixed window\n * - Not perfectly accurate (approximation)\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Sliding window counter algorithm implementation\n */\nexport class SlidingWindowAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'sliding-window' as const\n\n /**\n * Check if the request should be rate limited\n */\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Calculate window boundaries\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const previousWindowStart = windowStart - windowMs\n\n // Position within current window (0 to 1)\n const windowPosition = (now - windowStart) / windowMs\n\n // Keys for current and previous windows\n const currentKey = `${key}:${windowStart}`\n const previousKey = `${key}:${previousWindowStart}`\n\n // Get counts from both windows\n const [currentData, previousData] = await Promise.all([\n store.get(currentKey),\n store.get(previousKey),\n ])\n\n const currentCount = currentData?.count ?? 0\n const previousCount = previousData?.count ?? 0\n\n // Calculate weighted count using sliding window formula\n // Weight of previous window decreases as we move through current window\n const previousWeight = 1 - windowPosition\n const weightedCount = currentCount + Math.floor(previousCount * previousWeight)\n\n // Calculate reset time (end of current window)\n const reset = msToSeconds(windowEnd)\n\n // Check if limit exceeded\n if (weightedCount >= limit) {\n // Calculate retry time based on when enough requests will \"expire\"\n const retryAfter = this.calculateRetryAfter(\n currentCount,\n previousCount,\n limit,\n windowMs,\n windowPosition\n )\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter,\n }\n }\n\n // Increment current window counter\n await store.increment(currentKey, windowMs)\n\n // Calculate remaining\n const remaining = Math.max(0, limit - weightedCount - 1)\n\n return {\n limit,\n remaining,\n reset,\n limited: false,\n }\n }\n\n /**\n * Calculate how long until the client can make another request\n */\n private calculateRetryAfter(\n currentCount: number,\n previousCount: number,\n limit: number,\n windowMs: number,\n windowPosition: number\n ): number {\n // If previous window is empty, wait until current window resets\n if (previousCount === 0) {\n return Math.ceil((1 - windowPosition) * windowMs / 1000)\n }\n\n // Calculate when the weighted count will drop below limit\n // We need: currentCount + previousCount * (1 - newPosition) < limit\n // Solving for newPosition: newPosition > 1 - (limit - currentCount) / previousCount\n\n const requiredPosition = 1 - (limit - currentCount) / previousCount\n\n if (requiredPosition <= windowPosition) {\n // Should already be under limit, but we got here so add small delay\n return 1\n }\n\n if (requiredPosition >= 1) {\n // Need to wait until next window\n const remainingInCurrentWindow = (1 - windowPosition) * windowMs\n return Math.ceil(remainingInCurrentWindow / 1000)\n }\n\n // Calculate time until we reach required position\n const timeToWait = (requiredPosition - windowPosition) * windowMs\n return Math.ceil(timeToWait / 1000)\n }\n}\n\n/**\n * Create a sliding window algorithm instance\n */\nexport function createSlidingWindowAlgorithm(): SlidingWindowAlgorithm {\n return new SlidingWindowAlgorithm()\n}\n\n/**\n * Sliding Window Log Algorithm (more accurate but uses more memory)\n *\n * This stores individual request timestamps instead of just counters.\n * More accurate but not recommended for high-traffic scenarios.\n */\nexport class SlidingWindowLogAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'sliding-window' as const\n\n /**\n * In-memory log of request timestamps per key\n * For production, this should be stored externally (Redis sorted sets, etc.)\n */\n private logs: Map<string, number[]> = new Map()\n\n /**\n * Maximum log size before cleanup\n */\n private readonly maxLogSize = 10000\n\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n const windowStart = now - windowMs\n\n // Get or create log for this key\n let log = this.logs.get(key) ?? []\n\n // Remove expired entries\n log = log.filter((timestamp) => timestamp > windowStart)\n\n // Calculate reset (when oldest entry expires)\n const oldestTimestamp = log[0] ?? now\n const reset = msToSeconds(oldestTimestamp + windowMs)\n\n // Check if limit exceeded\n if (log.length >= limit) {\n const retryAfter = Math.ceil((oldestTimestamp + windowMs - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Add current request\n log.push(now)\n this.logs.set(key, log)\n\n // Cleanup if too many keys\n if (this.logs.size > this.maxLogSize) {\n this.cleanup()\n }\n\n return {\n limit,\n remaining: Math.max(0, limit - log.length),\n reset,\n limited: false,\n }\n }\n\n /**\n * Remove oldest entries when log size exceeded\n */\n private cleanup(): void {\n const keysToDelete: string[] = []\n const now = Date.now()\n\n for (const [key, log] of this.logs) {\n // Delete empty or very old logs\n if (log.length === 0 || log[log.length - 1]! < now - 3600000) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.logs.delete(key)\n }\n }\n\n /**\n * Clear all logs\n */\n clear(): void {\n this.logs.clear()\n }\n}\n","/**\n * Fixed Window Rate Limiting Algorithm\n *\n * The simplest rate limiting algorithm. Divides time into fixed windows\n * and counts requests within each window.\n *\n * How it works:\n * 1. Divide time into fixed windows (e.g., every minute starting at :00)\n * 2. Count requests within the current window\n * 3. Reset counter when new window starts\n *\n * Example (100 req/min limit):\n * - Window 1 (12:00:00 - 12:00:59): 80 requests -> allowed\n * - Window 2 (12:01:00 - 12:01:59): 0 requests (fresh start)\n *\n * Pros:\n * - Simple to implement\n * - Memory efficient (only 1 counter per key)\n * - Fast (O(1) operations)\n *\n * Cons:\n * - Burst problem: 200 requests possible in 2 seconds at window boundary\n * - 100 requests at 12:00:59 (end of window 1)\n * - 100 requests at 12:01:00 (start of window 2)\n * - Not smooth\n *\n * Use when:\n * - Simplicity is preferred\n * - Burst at boundaries is acceptable\n * - Memory/CPU is very constrained\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Fixed window algorithm implementation\n */\nexport class FixedWindowAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'fixed-window' as const\n\n /**\n * Check if the request should be rate limited\n */\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Calculate window boundaries\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const reset = msToSeconds(windowEnd)\n\n // Create window-specific key\n const windowKey = `${key}:${windowStart}`\n\n // Get current count\n const data = await store.get(windowKey)\n const currentCount = data?.count ?? 0\n\n // Check if limit exceeded\n if (currentCount >= limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Increment counter\n const { count } = await store.increment(windowKey, windowMs)\n\n // Double-check after increment (race condition protection)\n if (count > limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n return {\n limit,\n remaining: Math.max(0, limit - count),\n reset,\n limited: false,\n }\n }\n}\n\n/**\n * Create a fixed window algorithm instance\n */\nexport function createFixedWindowAlgorithm(): FixedWindowAlgorithm {\n return new FixedWindowAlgorithm()\n}\n\n/**\n * Fixed window with burst protection\n *\n * Adds a secondary limit to prevent bursts at window boundaries.\n * For example: 100 req/min with max 20 req/10sec burst.\n */\nexport class FixedWindowWithBurstProtection implements RateLimitAlgorithmImpl {\n public readonly name = 'fixed-window' as const\n\n constructor(\n private readonly burstLimit: number,\n private readonly burstWindowMs: number\n ) {}\n\n async check(\n store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Check burst limit first (smaller window)\n const burstWindowStart = Math.floor(now / this.burstWindowMs) * this.burstWindowMs\n const burstKey = `${key}:burst:${burstWindowStart}`\n const burstData = await store.get(burstKey)\n const burstCount = burstData?.count ?? 0\n\n if (burstCount >= this.burstLimit) {\n const burstWindowEnd = burstWindowStart + this.burstWindowMs\n const retryAfter = Math.ceil((burstWindowEnd - now) / 1000)\n\n return {\n limit: this.burstLimit,\n remaining: 0,\n reset: msToSeconds(burstWindowEnd),\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Check main limit\n const windowStart = Math.floor(now / windowMs) * windowMs\n const windowEnd = windowStart + windowMs\n const windowKey = `${key}:${windowStart}`\n const data = await store.get(windowKey)\n const currentCount = data?.count ?? 0\n\n if (currentCount >= limit) {\n const retryAfter = Math.ceil((windowEnd - now) / 1000)\n\n return {\n limit,\n remaining: 0,\n reset: msToSeconds(windowEnd),\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Increment both counters\n await Promise.all([\n store.increment(windowKey, windowMs),\n store.increment(burstKey, this.burstWindowMs),\n ])\n\n return {\n limit,\n remaining: Math.max(0, limit - currentCount - 1),\n reset: msToSeconds(windowEnd),\n limited: false,\n }\n }\n}\n\n/**\n * Create a fixed window with burst protection\n *\n * @example\n * ```typescript\n * // 100 req/min with max 20 req/10sec burst\n * const algorithm = createFixedWindowWithBurstProtection(20, 10000)\n * ```\n */\nexport function createFixedWindowWithBurstProtection(\n burstLimit: number,\n burstWindowMs: number\n): FixedWindowWithBurstProtection {\n return new FixedWindowWithBurstProtection(burstLimit, burstWindowMs)\n}\n","/**\n * Token Bucket Rate Limiting Algorithm\n *\n * A bucket holds tokens that are consumed by requests. Tokens are refilled\n * at a constant rate. This allows for controlled bursts while maintaining\n * an average rate.\n *\n * How it works:\n * 1. Bucket starts full with 'limit' tokens\n * 2. Each request consumes 1 token (or more for weighted requests)\n * 3. Tokens are refilled at 'limit / window' rate\n * 4. Request is allowed if tokens >= 1\n *\n * Example (100 tokens, refill 100/min = 1.67/sec):\n * - Initial: 100 tokens\n * - 50 requests instantly: 50 tokens remaining (burst allowed)\n * - Wait 30 seconds: 50 + (50 * 1.67) = 100 tokens (refilled)\n * - 100 requests instantly: 0 tokens\n * - Next request: denied until tokens refill\n *\n * Pros:\n * - Allows controlled bursts\n * - Smooth average rate\n * - Good for APIs with sporadic traffic\n *\n * Cons:\n * - More complex state management\n * - Requires storing last refill time\n *\n * Use when:\n * - You want to allow bursts\n * - Traffic is sporadic\n * - User experience matters (can handle burst then wait)\n */\n\nimport type { RateLimitStore, RateLimitAlgorithmImpl, TokenBucketState } from '../types'\nimport type { RateLimitInfo } from '../../../core/types'\nimport { msToSeconds } from '../../../utils/time'\n\n/**\n * Token bucket algorithm implementation\n */\nexport class TokenBucketAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'token-bucket' as const\n\n /**\n * In-memory bucket states\n * For distributed systems, this should be stored in Redis\n */\n private buckets: Map<string, TokenBucketState> = new Map()\n\n /**\n * Maximum number of buckets to store before cleanup\n */\n private readonly maxBuckets = 10000\n\n /**\n * Check if the request should be rate limited\n *\n * @param store - Not used directly, state stored in memory\n * @param key - Rate limit key\n * @param limit - Maximum tokens (bucket capacity)\n * @param windowMs - Time to refill bucket completely\n */\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Get or create bucket state\n let bucket = this.buckets.get(key)\n\n if (!bucket) {\n // New bucket, start full\n bucket = {\n tokens: limit,\n lastRefill: now,\n }\n } else {\n // Refill tokens based on time elapsed\n bucket = this.refillTokens(bucket, limit, windowMs, now)\n }\n\n // Calculate reset time (when bucket would be full again)\n const tokensNeeded = limit - bucket.tokens\n const refillRate = limit / windowMs // tokens per ms\n const timeToFull = tokensNeeded / refillRate\n const reset = msToSeconds(now + timeToFull)\n\n // Check if we have tokens\n if (bucket.tokens < 1) {\n // Calculate when we'll have 1 token\n const timeToOneToken = (1 - bucket.tokens) / refillRate\n const retryAfter = Math.ceil(timeToOneToken / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Consume a token\n bucket.tokens -= 1\n this.buckets.set(key, bucket)\n\n // Cleanup if too many buckets\n if (this.buckets.size > this.maxBuckets) {\n this.cleanup()\n }\n\n return {\n limit,\n remaining: Math.floor(bucket.tokens),\n reset,\n limited: false,\n }\n }\n\n /**\n * Refill tokens based on time elapsed\n */\n private refillTokens(\n bucket: TokenBucketState,\n limit: number,\n windowMs: number,\n now: number\n ): TokenBucketState {\n const elapsed = now - bucket.lastRefill\n const refillRate = limit / windowMs // tokens per ms\n const tokensToAdd = elapsed * refillRate\n\n return {\n tokens: Math.min(limit, bucket.tokens + tokensToAdd),\n lastRefill: now,\n }\n }\n\n /**\n * Remove old buckets\n */\n private cleanup(): void {\n const now = Date.now()\n const staleThreshold = 3600000 // 1 hour\n\n const keysToDelete: string[] = []\n\n for (const [key, bucket] of this.buckets) {\n if (now - bucket.lastRefill > staleThreshold) {\n keysToDelete.push(key)\n }\n }\n\n for (const key of keysToDelete) {\n this.buckets.delete(key)\n }\n }\n\n /**\n * Get current bucket state (for testing/debugging)\n */\n getBucketState(key: string): TokenBucketState | undefined {\n return this.buckets.get(key)\n }\n\n /**\n * Clear all buckets\n */\n clear(): void {\n this.buckets.clear()\n }\n}\n\n/**\n * Create a token bucket algorithm instance\n */\nexport function createTokenBucketAlgorithm(): TokenBucketAlgorithm {\n return new TokenBucketAlgorithm()\n}\n\n/**\n * Leaky Bucket Algorithm (variation of token bucket)\n *\n * Instead of refilling tokens, requests \"leak\" out of the bucket\n * at a constant rate. This enforces a strict output rate.\n *\n * Think of it as a bucket with a hole at the bottom:\n * - Requests are added to the bucket\n * - Requests leak out at a constant rate\n * - If bucket overflows, request is rejected\n *\n * Use when:\n * - You need strict rate enforcement\n * - Bursts should be queued, not rejected\n * - Output rate must be constant\n */\nexport class LeakyBucketAlgorithm implements RateLimitAlgorithmImpl {\n public readonly name = 'token-bucket' as const // Grouped with token bucket\n\n /**\n * In-memory bucket states\n * Stores the \"water level\" and last leak time\n */\n private buckets: Map<string, { level: number; lastLeak: number }> = new Map()\n\n /**\n * Maximum number of buckets\n */\n private readonly maxBuckets = 10000\n\n async check(\n _store: RateLimitStore,\n key: string,\n limit: number,\n windowMs: number\n ): Promise<RateLimitInfo> {\n const now = Date.now()\n\n // Get or create bucket\n let bucket = this.buckets.get(key) ?? { level: 0, lastLeak: now }\n\n // Calculate how much has leaked since last check\n const elapsed = now - bucket.lastLeak\n const leakRate = limit / windowMs // requests per ms\n const leaked = elapsed * leakRate\n\n // Update level (can't go below 0)\n bucket.level = Math.max(0, bucket.level - leaked)\n bucket.lastLeak = now\n\n // Calculate reset time\n const timeToEmpty = bucket.level / leakRate\n const reset = msToSeconds(now + timeToEmpty)\n\n // Check if bucket would overflow\n if (bucket.level + 1 > limit) {\n // Calculate when there's room for 1 more request\n const overflow = bucket.level + 1 - limit\n const timeToRoom = overflow / leakRate\n const retryAfter = Math.ceil(timeToRoom / 1000)\n\n return {\n limit,\n remaining: 0,\n reset,\n limited: true,\n retryAfter: Math.max(1, retryAfter),\n }\n }\n\n // Add request to bucket\n bucket.level += 1\n this.buckets.set(key, bucket)\n\n // Cleanup if needed\n if (this.buckets.size > this.maxBuckets) {\n this.cleanup(now)\n }\n\n return {\n limit,\n remaining: Math.floor(limit - bucket.level),\n reset,\n limited: false,\n }\n }\n\n private cleanup(now: number): void {\n const staleThreshold = 3600000\n\n for (const [key, bucket] of this.buckets) {\n if (now - bucket.lastLeak > staleThreshold) {\n this.buckets.delete(key)\n }\n }\n }\n\n clear(): void {\n this.buckets.clear()\n }\n}\n\n/**\n * Create a leaky bucket algorithm instance\n */\nexport function createLeakyBucketAlgorithm(): LeakyBucketAlgorithm {\n return new LeakyBucketAlgorithm()\n}\n","/**\n * Rate Limiting Middleware for Next.js App Router\n *\n * @example\n * ```typescript\n * // Basic usage\n * import { withRateLimit } from 'next-secure/rate-limit'\n *\n * export const GET = withRateLimit(\n * async (req) => Response.json({ data: [] }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // With custom identifier\n * export const GET = withRateLimit(handler, {\n * limit: 100,\n * window: '15m',\n * identifier: (req) => req.headers.get('x-api-key') ?? 'anonymous'\n * })\n *\n * // With Redis store\n * import { createRedisStore } from 'next-secure/rate-limit'\n *\n * const store = createRedisStore({ client: redis })\n *\n * export const GET = withRateLimit(handler, {\n * limit: 100,\n * window: '15m',\n * store\n * })\n * ```\n */\n\nimport type { NextRequest, RateLimitInfo, SecureContext } from '../../core/types'\nimport { RateLimitError } from '../../core/errors'\nimport { parseDuration } from '../../utils/time'\nimport { getClientIp } from '../../utils/ip'\nimport type { RateLimitConfig, RateLimitStore, RateLimitAlgorithmImpl } from './types'\nimport { MemoryStore } from './stores/memory'\nimport { SlidingWindowAlgorithm } from './algorithms/sliding-window'\nimport { FixedWindowAlgorithm } from './algorithms/fixed-window'\nimport { TokenBucketAlgorithm } from './algorithms/token-bucket'\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: Partial<RateLimitConfig> = {\n algorithm: 'sliding-window',\n identifier: 'ip',\n headers: true,\n prefix: 'rl',\n message: 'Too Many Requests',\n statusCode: 429,\n debug: false,\n}\n\n/**\n * Global default store (shared across handlers)\n */\nlet defaultStore: RateLimitStore | null = null\n\n/**\n * Get or create the default memory store\n */\nfunction getDefaultStore(): RateLimitStore {\n if (!defaultStore) {\n defaultStore = new MemoryStore()\n }\n return defaultStore\n}\n\n/**\n * Get algorithm instance by name\n */\nfunction getAlgorithm(name: RateLimitConfig['algorithm']): RateLimitAlgorithmImpl {\n switch (name) {\n case 'fixed-window':\n return new FixedWindowAlgorithm()\n case 'token-bucket':\n return new TokenBucketAlgorithm()\n case 'sliding-window':\n default:\n return new SlidingWindowAlgorithm()\n }\n}\n\n/**\n * Create rate limit headers\n */\nfunction createRateLimitHeaders(info: RateLimitInfo): Headers {\n const headers = new Headers()\n\n headers.set('X-RateLimit-Limit', String(info.limit))\n headers.set('X-RateLimit-Remaining', String(info.remaining))\n headers.set('X-RateLimit-Reset', String(info.reset))\n\n if (info.limited && info.retryAfter) {\n headers.set('Retry-After', String(info.retryAfter))\n }\n\n return headers\n}\n\n/**\n * Merge headers from multiple sources\n */\nfunction mergeHeaders(target: Headers, source: Headers): void {\n source.forEach((value, key) => {\n target.set(key, value)\n })\n}\n\n/**\n * Get client identifier from request\n */\nasync function getIdentifier(\n request: NextRequest,\n identifier: RateLimitConfig['identifier'],\n prefix: string,\n context?: SecureContext\n): Promise<string> {\n if (typeof identifier === 'function') {\n const id = await identifier(request)\n return `${prefix}:custom:${id}`\n }\n\n if (identifier === 'user') {\n // Requires auth middleware to have run first\n const userId = context?.user\n ? (context.user as { id?: string }).id ?? 'anonymous'\n : 'anonymous'\n return `${prefix}:user:${userId}`\n }\n\n // Default: IP-based\n const ip = getClientIp(request)\n return `${prefix}:ip:${ip}`\n}\n\n/**\n * Rate limiting middleware wrapper\n *\n * @example\n * ```typescript\n * // Simple usage\n * export const GET = withRateLimit(\n * async (req) => Response.json({ ok: true }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // With all options\n * export const POST = withRateLimit(\n * async (req, ctx) => {\n * // ctx.rateLimit contains info\n * return Response.json({ remaining: ctx.rateLimit?.remaining })\n * },\n * {\n * limit: 10,\n * window: '1m',\n * algorithm: 'sliding-window',\n * identifier: 'ip',\n * headers: true,\n * onLimit: (req, info) => new Response(\n * JSON.stringify({ error: 'Slow down!' }),\n * { status: 429 }\n * ),\n * skip: (req) => req.headers.get('x-bypass') === 'secret'\n * }\n * )\n * ```\n */\nexport function withRateLimit<TUser = unknown>(\n handler: (\n request: NextRequest,\n context: SecureContext<TUser> & { rateLimit?: RateLimitInfo }\n ) => Promise<Response> | Response,\n config: RateLimitConfig\n): (request: NextRequest, context?: SecureContext<TUser>) => Promise<Response> {\n // Merge config with defaults\n const finalConfig: Required<RateLimitConfig> = {\n ...DEFAULT_CONFIG,\n ...config,\n store: config.store ?? getDefaultStore(),\n } as Required<RateLimitConfig>\n\n // Parse window duration once\n const windowMs = parseDuration(finalConfig.window)\n\n // Get algorithm once\n const algorithm = getAlgorithm(finalConfig.algorithm)\n\n // Debug logging\n const debug = finalConfig.debug\n ? (msg: string, data?: unknown) => {\n // eslint-disable-next-line no-console\n console.log(`[next-secure:rate-limit] ${msg}`, data ?? '')\n }\n : () => {}\n\n debug('Initialized', {\n limit: finalConfig.limit,\n window: finalConfig.window,\n algorithm: finalConfig.algorithm,\n })\n\n return async (\n request: NextRequest,\n context?: SecureContext<TUser>\n ): Promise<Response> => {\n // Create context if not provided\n const ctx: SecureContext<TUser> & { rateLimit?: RateLimitInfo } = context ?? {\n user: null,\n requestId: crypto.randomUUID(),\n ip: getClientIp(request),\n userAgent: request.headers.get('user-agent') ?? '',\n startTime: Date.now(),\n metadata: {},\n }\n\n try {\n // Check if we should skip rate limiting\n if (finalConfig.skip) {\n const shouldSkip = await finalConfig.skip(request)\n if (shouldSkip) {\n debug('Skipping rate limit check')\n return handler(request, ctx)\n }\n }\n\n // Get identifier\n const key = await getIdentifier(\n request,\n finalConfig.identifier,\n finalConfig.prefix,\n ctx\n )\n debug('Rate limit key', key)\n\n // Check rate limit\n const info = await algorithm.check(\n finalConfig.store,\n key,\n finalConfig.limit,\n windowMs\n )\n debug('Rate limit info', info)\n\n // Add rate limit info to context\n ctx.rateLimit = info\n\n // Check if limited\n if (info.limited) {\n debug('Request rate limited')\n\n // Custom handler\n if (finalConfig.onLimit) {\n const response = await finalConfig.onLimit(request, info)\n\n // Add headers to custom response\n if (finalConfig.headers) {\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(response.headers, rateLimitHeaders)\n }\n\n return response\n }\n\n // Default rate limit response\n const error = new RateLimitError({\n retryAfter: info.retryAfter ?? 60,\n resetAt: info.reset * 1000,\n message: finalConfig.message,\n })\n\n const response = error.toResponse()\n\n if (finalConfig.headers) {\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(response.headers, rateLimitHeaders)\n }\n\n return response\n }\n\n // Call the handler\n const response = await handler(request, ctx)\n\n // Add rate limit headers to successful response\n if (finalConfig.headers) {\n // Clone response to modify headers\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n const rateLimitHeaders = createRateLimitHeaders(info)\n mergeHeaders(newResponse.headers, rateLimitHeaders)\n\n return newResponse\n }\n\n return response\n } catch (error) {\n debug('Error in rate limit middleware', error)\n\n // Re-throw RateLimitError\n if (error instanceof RateLimitError) {\n throw error\n }\n\n // For other errors, let the request through (fail open)\n // This prevents rate limiting from blocking all requests on errors\n // eslint-disable-next-line no-console\n console.error('[next-secure:rate-limit] Error:', error)\n return handler(request, ctx)\n }\n }\n}\n\n/**\n * Create a rate limiter instance for reuse\n *\n * @example\n * ```typescript\n * const apiLimiter = createRateLimiter({\n * limit: 100,\n * window: '15m'\n * })\n *\n * export const GET = apiLimiter(async (req) => Response.json({ ok: true }))\n * export const POST = apiLimiter(async (req) => Response.json({ ok: true }))\n * ```\n */\nexport function createRateLimiter(config: RateLimitConfig) {\n return <TUser = unknown>(\n handler: (\n request: NextRequest,\n context: SecureContext<TUser> & { rateLimit?: RateLimitInfo }\n ) => Promise<Response> | Response\n ) => withRateLimit(handler, config)\n}\n\n/**\n * Check rate limit without wrapping a handler\n * Useful for checking rate limit in existing code\n *\n * @example\n * ```typescript\n * export async function GET(req: NextRequest) {\n * const result = await checkRateLimit(req, {\n * limit: 100,\n * window: '15m'\n * })\n *\n * if (!result.success) {\n * return result.response\n * }\n *\n * // Continue with normal logic\n * return Response.json({ ok: true })\n * }\n * ```\n */\nexport async function checkRateLimit(\n request: NextRequest,\n config: RateLimitConfig\n): Promise<{\n success: boolean\n info: RateLimitInfo\n response?: Response\n headers: Headers\n}> {\n const finalConfig = {\n ...DEFAULT_CONFIG,\n ...config,\n store: config.store ?? getDefaultStore(),\n } as Required<RateLimitConfig>\n\n const windowMs = parseDuration(finalConfig.window)\n const algorithm = getAlgorithm(finalConfig.algorithm)\n\n // Check if should skip\n if (finalConfig.skip) {\n const shouldSkip = await finalConfig.skip(request)\n if (shouldSkip) {\n const info: RateLimitInfo = {\n limit: finalConfig.limit,\n remaining: finalConfig.limit,\n reset: Math.floor(Date.now() / 1000) + Math.floor(windowMs / 1000),\n limited: false,\n }\n return { success: true, info, headers: new Headers() }\n }\n }\n\n const key = await getIdentifier(request, finalConfig.identifier, finalConfig.prefix)\n const info = await algorithm.check(finalConfig.store, key, finalConfig.limit, windowMs)\n const headers = finalConfig.headers ? createRateLimitHeaders(info) : new Headers()\n\n if (info.limited) {\n let response: Response\n\n if (finalConfig.onLimit) {\n response = await finalConfig.onLimit(request, info)\n } else {\n const error = new RateLimitError({\n retryAfter: info.retryAfter ?? 60,\n resetAt: info.reset * 1000,\n message: finalConfig.message,\n })\n response = error.toResponse()\n }\n\n if (finalConfig.headers) {\n mergeHeaders(response.headers, headers)\n }\n\n return { success: false, info, response, headers }\n }\n\n return { success: true, info, headers }\n}\n\n/**\n * Reset rate limit for a specific key\n *\n * @example\n * ```typescript\n * // Reset rate limit for an IP\n * await resetRateLimit('ip', '192.168.1.1')\n *\n * // Reset for a user\n * await resetRateLimit('user', 'user-123')\n * ```\n */\nexport async function resetRateLimit(\n type: 'ip' | 'user' | 'custom',\n identifier: string,\n options?: {\n store?: RateLimitStore\n prefix?: string\n }\n): Promise<void> {\n const store = options?.store ?? getDefaultStore()\n const prefix = options?.prefix ?? 'rl'\n const key = `${prefix}:${type}:${identifier}`\n\n await store.reset(key)\n}\n\n/**\n * Get current rate limit status for a key (without incrementing)\n */\nexport async function getRateLimitStatus(\n type: 'ip' | 'user' | 'custom',\n identifier: string,\n options?: {\n store?: RateLimitStore\n prefix?: string\n }\n): Promise<{ count: number; reset: number } | null> {\n const store = options?.store ?? getDefaultStore()\n const prefix = options?.prefix ?? 'rl'\n const key = `${prefix}:${type}:${identifier}`\n\n return store.get(key)\n}\n\n/**\n * Clear all rate limits (useful for testing)\n */\nexport function clearAllRateLimits(): void {\n if (defaultStore && 'clear' in defaultStore) {\n (defaultStore as MemoryStore).clear()\n }\n}\n","import { webcrypto } from 'node:crypto'\n\nconst encoder = new TextEncoder()\n\n/**\n * Generate random bytes as hex string\n */\nexport function randomBytes(length: number): string {\n const bytes = new Uint8Array(length)\n webcrypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Create HMAC signature\n */\nasync function createSignature(data: string, secret: string): Promise<string> {\n const key = await webcrypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n\n const sig = await webcrypto.subtle.sign('HMAC', key, encoder.encode(data))\n return Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Constant-time string comparison to prevent timing attacks\n */\nfunction safeCompare(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n\n let result = 0\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i)\n }\n return result === 0\n}\n\n/**\n * Create a signed CSRF token\n */\nexport async function createToken(\n secret: string,\n length: number = 32\n): Promise<string> {\n const data = randomBytes(length)\n const sig = await createSignature(data, secret)\n return `${data}.${sig}`\n}\n\n/**\n * Verify a signed CSRF token\n */\nexport async function verifyToken(\n token: string,\n secret: string\n): Promise<boolean> {\n if (!token || typeof token !== 'string') return false\n\n const parts = token.split('.')\n if (parts.length !== 2) return false\n\n const [data, sig] = parts\n if (!data || !sig) return false\n\n try {\n const expected = await createSignature(data, secret)\n return safeCompare(sig, expected)\n } catch {\n return false\n }\n}\n\n/**\n * Compare two tokens (constant-time)\n */\nexport function tokensMatch(a: string, b: string): boolean {\n if (!a || !b) return false\n return safeCompare(a, b)\n}\n","import type { NextRequest } from 'next/server'\nimport type { CSRFConfig, CSRFCookieOptions } from './types'\nimport { createToken, verifyToken, tokensMatch } from './token'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\nconst DEFAULT_COOKIE: CSRFCookieOptions = {\n name: '__csrf',\n path: '/',\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 86400, // 24h\n}\n\nconst DEFAULT_CONFIG: Required<Omit<CSRFConfig, 'skip' | 'onError'>> = {\n cookie: DEFAULT_COOKIE,\n headerName: 'x-csrf-token',\n fieldName: '_csrf',\n secret: '',\n tokenLength: 32,\n protectedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'],\n}\n\nfunction getSecret(config: CSRFConfig): string {\n const secret = config.secret || process.env.CSRF_SECRET\n if (!secret) {\n throw new Error(\n 'CSRF secret is required. Set config.secret or CSRF_SECRET env variable.'\n )\n }\n return secret\n}\n\nfunction buildCookieString(name: string, value: string, opts: CSRFCookieOptions): string {\n let cookie = `${name}=${value}`\n\n if (opts.path) cookie += `; Path=${opts.path}`\n if (opts.domain) cookie += `; Domain=${opts.domain}`\n if (opts.maxAge) cookie += `; Max-Age=${opts.maxAge}`\n if (opts.httpOnly) cookie += '; HttpOnly'\n if (opts.secure) cookie += '; Secure'\n if (opts.sameSite) cookie += `; SameSite=${opts.sameSite}`\n\n return cookie\n}\n\n/**\n * Extract token from request (header or body)\n */\nasync function extractToken(\n req: NextRequest,\n headerName: string,\n fieldName: string\n): Promise<string | null> {\n // check header first\n const headerToken = req.headers.get(headerName)\n if (headerToken) return headerToken\n\n // try to get from form data\n const contentType = req.headers.get('content-type') || ''\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n try {\n const cloned = req.clone()\n const formData = await cloned.formData()\n const token = formData.get(fieldName)\n if (typeof token === 'string') return token\n } catch {\n // ignore parse errors\n }\n }\n\n if (contentType.includes('application/json')) {\n try {\n const cloned = req.clone()\n const body = await cloned.json()\n if (body && typeof body[fieldName] === 'string') {\n return body[fieldName]\n }\n } catch {\n // ignore parse errors\n }\n }\n\n return null\n}\n\nfunction defaultErrorResponse(_req: NextRequest, reason: string): Response {\n return new Response(JSON.stringify({ error: 'CSRF validation failed', reason }), {\n status: 403,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\n/**\n * CSRF protection middleware\n *\n * Uses double submit cookie pattern:\n * 1. Server sets a signed token in a cookie\n * 2. Client sends the same token in header/body\n * 3. Server compares both values\n */\nexport function withCSRF(handler: RouteHandler, config: CSRFConfig = {}): RouteHandler {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const headerName = config.headerName || DEFAULT_CONFIG.headerName\n const fieldName = config.fieldName || DEFAULT_CONFIG.fieldName\n const protectedMethods = config.protectedMethods || DEFAULT_CONFIG.protectedMethods\n const onError = config.onError || defaultErrorResponse\n\n return async (req: NextRequest): Promise<Response> => {\n const method = req.method.toUpperCase()\n\n // skip unprotected methods\n if (!protectedMethods.includes(method)) {\n return handler(req)\n }\n\n // custom skip logic\n if (config.skip) {\n const shouldSkip = await config.skip(req)\n if (shouldSkip) return handler(req)\n }\n\n const cookieName = cookieOpts.name || '__csrf'\n const cookieToken = req.cookies.get(cookieName)?.value\n\n // no cookie = first request, reject\n if (!cookieToken) {\n return onError(req, 'missing_cookie')\n }\n\n // verify cookie token is valid (signed by us)\n const cookieValid = await verifyToken(cookieToken, secret)\n if (!cookieValid) {\n return onError(req, 'invalid_cookie')\n }\n\n // get token from request\n const requestToken = await extractToken(req, headerName, fieldName)\n if (!requestToken) {\n return onError(req, 'missing_token')\n }\n\n // compare tokens\n if (!tokensMatch(cookieToken, requestToken)) {\n return onError(req, 'token_mismatch')\n }\n\n return handler(req)\n }\n}\n\n/**\n * Generate a new CSRF token and cookie header\n * Use this in GET routes to set the initial token\n */\nexport async function generateCSRF(config: CSRFConfig = {}): Promise<{\n token: string\n cookieHeader: string\n}> {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const tokenLength = config.tokenLength || DEFAULT_CONFIG.tokenLength\n const cookieName = cookieOpts.name || '__csrf'\n\n const token = await createToken(secret, tokenLength)\n const cookieHeader = buildCookieString(cookieName, token, cookieOpts)\n\n return { token, cookieHeader }\n}\n\n/**\n * Validate a CSRF token without middleware\n * Useful for custom validation flows\n */\nexport async function validateCSRF(\n req: NextRequest,\n config: CSRFConfig = {}\n): Promise<{ valid: boolean; reason?: string }> {\n const secret = getSecret(config)\n const cookieOpts = { ...DEFAULT_COOKIE, ...config.cookie }\n const headerName = config.headerName || DEFAULT_CONFIG.headerName\n const fieldName = config.fieldName || DEFAULT_CONFIG.fieldName\n const cookieName = cookieOpts.name || '__csrf'\n\n const cookieToken = req.cookies.get(cookieName)?.value\n if (!cookieToken) {\n return { valid: false, reason: 'missing_cookie' }\n }\n\n const cookieValid = await verifyToken(cookieToken, secret)\n if (!cookieValid) {\n return { valid: false, reason: 'invalid_cookie' }\n }\n\n const requestToken = await extractToken(req, headerName, fieldName)\n if (!requestToken) {\n return { valid: false, reason: 'missing_token' }\n }\n\n if (!tokensMatch(cookieToken, requestToken)) {\n return { valid: false, reason: 'token_mismatch' }\n }\n\n return { valid: true }\n}\n","import type {\n ContentSecurityPolicy,\n StrictTransportSecurity,\n PermissionsPolicy,\n SecurityHeadersConfig,\n SecurityHeadersPreset,\n} from './types'\n\n/**\n * Build CSP header string from config\n */\nexport function buildCSP(policy: ContentSecurityPolicy): string {\n const directives: string[] = []\n\n const directiveMap: Record<string, string> = {\n defaultSrc: 'default-src',\n scriptSrc: 'script-src',\n styleSrc: 'style-src',\n imgSrc: 'img-src',\n fontSrc: 'font-src',\n connectSrc: 'connect-src',\n mediaSrc: 'media-src',\n objectSrc: 'object-src',\n frameSrc: 'frame-src',\n childSrc: 'child-src',\n workerSrc: 'worker-src',\n frameAncestors: 'frame-ancestors',\n formAction: 'form-action',\n baseUri: 'base-uri',\n manifestSrc: 'manifest-src',\n reportUri: 'report-uri',\n reportTo: 'report-to',\n }\n\n for (const [key, directive] of Object.entries(directiveMap)) {\n const value = policy[key as keyof ContentSecurityPolicy]\n if (value !== undefined && value !== false) {\n if (Array.isArray(value)) {\n directives.push(`${directive} ${value.join(' ')}`)\n } else if (typeof value === 'string') {\n directives.push(`${directive} ${value}`)\n }\n }\n }\n\n if (policy.upgradeInsecureRequests) {\n directives.push('upgrade-insecure-requests')\n }\n\n if (policy.blockAllMixedContent) {\n directives.push('block-all-mixed-content')\n }\n\n return directives.join('; ')\n}\n\n/**\n * Build HSTS header string\n */\nexport function buildHSTS(config: StrictTransportSecurity): string {\n let value = `max-age=${config.maxAge}`\n\n if (config.includeSubDomains) {\n value += '; includeSubDomains'\n }\n\n if (config.preload) {\n value += '; preload'\n }\n\n return value\n}\n\n/**\n * Build Permissions-Policy header string\n */\nexport function buildPermissionsPolicy(policy: PermissionsPolicy): string {\n const directives: string[] = []\n\n const featureMap: Record<string, string> = {\n accelerometer: 'accelerometer',\n ambientLightSensor: 'ambient-light-sensor',\n autoplay: 'autoplay',\n battery: 'battery',\n camera: 'camera',\n displayCapture: 'display-capture',\n documentDomain: 'document-domain',\n encryptedMedia: 'encrypted-media',\n fullscreen: 'fullscreen',\n geolocation: 'geolocation',\n gyroscope: 'gyroscope',\n magnetometer: 'magnetometer',\n microphone: 'microphone',\n midi: 'midi',\n payment: 'payment',\n pictureInPicture: 'picture-in-picture',\n publicKeyCredentialsGet: 'publickey-credentials-get',\n screenWakeLock: 'screen-wake-lock',\n syncXhr: 'sync-xhr',\n usb: 'usb',\n webShare: 'web-share',\n xrSpatialTracking: 'xr-spatial-tracking',\n }\n\n for (const [key, feature] of Object.entries(featureMap)) {\n const origins = policy[key as keyof PermissionsPolicy]\n if (origins !== undefined) {\n if (origins.length === 0) {\n directives.push(`${feature}=()`)\n } else {\n const formatted = origins.map((o) => (o === 'self' ? 'self' : `\"${o}\"`)).join(' ')\n directives.push(`${feature}=(${formatted})`)\n }\n }\n }\n\n return directives.join(', ')\n}\n\n/**\n * Preset: Strict security headers\n */\nexport const PRESET_STRICT: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\"],\n imgSrc: [\"'self'\", 'data:'],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n frameAncestors: [\"'none'\"],\n formAction: [\"'self'\"],\n baseUri: [\"'self'\"],\n upgradeInsecureRequests: true,\n },\n strictTransportSecurity: {\n maxAge: 31536000, // 1 year\n includeSubDomains: true,\n preload: true,\n },\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n xDnsPrefetchControl: 'off',\n xDownloadOptions: true,\n xPermittedCrossDomainPolicies: 'none',\n referrerPolicy: 'strict-origin-when-cross-origin',\n crossOriginOpenerPolicy: 'same-origin',\n crossOriginEmbedderPolicy: 'require-corp',\n crossOriginResourcePolicy: 'same-origin',\n permissionsPolicy: {\n camera: [],\n microphone: [],\n geolocation: [],\n payment: [],\n },\n originAgentCluster: true,\n}\n\n/**\n * Preset: Relaxed security headers (for development or less strict needs)\n */\nexport const PRESET_RELAXED: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\", \"'unsafe-inline'\", \"'unsafe-eval'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'blob:', 'https:'],\n fontSrc: [\"'self'\", 'https:', 'data:'],\n connectSrc: [\"'self'\", 'https:', 'wss:'],\n frameSrc: [\"'self'\"],\n },\n strictTransportSecurity: {\n maxAge: 86400, // 1 day\n includeSubDomains: false,\n },\n xFrameOptions: 'SAMEORIGIN',\n xContentTypeOptions: true,\n referrerPolicy: 'no-referrer-when-downgrade',\n}\n\n/**\n * Preset: API-focused security headers\n */\nexport const PRESET_API: SecurityHeadersConfig = {\n contentSecurityPolicy: {\n defaultSrc: [\"'none'\"],\n frameAncestors: [\"'none'\"],\n },\n strictTransportSecurity: {\n maxAge: 31536000,\n includeSubDomains: true,\n },\n xFrameOptions: 'DENY',\n xContentTypeOptions: true,\n referrerPolicy: 'no-referrer',\n crossOriginResourcePolicy: 'same-origin',\n}\n\n/**\n * Get preset config by name\n */\nexport function getPreset(name: SecurityHeadersPreset): SecurityHeadersConfig {\n switch (name) {\n case 'strict':\n return PRESET_STRICT\n case 'relaxed':\n return PRESET_RELAXED\n case 'api':\n return PRESET_API\n default:\n return PRESET_STRICT\n }\n}\n\n/**\n * Build all headers from config\n */\nexport function buildHeaders(config: SecurityHeadersConfig): Headers {\n const headers = new Headers()\n\n // CSP\n if (config.contentSecurityPolicy) {\n const csp = buildCSP(config.contentSecurityPolicy)\n if (csp) headers.set('Content-Security-Policy', csp)\n }\n\n // HSTS\n if (config.strictTransportSecurity) {\n headers.set('Strict-Transport-Security', buildHSTS(config.strictTransportSecurity))\n }\n\n // X-Frame-Options\n if (config.xFrameOptions) {\n headers.set('X-Frame-Options', config.xFrameOptions)\n }\n\n // X-Content-Type-Options\n if (config.xContentTypeOptions) {\n headers.set('X-Content-Type-Options', 'nosniff')\n }\n\n // X-DNS-Prefetch-Control\n if (config.xDnsPrefetchControl) {\n headers.set('X-DNS-Prefetch-Control', config.xDnsPrefetchControl)\n }\n\n // X-Download-Options\n if (config.xDownloadOptions) {\n headers.set('X-Download-Options', 'noopen')\n }\n\n // X-Permitted-Cross-Domain-Policies\n if (config.xPermittedCrossDomainPolicies) {\n headers.set('X-Permitted-Cross-Domain-Policies', config.xPermittedCrossDomainPolicies)\n }\n\n // Referrer-Policy\n if (config.referrerPolicy) {\n const value = Array.isArray(config.referrerPolicy)\n ? config.referrerPolicy.join(', ')\n : config.referrerPolicy\n headers.set('Referrer-Policy', value)\n }\n\n // COOP\n if (config.crossOriginOpenerPolicy) {\n headers.set('Cross-Origin-Opener-Policy', config.crossOriginOpenerPolicy)\n }\n\n // COEP\n if (config.crossOriginEmbedderPolicy) {\n headers.set('Cross-Origin-Embedder-Policy', config.crossOriginEmbedderPolicy)\n }\n\n // CORP\n if (config.crossOriginResourcePolicy) {\n headers.set('Cross-Origin-Resource-Policy', config.crossOriginResourcePolicy)\n }\n\n // Permissions-Policy\n if (config.permissionsPolicy) {\n const pp = buildPermissionsPolicy(config.permissionsPolicy)\n if (pp) headers.set('Permissions-Policy', pp)\n }\n\n // Origin-Agent-Cluster\n if (config.originAgentCluster) {\n headers.set('Origin-Agent-Cluster', '?1')\n }\n\n return headers\n}\n","import type { NextRequest } from 'next/server'\nimport type { SecurityHeadersConfig, SecurityHeadersPreset } from './types'\nimport { buildHeaders, getPreset, PRESET_STRICT } from './builder'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\nexport interface WithSecurityHeadersOptions {\n /** Use a preset configuration */\n preset?: SecurityHeadersPreset\n\n /** Custom header configuration (merged with preset if provided) */\n config?: SecurityHeadersConfig\n\n /** Override response headers instead of merging */\n override?: boolean\n}\n\n/**\n * Merge two configs, with custom taking precedence\n */\nfunction mergeConfigs(\n base: SecurityHeadersConfig,\n custom: SecurityHeadersConfig\n): SecurityHeadersConfig {\n return {\n ...base,\n ...custom,\n // Deep merge CSP if both exist\n contentSecurityPolicy:\n custom.contentSecurityPolicy === false\n ? false\n : custom.contentSecurityPolicy\n ? base.contentSecurityPolicy\n ? { ...(base.contentSecurityPolicy as object), ...custom.contentSecurityPolicy }\n : custom.contentSecurityPolicy\n : base.contentSecurityPolicy,\n // Deep merge HSTS if both exist\n strictTransportSecurity:\n custom.strictTransportSecurity === false\n ? false\n : custom.strictTransportSecurity\n ? base.strictTransportSecurity\n ? { ...(base.strictTransportSecurity as object), ...custom.strictTransportSecurity }\n : custom.strictTransportSecurity\n : base.strictTransportSecurity,\n // Deep merge Permissions-Policy if both exist\n permissionsPolicy:\n custom.permissionsPolicy === false\n ? false\n : custom.permissionsPolicy\n ? base.permissionsPolicy\n ? { ...(base.permissionsPolicy as object), ...custom.permissionsPolicy }\n : custom.permissionsPolicy\n : base.permissionsPolicy,\n }\n}\n\n/**\n * Security headers middleware\n *\n * Adds security headers to responses. Use presets for quick setup\n * or provide custom configuration.\n *\n * @example\n * ```typescript\n * // Use strict preset\n * export const GET = withSecurityHeaders(handler, { preset: 'strict' })\n *\n * // Custom config\n * export const GET = withSecurityHeaders(handler, {\n * config: {\n * xFrameOptions: 'SAMEORIGIN',\n * referrerPolicy: 'no-referrer'\n * }\n * })\n * ```\n */\nexport function withSecurityHeaders(\n handler: RouteHandler,\n options: WithSecurityHeadersOptions = {}\n): RouteHandler {\n const { preset, config, override = false } = options\n\n // Get base config from preset or default to strict\n let baseConfig: SecurityHeadersConfig = preset ? getPreset(preset) : PRESET_STRICT\n\n // Merge with custom config if provided\n if (config) {\n baseConfig = mergeConfigs(baseConfig, config)\n }\n\n // Pre-build headers for performance\n const securityHeaders = buildHeaders(baseConfig)\n\n return async (req: NextRequest): Promise<Response> => {\n const response = await handler(req)\n\n // Clone response to modify headers\n const newHeaders = new Headers(response.headers)\n\n // Add security headers\n securityHeaders.forEach((value, key) => {\n if (override || !newHeaders.has(key)) {\n newHeaders.set(key, value)\n }\n })\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n })\n }\n}\n\n/**\n * Create headers object for use in responses\n * Useful when you want to add headers manually\n *\n * @example\n * ```typescript\n * const headers = createSecurityHeaders({ preset: 'api' })\n *\n * return Response.json(data, { headers })\n * ```\n */\nexport function createSecurityHeaders(\n options: WithSecurityHeadersOptions = {}\n): Headers {\n const { preset, config } = options\n\n let baseConfig: SecurityHeadersConfig = preset ? getPreset(preset) : PRESET_STRICT\n\n if (config) {\n baseConfig = mergeConfigs(baseConfig, config)\n }\n\n return buildHeaders(baseConfig)\n}\n\n/**\n * Create a headers object as a plain object (for Next.js headers())\n */\nexport function createSecurityHeadersObject(\n options: WithSecurityHeadersOptions = {}\n): Record<string, string> {\n const headers = createSecurityHeaders(options)\n const obj: Record<string, string> = {}\n\n headers.forEach((value, key) => {\n obj[key] = value\n })\n\n return obj\n}\n","import { webcrypto } from 'node:crypto'\nimport type { JWTPayload, JWTConfig, AuthError } from './types'\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\n/**\n * Base64URL decode\n */\nfunction base64UrlDecode(str: string): Uint8Array {\n // Add padding if needed\n const pad = str.length % 4\n if (pad) {\n str += '='.repeat(4 - pad)\n }\n\n // Replace URL-safe chars\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n\n const binary = atob(base64)\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 * Parse JWT without verification (for header inspection)\n */\nexport function decodeJWT(token: string): {\n header: Record<string, unknown>\n payload: JWTPayload\n signature: Uint8Array\n} | null {\n try {\n const parts = token.split('.')\n if (parts.length !== 3) return null\n\n const header = JSON.parse(decoder.decode(base64UrlDecode(parts[0])))\n const payload = JSON.parse(decoder.decode(base64UrlDecode(parts[1])))\n const signature = base64UrlDecode(parts[2])\n\n return { header, payload, signature }\n } catch {\n return null\n }\n}\n\n/**\n * Get crypto algorithm params from JWT algorithm\n */\nfunction getAlgorithmParams(alg: string): {\n name: string\n hash?: string\n namedCurve?: string\n} | null {\n switch (alg) {\n case 'HS256':\n return { name: 'HMAC', hash: 'SHA-256' }\n case 'HS384':\n return { name: 'HMAC', hash: 'SHA-384' }\n case 'HS512':\n return { name: 'HMAC', hash: 'SHA-512' }\n case 'RS256':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }\n case 'RS384':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-384' }\n case 'RS512':\n return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' }\n case 'ES256':\n return { name: 'ECDSA', hash: 'SHA-256', namedCurve: 'P-256' }\n case 'ES384':\n return { name: 'ECDSA', hash: 'SHA-384', namedCurve: 'P-384' }\n case 'ES512':\n return { name: 'ECDSA', hash: 'SHA-512', namedCurve: 'P-521' }\n default:\n return null\n }\n}\n\n/**\n * Verify HMAC signature\n */\nasync function verifyHMAC(\n data: string,\n signature: Uint8Array,\n secret: string,\n hash: string\n): Promise<boolean> {\n const key = await webcrypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash },\n false,\n ['verify']\n )\n\n return webcrypto.subtle.verify('HMAC', key, signature, encoder.encode(data))\n}\n\n/**\n * Import PEM public key\n */\nasync function importPublicKey(\n pem: string,\n algorithm: { name: string; hash?: string; namedCurve?: string }\n): Promise<CryptoKey> {\n // Remove PEM headers and decode\n const pemContents = pem\n .replace(/-----BEGIN.*-----/, '')\n .replace(/-----END.*-----/, '')\n .replace(/\\s/g, '')\n\n const binaryDer = base64UrlDecode(pemContents.replace(/\\+/g, '-').replace(/\\//g, '_'))\n\n const keyUsages: KeyUsage[] = ['verify']\n\n if (algorithm.name === 'RSASSA-PKCS1-v1_5') {\n return webcrypto.subtle.importKey(\n 'spki',\n binaryDer,\n { name: algorithm.name, hash: algorithm.hash! },\n false,\n keyUsages\n )\n }\n\n if (algorithm.name === 'ECDSA') {\n return webcrypto.subtle.importKey(\n 'spki',\n binaryDer,\n { name: algorithm.name, namedCurve: algorithm.namedCurve! },\n false,\n keyUsages\n )\n }\n\n throw new Error(`Unsupported algorithm: ${algorithm.name}`)\n}\n\n/**\n * Verify RSA/ECDSA signature\n */\nasync function verifyAsymmetric(\n data: string,\n signature: Uint8Array,\n publicKey: string,\n algorithm: { name: string; hash?: string; namedCurve?: string }\n): Promise<boolean> {\n const key = await importPublicKey(publicKey, algorithm)\n\n const params = algorithm.name === 'ECDSA'\n ? { name: 'ECDSA', hash: algorithm.hash! } as EcdsaParams\n : algorithm.name\n\n return webcrypto.subtle.verify(params, key, signature, encoder.encode(data))\n}\n\n/**\n * Validate JWT claims\n */\nfunction validateClaims(\n payload: JWTPayload,\n config: JWTConfig\n): AuthError | null {\n const now = Math.floor(Date.now() / 1000)\n const tolerance = config.clockTolerance || 0\n\n // Check expiration\n if (payload.exp !== undefined && payload.exp < now - tolerance) {\n return {\n code: 'expired_token',\n message: 'Token has expired',\n status: 401,\n }\n }\n\n // Check not before\n if (payload.nbf !== undefined && payload.nbf > now + tolerance) {\n return {\n code: 'invalid_token',\n message: 'Token not yet valid',\n status: 401,\n }\n }\n\n // Check issuer\n if (config.issuer) {\n const issuers = Array.isArray(config.issuer) ? config.issuer : [config.issuer]\n if (!payload.iss || !issuers.includes(payload.iss)) {\n return {\n code: 'invalid_token',\n message: 'Invalid token issuer',\n status: 401,\n }\n }\n }\n\n // Check audience\n if (config.audience) {\n const audiences = Array.isArray(config.audience) ? config.audience : [config.audience]\n const tokenAudiences = Array.isArray(payload.aud)\n ? payload.aud\n : payload.aud\n ? [payload.aud]\n : []\n\n const hasValidAudience = audiences.some((aud) => tokenAudiences.includes(aud))\n if (!hasValidAudience) {\n return {\n code: 'invalid_token',\n message: 'Invalid token audience',\n status: 401,\n }\n }\n }\n\n return null\n}\n\n/**\n * Verify and decode JWT\n */\nexport async function verifyJWT(\n token: string,\n config: JWTConfig\n): Promise<{ payload: JWTPayload; error: null } | { payload: null; error: AuthError }> {\n // Decode token\n const decoded = decodeJWT(token)\n if (!decoded) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Malformed token',\n status: 401,\n },\n }\n }\n\n const { header, payload, signature } = decoded\n const alg = header.alg as string\n\n // Check algorithm\n const allowedAlgorithms = config.algorithms || ['HS256']\n if (!allowedAlgorithms.includes(alg)) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: `Algorithm ${alg} not allowed`,\n status: 401,\n },\n }\n }\n\n // Get algorithm params\n const algorithmParams = getAlgorithmParams(alg)\n if (!algorithmParams) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: `Unsupported algorithm: ${alg}`,\n status: 401,\n },\n }\n }\n\n // Verify signature\n const parts = token.split('.')\n const signedData = `${parts[0]}.${parts[1]}`\n let isValid = false\n\n try {\n if (algorithmParams.name === 'HMAC') {\n if (!config.secret) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Secret required for HMAC algorithms',\n status: 500,\n },\n }\n }\n isValid = await verifyHMAC(signedData, signature, config.secret, algorithmParams.hash!)\n } else {\n if (!config.publicKey) {\n return {\n payload: null,\n error: {\n code: 'invalid_token',\n message: 'Public key required for asymmetric algorithms',\n status: 500,\n },\n }\n }\n isValid = await verifyAsymmetric(signedData, signature, config.publicKey, algorithmParams)\n }\n } catch {\n isValid = false\n }\n\n if (!isValid) {\n return {\n payload: null,\n error: {\n code: 'invalid_signature',\n message: 'Invalid token signature',\n status: 401,\n },\n }\n }\n\n // Validate claims\n const claimsError = validateClaims(payload, config)\n if (claimsError) {\n return { payload: null, error: claimsError }\n }\n\n return { payload, error: null }\n}\n\n/**\n * Extract token from Authorization header\n */\nexport function extractBearerToken(authHeader: string | null): string | null {\n if (!authHeader) return null\n if (!authHeader.startsWith('Bearer ')) return null\n return authHeader.slice(7)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n AuthConfig,\n AuthUser,\n AuthError,\n JWTConfig,\n APIKeyConfig,\n SessionConfig,\n RBACConfig,\n} from './types'\nimport { verifyJWT, extractBearerToken } from './jwt'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\ntype AuthenticatedHandler = (\n req: NextRequest,\n ctx: { user: AuthUser; token?: string }\n) => Response | Promise<Response>\n\n/**\n * Default error response\n */\nfunction defaultErrorResponse(_req: NextRequest, error: AuthError): Response {\n return new Response(\n JSON.stringify({\n error: error.code,\n message: error.message,\n }),\n {\n status: error.status,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Extract token from request\n */\nasync function getTokenFromRequest(\n req: NextRequest,\n config?: JWTConfig\n): Promise<string | null> {\n // Custom extractor\n if (config?.getToken) {\n return config.getToken(req)\n }\n\n // Default: Authorization header\n return extractBearerToken(req.headers.get('authorization'))\n}\n\n/**\n * JWT Authentication middleware\n */\nexport function withJWT(\n handler: AuthenticatedHandler,\n config: JWTConfig\n): RouteHandler {\n const secret = config.secret || process.env.JWT_SECRET\n const effectiveConfig = { ...config, secret }\n\n return async (req: NextRequest): Promise<Response> => {\n const token = await getTokenFromRequest(req, effectiveConfig)\n\n if (!token) {\n return defaultErrorResponse(req, {\n code: 'missing_token',\n message: 'Authentication required',\n status: 401,\n })\n }\n\n const { payload, error } = await verifyJWT(token, effectiveConfig)\n\n if (error) {\n return defaultErrorResponse(req, error)\n }\n\n // Map payload to user\n const user: AuthUser = effectiveConfig.mapUser\n ? await effectiveConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n permissions: payload.permissions as string[] | undefined,\n }\n\n return handler(req, { user, token })\n }\n}\n\n/**\n * API Key Authentication middleware\n */\nexport function withAPIKey(\n handler: AuthenticatedHandler,\n config: APIKeyConfig\n): RouteHandler {\n const headerName = config.headerName || 'x-api-key'\n const queryParam = config.queryParam || 'api_key'\n\n return async (req: NextRequest): Promise<Response> => {\n // Try header first\n let apiKey = req.headers.get(headerName)\n\n // Try query param\n if (!apiKey) {\n const url = new URL(req.url)\n apiKey = url.searchParams.get(queryParam)\n }\n\n if (!apiKey) {\n return defaultErrorResponse(req, {\n code: 'missing_api_key',\n message: 'API key required',\n status: 401,\n })\n }\n\n const user = await config.validate(apiKey, req)\n\n if (!user) {\n return defaultErrorResponse(req, {\n code: 'invalid_api_key',\n message: 'Invalid API key',\n status: 401,\n })\n }\n\n return handler(req, { user })\n }\n}\n\n/**\n * Session/Cookie Authentication middleware\n */\nexport function withSession(\n handler: AuthenticatedHandler,\n config: SessionConfig\n): RouteHandler {\n const cookieName = config.cookieName || 'session'\n\n return async (req: NextRequest): Promise<Response> => {\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (!sessionId) {\n return defaultErrorResponse(req, {\n code: 'missing_session',\n message: 'Session required',\n status: 401,\n })\n }\n\n const user = await config.validate(sessionId, req)\n\n if (!user) {\n return defaultErrorResponse(req, {\n code: 'invalid_session',\n message: 'Invalid or expired session',\n status: 401,\n })\n }\n\n return handler(req, { user })\n }\n}\n\n/**\n * Role-based access control middleware\n * Must be used after authentication middleware\n */\nexport function withRoles(\n handler: AuthenticatedHandler,\n config: RBACConfig\n): (req: NextRequest, ctx: { user: AuthUser; token?: string }) => Promise<Response> {\n return async (\n req: NextRequest,\n ctx: { user: AuthUser; token?: string }\n ): Promise<Response> => {\n const { user } = ctx\n\n // Get user roles\n const userRoles = config.getUserRoles\n ? config.getUserRoles(user)\n : user.roles || []\n\n // Check required roles (any match)\n if (config.roles && config.roles.length > 0) {\n const hasRole = config.roles.some((role) => userRoles.includes(role))\n if (!hasRole) {\n return defaultErrorResponse(req, {\n code: 'insufficient_roles',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n // Get user permissions\n const userPermissions = config.getUserPermissions\n ? config.getUserPermissions(user)\n : user.permissions || []\n\n // Check required permissions (all required)\n if (config.permissions && config.permissions.length > 0) {\n const hasAllPermissions = config.permissions.every((perm) =>\n userPermissions.includes(perm)\n )\n if (!hasAllPermissions) {\n return defaultErrorResponse(req, {\n code: 'insufficient_permissions',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n // Custom authorization\n if (config.authorize) {\n const authorized = await config.authorize(user, req)\n if (!authorized) {\n return defaultErrorResponse(req, {\n code: 'unauthorized',\n message: 'Unauthorized',\n status: 403,\n })\n }\n }\n\n return handler(req, ctx)\n }\n}\n\n/**\n * Combined auth middleware with multiple strategies\n */\nexport function withAuth(\n handler: AuthenticatedHandler,\n config: AuthConfig\n): RouteHandler {\n const onError = config.onError || defaultErrorResponse\n\n return async (req: NextRequest): Promise<Response> => {\n let user: AuthUser | null = null\n let token: string | undefined\n\n // Try JWT auth\n if (config.jwt) {\n const secret = config.jwt.secret || process.env.JWT_SECRET\n const jwtConfig = { ...config.jwt, secret }\n const jwtToken = await getTokenFromRequest(req, jwtConfig)\n\n if (jwtToken) {\n const { payload, error } = await verifyJWT(jwtToken, jwtConfig)\n if (!error && payload) {\n user = jwtConfig.mapUser\n ? await jwtConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n }\n token = jwtToken\n }\n }\n }\n\n // Try API Key auth\n if (!user && config.apiKey) {\n const headerName = config.apiKey.headerName || 'x-api-key'\n const queryParam = config.apiKey.queryParam || 'api_key'\n\n let apiKey = req.headers.get(headerName)\n if (!apiKey) {\n const url = new URL(req.url)\n apiKey = url.searchParams.get(queryParam)\n }\n\n if (apiKey) {\n const apiUser = await config.apiKey.validate(apiKey, req)\n if (apiUser) {\n user = apiUser\n }\n }\n }\n\n // Try Session auth\n if (!user && config.session) {\n const cookieName = config.session.cookieName || 'session'\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (sessionId) {\n const sessionUser = await config.session.validate(sessionId, req)\n if (sessionUser) {\n user = sessionUser\n }\n }\n }\n\n // No authentication found\n if (!user) {\n return onError(req, {\n code: 'unauthorized',\n message: 'Authentication required',\n status: 401,\n })\n }\n\n // RBAC check\n if (config.rbac) {\n const userRoles = config.rbac.getUserRoles\n ? config.rbac.getUserRoles(user)\n : user.roles || []\n\n if (config.rbac.roles && config.rbac.roles.length > 0) {\n const hasRole = config.rbac.roles.some((role) => userRoles.includes(role))\n if (!hasRole) {\n return onError(req, {\n code: 'insufficient_roles',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n const userPermissions = config.rbac.getUserPermissions\n ? config.rbac.getUserPermissions(user)\n : user.permissions || []\n\n if (config.rbac.permissions && config.rbac.permissions.length > 0) {\n const hasAllPermissions = config.rbac.permissions.every((perm) =>\n userPermissions.includes(perm)\n )\n if (!hasAllPermissions) {\n return onError(req, {\n code: 'insufficient_permissions',\n message: 'Insufficient permissions',\n status: 403,\n })\n }\n }\n\n if (config.rbac.authorize) {\n const authorized = await config.rbac.authorize(user, req)\n if (!authorized) {\n return onError(req, {\n code: 'unauthorized',\n message: 'Unauthorized',\n status: 403,\n })\n }\n }\n }\n\n // Success callback\n if (config.onSuccess) {\n await config.onSuccess(req, user)\n }\n\n return handler(req, { user, token })\n }\n}\n\n/**\n * Optional auth - doesn't fail if no auth present\n */\nexport function withOptionalAuth(\n handler: (\n req: NextRequest,\n ctx: { user: AuthUser | null; token?: string }\n ) => Response | Promise<Response>,\n config: Omit<AuthConfig, 'rbac'>\n): RouteHandler {\n return async (req: NextRequest): Promise<Response> => {\n let user: AuthUser | null = null\n let token: string | undefined\n\n // Try JWT auth\n if (config.jwt) {\n const secret = config.jwt.secret || process.env.JWT_SECRET\n const jwtConfig = { ...config.jwt, secret }\n const jwtToken = await getTokenFromRequest(req, jwtConfig)\n\n if (jwtToken) {\n const { payload, error } = await verifyJWT(jwtToken, jwtConfig)\n if (!error && payload) {\n user = jwtConfig.mapUser\n ? await jwtConfig.mapUser(payload)\n : {\n id: payload.sub || '',\n email: payload.email as string | undefined,\n name: payload.name as string | undefined,\n roles: payload.roles as string[] | undefined,\n }\n token = jwtToken\n }\n }\n }\n\n // Try API Key auth\n if (!user && config.apiKey) {\n const headerName = config.apiKey.headerName || 'x-api-key'\n let apiKey = req.headers.get(headerName)\n\n if (apiKey) {\n const apiUser = await config.apiKey.validate(apiKey, req)\n if (apiUser) user = apiUser\n }\n }\n\n // Try Session auth\n if (!user && config.session) {\n const cookieName = config.session.cookieName || 'session'\n const sessionId = req.cookies.get(cookieName)?.value\n\n if (sessionId) {\n const sessionUser = await config.session.validate(sessionId, req)\n if (sessionUser) user = sessionUser\n }\n }\n\n return handler(req, { user, token })\n }\n}\n","import type { Schema, CustomSchema, FieldRule, ValidationError, ValidationResult } from './types'\n\n/**\n * Check if a schema is a Zod-like schema (has safeParse method)\n */\nexport function isZodSchema(schema: unknown): schema is Schema {\n return (\n typeof schema === 'object' &&\n schema !== null &&\n 'safeParse' in schema &&\n typeof (schema as Schema).safeParse === 'function'\n )\n}\n\n/**\n * Check if a schema is a custom schema (plain object with field rules)\n */\nexport function isCustomSchema(schema: unknown): schema is CustomSchema {\n if (typeof schema !== 'object' || schema === null) return false\n if ('safeParse' in schema) return false\n\n const entries = Object.entries(schema)\n if (entries.length === 0) return false\n\n return entries.every(([_, rule]) => {\n return typeof rule === 'object' && rule !== null && 'type' in rule\n })\n}\n\n/**\n * Email regex pattern (RFC 5322 simplified)\n */\nconst EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/\n\n/**\n * URL regex pattern (supports domain names, localhost, and IP addresses)\n */\nconst URL_PATTERN = /^https?:\\/\\/(?:(?:www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}|localhost|(?:\\d{1,3}\\.){3}\\d{1,3})(?::\\d{1,5})?(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/\n\n/**\n * UUID regex pattern (v4)\n */\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\n/**\n * ISO date pattern\n */\nconst DATE_PATTERN = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?(?:Z|[+-]\\d{2}:?\\d{2})?)?$/\n\n/**\n * Validate a single field with a rule\n */\nexport function validateField(value: unknown, rule: FieldRule, fieldName: string): ValidationError | null {\n // Handle required\n if (value === undefined || value === null || value === '') {\n if (rule.required) {\n return {\n field: fieldName,\n code: 'required',\n message: rule.message || `${fieldName} is required`,\n received: value,\n }\n }\n return null // Optional field with no value\n }\n\n // Type validation\n switch (rule.type) {\n case 'string':\n if (typeof value !== 'string') {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a string`,\n expected: 'string',\n received: typeof value,\n }\n }\n // String length validation\n if (rule.minLength !== undefined && value.length < rule.minLength) {\n return {\n field: fieldName,\n code: 'too_short',\n message: rule.message || `${fieldName} must be at least ${rule.minLength} characters`,\n received: value.length,\n }\n }\n if (rule.maxLength !== undefined && value.length > rule.maxLength) {\n return {\n field: fieldName,\n code: 'too_long',\n message: rule.message || `${fieldName} must be at most ${rule.maxLength} characters`,\n received: value.length,\n }\n }\n // Pattern validation\n if (rule.pattern && !rule.pattern.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_pattern',\n message: rule.message || `${fieldName} has invalid format`,\n received: value,\n }\n }\n break\n\n case 'number':\n const num = typeof value === 'number' ? value : Number(value)\n if (isNaN(num)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a number`,\n expected: 'number',\n received: typeof value,\n }\n }\n if (rule.integer && !Number.isInteger(num)) {\n return {\n field: fieldName,\n code: 'invalid_integer',\n message: rule.message || `${fieldName} must be an integer`,\n received: num,\n }\n }\n if (rule.min !== undefined && num < rule.min) {\n return {\n field: fieldName,\n code: 'too_small',\n message: rule.message || `${fieldName} must be at least ${rule.min}`,\n received: num,\n }\n }\n if (rule.max !== undefined && num > rule.max) {\n return {\n field: fieldName,\n code: 'too_large',\n message: rule.message || `${fieldName} must be at most ${rule.max}`,\n received: num,\n }\n }\n break\n\n case 'boolean':\n if (typeof value !== 'boolean' && value !== 'true' && value !== 'false') {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be a boolean`,\n expected: 'boolean',\n received: typeof value,\n }\n }\n break\n\n case 'email':\n if (typeof value !== 'string' || !EMAIL_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_email',\n message: rule.message || `${fieldName} must be a valid email address`,\n received: value,\n }\n }\n break\n\n case 'url':\n if (typeof value !== 'string' || !URL_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_url',\n message: rule.message || `${fieldName} must be a valid URL`,\n received: value,\n }\n }\n break\n\n case 'uuid':\n if (typeof value !== 'string' || !UUID_PATTERN.test(value)) {\n return {\n field: fieldName,\n code: 'invalid_uuid',\n message: rule.message || `${fieldName} must be a valid UUID`,\n received: value,\n }\n }\n break\n\n case 'date':\n if (typeof value !== 'string' || !DATE_PATTERN.test(value)) {\n const parsed = new Date(value as string)\n if (isNaN(parsed.getTime())) {\n return {\n field: fieldName,\n code: 'invalid_date',\n message: rule.message || `${fieldName} must be a valid date`,\n received: value,\n }\n }\n }\n break\n\n case 'array':\n if (!Array.isArray(value)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be an array`,\n expected: 'array',\n received: typeof value,\n }\n }\n if (rule.minItems !== undefined && value.length < rule.minItems) {\n return {\n field: fieldName,\n code: 'too_few_items',\n message: rule.message || `${fieldName} must have at least ${rule.minItems} items`,\n received: value.length,\n }\n }\n if (rule.maxItems !== undefined && value.length > rule.maxItems) {\n return {\n field: fieldName,\n code: 'too_many_items',\n message: rule.message || `${fieldName} must have at most ${rule.maxItems} items`,\n received: value.length,\n }\n }\n // Validate items if rule provided\n if (rule.items) {\n for (let i = 0; i < value.length; i++) {\n const itemError = validateField(value[i], rule.items, `${fieldName}[${i}]`)\n if (itemError) return itemError\n }\n }\n break\n\n case 'object':\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return {\n field: fieldName,\n code: 'invalid_type',\n message: rule.message || `${fieldName} must be an object`,\n expected: 'object',\n received: Array.isArray(value) ? 'array' : typeof value,\n }\n }\n break\n }\n\n // Custom validation\n if (rule.custom) {\n const result = rule.custom(value)\n if (result !== true) {\n return {\n field: fieldName,\n code: 'custom_validation',\n message: typeof result === 'string' ? result : rule.message || `${fieldName} failed validation`,\n received: value,\n }\n }\n }\n\n return null\n}\n\n/**\n * Validate data against a custom schema\n */\nexport function validateCustomSchema<T>(data: unknown, schema: CustomSchema): ValidationResult<T> {\n if (typeof data !== 'object' || data === null) {\n return {\n success: false,\n errors: [{\n field: '_root',\n code: 'invalid_type',\n message: 'Expected an object',\n received: data,\n }],\n }\n }\n\n const errors: ValidationError[] = []\n const record = data as Record<string, unknown>\n\n for (const [fieldName, rule] of Object.entries(schema)) {\n const error = validateField(record[fieldName], rule, fieldName)\n if (error) {\n errors.push(error)\n }\n }\n\n if (errors.length > 0) {\n return { success: false, errors }\n }\n\n return { success: true, data: data as T }\n}\n\n/**\n * Validate data against a Zod schema\n */\nexport function validateZodSchema<T>(data: unknown, schema: Schema<T>): ValidationResult<T> {\n const result = schema.safeParse(data)\n\n if (result.success) {\n return { success: true, data: result.data }\n }\n\n const errors: ValidationError[] = result.error.issues.map(issue => ({\n field: issue.path.join('.') || '_root',\n code: issue.code,\n message: issue.message,\n path: issue.path.map(String),\n }))\n\n return { success: false, errors }\n}\n\n/**\n * Deep get value from object by path\n */\nexport function getByPath(obj: unknown, path: string): unknown {\n if (typeof obj !== 'object' || obj === null) return undefined\n\n const parts = path.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (typeof current !== 'object' || current === null) return undefined\n current = (current as Record<string, unknown>)[part]\n }\n\n return current\n}\n\n/**\n * Deep set value in object by path\n */\nexport function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void {\n const parts = path.split('.')\n let current = obj\n\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]\n if (!(part in current) || typeof current[part] !== 'object') {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n\n current[parts[parts.length - 1]] = value\n}\n\n/**\n * Walk through object and apply function to all string values\n */\nexport function walkObject(\n obj: unknown,\n fn: (value: string, path: string) => string,\n path = ''\n): unknown {\n if (typeof obj === 'string') {\n return fn(obj, path)\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, i) => walkObject(item, fn, `${path}[${i}]`))\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n const newPath = path ? `${path}.${key}` : key\n result[key] = walkObject(value, fn, newPath)\n }\n return result\n }\n\n return obj\n}\n\n/**\n * Parse query string to object\n */\nexport function parseQueryString(url: string): Record<string, string | string[]> {\n const result: Record<string, string | string[]> = {}\n\n try {\n const urlObj = new URL(url)\n for (const [key, value] of urlObj.searchParams.entries()) {\n if (key in result) {\n const existing = result[key]\n if (Array.isArray(existing)) {\n existing.push(value)\n } else {\n result[key] = [existing, value]\n }\n } else {\n result[key] = value\n }\n }\n } catch {\n // Invalid URL, return empty\n }\n\n return result\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n Schema,\n CustomSchema,\n ValidationResult,\n ValidationError,\n ValidatedContext,\n} from '../types'\nimport { isZodSchema, isCustomSchema, validateCustomSchema, validateZodSchema, parseQueryString } from '../utils'\n\n/**\n * Validate data against a schema (Zod or custom)\n */\nexport function validate<T>(\n data: unknown,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n if (isZodSchema(schema)) {\n return validateZodSchema(data, schema)\n }\n\n if (isCustomSchema(schema)) {\n return validateCustomSchema<T>(data, schema)\n }\n\n // Unknown schema type\n return {\n success: false,\n errors: [{\n field: '_schema',\n code: 'invalid_schema',\n message: 'Invalid schema provided',\n }],\n }\n}\n\n/**\n * Extract and validate request body\n */\nexport async function validateBody<T>(\n request: NextRequest,\n schema: Schema<T> | CustomSchema\n): Promise<ValidationResult<T>> {\n let body: unknown\n\n try {\n const contentType = request.headers.get('content-type') || ''\n\n if (contentType.includes('application/json')) {\n body = await request.json()\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n const text = await request.text()\n body = Object.fromEntries(new URLSearchParams(text))\n } else if (contentType.includes('multipart/form-data')) {\n const formData = await request.formData()\n const obj: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n // Skip File objects for validation, only include strings\n if (typeof value === 'string') {\n obj[key] = value\n }\n })\n body = obj\n } else {\n // Try JSON as fallback\n try {\n body = await request.json()\n } catch {\n body = {}\n }\n }\n } catch (error) {\n return {\n success: false,\n errors: [{\n field: '_body',\n code: 'parse_error',\n message: 'Failed to parse request body',\n }],\n }\n }\n\n return validate<T>(body, schema)\n}\n\n/**\n * Extract and validate query parameters\n */\nexport function validateQuery<T>(\n request: NextRequest,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n const query = parseQueryString(request.url)\n return validate<T>(query, schema)\n}\n\n/**\n * Validate path parameters (from URL pattern)\n */\nexport function validateParams<T>(\n params: Record<string, string | string[]>,\n schema: Schema<T> | CustomSchema\n): ValidationResult<T> {\n return validate<T>(params, schema)\n}\n\n/**\n * Combined request validation\n */\nexport async function validateRequest<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n request: NextRequest,\n config: {\n body?: Schema<TBody> | CustomSchema\n query?: Schema<TQuery> | CustomSchema\n params?: Schema<TParams> | CustomSchema\n routeParams?: Record<string, string | string[]>\n }\n): Promise<{\n success: boolean\n data?: ValidatedContext<TBody, TQuery, TParams>\n errors?: ValidationError[]\n}> {\n const allErrors: ValidationError[] = []\n const data: Partial<ValidatedContext<TBody, TQuery, TParams>> = {}\n\n // Validate body\n if (config.body) {\n const bodyResult = await validateBody<TBody>(request, config.body)\n if (!bodyResult.success) {\n allErrors.push(...(bodyResult.errors || []).map(e => ({\n ...e,\n field: `body.${e.field}`.replace('body._root', 'body'),\n })))\n } else {\n data.body = bodyResult.data\n }\n } else {\n data.body = {} as TBody\n }\n\n // Validate query\n if (config.query) {\n const queryResult = validateQuery<TQuery>(request, config.query)\n if (!queryResult.success) {\n allErrors.push(...(queryResult.errors || []).map(e => ({\n ...e,\n field: `query.${e.field}`.replace('query._root', 'query'),\n })))\n } else {\n data.query = queryResult.data\n }\n } else {\n data.query = {} as TQuery\n }\n\n // Validate params\n if (config.params && config.routeParams) {\n const paramsResult = validateParams<TParams>(config.routeParams, config.params)\n if (!paramsResult.success) {\n allErrors.push(...(paramsResult.errors || []).map(e => ({\n ...e,\n field: `params.${e.field}`.replace('params._root', 'params'),\n })))\n } else {\n data.params = paramsResult.data\n }\n } else {\n data.params = {} as TParams\n }\n\n if (allErrors.length > 0) {\n return { success: false, errors: allErrors }\n }\n\n return {\n success: true,\n data: data as ValidatedContext<TBody, TQuery, TParams>,\n }\n}\n\n/**\n * Default validation error response\n */\nexport function defaultValidationErrorResponse(\n errors: ValidationError[]\n): Response {\n return new Response(\n JSON.stringify({\n error: 'validation_error',\n message: 'Request validation failed',\n details: errors.map(e => ({\n field: e.field,\n code: e.code,\n message: e.message,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Create a validation function for a schema\n */\nexport function createValidator<T>(\n schema: Schema<T> | CustomSchema\n): (data: unknown) => ValidationResult<T> {\n return (data: unknown) => validate<T>(data, schema)\n}\n\n/**\n * Check if all validation results are successful\n */\nexport function allValid(...results: ValidationResult[]): boolean {\n return results.every(r => r.success)\n}\n\n/**\n * Merge validation errors from multiple results\n */\nexport function mergeErrors(...results: ValidationResult[]): ValidationError[] {\n const errors: ValidationError[] = []\n for (const result of results) {\n if (result.errors) {\n errors.push(...result.errors)\n }\n }\n return errors\n}\n","import type { NextRequest } from 'next/server'\nimport type { ContentTypeConfig } from '../types'\n\n/**\n * Common MIME types\n */\nexport const MIME_TYPES = {\n // Text\n TEXT_PLAIN: 'text/plain',\n TEXT_HTML: 'text/html',\n TEXT_CSS: 'text/css',\n TEXT_JAVASCRIPT: 'text/javascript',\n\n // Application\n JSON: 'application/json',\n FORM_URLENCODED: 'application/x-www-form-urlencoded',\n MULTIPART_FORM: 'multipart/form-data',\n XML: 'application/xml',\n PDF: 'application/pdf',\n ZIP: 'application/zip',\n GZIP: 'application/gzip',\n OCTET_STREAM: 'application/octet-stream',\n\n // Image\n IMAGE_PNG: 'image/png',\n IMAGE_JPEG: 'image/jpeg',\n IMAGE_GIF: 'image/gif',\n IMAGE_WEBP: 'image/webp',\n IMAGE_SVG: 'image/svg+xml',\n\n // Audio\n AUDIO_MP3: 'audio/mpeg',\n AUDIO_WAV: 'audio/wav',\n AUDIO_OGG: 'audio/ogg',\n\n // Video\n VIDEO_MP4: 'video/mp4',\n VIDEO_WEBM: 'video/webm',\n} as const\n\n/**\n * Parse Content-Type header\n */\nexport function parseContentType(header: string | null): {\n type: string\n subtype: string\n mediaType: string\n charset?: string\n boundary?: string\n parameters: Record<string, string>\n} {\n if (!header) {\n return {\n type: '',\n subtype: '',\n mediaType: '',\n parameters: {},\n }\n }\n\n // Split by semicolon to separate media type from parameters\n const parts = header.split(';').map(p => p.trim())\n const mediaType = parts[0].toLowerCase()\n\n // Split media type into type/subtype\n const [type = '', subtype = ''] = mediaType.split('/')\n\n // Parse parameters\n const parameters: Record<string, string> = {}\n for (let i = 1; i < parts.length; i++) {\n const [key, value] = parts[i].split('=').map(p => p.trim())\n if (key && value) {\n // Remove quotes if present\n parameters[key.toLowerCase()] = value.replace(/^[\"']|[\"']$/g, '')\n }\n }\n\n return {\n type,\n subtype,\n mediaType,\n charset: parameters['charset'],\n boundary: parameters['boundary'],\n parameters,\n }\n}\n\n/**\n * Check if Content-Type matches allowed types\n */\nexport function isAllowedContentType(\n contentType: string | null,\n allowedTypes: string[],\n strict = false\n): boolean {\n if (!contentType) {\n return !strict\n }\n\n const { mediaType } = parseContentType(contentType)\n\n return allowedTypes.some(allowed => {\n const normalizedAllowed = allowed.toLowerCase().trim()\n\n // Exact match\n if (mediaType === normalizedAllowed) {\n return true\n }\n\n // Wildcard match (e.g., 'application/*' matches 'application/json')\n if (normalizedAllowed.endsWith('/*')) {\n const prefix = normalizedAllowed.slice(0, -2)\n return mediaType.startsWith(prefix + '/')\n }\n\n // Type-only match (e.g., 'application' matches 'application/json')\n if (!normalizedAllowed.includes('/')) {\n const { type } = parseContentType(contentType)\n return type === normalizedAllowed\n }\n\n return false\n })\n}\n\n/**\n * Validate Content-Type header\n */\nexport function validateContentType(\n request: NextRequest,\n config: ContentTypeConfig\n): { valid: boolean; contentType: string | null; reason?: string } {\n const contentType = request.headers.get('content-type')\n const { allowed, strict = false, charset } = config\n\n // Check if Content-Type is required but missing\n if (strict && !contentType) {\n return {\n valid: false,\n contentType: null,\n reason: 'Content-Type header is required',\n }\n }\n\n // Check if Content-Type is allowed\n if (contentType && !isAllowedContentType(contentType, allowed, strict)) {\n return {\n valid: false,\n contentType,\n reason: `Content-Type '${contentType}' is not allowed`,\n }\n }\n\n // Check charset if specified\n if (charset && contentType) {\n const parsed = parseContentType(contentType)\n if (parsed.charset && parsed.charset.toLowerCase() !== charset.toLowerCase()) {\n return {\n valid: false,\n contentType,\n reason: `Charset '${parsed.charset}' is not allowed, expected '${charset}'`,\n }\n }\n }\n\n return { valid: true, contentType }\n}\n\n/**\n * Default Content-Type validation error response\n */\nexport function defaultContentTypeErrorResponse(\n contentType: string | null,\n reason: string\n): Response {\n return new Response(\n JSON.stringify({\n error: 'invalid_content_type',\n message: reason,\n received: contentType,\n }),\n {\n status: 415, // Unsupported Media Type\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Check if request has JSON content type\n */\nexport function isJsonRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.JSON]\n )\n}\n\n/**\n * Check if request has form content type\n */\nexport function isFormRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.FORM_URLENCODED, MIME_TYPES.MULTIPART_FORM]\n )\n}\n\n/**\n * Check if request has multipart content type\n */\nexport function isMultipartRequest(request: NextRequest): boolean {\n return isAllowedContentType(\n request.headers.get('content-type'),\n [MIME_TYPES.MULTIPART_FORM]\n )\n}\n\n/**\n * Get boundary from multipart Content-Type\n */\nexport function getMultipartBoundary(request: NextRequest): string | null {\n const contentType = request.headers.get('content-type')\n if (!contentType) return null\n\n const { boundary } = parseContentType(contentType)\n return boundary || null\n}\n","import type { PathValidationConfig, PathValidationResult } from '../types'\n\n/**\n * Dangerous path patterns\n */\nconst DANGEROUS_PATTERNS = [\n // Unix path traversal\n /\\.\\.\\//g,\n /\\.\\./g,\n // Windows path traversal\n /\\.\\.\\\\/g,\n // Null byte (can truncate paths in some systems)\n /%00/g,\n /\\0/g,\n // URL encoded traversal\n /%2e%2e%2f/gi, // ../\n /%2e%2e\\//gi, // ../\n /%2e%2e%5c/gi, // ..\\\n /%2e%2e\\\\/gi, // ..\\\n // Double URL encoding\n /%252e%252e%252f/gi,\n /%252e%252e%255c/gi,\n // Unicode encoding\n /\\.%u002e\\//gi,\n /%u002e%u002e%u002f/gi,\n // Overlong UTF-8 encoding\n /%c0%ae%c0%ae%c0%af/gi,\n /%c1%9c/gi, // Backslash variant\n]\n\n/**\n * Default blocked extensions\n */\nconst DEFAULT_BLOCKED_EXTENSIONS = [\n '.exe', '.dll', '.so', '.dylib', // Executables\n '.sh', '.bash', '.bat', '.cmd', '.ps1', // Scripts\n '.php', '.asp', '.aspx', '.jsp', '.cgi', // Server scripts\n '.htaccess', '.htpasswd', // Apache config\n '.env', '.git', '.svn', // Config/VCS\n]\n\n/**\n * Normalize path separators\n */\nfunction normalizePathSeparators(path: string): string {\n return path.replace(/\\\\/g, '/')\n}\n\n/**\n * URL decode a path (handles double encoding)\n */\nfunction decodePathComponent(path: string): string {\n let result = path\n let previous = ''\n\n // Keep decoding until no more changes (handles double encoding)\n while (result !== previous) {\n previous = result\n try {\n result = decodeURIComponent(result)\n } catch {\n break\n }\n }\n\n return result\n}\n\n/**\n * Check if path contains traversal patterns\n */\nexport function hasPathTraversal(path: string): boolean {\n if (!path || typeof path !== 'string') return false\n\n // Normalize and decode\n const normalized = normalizePathSeparators(decodePathComponent(path))\n\n // Check for dangerous patterns\n for (const pattern of DANGEROUS_PATTERNS) {\n pattern.lastIndex = 0\n if (pattern.test(normalized)) {\n return true\n }\n }\n\n // Check for .. sequences (already handled by patterns but double check)\n if (normalized.includes('..')) {\n return true\n }\n\n return false\n}\n\n/**\n * Validate and sanitize a path\n */\nexport function validatePath(\n path: string,\n config: PathValidationConfig = {}\n): PathValidationResult {\n if (!path || typeof path !== 'string') {\n return { valid: false, reason: 'Path is empty or not a string' }\n }\n\n const {\n allowAbsolute = false,\n allowedPrefixes = [],\n allowedExtensions,\n blockedExtensions = DEFAULT_BLOCKED_EXTENSIONS,\n maxDepth = 10,\n maxLength = 255,\n normalize = true,\n } = config\n\n // Check length\n if (path.length > maxLength) {\n return { valid: false, reason: `Path exceeds maximum length of ${maxLength}` }\n }\n\n // Decode and normalize\n let normalized = decodePathComponent(path)\n if (normalize) {\n normalized = normalizePathSeparators(normalized)\n }\n\n // Check for null bytes\n if (normalized.includes('\\0') || path.includes('%00')) {\n return { valid: false, reason: 'Path contains null bytes' }\n }\n\n // Check for path traversal\n if (hasPathTraversal(path)) {\n return { valid: false, reason: 'Path contains traversal sequences' }\n }\n\n // Check absolute path\n const isAbsolute = normalized.startsWith('/') ||\n /^[a-zA-Z]:/.test(normalized) || // Windows drive letter\n normalized.startsWith('\\\\\\\\') // UNC path\n\n if (isAbsolute && !allowAbsolute) {\n return { valid: false, reason: 'Absolute paths are not allowed' }\n }\n\n // Check allowed prefixes\n if (allowedPrefixes.length > 0) {\n const hasValidPrefix = allowedPrefixes.some(prefix => {\n const normalizedPrefix = normalizePathSeparators(prefix)\n return normalized.startsWith(normalizedPrefix)\n })\n\n if (!hasValidPrefix) {\n return { valid: false, reason: 'Path does not start with an allowed prefix' }\n }\n }\n\n // Check path depth\n const segments = normalized.split('/').filter(s => s && s !== '.')\n if (segments.length > maxDepth) {\n return { valid: false, reason: `Path depth exceeds maximum of ${maxDepth}` }\n }\n\n // Get extension\n const lastSegment = segments[segments.length - 1] || ''\n const dotIndex = lastSegment.lastIndexOf('.')\n const extension = dotIndex > 0 ? lastSegment.slice(dotIndex).toLowerCase() : ''\n\n // Check blocked extensions\n if (extension && blockedExtensions.length > 0) {\n if (blockedExtensions.map(e => e.toLowerCase()).includes(extension)) {\n return { valid: false, reason: `Extension ${extension} is not allowed` }\n }\n }\n\n // Check allowed extensions\n if (extension && allowedExtensions && allowedExtensions.length > 0) {\n if (!allowedExtensions.map(e => e.toLowerCase()).includes(extension)) {\n return { valid: false, reason: `Extension ${extension} is not in allowed list` }\n }\n }\n\n // Normalize double slashes\n const sanitized = normalized.replace(/\\/+/g, '/')\n\n return { valid: true, sanitized }\n}\n\n/**\n * Sanitize a path by removing dangerous elements\n */\nexport function sanitizePath(\n path: string,\n config: PathValidationConfig = {}\n): string {\n if (!path || typeof path !== 'string') return ''\n\n const { normalize = true, maxLength = 255 } = config\n\n // Decode\n let result = decodePathComponent(path)\n\n // Normalize separators\n if (normalize) {\n result = normalizePathSeparators(result)\n }\n\n // Remove null bytes\n result = result.replace(/\\0/g, '').replace(/%00/g, '')\n\n // Remove traversal sequences\n result = result.replace(/\\.\\.\\//g, '').replace(/\\.\\.\\\\/g, '')\n\n // Remove leading slashes if not allowed absolute\n if (!config.allowAbsolute) {\n result = result.replace(/^\\/+/, '')\n result = result.replace(/^[a-zA-Z]:/, '')\n result = result.replace(/^\\\\\\\\/, '')\n }\n\n // Remove double slashes\n result = result.replace(/\\/+/g, '/')\n\n // Remove trailing slashes\n result = result.replace(/\\/+$/, '')\n\n // Limit length\n if (result.length > maxLength) {\n result = result.slice(0, maxLength)\n }\n\n return result\n}\n\n/**\n * Check if a path is within a base directory (safe containment)\n */\nexport function isPathContained(path: string, baseDir: string): boolean {\n if (!path || !baseDir) return false\n\n // Normalize both paths\n const normalizedPath = normalizePathSeparators(decodePathComponent(path))\n const normalizedBase = normalizePathSeparators(baseDir)\n\n // Resolve the path (simulate what a file system would do)\n const resolvedPath = resolvePath(normalizedPath, normalizedBase)\n\n // Check if resolved path starts with base directory\n return resolvedPath.startsWith(normalizedBase.replace(/\\/$/, '') + '/')\n}\n\n/**\n * Simple path resolver (simulates path.resolve)\n */\nfunction resolvePath(path: string, base: string): string {\n // Combine base and path\n let combined: string\n if (path.startsWith('/')) {\n combined = path\n } else {\n combined = `${base.replace(/\\/$/, '')}/${path}`\n }\n\n // Resolve . and ..\n const segments: string[] = []\n for (const segment of combined.split('/')) {\n if (segment === '' || segment === '.') {\n continue\n }\n if (segment === '..') {\n segments.pop()\n } else {\n segments.push(segment)\n }\n }\n\n return '/' + segments.join('/')\n}\n\n/**\n * Get the file extension from a path\n */\nexport function getExtension(path: string): string {\n if (!path || typeof path !== 'string') return ''\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/')\n const filename = segments[segments.length - 1] || ''\n\n const dotIndex = filename.lastIndexOf('.')\n if (dotIndex <= 0) return '' // No extension or hidden file\n\n return filename.slice(dotIndex).toLowerCase()\n}\n\n/**\n * Get the filename from a path\n */\nexport function getFilename(path: string): string {\n if (!path || typeof path !== 'string') return ''\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/')\n\n return segments[segments.length - 1] || ''\n}\n\n/**\n * Sanitize a filename (remove dangerous characters)\n */\nexport function sanitizeFilename(filename: string): string {\n if (typeof filename !== 'string') return 'file'\n if (!filename) return 'file'\n\n let result = filename\n\n // Remove path separators\n result = result.replace(/[/\\\\]/g, '')\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n // Remove control characters\n result = result.replace(/[\\x00-\\x1f\\x7f]/g, '')\n\n // Remove dangerous characters for file systems\n result = result.replace(/[<>:\"|?*]/g, '')\n\n // Remove leading/trailing dots and spaces\n result = result.replace(/^[.\\s]+|[.\\s]+$/g, '')\n\n // Limit length (common file system limit)\n if (result.length > 255) {\n const ext = getExtension(result)\n const name = result.slice(0, 255 - ext.length)\n result = name + ext\n }\n\n return result || 'file'\n}\n\n/**\n * Check if path is a hidden file (starts with dot)\n */\nexport function isHiddenPath(path: string): boolean {\n if (!path) return false\n\n const normalized = normalizePathSeparators(path)\n const segments = normalized.split('/').filter(Boolean)\n\n return segments.some(segment => segment.startsWith('.'))\n}\n","import type { NextRequest } from 'next/server'\nimport type { FileValidationConfig, FileValidationError, FileInfo, MagicNumber } from '../types'\nimport { sanitizeFilename, getExtension } from '../sanitizers/path'\n\n/**\n * Known magic numbers for file type validation\n */\nconst MAGIC_NUMBERS: MagicNumber[] = [\n // Images\n { type: 'image/jpeg', extension: '.jpg', signature: [0xFF, 0xD8, 0xFF] },\n { type: 'image/png', extension: '.png', signature: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] },\n { type: 'image/gif', extension: '.gif', signature: [0x47, 0x49, 0x46, 0x38] }, // GIF87a or GIF89a\n { type: 'image/webp', extension: '.webp', signature: [0x52, 0x49, 0x46, 0x46], offset: 0 }, // RIFF\n { type: 'image/bmp', extension: '.bmp', signature: [0x42, 0x4D] },\n { type: 'image/tiff', extension: '.tiff', signature: [0x49, 0x49, 0x2A, 0x00] }, // Little endian\n { type: 'image/tiff', extension: '.tiff', signature: [0x4D, 0x4D, 0x00, 0x2A] }, // Big endian\n { type: 'image/x-icon', extension: '.ico', signature: [0x00, 0x00, 0x01, 0x00] },\n { type: 'image/svg+xml', extension: '.svg', signature: [0x3C, 0x3F, 0x78, 0x6D, 0x6C] }, // <?xml\n\n // Documents\n { type: 'application/pdf', extension: '.pdf', signature: [0x25, 0x50, 0x44, 0x46] }, // %PDF\n { type: 'application/zip', extension: '.zip', signature: [0x50, 0x4B, 0x03, 0x04] }, // PK\n { type: 'application/gzip', extension: '.gz', signature: [0x1F, 0x8B] },\n { type: 'application/x-rar-compressed', extension: '.rar', signature: [0x52, 0x61, 0x72, 0x21] },\n { type: 'application/x-7z-compressed', extension: '.7z', signature: [0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C] },\n\n // Microsoft Office (new format - zip based)\n { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', extension: '.xlsx', signature: [0x50, 0x4B, 0x03, 0x04] },\n { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extension: '.docx', signature: [0x50, 0x4B, 0x03, 0x04] },\n { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', extension: '.pptx', signature: [0x50, 0x4B, 0x03, 0x04] },\n\n // Microsoft Office (old format)\n { type: 'application/msword', extension: '.doc', signature: [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1] },\n { type: 'application/vnd.ms-excel', extension: '.xls', signature: [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1] },\n\n // Audio\n { type: 'audio/mpeg', extension: '.mp3', signature: [0xFF, 0xFB] }, // MP3 frame sync\n { type: 'audio/mpeg', extension: '.mp3', signature: [0x49, 0x44, 0x33] }, // ID3\n { type: 'audio/wav', extension: '.wav', signature: [0x52, 0x49, 0x46, 0x46] }, // RIFF\n { type: 'audio/ogg', extension: '.ogg', signature: [0x4F, 0x67, 0x67, 0x53] },\n { type: 'audio/flac', extension: '.flac', signature: [0x66, 0x4C, 0x61, 0x43] },\n\n // Video\n { type: 'video/mp4', extension: '.mp4', signature: [0x00, 0x00, 0x00], offset: 0 }, // Partial match\n { type: 'video/webm', extension: '.webm', signature: [0x1A, 0x45, 0xDF, 0xA3] },\n { type: 'video/avi', extension: '.avi', signature: [0x52, 0x49, 0x46, 0x46] }, // RIFF\n { type: 'video/quicktime', extension: '.mov', signature: [0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70] },\n\n // Web\n { type: 'application/wasm', extension: '.wasm', signature: [0x00, 0x61, 0x73, 0x6D] }, // \\0asm\n\n // Fonts\n { type: 'font/woff', extension: '.woff', signature: [0x77, 0x4F, 0x46, 0x46] },\n { type: 'font/woff2', extension: '.woff2', signature: [0x77, 0x4F, 0x46, 0x32] },\n]\n\n/**\n * Default file size limits\n */\nexport const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB\nexport const DEFAULT_MAX_FILES = 10\n\n/**\n * Dangerous file extensions to block by default\n */\nexport const DANGEROUS_EXTENSIONS = [\n '.exe', '.dll', '.so', '.dylib', '.bin',\n '.sh', '.bash', '.bat', '.cmd', '.ps1', '.vbs',\n '.php', '.asp', '.aspx', '.jsp', '.cgi', '.pl',\n '.py', '.rb', '.jar', '.class',\n '.msi', '.dmg', '.pkg', '.deb', '.rpm',\n '.scr', '.pif', '.com', '.hta',\n]\n\n/**\n * Check magic number signature\n */\nexport function checkMagicNumber(bytes: Uint8Array, magicNumber: MagicNumber): boolean {\n const offset = magicNumber.offset || 0\n const signature = magicNumber.signature\n\n if (bytes.length < offset + signature.length) {\n return false\n }\n\n for (let i = 0; i < signature.length; i++) {\n if (bytes[offset + i] !== signature[i]) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Detect file type from magic number\n */\nexport function detectFileType(bytes: Uint8Array): { type: string; extension: string } | null {\n for (const magic of MAGIC_NUMBERS) {\n if (checkMagicNumber(bytes, magic)) {\n return { type: magic.type, extension: magic.extension }\n }\n }\n return null\n}\n\n/**\n * Validate a single file\n */\nexport async function validateFile(\n file: File,\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; info: FileInfo; errors: FileValidationError[] }> {\n const {\n maxSize = DEFAULT_MAX_FILE_SIZE,\n minSize = 0,\n allowedTypes = [],\n blockedTypes = [],\n allowedExtensions = [],\n blockedExtensions = DANGEROUS_EXTENSIONS,\n validateMagicNumbers = true,\n sanitizeFilename: doSanitize = true,\n } = config\n\n const errors: FileValidationError[] = []\n const extension = getExtension(file.name)\n\n const info: FileInfo = {\n filename: doSanitize ? sanitizeFilename(file.name) : file.name,\n size: file.size,\n type: file.type,\n extension,\n }\n\n // Check size\n if (file.size > maxSize) {\n errors.push({\n filename: file.name,\n code: 'size_exceeded',\n message: `File size (${formatBytes(file.size)}) exceeds maximum allowed (${formatBytes(maxSize)})`,\n details: { size: file.size, maxSize },\n })\n }\n\n if (file.size < minSize) {\n errors.push({\n filename: file.name,\n code: 'size_too_small',\n message: `File size (${formatBytes(file.size)}) is below minimum required (${formatBytes(minSize)})`,\n details: { size: file.size, minSize },\n })\n }\n\n // Check extension\n if (blockedExtensions.length > 0 && extension) {\n if (blockedExtensions.map(e => e.toLowerCase()).includes(extension.toLowerCase())) {\n errors.push({\n filename: file.name,\n code: 'extension_not_allowed',\n message: `File extension '${extension}' is not allowed`,\n details: { extension, blockedExtensions },\n })\n }\n }\n\n if (allowedExtensions.length > 0 && extension) {\n if (!allowedExtensions.map(e => e.toLowerCase()).includes(extension.toLowerCase())) {\n errors.push({\n filename: file.name,\n code: 'extension_not_allowed',\n message: `File extension '${extension}' is not in allowed list`,\n details: { extension, allowedExtensions },\n })\n }\n }\n\n // Check MIME type\n if (blockedTypes.length > 0 && file.type) {\n if (blockedTypes.includes(file.type)) {\n errors.push({\n filename: file.name,\n code: 'type_not_allowed',\n message: `File type '${file.type}' is not allowed`,\n details: { type: file.type, blockedTypes },\n })\n }\n }\n\n if (allowedTypes.length > 0) {\n if (!allowedTypes.includes(file.type)) {\n errors.push({\n filename: file.name,\n code: 'type_not_allowed',\n message: `File type '${file.type}' is not in allowed list`,\n details: { type: file.type, allowedTypes },\n })\n }\n }\n\n // Validate magic numbers\n if (validateMagicNumbers && errors.length === 0) {\n try {\n const buffer = await file.arrayBuffer()\n const bytes = new Uint8Array(buffer.slice(0, 32)) // Read first 32 bytes\n const detected = detectFileType(bytes)\n\n if (detected) {\n // Check if detected type matches claimed type\n if (file.type && detected.type !== file.type) {\n // Allow some flexibility for similar types\n const isSimilar =\n (detected.type.startsWith('image/') && file.type.startsWith('image/')) ||\n (detected.type.startsWith('audio/') && file.type.startsWith('audio/')) ||\n (detected.type.startsWith('video/') && file.type.startsWith('video/'))\n\n if (!isSimilar) {\n errors.push({\n filename: file.name,\n code: 'invalid_content',\n message: `File content doesn't match declared type (claimed: ${file.type}, detected: ${detected.type})`,\n details: { claimed: file.type, detected: detected.type },\n })\n }\n }\n }\n } catch {\n // Ignore read errors\n }\n }\n\n return {\n valid: errors.length === 0,\n info,\n errors,\n }\n}\n\n/**\n * Validate multiple files\n */\nexport async function validateFiles(\n files: File[],\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; infos: FileInfo[]; errors: FileValidationError[] }> {\n const { maxFiles = DEFAULT_MAX_FILES } = config\n\n const allErrors: FileValidationError[] = []\n const infos: FileInfo[] = []\n\n // Check total file count\n if (files.length > maxFiles) {\n allErrors.push({\n filename: '',\n code: 'too_many_files',\n message: `Too many files (${files.length}), maximum allowed is ${maxFiles}`,\n details: { count: files.length, maxFiles },\n })\n }\n\n // Validate each file\n for (const file of files) {\n const result = await validateFile(file, config)\n infos.push(result.info)\n allErrors.push(...result.errors)\n }\n\n return {\n valid: allErrors.length === 0,\n infos,\n errors: allErrors,\n }\n}\n\n/**\n * Extract files from FormData\n */\nexport function extractFilesFromFormData(formData: FormData): Map<string, File[]> {\n const files = new Map<string, File[]>()\n\n formData.forEach((value, key) => {\n if (value instanceof File) {\n const existing = files.get(key) || []\n existing.push(value)\n files.set(key, existing)\n }\n })\n\n return files\n}\n\n/**\n * Validate files from a request\n */\nexport async function validateFilesFromRequest(\n request: NextRequest,\n config: FileValidationConfig = {}\n): Promise<{ valid: boolean; files: Map<string, FileInfo[]>; errors: FileValidationError[] }> {\n const contentType = request.headers.get('content-type') || ''\n\n if (!contentType.includes('multipart/form-data')) {\n return { valid: true, files: new Map(), errors: [] }\n }\n\n try {\n const formData = await request.formData()\n const fileMap = extractFilesFromFormData(formData)\n\n const allInfos = new Map<string, FileInfo[]>()\n const allErrors: FileValidationError[] = []\n\n let totalFileCount = 0\n\n for (const [field, files] of fileMap.entries()) {\n totalFileCount += files.length\n const result = await validateFiles(files, { ...config, maxFiles: Infinity }) // Check max later\n\n allInfos.set(field, result.infos)\n allErrors.push(...result.errors.map(e => ({ ...e, field })))\n }\n\n // Check total file count across all fields\n const maxFiles = config.maxFiles ?? DEFAULT_MAX_FILES\n if (totalFileCount > maxFiles) {\n allErrors.push({\n filename: '',\n code: 'too_many_files',\n message: `Total file count (${totalFileCount}) exceeds maximum (${maxFiles})`,\n details: { count: totalFileCount, maxFiles },\n })\n }\n\n return {\n valid: allErrors.length === 0,\n files: allInfos,\n errors: allErrors,\n }\n } catch {\n return {\n valid: false,\n files: new Map(),\n errors: [{\n filename: '',\n code: 'invalid_content',\n message: 'Failed to parse multipart form data',\n }],\n }\n }\n}\n\n/**\n * Default file validation error response\n */\nexport function defaultFileErrorResponse(errors: FileValidationError[]): Response {\n return new Response(\n JSON.stringify({\n error: 'file_validation_error',\n message: 'File validation failed',\n details: errors.map(e => ({\n filename: e.filename,\n field: e.field,\n code: e.code,\n message: e.message,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n}\n\n/**\n * Format bytes to human readable string\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B'\n\n const units = ['B', 'KB', 'MB', 'GB']\n const k = 1024\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${units[i]}`\n}\n","import type { SanitizeConfig } from '../types'\n\n/**\n * Default allowed tags for 'allow-safe' mode\n */\nconst DEFAULT_ALLOWED_TAGS = [\n 'a', 'abbr', 'b', 'blockquote', 'br', 'code', 'del', 'em', 'h1', 'h2', 'h3',\n 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'li', 'mark', 'ol', 'p', 'pre', 'q',\n 's', 'small', 'span', 'strong', 'sub', 'sup', 'u', 'ul',\n]\n\n/**\n * Default allowed attributes per tag\n */\nconst DEFAULT_ALLOWED_ATTRIBUTES: Record<string, string[]> = {\n a: ['href', 'title', 'target', 'rel'],\n img: ['src', 'alt', 'title', 'width', 'height'],\n abbr: ['title'],\n q: ['cite'],\n blockquote: ['cite'],\n}\n\n/**\n * Safe protocols for URLs\n */\nconst DEFAULT_SAFE_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:']\n\n/**\n * Dangerous patterns to detect\n */\nconst DANGEROUS_PATTERNS = [\n // Event handlers\n /\\bon\\w+\\s*=/gi,\n // JavaScript protocol\n /javascript\\s*:/gi,\n // VBScript protocol\n /vbscript\\s*:/gi,\n // Data URI with scripts\n /data\\s*:[^,]*(?:text\\/html|application\\/javascript|text\\/javascript)/gi,\n // Expression in CSS\n /expression\\s*\\(/gi,\n // Binding in CSS (Firefox)\n /-moz-binding\\s*:/gi,\n // Behavior in CSS (IE)\n /behavior\\s*:/gi,\n // Import in CSS\n /@import/gi,\n // Script tags\n /<\\s*script/gi,\n // Style tags with expressions\n /<\\s*style[^>]*>[^<]*expression/gi,\n // SVG with scripts\n /<\\s*svg[^>]*onload/gi,\n // Object/embed/applet tags\n /<\\s*(object|embed|applet)/gi,\n // Base tag (can redirect resources)\n /<\\s*base/gi,\n // Meta refresh\n /<\\s*meta[^>]*http-equiv\\s*=\\s*[\"']?refresh/gi,\n // Form action hijacking\n /<\\s*form[^>]*action\\s*=\\s*[\"']?javascript/gi,\n // Link tag with import\n /<\\s*link[^>]*rel\\s*=\\s*[\"']?import/gi,\n]\n\n/**\n * HTML entities map\n */\nconst HTML_ENTITIES: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#x27;',\n '/': '&#x2F;',\n '`': '&#x60;',\n '=': '&#x3D;',\n}\n\n/**\n * Escape HTML special characters\n */\nexport function escapeHtml(str: string): string {\n return str.replace(/[&<>\"'`=/]/g, char => HTML_ENTITIES[char] || char)\n}\n\n/**\n * Unescape HTML entities\n */\nexport function unescapeHtml(str: string): string {\n const entityMap: Record<string, string> = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#x27;': \"'\",\n '&#x2F;': '/',\n '&#x60;': '`',\n '&#x3D;': '=',\n '&#39;': \"'\",\n '&#47;': '/',\n }\n\n return str.replace(/&(?:amp|lt|gt|quot|#x27|#x2F|#x60|#x3D|#39|#47);/gi, entity => {\n return entityMap[entity.toLowerCase()] || entity\n })\n}\n\n/**\n * Strip all HTML tags\n */\nexport function stripHtml(str: string): string {\n // Remove script and style content completely\n let result = str.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n result = result.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n\n // Remove all HTML tags\n result = result.replace(/<[^>]*>/g, '')\n\n // Decode entities\n result = unescapeHtml(result)\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n return result.trim()\n}\n\n/**\n * Check if a URL is safe\n */\nexport function isSafeUrl(url: string, allowedProtocols: string[] = DEFAULT_SAFE_PROTOCOLS): boolean {\n if (!url) return true\n\n // Normalize\n const trimmed = url.trim().toLowerCase()\n\n // Check for dangerous protocols\n if (trimmed.startsWith('javascript:')) return false\n if (trimmed.startsWith('vbscript:')) return false\n\n // Allow data:image URLs (commonly used for base64 images)\n if (trimmed.startsWith('data:image/')) return true\n\n // Block other data URLs\n if (trimmed.startsWith('data:')) return false\n\n // Check if protocol is allowed\n try {\n const parsed = new URL(url, 'https://example.com')\n if (parsed.protocol && !allowedProtocols.includes(parsed.protocol)) {\n // Allow relative URLs\n if (!url.includes(':')) return true\n return false\n }\n } catch {\n // Relative URL, allow\n return true\n }\n\n return true\n}\n\n/**\n * Sanitize HTML with allowed tags\n */\nexport function sanitizeHtml(\n str: string,\n allowedTags: string[] = DEFAULT_ALLOWED_TAGS,\n allowedAttributes: Record<string, string[]> = DEFAULT_ALLOWED_ATTRIBUTES,\n allowedProtocols: string[] = DEFAULT_SAFE_PROTOCOLS\n): string {\n // Remove null bytes first\n let result = str.replace(/\\0/g, '')\n\n // Remove script and style content completely\n result = result.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n result = result.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n\n // Remove comments\n result = result.replace(/<!--[\\s\\S]*?-->/g, '')\n\n // Process tags\n result = result.replace(/<\\/?([a-z][a-z0-9]*)\\b([^>]*)>/gi, (match, tagName, attributes) => {\n const lowerTag = tagName.toLowerCase()\n const isClosing = match.startsWith('</')\n\n // Check if tag is allowed\n if (!allowedTags.includes(lowerTag)) {\n return ''\n }\n\n if (isClosing) {\n return `</${lowerTag}>`\n }\n\n // Process attributes\n const allowedAttrs = allowedAttributes[lowerTag] || []\n const safeAttrs: string[] = []\n\n // Parse attributes\n const attrRegex = /([a-z][a-z0-9-]*)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]*))/gi\n let attrMatch\n\n while ((attrMatch = attrRegex.exec(attributes)) !== null) {\n const attrName = attrMatch[1].toLowerCase()\n const attrValue = attrMatch[2] || attrMatch[3] || attrMatch[4] || ''\n\n // Check if attribute is allowed\n if (!allowedAttrs.includes(attrName)) continue\n\n // Check for dangerous patterns in value\n if (DANGEROUS_PATTERNS.some(pattern => pattern.test(attrValue))) continue\n\n // Check URL attributes\n if (['href', 'src', 'action', 'formaction'].includes(attrName)) {\n if (!isSafeUrl(attrValue, allowedProtocols)) continue\n }\n\n // Escape attribute value\n const safeValue = escapeHtml(attrValue)\n safeAttrs.push(`${attrName}=\"${safeValue}\"`)\n }\n\n const attrStr = safeAttrs.length > 0 ? ' ' + safeAttrs.join(' ') : ''\n return `<${lowerTag}${attrStr}>`\n })\n\n // Final check for any remaining dangerous patterns\n for (const pattern of DANGEROUS_PATTERNS) {\n result = result.replace(pattern, '')\n }\n\n return result\n}\n\n/**\n * Detect if string contains potential XSS\n */\nexport function detectXSS(str: string): boolean {\n if (!str || typeof str !== 'string') return false\n\n // Normalize\n const normalized = str\n .replace(/\\\\x([0-9a-f]{2})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/\\\\u([0-9a-f]{4})/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#x([0-9a-f]+);?/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#(\\d+);?/gi, (_, dec) => String.fromCharCode(parseInt(dec, 10)))\n\n // Reset lastIndex for global regexes before testing\n for (const pattern of DANGEROUS_PATTERNS) {\n pattern.lastIndex = 0\n if (pattern.test(normalized)) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Main sanitize function\n */\nexport function sanitize(input: string, config: SanitizeConfig = {}): string {\n if (!input || typeof input !== 'string') return ''\n\n const {\n mode = 'escape',\n allowedTags = DEFAULT_ALLOWED_TAGS,\n allowedAttributes = DEFAULT_ALLOWED_ATTRIBUTES,\n allowedProtocols = DEFAULT_SAFE_PROTOCOLS,\n maxLength,\n stripNull = true,\n } = config\n\n let result = input\n\n // Strip null bytes\n if (stripNull) {\n result = result.replace(/\\0/g, '')\n }\n\n // Apply sanitization based on mode\n switch (mode) {\n case 'escape':\n result = escapeHtml(result)\n break\n\n case 'strip':\n result = stripHtml(result)\n break\n\n case 'allow-safe':\n result = sanitizeHtml(result, allowedTags, allowedAttributes, allowedProtocols)\n break\n }\n\n // Apply max length\n if (maxLength !== undefined && result.length > maxLength) {\n result = result.slice(0, maxLength)\n }\n\n return result\n}\n\n/**\n * Sanitize object values recursively\n */\nexport function sanitizeObject<T>(obj: T, config: SanitizeConfig = {}): T {\n if (typeof obj === 'string') {\n return sanitize(obj, config) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => sanitizeObject(item, config)) as T\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n result[key] = sanitizeObject(value, config)\n }\n return result as T\n }\n\n return obj\n}\n\n/**\n * Sanitize specific fields in an object\n */\nexport function sanitizeFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[],\n config: SanitizeConfig = {}\n): T {\n const result = { ...obj }\n\n for (const field of fields) {\n if (field in result && typeof result[field] === 'string') {\n (result as Record<string, unknown>)[field] = sanitize(result[field] as string, config)\n }\n }\n\n return result\n}\n","import type { SQLDetection } from '../types'\n\n/**\n * SQL injection patterns with severity levels\n */\ninterface SQLPattern {\n pattern: RegExp\n name: string\n severity: 'low' | 'medium' | 'high'\n}\n\n/**\n * Common SQL injection patterns\n */\nconst SQL_PATTERNS: SQLPattern[] = [\n // High severity - Definite attacks\n {\n pattern: /'\\s*OR\\s+'?\\d+'?\\s*=\\s*'?\\d+'?/gi,\n name: \"OR '1'='1' attack\",\n severity: 'high',\n },\n {\n pattern: /'\\s*OR\\s+'[^']*'\\s*=\\s*'[^']*'/gi,\n name: \"OR 'x'='x' attack\",\n severity: 'high',\n },\n {\n pattern: /;\\s*DROP\\s+(TABLE|DATABASE|INDEX|VIEW)/gi,\n name: 'DROP statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*DELETE\\s+FROM/gi,\n name: 'DELETE statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*TRUNCATE\\s+/gi,\n name: 'TRUNCATE statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*INSERT\\s+INTO/gi,\n name: 'INSERT statement',\n severity: 'high',\n },\n {\n pattern: /;\\s*UPDATE\\s+\\w+\\s+SET/gi,\n name: 'UPDATE statement',\n severity: 'high',\n },\n {\n pattern: /UNION\\s+(ALL\\s+)?SELECT/gi,\n name: 'UNION SELECT attack',\n severity: 'high',\n },\n {\n pattern: /EXEC(\\s+|\\()+(sp_|xp_)/gi,\n name: 'SQL Server stored procedure',\n severity: 'high',\n },\n {\n pattern: /EXECUTE\\s+IMMEDIATE/gi,\n name: 'Oracle EXECUTE IMMEDIATE',\n severity: 'high',\n },\n {\n pattern: /INTO\\s+(OUT|DUMP)FILE/gi,\n name: 'MySQL file write',\n severity: 'high',\n },\n {\n pattern: /LOAD_FILE\\s*\\(/gi,\n name: 'MySQL file read',\n severity: 'high',\n },\n {\n pattern: /BENCHMARK\\s*\\(\\s*\\d+\\s*,/gi,\n name: 'MySQL BENCHMARK DoS',\n severity: 'high',\n },\n {\n pattern: /SLEEP\\s*\\(\\s*\\d+\\s*\\)/gi,\n name: 'SQL SLEEP time-based attack',\n severity: 'high',\n },\n {\n pattern: /WAITFOR\\s+DELAY/gi,\n name: 'SQL Server WAITFOR DELAY',\n severity: 'high',\n },\n {\n pattern: /PG_SLEEP\\s*\\(/gi,\n name: 'PostgreSQL pg_sleep',\n severity: 'high',\n },\n\n // Medium severity - Likely attacks\n {\n pattern: /'\\s*--/g,\n name: 'SQL comment injection',\n severity: 'medium',\n },\n {\n pattern: /'\\s*#/g,\n name: 'MySQL comment injection',\n severity: 'medium',\n },\n {\n pattern: /\\/\\*[\\s\\S]*?\\*\\//g,\n name: 'Block comment',\n severity: 'medium',\n },\n {\n pattern: /'\\s*;\\s*$/g,\n name: 'Statement terminator',\n severity: 'medium',\n },\n {\n pattern: /HAVING\\s+\\d+\\s*=\\s*\\d+/gi,\n name: 'HAVING clause injection',\n severity: 'medium',\n },\n {\n pattern: /GROUP\\s+BY\\s+\\d+/gi,\n name: 'GROUP BY injection',\n severity: 'medium',\n },\n {\n pattern: /ORDER\\s+BY\\s+\\d+/gi,\n name: 'ORDER BY injection',\n severity: 'medium',\n },\n {\n pattern: /CONCAT\\s*\\(/gi,\n name: 'CONCAT function',\n severity: 'medium',\n },\n {\n pattern: /CHAR\\s*\\(\\s*\\d+\\s*\\)/gi,\n name: 'CHAR function bypass',\n severity: 'medium',\n },\n {\n pattern: /0x[0-9a-f]{2,}/gi,\n name: 'Hex encoded value',\n severity: 'medium',\n },\n {\n pattern: /CONVERT\\s*\\(/gi,\n name: 'CONVERT function',\n severity: 'medium',\n },\n {\n pattern: /CAST\\s*\\(/gi,\n name: 'CAST function',\n severity: 'medium',\n },\n\n // Low severity - Suspicious but may be false positives\n {\n pattern: /'\\s*AND\\s+'?\\d+'?\\s*=\\s*'?\\d+'?/gi,\n name: \"AND '1'='1' pattern\",\n severity: 'low',\n },\n {\n pattern: /'\\s*AND\\s+'[^']*'\\s*=\\s*'[^']*'/gi,\n name: \"AND 'x'='x' pattern\",\n severity: 'low',\n },\n {\n pattern: /SELECT\\s+[\\w\\s,*]+\\s+FROM/gi,\n name: 'SELECT statement',\n severity: 'low',\n },\n {\n pattern: /'\\s*\\+\\s*'/g,\n name: 'String concatenation',\n severity: 'low',\n },\n {\n pattern: /'\\s*\\|\\|\\s*'/g,\n name: 'Oracle string concatenation',\n severity: 'low',\n },\n]\n\n/**\n * Additional encoded patterns (URL, hex, unicode)\n * Note: These match on the NORMALIZED (decoded) input\n */\nconst ENCODED_PATTERNS: SQLPattern[] = [\n {\n pattern: /%27\\s*%4f%52\\s*%27/gi, // URL encoded ' OR '\n name: 'URL encoded OR injection',\n severity: 'high',\n },\n {\n pattern: /%27\\s*%2d%2d/gi, // URL encoded ' --\n name: 'URL encoded comment injection',\n severity: 'medium',\n },\n {\n pattern: /\\0|%00/g, // Null byte (decoded or encoded)\n name: 'Null byte injection',\n severity: 'high',\n },\n {\n pattern: /\\\\x27/gi, // Hex escape\n name: 'Hex escaped quote',\n severity: 'medium',\n },\n {\n pattern: /\\\\u0027/gi, // Unicode escape\n name: 'Unicode escaped quote',\n severity: 'medium',\n },\n]\n\n/**\n * Normalize input by decoding common encodings\n */\nfunction normalizeInput(input: string): string {\n let result = input\n\n // URL decode\n try {\n result = decodeURIComponent(result)\n } catch {\n // Ignore decode errors\n }\n\n // HTML entity decode\n result = result\n .replace(/&#x([0-9a-f]+);?/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)))\n .replace(/&#(\\d+);?/gi, (_, dec) => String.fromCharCode(parseInt(dec, 10)))\n .replace(/&quot;/gi, '\"')\n .replace(/&apos;/gi, \"'\")\n .replace(/&lt;/gi, '<')\n .replace(/&gt;/gi, '>')\n .replace(/&amp;/gi, '&')\n\n // Hex escape decode\n result = result.replace(/\\\\x([0-9a-f]{2})/gi, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n )\n\n // Unicode escape decode\n result = result.replace(/\\\\u([0-9a-f]{4})/gi, (_, hex) =>\n String.fromCharCode(parseInt(hex, 16))\n )\n\n return result\n}\n\n/**\n * Detect SQL injection in a string\n */\nexport function detectSQLInjection(\n input: string,\n options: {\n customPatterns?: RegExp[]\n checkEncoded?: boolean\n minSeverity?: 'low' | 'medium' | 'high'\n } = {}\n): SQLDetection[] {\n if (!input || typeof input !== 'string') return []\n\n const {\n customPatterns = [],\n checkEncoded = true,\n minSeverity = 'low',\n } = options\n\n const severityOrder = { low: 0, medium: 1, high: 2 }\n const minSeverityLevel = severityOrder[minSeverity]\n\n const detections: SQLDetection[] = []\n const seenPatterns = new Set<string>()\n\n // Normalize input for encoded pattern detection\n const normalizedInput = checkEncoded ? normalizeInput(input) : input\n\n // Check all patterns\n const allPatterns = [\n ...SQL_PATTERNS,\n ...(checkEncoded ? ENCODED_PATTERNS : []),\n ...customPatterns.map(p => ({ pattern: p, name: 'Custom pattern', severity: 'high' as const })),\n ]\n\n for (const { pattern, name, severity } of allPatterns) {\n if (severityOrder[severity] < minSeverityLevel) continue\n\n // Reset regex state\n pattern.lastIndex = 0\n\n const testInput = checkEncoded ? normalizedInput : input\n if (pattern.test(testInput)) {\n const key = `${name}:${severity}`\n if (!seenPatterns.has(key)) {\n seenPatterns.add(key)\n detections.push({\n field: '', // Will be set by caller\n value: input,\n pattern: name,\n severity,\n })\n }\n }\n }\n\n return detections\n}\n\n/**\n * Check if string contains SQL injection (boolean check)\n */\nexport function hasSQLInjection(\n input: string,\n minSeverity: 'low' | 'medium' | 'high' = 'medium'\n): boolean {\n return detectSQLInjection(input, { minSeverity }).length > 0\n}\n\n/**\n * Sanitize input to prevent SQL injection\n * NOTE: This should NOT be a replacement for parameterized queries!\n */\nexport function sanitizeSQLInput(input: string): string {\n if (!input || typeof input !== 'string') return ''\n\n let result = input\n\n // Remove null bytes\n result = result.replace(/\\0/g, '')\n\n // Escape single quotes\n result = result.replace(/'/g, \"''\")\n\n // Remove dangerous characters\n result = result.replace(/;/g, '')\n result = result.replace(/--/g, '')\n result = result.replace(/\\/\\*/g, '')\n result = result.replace(/\\*\\//g, '')\n\n // Remove hex encoded values\n result = result.replace(/0x[0-9a-f]+/gi, '')\n\n return result\n}\n\n/**\n * Detect SQL injection in object fields\n */\nexport function detectSQLInjectionInObject(\n obj: unknown,\n options: {\n fields?: string[]\n deep?: boolean\n customPatterns?: RegExp[]\n minSeverity?: 'low' | 'medium' | 'high'\n } = {}\n): SQLDetection[] {\n const { fields, deep = true, customPatterns, minSeverity } = options\n const detections: SQLDetection[] = []\n\n function walk(value: unknown, path: string): void {\n if (typeof value === 'string') {\n // If fields specified, only check those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) return\n }\n\n const detected = detectSQLInjection(value, { customPatterns, minSeverity })\n for (const d of detected) {\n detections.push({ ...d, field: path })\n }\n } else if (deep && Array.isArray(value)) {\n value.forEach((item, i) => walk(item, `${path}[${i}]`))\n } else if (deep && typeof value === 'object' && value !== null) {\n for (const [key, val] of Object.entries(value)) {\n walk(val, path ? `${path}.${key}` : key)\n }\n }\n }\n\n walk(obj, '')\n return detections\n}\n\n/**\n * Check if value is in allowlist (safe values)\n */\nexport function isAllowedValue(value: string, allowList: string[]): boolean {\n if (!allowList || allowList.length === 0) return false\n return allowList.includes(value)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n ValidationConfig,\n ValidatedContext,\n ValidationError,\n SanitizationMiddlewareConfig,\n SanitizationChange,\n SQLProtectionConfig,\n ContentTypeConfig,\n FileValidationConfig,\n FileInfo,\n Schema,\n CustomSchema,\n} from './types'\nimport { validateRequest, defaultValidationErrorResponse } from './validators/schema'\nimport { validateContentType, defaultContentTypeErrorResponse } from './validators/content-type'\nimport { validateFilesFromRequest, defaultFileErrorResponse } from './validators/file'\nimport { sanitize, detectXSS } from './sanitizers/xss'\nimport { detectSQLInjectionInObject } from './sanitizers/sql'\nimport { walkObject } from './utils'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\n/**\n * Validation middleware\n * Validates request body, query, and params against schemas\n */\nexport function withValidation<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n handler: (\n req: NextRequest,\n ctx: { validated: ValidatedContext<TBody, TQuery, TParams> }\n ) => Response | Promise<Response>,\n config: ValidationConfig<TBody, TQuery, TParams> & {\n routeParams?: Record<string, string | string[]>\n }\n): RouteHandler {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n\n return async (req: NextRequest): Promise<Response> => {\n const result = await validateRequest<TBody, TQuery, TParams>(req, {\n body: config.body as Schema<TBody> | CustomSchema | undefined,\n query: config.query as Schema<TQuery> | CustomSchema | undefined,\n params: config.params as Schema<TParams> | CustomSchema | undefined,\n routeParams: config.routeParams,\n })\n\n if (!result.success) {\n return onError(req, result.errors || [])\n }\n\n return handler(req, { validated: result.data! })\n }\n}\n\n/**\n * XSS Sanitization middleware\n * Sanitizes string values in request body\n */\nexport function withSanitization(\n handler: (\n req: NextRequest,\n ctx: { sanitized: unknown; changes: SanitizationChange[] }\n ) => Response | Promise<Response>,\n config: SanitizationMiddlewareConfig = {}\n): RouteHandler {\n const {\n fields,\n mode = 'escape',\n allowedTags,\n skip,\n onSanitized,\n } = config\n\n return async (req: NextRequest): Promise<Response> => {\n // Check skip condition\n if (skip && await skip(req)) {\n return handler(req, { sanitized: null, changes: [] })\n }\n\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return handler(req, { sanitized: null, changes: [] })\n }\n\n const changes: SanitizationChange[] = []\n\n const sanitized = walkObject(body, (value, path) => {\n // If specific fields are specified, only sanitize those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) {\n return value\n }\n }\n\n const cleaned = sanitize(value, { mode, allowedTags })\n\n if (cleaned !== value) {\n changes.push({\n field: path,\n original: value,\n sanitized: cleaned,\n })\n }\n\n return cleaned\n }, '')\n\n // Callback for tracking\n if (onSanitized && changes.length > 0) {\n onSanitized(req, changes)\n }\n\n return handler(req, { sanitized, changes })\n }\n}\n\n/**\n * XSS Detection middleware\n * Blocks requests with potential XSS payloads in body and query parameters\n */\nexport function withXSSProtection(\n handler: RouteHandler,\n config: {\n fields?: string[]\n deep?: boolean\n checkQuery?: boolean\n onDetection?: (req: NextRequest, field: string, value: string) => Response | void | Promise<Response | void>\n } = {}\n): RouteHandler {\n const { fields, onDetection, checkQuery = true } = config\n\n return async (req: NextRequest): Promise<Response> => {\n const detections: { field: string; value: string }[] = []\n\n // Check query parameters for XSS\n if (checkQuery) {\n const url = new URL(req.url)\n for (const [key, value] of url.searchParams.entries()) {\n if (detectXSS(value)) {\n detections.push({ field: `query.${key}`, value })\n }\n }\n }\n\n // Check body\n let body: unknown\n try {\n body = await req.json()\n } catch {\n // No body or invalid JSON, skip body check\n body = null\n }\n\n if (body) {\n walkObject(body, (value, path) => {\n // If specific fields are specified, only check those\n if (fields && fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!fields.includes(fieldName)) {\n return value\n }\n }\n\n if (detectXSS(value)) {\n detections.push({ field: path, value })\n }\n\n return value\n }, '')\n }\n\n if (detections.length > 0) {\n if (onDetection) {\n for (const { field, value } of detections) {\n const result = await onDetection(req, field, value)\n if (result instanceof Response) {\n return result\n }\n }\n }\n\n // Default: block request\n return new Response(\n JSON.stringify({\n error: 'xss_detected',\n message: 'Potentially malicious content detected',\n fields: detections.map(d => d.field),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n\n return handler(req)\n }\n}\n\n/**\n * SQL Injection Protection middleware\n */\nexport function withSQLProtection(\n handler: RouteHandler,\n config: SQLProtectionConfig = {}\n): RouteHandler {\n const {\n fields,\n deep = true,\n mode = 'block',\n customPatterns,\n allowList = [],\n onDetection,\n } = config\n\n return async (req: NextRequest): Promise<Response> => {\n let body: unknown\n try {\n body = await req.json()\n } catch {\n return handler(req)\n }\n\n const detections = detectSQLInjectionInObject(body, {\n fields,\n deep,\n customPatterns,\n minSeverity: mode === 'detect' ? 'low' : 'medium',\n })\n\n // Filter out allowed values\n const filtered = detections.filter(d => !allowList.includes(d.value))\n\n if (filtered.length > 0) {\n if (onDetection) {\n const result = await onDetection(req, filtered)\n if (result instanceof Response) {\n return result\n }\n }\n\n if (mode === 'block') {\n return new Response(\n JSON.stringify({\n error: 'sql_injection_detected',\n message: 'Potentially malicious SQL detected',\n detections: filtered.map(d => ({\n field: d.field,\n pattern: d.pattern,\n severity: d.severity,\n })),\n }),\n {\n status: 400,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n }\n\n return handler(req)\n }\n}\n\n/**\n * Content-Type validation middleware\n */\nexport function withContentType(\n handler: RouteHandler,\n config: ContentTypeConfig\n): RouteHandler {\n const onInvalid = config.onInvalid || ((_, contentType) =>\n defaultContentTypeErrorResponse(contentType, `Content-Type '${contentType}' is not allowed`)\n )\n\n return async (req: NextRequest): Promise<Response> => {\n const result = validateContentType(req, config)\n\n if (!result.valid) {\n return onInvalid(req, result.contentType)\n }\n\n return handler(req)\n }\n}\n\n/**\n * File upload validation middleware\n */\nexport function withFileValidation(\n handler: (\n req: NextRequest,\n ctx: { files: Map<string, FileInfo[]> }\n ) => Response | Promise<Response>,\n config: FileValidationConfig = {}\n): RouteHandler {\n const onInvalid = config.onInvalid || ((_, errors) => defaultFileErrorResponse(errors))\n\n return async (req: NextRequest): Promise<Response> => {\n const result = await validateFilesFromRequest(req, config)\n\n if (!result.valid) {\n return onInvalid(req, result.errors)\n }\n\n return handler(req, { files: result.files })\n }\n}\n\n/**\n * Combined validation middleware\n * Combines schema validation, sanitization, and protection\n */\nexport function withSecureValidation<\n TBody = unknown,\n TQuery = unknown,\n TParams = unknown\n>(\n handler: (\n req: NextRequest,\n ctx: {\n validated: ValidatedContext<TBody, TQuery, TParams>\n files?: Map<string, FileInfo[]>\n }\n ) => Response | Promise<Response>,\n config: {\n schema?: ValidationConfig<TBody, TQuery, TParams>\n routeParams?: Record<string, string | string[]>\n contentType?: ContentTypeConfig\n files?: FileValidationConfig\n sanitize?: SanitizationMiddlewareConfig\n xss?: { enabled: boolean; fields?: string[] }\n sql?: SQLProtectionConfig\n onError?: (req: NextRequest, errors: ValidationError[]) => Response | Promise<Response>\n }\n): RouteHandler {\n return async (req: NextRequest): Promise<Response> => {\n const allErrors: ValidationError[] = []\n\n // 1. Content-Type validation\n if (config.contentType) {\n const ctResult = validateContentType(req, config.contentType)\n if (!ctResult.valid) {\n allErrors.push({\n field: 'Content-Type',\n code: 'invalid_content_type',\n message: ctResult.reason || 'Invalid Content-Type',\n })\n }\n }\n\n // 2. File validation (if multipart)\n let files: Map<string, FileInfo[]> | undefined\n if (config.files) {\n const fileResult = await validateFilesFromRequest(req, config.files)\n if (!fileResult.valid) {\n allErrors.push(...fileResult.errors.map(e => ({\n field: e.field || e.filename,\n code: e.code,\n message: e.message,\n })))\n } else {\n files = fileResult.files\n }\n }\n\n // Early return on content errors\n if (allErrors.length > 0) {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n return onError(req, allErrors)\n }\n\n // 3. Schema validation\n let validated: ValidatedContext<TBody, TQuery, TParams> | undefined\n if (config.schema) {\n const schemaResult = await validateRequest<TBody, TQuery, TParams>(req, {\n body: config.schema.body as Schema<TBody> | CustomSchema | undefined,\n query: config.schema.query as Schema<TQuery> | CustomSchema | undefined,\n params: config.schema.params as Schema<TParams> | CustomSchema | undefined,\n routeParams: config.routeParams,\n })\n\n if (!schemaResult.success) {\n allErrors.push(...(schemaResult.errors || []))\n } else {\n validated = schemaResult.data\n }\n } else {\n validated = {\n body: {} as TBody,\n query: {} as TQuery,\n params: {} as TParams,\n }\n }\n\n // 4. SQL injection detection\n if (config.sql && validated?.body) {\n const sqlDetections = detectSQLInjectionInObject(validated.body, {\n fields: config.sql.fields,\n deep: config.sql.deep,\n customPatterns: config.sql.customPatterns,\n })\n\n if (sqlDetections.length > 0 && config.sql.mode !== 'detect') {\n allErrors.push(...sqlDetections.map(d => ({\n field: d.field,\n code: 'sql_injection',\n message: `Potential SQL injection detected: ${d.pattern}`,\n })))\n }\n }\n\n // 5. XSS detection\n if (config.xss?.enabled && validated?.body) {\n walkObject(validated.body, (value, path) => {\n if (config.xss?.fields && config.xss.fields.length > 0) {\n const fieldName = path.split('.').pop() || path\n if (!config.xss.fields.includes(fieldName)) {\n return value\n }\n }\n\n if (detectXSS(value)) {\n allErrors.push({\n field: path,\n code: 'xss_detected',\n message: 'Potentially malicious content detected',\n })\n }\n\n return value\n }, '')\n }\n\n // Return errors\n if (allErrors.length > 0) {\n const onError = config.onError || ((_, errors) => defaultValidationErrorResponse(errors))\n return onError(req, allErrors)\n }\n\n return handler(req, { validated: validated!, files })\n }\n}\n","import type { LogStore, AuditLogEntry, LogQueryOptions, MemoryStoreOptions, SecurityEventType } from '../types'\n\n/**\n * In-memory log store with LRU eviction\n * Useful for development and testing\n */\nexport class MemoryStore implements LogStore {\n private entries: AuditLogEntry[] = []\n private readonly maxEntries: number\n private readonly ttl: number\n\n constructor(options: MemoryStoreOptions = {}) {\n this.maxEntries = options.maxEntries || 1000\n this.ttl = options.ttl || 0 // 0 = no TTL\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n // Add entry\n this.entries.push(entry)\n\n // Evict old entries if over limit\n if (this.entries.length > this.maxEntries) {\n this.entries = this.entries.slice(-this.maxEntries)\n }\n\n // Clean expired entries if TTL is set\n if (this.ttl > 0) {\n this.cleanExpired()\n }\n }\n\n async query(options: LogQueryOptions = {}): Promise<AuditLogEntry[]> {\n let result = [...this.entries]\n\n // Filter by level\n if (options.level) {\n const levels = Array.isArray(options.level) ? options.level : [options.level]\n result = result.filter(e => levels.includes(e.level))\n }\n\n // Filter by type\n if (options.type) {\n result = result.filter(e => e.type === options.type)\n }\n\n // Filter by event type (for security events)\n if (options.event) {\n const events = Array.isArray(options.event) ? options.event : [options.event]\n result = result.filter(e =>\n e.type === 'security' && events.includes((e as { event: SecurityEventType }).event)\n )\n }\n\n // Filter by time range\n if (options.startTime) {\n result = result.filter(e => e.timestamp >= options.startTime!)\n }\n if (options.endTime) {\n result = result.filter(e => e.timestamp <= options.endTime!)\n }\n\n // Filter by IP\n if (options.ip) {\n result = result.filter(e => {\n if (e.type === 'request') return e.request.ip === options.ip\n if (e.type === 'security') return e.source.ip === options.ip\n return false\n })\n }\n\n // Filter by user ID\n if (options.userId) {\n result = result.filter(e => {\n if (e.type === 'request') return e.user?.id === options.userId\n if (e.type === 'security') return e.source.userId === options.userId\n return false\n })\n }\n\n // Apply offset\n if (options.offset) {\n result = result.slice(options.offset)\n }\n\n // Apply limit\n if (options.limit) {\n result = result.slice(0, options.limit)\n }\n\n return result\n }\n\n async flush(): Promise<void> {\n // No-op for memory store\n }\n\n async close(): Promise<void> {\n this.entries = []\n }\n\n /**\n * Get all entries (for testing)\n */\n getEntries(): AuditLogEntry[] {\n return [...this.entries]\n }\n\n /**\n * Clear all entries\n */\n clear(): void {\n this.entries = []\n }\n\n /**\n * Get entry count\n */\n size(): number {\n return this.entries.length\n }\n\n /**\n * Clean expired entries\n */\n private cleanExpired(): void {\n if (this.ttl <= 0) return\n\n const now = Date.now()\n this.entries = this.entries.filter(e => {\n const age = now - e.timestamp.getTime()\n return age < this.ttl\n })\n }\n}\n\n/**\n * Create a memory store\n */\nexport function createMemoryStore(options?: MemoryStoreOptions): MemoryStore {\n return new MemoryStore(options)\n}\n","import type { LogStore, AuditLogEntry, ConsoleStoreOptions, LogLevel } from '../types'\n\n/**\n * ANSI color codes\n */\nconst COLORS = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n\n // Log levels\n debug: '\\x1b[36m', // Cyan\n info: '\\x1b[32m', // Green\n warn: '\\x1b[33m', // Yellow\n error: '\\x1b[31m', // Red\n critical: '\\x1b[35m', // Magenta\n\n // Security severity\n low: '\\x1b[36m', // Cyan\n medium: '\\x1b[33m', // Yellow\n high: '\\x1b[31m', // Red\n\n // Other\n timestamp: '\\x1b[90m', // Gray\n method: '\\x1b[34m', // Blue\n status2xx: '\\x1b[32m', // Green\n status3xx: '\\x1b[36m', // Cyan\n status4xx: '\\x1b[33m', // Yellow\n status5xx: '\\x1b[31m', // Red\n}\n\n/**\n * Log level priority\n */\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n critical: 4,\n}\n\n/**\n * Console log store\n * Outputs formatted logs to console\n */\nexport class ConsoleStore implements LogStore {\n private readonly colorize: boolean\n private readonly showTimestamp: boolean\n private readonly pretty: boolean\n private readonly minLevel: LogLevel\n\n constructor(options: ConsoleStoreOptions = {}) {\n this.colorize = options.colorize ?? (process.env.NODE_ENV !== 'production')\n this.showTimestamp = options.timestamp ?? true\n this.pretty = options.pretty ?? false\n this.minLevel = options.level || 'info'\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n // Check log level\n if (LEVEL_PRIORITY[entry.level] < LEVEL_PRIORITY[this.minLevel]) {\n return\n }\n\n const output = this.pretty\n ? this.formatPretty(entry)\n : this.formatCompact(entry)\n\n // Use appropriate console method\n switch (entry.level) {\n case 'debug':\n console.debug(output)\n break\n case 'info':\n console.info(output)\n break\n case 'warn':\n console.warn(output)\n break\n case 'error':\n case 'critical':\n console.error(output)\n break\n default:\n console.log(output)\n }\n }\n\n async flush(): Promise<void> {\n // No-op for console\n }\n\n async close(): Promise<void> {\n // No-op for console\n }\n\n /**\n * Format entry in compact single-line format\n */\n private formatCompact(entry: AuditLogEntry): string {\n const parts: string[] = []\n\n // Timestamp\n if (this.showTimestamp) {\n const ts = entry.timestamp.toISOString()\n parts.push(this.color(ts, 'timestamp'))\n }\n\n // Level\n parts.push(this.colorLevel(entry.level))\n\n if (entry.type === 'request') {\n // Request log\n const req = entry.request\n const res = entry.response\n\n // Method and path\n parts.push(this.color(req.method, 'method'))\n parts.push(req.path)\n\n // Status and duration\n if (res) {\n parts.push(this.colorStatus(res.status))\n parts.push(this.color(`${res.duration}ms`, 'dim'))\n }\n\n // IP\n if (req.ip) {\n parts.push(this.color(`[${req.ip}]`, 'dim'))\n }\n\n // User\n if (entry.user?.id) {\n parts.push(this.color(`user:${entry.user.id}`, 'dim'))\n }\n\n // Error\n if (entry.error) {\n parts.push(this.color(`ERROR: ${entry.error.message}`, 'error'))\n }\n } else if (entry.type === 'security') {\n // Security event\n parts.push(this.colorSeverity(entry.severity))\n parts.push(entry.event)\n\n if (entry.source.ip) {\n parts.push(this.color(`[${entry.source.ip}]`, 'dim'))\n }\n\n if (entry.source.userId) {\n parts.push(this.color(`user:${entry.source.userId}`, 'dim'))\n }\n\n parts.push(entry.message)\n }\n\n return parts.join(' ')\n }\n\n /**\n * Format entry in pretty multi-line format\n */\n private formatPretty(entry: AuditLogEntry): string {\n const lines: string[] = []\n\n // Header\n const header = [\n this.color(entry.timestamp.toISOString(), 'timestamp'),\n this.colorLevel(entry.level),\n `[${entry.type.toUpperCase()}]`,\n ].join(' ')\n\n lines.push(header)\n\n if (entry.type === 'request') {\n const req = entry.request\n const res = entry.response\n\n // Request line\n lines.push(` ${this.color(req.method, 'method')} ${req.url}`)\n\n // Request details\n if (req.ip) lines.push(` IP: ${req.ip}`)\n if (req.userAgent) lines.push(` UA: ${req.userAgent}`)\n\n // Response\n if (res) {\n lines.push(` Status: ${this.colorStatus(res.status)} (${res.duration}ms)`)\n }\n\n // User\n if (entry.user) {\n lines.push(` User: ${JSON.stringify(entry.user)}`)\n }\n\n // Error\n if (entry.error) {\n lines.push(` ${this.color('Error:', 'error')} ${entry.error.message}`)\n if (entry.error.stack) {\n lines.push(` ${this.color(entry.error.stack, 'dim')}`)\n }\n }\n } else if (entry.type === 'security') {\n lines.push(` Event: ${entry.event}`)\n lines.push(` Severity: ${this.colorSeverity(entry.severity)}`)\n lines.push(` Message: ${entry.message}`)\n\n if (entry.source.ip) lines.push(` Source IP: ${entry.source.ip}`)\n if (entry.source.userId) lines.push(` Source User: ${entry.source.userId}`)\n\n if (entry.target) {\n lines.push(` Target: ${JSON.stringify(entry.target)}`)\n }\n\n if (entry.details) {\n lines.push(` Details: ${JSON.stringify(entry.details)}`)\n }\n }\n\n // Metadata\n if (entry.metadata && Object.keys(entry.metadata).length > 0) {\n lines.push(` Metadata: ${JSON.stringify(entry.metadata)}`)\n }\n\n return lines.join('\\n')\n }\n\n /**\n * Apply color if enabled\n */\n private color(text: string, colorName: keyof typeof COLORS): string {\n if (!this.colorize) return text\n return `${COLORS[colorName]}${text}${COLORS.reset}`\n }\n\n /**\n * Color log level\n */\n private colorLevel(level: LogLevel): string {\n const text = level.toUpperCase().padEnd(8)\n if (!this.colorize) return `[${text}]`\n return `[${COLORS[level]}${text}${COLORS.reset}]`\n }\n\n /**\n * Color HTTP status\n */\n private colorStatus(status: number): string {\n const text = status.toString()\n if (!this.colorize) return text\n\n if (status >= 500) return `${COLORS.status5xx}${text}${COLORS.reset}`\n if (status >= 400) return `${COLORS.status4xx}${text}${COLORS.reset}`\n if (status >= 300) return `${COLORS.status3xx}${text}${COLORS.reset}`\n return `${COLORS.status2xx}${text}${COLORS.reset}`\n }\n\n /**\n * Color severity\n */\n private colorSeverity(severity: 'low' | 'medium' | 'high' | 'critical'): string {\n const text = `[${severity.toUpperCase()}]`\n if (!this.colorize) return text\n\n const colorKey = severity === 'critical' ? 'critical' : severity\n return `${COLORS[colorKey]}${text}${COLORS.reset}`\n }\n}\n\n/**\n * Create a console store\n */\nexport function createConsoleStore(options?: ConsoleStoreOptions): ConsoleStore {\n return new ConsoleStore(options)\n}\n","import type { LogStore, AuditLogEntry, ExternalStoreOptions } from '../types'\n\n/**\n * External HTTP log store\n * Sends logs to external services (Datadog, Sentry, custom endpoints)\n */\nexport class ExternalStore implements LogStore {\n private readonly endpoint: string\n private readonly headers: Record<string, string>\n private readonly batchSize: number\n private readonly flushInterval: number\n private readonly retryAttempts: number\n private readonly timeout: number\n\n private buffer: AuditLogEntry[] = []\n private flushTimer: ReturnType<typeof setInterval> | null = null\n private isFlushing = false\n\n constructor(options: ExternalStoreOptions) {\n this.endpoint = options.endpoint\n this.headers = {\n 'Content-Type': 'application/json',\n ...(options.apiKey ? { 'Authorization': `Bearer ${options.apiKey}` } : {}),\n ...options.headers,\n }\n this.batchSize = options.batchSize || 100\n this.flushInterval = options.flushInterval || 5000 // 5 seconds\n this.retryAttempts = options.retryAttempts || 3\n this.timeout = options.timeout || 10000 // 10 seconds\n\n // Start auto-flush timer\n if (this.flushInterval > 0) {\n this.flushTimer = setInterval(() => this.flush(), this.flushInterval)\n }\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n this.buffer.push(entry)\n\n // Flush if batch size reached\n if (this.buffer.length >= this.batchSize) {\n await this.flush()\n }\n }\n\n async flush(): Promise<void> {\n if (this.isFlushing || this.buffer.length === 0) return\n\n this.isFlushing = true\n const entries = [...this.buffer]\n this.buffer = []\n\n try {\n await this.send(entries)\n } catch (error) {\n // Put entries back in buffer on failure\n this.buffer = [...entries, ...this.buffer]\n console.error('[ExternalStore] Failed to flush logs:', error)\n } finally {\n this.isFlushing = false\n }\n }\n\n async close(): Promise<void> {\n // Clear timer\n if (this.flushTimer) {\n clearInterval(this.flushTimer)\n this.flushTimer = null\n }\n\n // Final flush\n await this.flush()\n }\n\n /**\n * Send entries to external endpoint\n */\n private async send(entries: AuditLogEntry[]): Promise<void> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < this.retryAttempts; attempt++) {\n try {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.timeout)\n\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({\n logs: entries.map(e => this.serialize(e)),\n timestamp: new Date().toISOString(),\n count: entries.length,\n }),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n return // Success\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // Wait before retry (exponential backoff)\n if (attempt < this.retryAttempts - 1) {\n await this.sleep(Math.pow(2, attempt) * 1000)\n }\n }\n }\n\n throw lastError || new Error('Failed to send logs')\n }\n\n /**\n * Serialize entry for transmission\n */\n private serialize(entry: AuditLogEntry): Record<string, unknown> {\n return {\n ...entry,\n timestamp: entry.timestamp.toISOString(),\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n /**\n * Get buffer size (for monitoring)\n */\n getBufferSize(): number {\n return this.buffer.length\n }\n}\n\n/**\n * Create an external store\n */\nexport function createExternalStore(options: ExternalStoreOptions): ExternalStore {\n return new ExternalStore(options)\n}\n\n/**\n * Create a Datadog store\n */\nexport function createDatadogStore(options: {\n apiKey: string\n site?: 'datadoghq.com' | 'datadoghq.eu' | 'us3.datadoghq.com' | 'us5.datadoghq.com'\n service?: string\n source?: string\n tags?: string[]\n batchSize?: number\n flushInterval?: number\n}): ExternalStore {\n const site = options.site || 'datadoghq.com'\n const endpoint = `https://http-intake.logs.${site}/api/v2/logs`\n\n return new ExternalStore({\n endpoint,\n headers: {\n 'DD-API-KEY': options.apiKey,\n 'Content-Type': 'application/json',\n },\n batchSize: options.batchSize || 100,\n flushInterval: options.flushInterval || 5000,\n })\n}\n\n/**\n * Create a multi-store that writes to multiple stores\n */\nexport class MultiStore implements LogStore {\n private stores: LogStore[]\n\n constructor(stores: LogStore[]) {\n this.stores = stores\n }\n\n async write(entry: AuditLogEntry): Promise<void> {\n await Promise.all(this.stores.map(store => store.write(entry)))\n }\n\n async query(options: Parameters<NonNullable<LogStore['query']>>[0]): Promise<AuditLogEntry[]> {\n // Query from first store that supports it\n for (const store of this.stores) {\n if (store.query) {\n return store.query(options)\n }\n }\n return []\n }\n\n async flush(): Promise<void> {\n await Promise.all(this.stores.map(store => store.flush?.()))\n }\n\n async close(): Promise<void> {\n await Promise.all(this.stores.map(store => store.close?.()))\n }\n}\n\n/**\n * Create a multi-store\n */\nexport function createMultiStore(stores: LogStore[]): MultiStore {\n return new MultiStore(stores)\n}\n","import type { LogFormatter, AuditLogEntry } from './types'\n\n/**\n * JSON formatter - outputs logs as JSON strings\n */\nexport class JSONFormatter implements LogFormatter {\n private readonly pretty: boolean\n private readonly includeTimestamp: boolean\n\n constructor(options: { pretty?: boolean; includeTimestamp?: boolean } = {}) {\n this.pretty = options.pretty ?? false\n this.includeTimestamp = options.includeTimestamp ?? true\n }\n\n format(entry: AuditLogEntry): string {\n const output = {\n ...entry,\n timestamp: this.includeTimestamp ? entry.timestamp.toISOString() : undefined,\n }\n\n return this.pretty\n ? JSON.stringify(output, null, 2)\n : JSON.stringify(output)\n }\n}\n\n/**\n * Text formatter - outputs logs as human-readable text\n */\nexport class TextFormatter implements LogFormatter {\n private readonly template: string\n private readonly dateFormat: 'iso' | 'utc' | 'local'\n\n constructor(options: {\n template?: string\n dateFormat?: 'iso' | 'utc' | 'local'\n } = {}) {\n this.template = options.template || '{timestamp} [{level}] {message}'\n this.dateFormat = options.dateFormat || 'iso'\n }\n\n format(entry: AuditLogEntry): string {\n let output = this.template\n\n // Replace placeholders\n output = output.replace('{timestamp}', this.formatDate(entry.timestamp))\n output = output.replace('{level}', entry.level.toUpperCase().padEnd(8))\n output = output.replace('{message}', entry.message)\n output = output.replace('{type}', entry.type)\n output = output.replace('{id}', entry.id)\n\n if (entry.category) {\n output = output.replace('{category}', entry.category)\n }\n\n // Request-specific\n if (entry.type === 'request') {\n output = output.replace('{method}', entry.request.method)\n output = output.replace('{path}', entry.request.path)\n output = output.replace('{url}', entry.request.url)\n output = output.replace('{ip}', entry.request.ip || '-')\n output = output.replace('{status}', entry.response?.status?.toString() || '-')\n output = output.replace('{duration}', entry.response?.duration?.toString() || '-')\n }\n\n // Security-specific\n if (entry.type === 'security') {\n output = output.replace('{event}', entry.event)\n output = output.replace('{severity}', entry.severity)\n }\n\n return output\n }\n\n private formatDate(date: Date): string {\n switch (this.dateFormat) {\n case 'utc':\n return date.toUTCString()\n case 'local':\n return date.toLocaleString()\n case 'iso':\n default:\n return date.toISOString()\n }\n }\n}\n\n/**\n * CLF (Common Log Format) formatter\n * Apache/Nginx style: host ident authuser date request status bytes\n */\nexport class CLFFormatter implements LogFormatter {\n format(entry: AuditLogEntry): string {\n if (entry.type !== 'request') {\n // Fall back to simple format for non-request entries\n return `[${entry.timestamp.toISOString()}] ${entry.level.toUpperCase()} ${entry.message}`\n }\n\n const req = entry.request\n const res = entry.response\n\n const host = req.ip || '-'\n const ident = '-'\n const authuser = entry.user?.id || '-'\n const date = this.formatCLFDate(entry.timestamp)\n const request = `${req.method} ${req.path} HTTP/1.1`\n const status = res?.status || 0\n const bytes = res?.contentLength || 0\n\n return `${host} ${ident} ${authuser} [${date}] \"${request}\" ${status} ${bytes}`\n }\n\n private formatCLFDate(date: Date): string {\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n\n const day = date.getDate().toString().padStart(2, '0')\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n const hours = date.getHours().toString().padStart(2, '0')\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n\n const offset = -date.getTimezoneOffset()\n const offsetSign = offset >= 0 ? '+' : '-'\n const offsetHours = Math.floor(Math.abs(offset) / 60).toString().padStart(2, '0')\n const offsetMins = (Math.abs(offset) % 60).toString().padStart(2, '0')\n\n return `${day}/${month}/${year}:${hours}:${minutes}:${seconds} ${offsetSign}${offsetHours}${offsetMins}`\n }\n}\n\n/**\n * Structured formatter for ELK/Splunk\n * Outputs key=value pairs\n */\nexport class StructuredFormatter implements LogFormatter {\n private readonly delimiter: string\n private readonly kvSeparator: string\n\n constructor(options: { delimiter?: string; kvSeparator?: string } = {}) {\n this.delimiter = options.delimiter || ' '\n this.kvSeparator = options.kvSeparator || '='\n }\n\n format(entry: AuditLogEntry): string {\n const pairs: string[] = []\n\n pairs.push(this.pair('timestamp', entry.timestamp.toISOString()))\n pairs.push(this.pair('level', entry.level))\n pairs.push(this.pair('type', entry.type))\n pairs.push(this.pair('id', entry.id))\n pairs.push(this.pair('message', this.escape(entry.message)))\n\n if (entry.category) {\n pairs.push(this.pair('category', entry.category))\n }\n\n if (entry.type === 'request') {\n pairs.push(this.pair('method', entry.request.method))\n pairs.push(this.pair('path', entry.request.path))\n if (entry.request.ip) pairs.push(this.pair('ip', entry.request.ip))\n if (entry.response) {\n pairs.push(this.pair('status', entry.response.status.toString()))\n pairs.push(this.pair('duration_ms', entry.response.duration.toString()))\n }\n if (entry.user?.id) pairs.push(this.pair('user_id', entry.user.id))\n if (entry.error) {\n pairs.push(this.pair('error', this.escape(entry.error.message)))\n }\n }\n\n if (entry.type === 'security') {\n pairs.push(this.pair('event', entry.event))\n pairs.push(this.pair('severity', entry.severity))\n if (entry.source.ip) pairs.push(this.pair('source_ip', entry.source.ip))\n if (entry.source.userId) pairs.push(this.pair('source_user', entry.source.userId))\n }\n\n return pairs.join(this.delimiter)\n }\n\n private pair(key: string, value: string): string {\n return `${key}${this.kvSeparator}${value}`\n }\n\n private escape(value: string): string {\n // Escape quotes and wrap in quotes if contains spaces\n if (value.includes(' ') || value.includes('\"')) {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`\n }\n return value\n }\n}\n\n/**\n * Create a JSON formatter\n */\nexport function createJSONFormatter(options?: { pretty?: boolean }): JSONFormatter {\n return new JSONFormatter(options)\n}\n\n/**\n * Create a text formatter\n */\nexport function createTextFormatter(options?: {\n template?: string\n dateFormat?: 'iso' | 'utc' | 'local'\n}): TextFormatter {\n return new TextFormatter(options)\n}\n\n/**\n * Create a CLF formatter\n */\nexport function createCLFFormatter(): CLFFormatter {\n return new CLFFormatter()\n}\n\n/**\n * Create a structured formatter\n */\nexport function createStructuredFormatter(options?: {\n delimiter?: string\n kvSeparator?: string\n}): StructuredFormatter {\n return new StructuredFormatter(options)\n}\n","import type { PIIConfig } from './types'\n\n/**\n * Default PII fields to redact\n */\nexport const DEFAULT_PII_FIELDS = [\n // Authentication\n 'password',\n 'passwd',\n 'secret',\n 'token',\n 'api_key',\n 'apiKey',\n 'api-key',\n 'access_token',\n 'accessToken',\n 'refresh_token',\n 'refreshToken',\n 'authorization',\n 'auth',\n\n // Personal information\n 'ssn',\n 'social_security',\n 'socialSecurity',\n 'credit_card',\n 'creditCard',\n 'card_number',\n 'cardNumber',\n 'cvv',\n 'cvc',\n 'pin',\n\n // Contact\n 'email',\n 'phone',\n 'phone_number',\n 'phoneNumber',\n 'mobile',\n 'address',\n 'street',\n 'zip',\n 'zipcode',\n 'postal_code',\n 'postalCode',\n\n // Identity\n 'date_of_birth',\n 'dateOfBirth',\n 'dob',\n 'birth_date',\n 'birthDate',\n 'passport',\n 'license',\n 'national_id',\n 'nationalId',\n]\n\n/**\n * Mask a value with asterisks\n */\nexport function mask(\n value: string,\n options: {\n char?: string\n preserveLength?: boolean\n showFirst?: number\n showLast?: number\n } = {}\n): string {\n const {\n char = '*',\n preserveLength = false,\n showFirst = 0,\n showLast = 0,\n } = options\n\n if (!value) return value\n\n const len = value.length\n\n if (preserveLength) {\n const first = value.slice(0, showFirst)\n const last = value.slice(-showLast || len)\n const middle = char.repeat(Math.max(0, len - showFirst - showLast))\n return first + middle + (showLast > 0 ? last : '')\n }\n\n // Default: show first/last chars with fixed mask\n const maskLen = 8\n const first = showFirst > 0 ? value.slice(0, showFirst) : ''\n const last = showLast > 0 ? value.slice(-showLast) : ''\n\n return first + char.repeat(maskLen) + last\n}\n\n/**\n * Simple hash function for Edge Runtime compatibility\n * Uses a fast, deterministic string hash (not cryptographic)\n */\nexport function hash(value: string, salt = ''): string {\n const str = salt + value\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32bit integer\n }\n // Convert to hex and ensure positive, pad to 16 chars\n const hex = Math.abs(hash).toString(16).padStart(8, '0')\n return hex + hex.slice(0, 8) // Return 16 char string\n}\n\n/**\n * Redact a single value\n */\nexport function redactValue(\n value: unknown,\n field: string,\n config: PIIConfig\n): unknown {\n if (typeof value !== 'string') return value\n if (!value) return value\n\n // Check if field should be redacted\n const shouldRedact = config.fields.some(f => {\n const fieldLower = field.toLowerCase()\n const fLower = f.toLowerCase()\n return fieldLower === fLower ||\n fieldLower.endsWith('.' + fLower) ||\n fieldLower.includes('[' + fLower + ']')\n })\n\n if (!shouldRedact) return value\n\n // Apply custom redactor if provided\n if (config.customRedactor) {\n return config.customRedactor(value, field)\n }\n\n // Apply redaction based on mode\n switch (config.mode) {\n case 'mask':\n return mask(value, {\n char: config.maskChar || '*',\n preserveLength: config.preserveLength,\n showFirst: 2,\n showLast: 2,\n })\n\n case 'hash':\n return `[HASH:${hash(value)}]`\n\n case 'remove':\n return '[REDACTED]'\n\n default:\n return '[REDACTED]'\n }\n}\n\n/**\n * Redact PII from an object recursively\n */\nexport function redactObject<T>(obj: T, config: PIIConfig, path = ''): T {\n if (typeof obj === 'string') {\n return redactValue(obj, path, config) as T\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item, i) => redactObject(item, config, `${path}[${i}]`)) as T\n }\n\n if (typeof obj === 'object' && obj !== null) {\n const result: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n const newPath = path ? `${path}.${key}` : key\n result[key] = redactObject(value, config, newPath)\n }\n\n return result as T\n }\n\n return obj\n}\n\n/**\n * Create a redactor function with preset config\n */\nexport function createRedactor(config: Partial<PIIConfig> = {}): <T>(obj: T) => T {\n const fullConfig: PIIConfig = {\n fields: config.fields || DEFAULT_PII_FIELDS,\n mode: config.mode || 'mask',\n maskChar: config.maskChar || '*',\n preserveLength: config.preserveLength || false,\n customRedactor: config.customRedactor,\n }\n\n return <T>(obj: T) => redactObject(obj, fullConfig)\n}\n\n/**\n * Redact sensitive headers\n */\nexport function redactHeaders(\n headers: Record<string, string>,\n sensitiveHeaders: string[] = ['authorization', 'cookie', 'x-api-key', 'x-auth-token']\n): Record<string, string> {\n const result: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(headers)) {\n const keyLower = key.toLowerCase()\n if (sensitiveHeaders.some(h => keyLower === h.toLowerCase())) {\n result[key] = '[REDACTED]'\n } else {\n result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Redact query parameters\n */\nexport function redactQuery(\n query: Record<string, string>,\n sensitiveParams: string[] = ['token', 'key', 'secret', 'password', 'auth']\n): Record<string, string> {\n const result: Record<string, string> = {}\n\n for (const [key, value] of Object.entries(query)) {\n const keyLower = key.toLowerCase()\n if (sensitiveParams.some(p => keyLower.includes(p.toLowerCase()))) {\n result[key] = '[REDACTED]'\n } else {\n result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Redact email (show only domain)\n */\nexport function redactEmail(email: string): string {\n if (!email || !email.includes('@')) return mask(email)\n\n const [, domain] = email.split('@')\n return `****@${domain}`\n}\n\n/**\n * Redact credit card number (show last 4 digits)\n */\nexport function redactCreditCard(cardNumber: string): string {\n const cleaned = cardNumber.replace(/\\D/g, '')\n if (cleaned.length < 4) return mask(cardNumber)\n\n return '**** **** **** ' + cleaned.slice(-4)\n}\n\n/**\n * Redact phone number\n */\nexport function redactPhone(phone: string): string {\n const cleaned = phone.replace(/\\D/g, '')\n if (cleaned.length < 4) return mask(phone)\n\n return mask(phone, { preserveLength: true, showLast: 4 })\n}\n\n/**\n * Redact IP address (show only first two octets for IPv4)\n */\nexport function redactIP(ip: string): string {\n if (ip.includes(':')) {\n // IPv6 - show first segment\n const parts = ip.split(':')\n return parts[0] + ':****:****:****'\n }\n\n // IPv4 - show first two octets\n const parts = ip.split('.')\n if (parts.length !== 4) return mask(ip)\n\n return `${parts[0]}.${parts[1]}.*.*`\n}\n","import type {\n SecurityEventEntry,\n SecurityEventType,\n SecurityEventConfig,\n LogStore,\n LogLevel,\n} from './types'\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n return `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Map severity to log level\n */\nfunction severityToLevel(severity: 'low' | 'medium' | 'high' | 'critical'): LogLevel {\n switch (severity) {\n case 'low': return 'info'\n case 'medium': return 'warn'\n case 'high': return 'error'\n case 'critical': return 'critical'\n }\n}\n\n/**\n * Security event tracker\n */\nexport class SecurityEventTracker {\n private store: LogStore\n private defaultSeverity: 'low' | 'medium' | 'high' | 'critical'\n private onEvent?: (event: SecurityEventEntry) => void | Promise<void>\n\n constructor(config: SecurityEventConfig) {\n this.store = config.store\n this.defaultSeverity = config.defaultSeverity || 'medium'\n this.onEvent = config.onEvent\n }\n\n /**\n * Track a security event\n */\n async track(options: {\n event: SecurityEventType\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n userId?: string\n }\n details?: Record<string, unknown>\n mitigated?: boolean\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n const severity = options.severity || this.defaultSeverity\n\n const entry: SecurityEventEntry = {\n id: generateId(),\n timestamp: new Date(),\n type: 'security',\n level: severityToLevel(severity),\n message: options.message,\n event: options.event,\n severity,\n source: options.source || {},\n target: options.target,\n details: options.details,\n mitigated: options.mitigated,\n metadata: options.metadata,\n }\n\n // Write to store\n await this.store.write(entry)\n\n // Call event handler\n if (this.onEvent) {\n await this.onEvent(entry)\n }\n\n return entry\n }\n\n // Convenience methods for common events\n\n /**\n * Track failed authentication\n */\n async authFailed(options: {\n ip?: string\n userAgent?: string\n email?: string\n reason?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.failed',\n message: options.reason || 'Authentication failed',\n severity: 'medium',\n source: {\n ip: options.ip,\n userAgent: options.userAgent,\n },\n details: {\n attemptedEmail: options.email,\n reason: options.reason,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track successful login\n */\n async authLogin(options: {\n userId: string\n ip?: string\n userAgent?: string\n method?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.login',\n message: `User ${options.userId} logged in`,\n severity: 'low',\n source: {\n ip: options.ip,\n userAgent: options.userAgent,\n userId: options.userId,\n },\n details: {\n method: options.method || 'credentials',\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track logout\n */\n async authLogout(options: {\n userId: string\n ip?: string\n reason?: 'user' | 'timeout' | 'forced'\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.logout',\n message: `User ${options.userId} logged out`,\n severity: 'low',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n details: {\n reason: options.reason || 'user',\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track permission denied\n */\n async permissionDenied(options: {\n userId?: string\n ip?: string\n resource: string\n action: string\n requiredRole?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'auth.permission_denied',\n message: `Permission denied for ${options.action} on ${options.resource}`,\n severity: 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.resource,\n action: options.action,\n },\n details: {\n requiredRole: options.requiredRole,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track rate limit exceeded\n */\n async rateLimitExceeded(options: {\n ip?: string\n userId?: string\n endpoint: string\n limit: number\n window: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ratelimit.exceeded',\n message: `Rate limit exceeded for ${options.endpoint}`,\n severity: 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n limit: options.limit,\n window: options.window,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track CSRF validation failure\n */\n async csrfInvalid(options: {\n ip?: string\n userId?: string\n endpoint: string\n reason?: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'csrf.invalid',\n message: `CSRF validation failed for ${options.endpoint}`,\n severity: 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n reason: options.reason,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track XSS detection\n */\n async xssDetected(options: {\n ip?: string\n userId?: string\n field: string\n payload?: string\n endpoint: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'xss.detected',\n message: `XSS payload detected in ${options.field}`,\n severity: 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n field: options.field,\n payload: options.payload?.slice(0, 100), // Truncate\n },\n mitigated: true,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track SQL injection detection\n */\n async sqliDetected(options: {\n ip?: string\n userId?: string\n field: string\n pattern: string\n severity?: 'low' | 'medium' | 'high'\n endpoint: string\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'sqli.detected',\n message: `SQL injection attempt detected in ${options.field}`,\n severity: options.severity || 'high',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n target: {\n resource: options.endpoint,\n },\n details: {\n field: options.field,\n pattern: options.pattern,\n },\n mitigated: true,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track IP block\n */\n async ipBlocked(options: {\n ip: string\n reason: string\n duration?: number\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ip.blocked',\n message: `IP ${options.ip} blocked: ${options.reason}`,\n severity: 'high',\n source: {\n ip: options.ip,\n },\n details: {\n reason: options.reason,\n duration: options.duration,\n },\n metadata: options.metadata,\n })\n }\n\n /**\n * Track suspicious activity\n */\n async suspicious(options: {\n ip?: string\n userId?: string\n activity: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'ip.suspicious',\n message: options.activity,\n severity: options.severity || 'medium',\n source: {\n ip: options.ip,\n userId: options.userId,\n },\n details: options.details,\n metadata: options.metadata,\n })\n }\n\n /**\n * Track custom event\n */\n async custom(options: {\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n }\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }): Promise<SecurityEventEntry> {\n return this.track({\n event: 'custom',\n ...options,\n })\n }\n}\n\n/**\n * Create a security event tracker\n */\nexport function createSecurityTracker(config: SecurityEventConfig): SecurityEventTracker {\n return new SecurityEventTracker(config)\n}\n\n/**\n * Standalone function to track security events\n */\nexport async function trackSecurityEvent(\n store: LogStore,\n options: {\n event: SecurityEventType\n message: string\n severity?: 'low' | 'medium' | 'high' | 'critical'\n source?: {\n ip?: string\n userAgent?: string\n userId?: string\n }\n target?: {\n resource?: string\n action?: string\n userId?: string\n }\n details?: Record<string, unknown>\n metadata?: Record<string, unknown>\n }\n): Promise<SecurityEventEntry> {\n const tracker = new SecurityEventTracker({ store })\n return tracker.track(options)\n}\n","import type { NextRequest } from 'next/server'\nimport type {\n AuditConfig,\n RequestLogEntry,\n LogLevel,\n PIIConfig,\n} from './types'\nimport { redactObject, redactHeaders, redactQuery, DEFAULT_PII_FIELDS } from './redaction'\n\ntype RouteHandler = (req: NextRequest) => Response | Promise<Response>\n\n/**\n * Generate unique request ID\n */\nfunction generateRequestId(): string {\n return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string | undefined {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n undefined\n )\n}\n\n/**\n * Convert headers to record\n */\nfunction headersToRecord(headers: Headers, includeHeaders?: boolean | string[]): Record<string, string> {\n if (!includeHeaders) return {}\n\n const result: Record<string, string> = {}\n\n if (includeHeaders === true) {\n headers.forEach((value, key) => {\n result[key] = value\n })\n } else if (Array.isArray(includeHeaders)) {\n for (const key of includeHeaders) {\n const value = headers.get(key)\n if (value) result[key] = value\n }\n }\n\n return result\n}\n\n/**\n * Parse query parameters from URL\n */\nfunction parseQuery(url: string): Record<string, string> {\n const result: Record<string, string> = {}\n\n try {\n const urlObj = new URL(url)\n urlObj.searchParams.forEach((value, key) => {\n result[key] = value\n })\n } catch {\n // Invalid URL\n }\n\n return result\n}\n\n/**\n * Determine log level from status code\n */\nfunction statusToLevel(status: number): LogLevel {\n if (status >= 500) return 'error'\n if (status >= 400) return 'warn'\n return 'info'\n}\n\n/**\n * Should skip logging for this request\n */\nfunction shouldSkip(\n req: NextRequest,\n status: number,\n exclude?: AuditConfig['exclude']\n): boolean {\n if (!exclude) return false\n\n const url = new URL(req.url)\n\n // Check path\n if (exclude.paths?.length) {\n const matchesPath = exclude.paths.some(pattern => {\n if (pattern.includes('*')) {\n const regex = new RegExp('^' + pattern.replace(/\\*/g, '.*') + '$')\n return regex.test(url.pathname)\n }\n return url.pathname === pattern || url.pathname.startsWith(pattern)\n })\n if (matchesPath) return true\n }\n\n // Check method\n if (exclude.methods?.includes(req.method)) {\n return true\n }\n\n // Check status code\n if (exclude.statusCodes?.includes(status)) {\n return true\n }\n\n return false\n}\n\n/**\n * Audit logging middleware\n */\nexport function withAuditLog(\n handler: RouteHandler,\n config: AuditConfig\n): RouteHandler {\n const {\n enabled = true,\n store,\n include = {},\n exclude,\n pii,\n getUser,\n requestIdHeader = 'x-request-id',\n generateRequestId: customGenerateId,\n onError,\n skip,\n } = config\n\n // Default include settings\n const includeSettings = {\n ip: include.ip ?? true,\n userAgent: include.userAgent ?? true,\n headers: include.headers ?? false,\n query: include.query ?? true,\n body: include.body ?? false,\n response: include.response ?? true,\n responseBody: include.responseBody ?? false,\n duration: include.duration ?? true,\n user: include.user ?? true,\n }\n\n // PII config\n const piiConfig: PIIConfig = pii || {\n fields: DEFAULT_PII_FIELDS,\n mode: 'mask',\n }\n\n return async (req: NextRequest): Promise<Response> => {\n // Check if logging is enabled\n if (!enabled) {\n return handler(req)\n }\n\n // Check skip condition\n if (skip && await skip(req)) {\n return handler(req)\n }\n\n const startTime = Date.now()\n const requestId = req.headers.get(requestIdHeader) ||\n (customGenerateId ? customGenerateId() : generateRequestId())\n\n const url = new URL(req.url)\n\n // Build request info\n let requestInfo: RequestLogEntry['request'] = {\n id: requestId,\n method: req.method,\n url: req.url,\n path: url.pathname,\n }\n\n if (includeSettings.ip) {\n requestInfo.ip = getClientIP(req)\n }\n\n if (includeSettings.userAgent) {\n requestInfo.userAgent = req.headers.get('user-agent') || undefined\n }\n\n if (includeSettings.headers) {\n let headers = headersToRecord(req.headers, includeSettings.headers)\n headers = redactHeaders(headers)\n requestInfo.headers = headers\n }\n\n if (includeSettings.query) {\n let query = parseQuery(req.url)\n query = redactQuery(query)\n requestInfo.query = query\n }\n\n requestInfo.contentType = req.headers.get('content-type') || undefined\n requestInfo.contentLength = parseInt(req.headers.get('content-length') || '0', 10) || undefined\n\n // Get user if configured\n let user: RequestLogEntry['user']\n if (includeSettings.user && getUser) {\n try {\n user = await getUser(req) || undefined\n } catch {\n // Ignore user extraction errors\n }\n }\n\n // Execute handler\n let response: Response\n let error: Error | undefined\n\n try {\n response = await handler(req)\n } catch (err) {\n error = err instanceof Error ? err : new Error(String(err))\n // Re-throw to let error propagate\n throw err\n } finally {\n const duration = Date.now() - startTime\n const status = response!?.status || 500\n\n // Check if we should skip this request\n if (!shouldSkip(req, status, exclude)) {\n // Build log entry\n const entry: RequestLogEntry = {\n id: requestId,\n timestamp: new Date(),\n type: 'request',\n level: error ? 'error' : statusToLevel(status),\n message: `${req.method} ${url.pathname} ${status} ${duration}ms`,\n request: requestInfo,\n user,\n }\n\n // Add response info\n if (includeSettings.response && response!) {\n entry.response = {\n status: response.status,\n duration,\n }\n\n if (includeSettings.headers) {\n entry.response.headers = headersToRecord(response.headers, includeSettings.headers)\n }\n }\n\n // Add error info\n if (error) {\n entry.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n }\n\n // Redact PII\n const redactedEntry = redactObject(entry, piiConfig)\n\n // Write to store\n try {\n await store.write(redactedEntry)\n } catch (writeError) {\n if (onError) {\n onError(writeError instanceof Error ? writeError : new Error(String(writeError)), entry)\n } else {\n console.error('[AuditLog] Failed to write log:', writeError)\n }\n }\n }\n }\n\n return response!\n }\n}\n\n/**\n * Create audit middleware with default console logging\n */\nexport function createAuditMiddleware(\n config: Partial<AuditConfig> & { store: AuditConfig['store'] }\n): (handler: RouteHandler) => RouteHandler {\n return (handler: RouteHandler) => withAuditLog(handler, config as AuditConfig)\n}\n\n/**\n * Request logger that adds request ID to response headers\n */\nexport function withRequestId(\n handler: RouteHandler,\n options: {\n headerName?: string\n generateId?: () => string\n } = {}\n): RouteHandler {\n const { headerName = 'x-request-id', generateId = generateRequestId } = options\n\n return async (req: NextRequest): Promise<Response> => {\n const requestId = req.headers.get(headerName) || generateId()\n\n const response = await handler(req)\n\n // Clone response to add header\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n newResponse.headers.set(headerName, requestId)\n\n return newResponse\n }\n}\n\n/**\n * Simple request timing middleware\n */\nexport function withTiming(\n handler: RouteHandler,\n options: {\n headerName?: string\n log?: boolean\n } = {}\n): RouteHandler {\n const { headerName = 'x-response-time', log = false } = options\n\n return async (req: NextRequest): Promise<Response> => {\n const start = Date.now()\n\n const response = await handler(req)\n\n const duration = Date.now() - start\n\n // Clone response to add header\n const newResponse = new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: new Headers(response.headers),\n })\n\n newResponse.headers.set(headerName, `${duration}ms`)\n\n if (log) {\n const url = new URL(req.url)\n console.log(`${req.method} ${url.pathname} ${response.status} ${duration}ms`)\n }\n\n return newResponse\n }\n}\n","/**\n * User-Agent Analysis for Bot Detection\n * @module nextjs-secure/bot\n */\n\nimport type {\n BotPattern,\n BotCategory,\n BotDetectionResult,\n UserAgentOptions,\n} from './types'\n\n// ============================================================================\n// Known Bot Patterns\n// ============================================================================\n\n/**\n * Comprehensive list of known bot patterns\n */\nexport const KNOWN_BOT_PATTERNS: BotPattern[] = [\n // Search Engines - Generally allowed\n {\n name: 'Googlebot',\n pattern: /Googlebot|Google-InspectionTool|Storebot-Google|GoogleOther/i,\n category: 'search_engine',\n allowed: true,\n description: 'Google search crawler',\n },\n {\n name: 'Bingbot',\n pattern: /bingbot|msnbot|BingPreview/i,\n category: 'search_engine',\n allowed: true,\n description: 'Microsoft Bing crawler',\n },\n {\n name: 'Yahoo Slurp',\n pattern: /Slurp/i,\n category: 'search_engine',\n allowed: true,\n description: 'Yahoo search crawler',\n },\n {\n name: 'DuckDuckBot',\n pattern: /DuckDuckBot|DuckDuckGo-Favicons-Bot/i,\n category: 'search_engine',\n allowed: true,\n description: 'DuckDuckGo crawler',\n },\n {\n name: 'Baiduspider',\n pattern: /Baiduspider/i,\n category: 'search_engine',\n allowed: true,\n description: 'Baidu search crawler',\n },\n {\n name: 'Yandex',\n pattern: /YandexBot|YandexImages|YandexMobileBot/i,\n category: 'search_engine',\n allowed: true,\n description: 'Yandex search crawler',\n },\n {\n name: 'Applebot',\n pattern: /Applebot/i,\n category: 'search_engine',\n allowed: true,\n description: 'Apple search crawler',\n },\n {\n name: 'Sogou',\n pattern: /Sogou/i,\n category: 'search_engine',\n allowed: true,\n description: 'Sogou search crawler',\n },\n {\n name: 'Exabot',\n pattern: /Exabot/i,\n category: 'search_engine',\n allowed: true,\n description: 'Exalead search crawler',\n },\n\n // Social Media - Generally allowed\n {\n name: 'Facebook',\n pattern: /facebookexternalhit|Facebot|facebookcatalog/i,\n category: 'social_media',\n allowed: true,\n description: 'Facebook crawler for link previews',\n },\n {\n name: 'Twitter',\n pattern: /Twitterbot/i,\n category: 'social_media',\n allowed: true,\n description: 'Twitter/X crawler for cards',\n },\n {\n name: 'LinkedIn',\n pattern: /LinkedInBot/i,\n category: 'social_media',\n allowed: true,\n description: 'LinkedIn crawler for previews',\n },\n {\n name: 'Pinterest',\n pattern: /Pinterest|Pinterestbot/i,\n category: 'social_media',\n allowed: true,\n description: 'Pinterest crawler',\n },\n {\n name: 'Slack',\n pattern: /Slackbot/i,\n category: 'social_media',\n allowed: true,\n description: 'Slack link preview bot',\n },\n {\n name: 'Discord',\n pattern: /Discordbot/i,\n category: 'social_media',\n allowed: true,\n description: 'Discord link preview bot',\n },\n {\n name: 'Telegram',\n pattern: /TelegramBot/i,\n category: 'social_media',\n allowed: true,\n description: 'Telegram link preview bot',\n },\n {\n name: 'WhatsApp',\n pattern: /WhatsApp/i,\n category: 'social_media',\n allowed: true,\n description: 'WhatsApp link preview',\n },\n {\n name: 'Snapchat',\n pattern: /Snapchat/i,\n category: 'social_media',\n allowed: true,\n description: 'Snapchat crawler',\n },\n\n // Monitoring - Generally allowed\n {\n name: 'UptimeRobot',\n pattern: /UptimeRobot/i,\n category: 'monitoring',\n allowed: true,\n description: 'UptimeRobot monitoring',\n },\n {\n name: 'Pingdom',\n pattern: /Pingdom/i,\n category: 'monitoring',\n allowed: true,\n description: 'Pingdom monitoring',\n },\n {\n name: 'StatusCake',\n pattern: /StatusCake/i,\n category: 'monitoring',\n allowed: true,\n description: 'StatusCake monitoring',\n },\n {\n name: 'Site24x7',\n pattern: /Site24x7/i,\n category: 'monitoring',\n allowed: true,\n description: 'Site24x7 monitoring',\n },\n {\n name: 'Datadog',\n pattern: /Datadog/i,\n category: 'monitoring',\n allowed: true,\n description: 'Datadog synthetic monitoring',\n },\n {\n name: 'New Relic',\n pattern: /NewRelicPinger/i,\n category: 'monitoring',\n allowed: true,\n description: 'New Relic synthetic monitoring',\n },\n {\n name: 'Checkly',\n pattern: /Checkly/i,\n category: 'monitoring',\n allowed: true,\n description: 'Checkly monitoring',\n },\n\n // SEO Tools - Usually allowed but can be blocked\n {\n name: 'Ahrefs',\n pattern: /AhrefsBot|AhrefsSiteAudit/i,\n category: 'seo',\n allowed: false,\n description: 'Ahrefs SEO crawler',\n },\n {\n name: 'Semrush',\n pattern: /SemrushBot/i,\n category: 'seo',\n allowed: false,\n description: 'Semrush SEO crawler',\n },\n {\n name: 'Moz',\n pattern: /rogerbot|DotBot/i,\n category: 'seo',\n allowed: false,\n description: 'Moz SEO crawler',\n },\n {\n name: 'Majestic',\n pattern: /MJ12bot/i,\n category: 'seo',\n allowed: false,\n description: 'Majestic SEO crawler',\n },\n {\n name: 'Screaming Frog',\n pattern: /Screaming Frog/i,\n category: 'seo',\n allowed: false,\n description: 'Screaming Frog SEO Spider',\n },\n\n // AI Crawlers - Configurable\n {\n name: 'GPTBot',\n pattern: /GPTBot/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'OpenAI GPT training crawler',\n },\n {\n name: 'ChatGPT-User',\n pattern: /ChatGPT-User/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'ChatGPT user browsing',\n },\n {\n name: 'Claude-Web',\n pattern: /Claude-Web|ClaudeBot|anthropic-ai/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'Anthropic Claude crawler',\n },\n {\n name: 'Bytespider',\n pattern: /Bytespider/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'ByteDance AI crawler',\n },\n {\n name: 'CCBot',\n pattern: /CCBot/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'Common Crawl bot',\n },\n {\n name: 'Google-Extended',\n pattern: /Google-Extended/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'Google AI training crawler',\n },\n {\n name: 'Cohere-ai',\n pattern: /cohere-ai/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'Cohere AI crawler',\n },\n {\n name: 'PerplexityBot',\n pattern: /PerplexityBot/i,\n category: 'ai_crawler',\n allowed: false,\n description: 'Perplexity AI crawler',\n },\n\n // Feed Readers - Generally allowed\n {\n name: 'Feedly',\n pattern: /Feedly/i,\n category: 'feed_reader',\n allowed: true,\n description: 'Feedly RSS reader',\n },\n {\n name: 'Feedbin',\n pattern: /Feedbin/i,\n category: 'feed_reader',\n allowed: true,\n description: 'Feedbin RSS reader',\n },\n {\n name: 'NewsBlur',\n pattern: /NewsBlur/i,\n category: 'feed_reader',\n allowed: true,\n description: 'NewsBlur RSS reader',\n },\n\n // Link Previews - Generally allowed\n {\n name: 'Embedly',\n pattern: /Embedly/i,\n category: 'preview',\n allowed: true,\n description: 'Embedly link preview',\n },\n {\n name: 'Iframely',\n pattern: /Iframely/i,\n category: 'preview',\n allowed: true,\n description: 'Iframely link preview',\n },\n\n // Security Scanners - Block by default\n {\n name: 'Nessus',\n pattern: /Nessus/i,\n category: 'security',\n allowed: false,\n description: 'Nessus vulnerability scanner',\n },\n {\n name: 'Nikto',\n pattern: /Nikto/i,\n category: 'security',\n allowed: false,\n description: 'Nikto web scanner',\n },\n {\n name: 'sqlmap',\n pattern: /sqlmap/i,\n category: 'security',\n allowed: false,\n description: 'sqlmap SQL injection tool',\n },\n {\n name: 'WPScan',\n pattern: /WPScan/i,\n category: 'security',\n allowed: false,\n description: 'WordPress vulnerability scanner',\n },\n {\n name: 'Acunetix',\n pattern: /Acunetix/i,\n category: 'security',\n allowed: false,\n description: 'Acunetix vulnerability scanner',\n },\n\n // Known Scrapers - Block\n {\n name: 'Scrapy',\n pattern: /Scrapy/i,\n category: 'scraper',\n allowed: false,\n description: 'Scrapy web scraper',\n },\n {\n name: 'HTTrack',\n pattern: /HTTrack/i,\n category: 'scraper',\n allowed: false,\n description: 'HTTrack website copier',\n },\n {\n name: 'WebCopier',\n pattern: /WebCopier/i,\n category: 'scraper',\n allowed: false,\n description: 'WebCopier tool',\n },\n {\n name: 'SiteSnagger',\n pattern: /SiteSnagger/i,\n category: 'scraper',\n allowed: false,\n description: 'SiteSnagger downloader',\n },\n\n // Spam Bots - Always block\n {\n name: 'Spam Bot',\n pattern: /spam|harvester|extractor|collect/i,\n category: 'spam',\n allowed: false,\n description: 'Generic spam bot pattern',\n },\n {\n name: 'Email Harvester',\n pattern: /email.*harvest|harvest.*email/i,\n category: 'spam',\n allowed: false,\n description: 'Email harvesting bot',\n },\n\n // Malicious - Always block\n {\n name: 'Malicious Generic',\n pattern: /masscan|ZmEu|morfeus|nmap/i,\n category: 'malicious',\n allowed: false,\n description: 'Known malicious tools',\n },\n {\n name: 'Vulnerability Scanner',\n pattern: /havij|w3af|webscarab/i,\n category: 'malicious',\n allowed: false,\n description: 'Vulnerability scanning tools',\n },\n\n // Generic Bot Pattern\n {\n name: 'Generic Bot',\n pattern: /bot|crawl|spider|scrape|fetch/i,\n category: 'unknown',\n allowed: false,\n description: 'Generic bot pattern',\n },\n {\n name: 'HTTP Library',\n pattern: /python-requests|python-urllib|curl|wget|axios|node-fetch|got\\//i,\n category: 'unknown',\n allowed: false,\n description: 'HTTP library user agent',\n },\n]\n\n/**\n * Default allowed bot categories\n */\nexport const DEFAULT_ALLOWED_CATEGORIES: BotCategory[] = [\n 'search_engine',\n 'social_media',\n 'monitoring',\n 'feed_reader',\n 'preview',\n]\n\n/**\n * Default allowed bot names\n */\nexport const DEFAULT_ALLOWED_BOTS: string[] = [\n 'Googlebot',\n 'Bingbot',\n 'Yahoo Slurp',\n 'DuckDuckBot',\n 'Applebot',\n 'Facebook',\n 'Twitter',\n 'LinkedIn',\n 'Slack',\n 'Discord',\n 'UptimeRobot',\n 'Pingdom',\n]\n\n// ============================================================================\n// User-Agent Analyzer\n// ============================================================================\n\n/**\n * Analyze a User-Agent string for bot patterns\n */\nexport function analyzeUserAgent(\n userAgent: string | null,\n options: UserAgentOptions = {}\n): BotDetectionResult {\n const {\n blockAllBots = false,\n allowCategories = DEFAULT_ALLOWED_CATEGORIES,\n allowList = DEFAULT_ALLOWED_BOTS,\n blockList = [],\n customPatterns = [],\n blockEmptyUA = true,\n blockSuspiciousUA = true,\n } = options\n\n // Empty User-Agent check\n if (!userAgent || userAgent.trim() === '') {\n return {\n isBot: blockEmptyUA,\n category: 'unknown',\n confidence: blockEmptyUA ? 0.9 : 0,\n reason: 'Empty User-Agent',\n userAgent: userAgent || '',\n }\n }\n\n // Combine built-in and custom patterns\n const allPatterns = [...customPatterns, ...KNOWN_BOT_PATTERNS]\n\n // First, check if it matches any known bot pattern\n // This takes priority over suspicious UA checks\n let matchedPattern: BotPattern | null = null\n for (const pattern of allPatterns) {\n if (pattern.pattern.test(userAgent)) {\n matchedPattern = pattern\n break\n }\n }\n\n // If no known pattern matched, check for suspicious UA\n if (!matchedPattern && blockSuspiciousUA && isSuspiciousUA(userAgent)) {\n return {\n isBot: true,\n category: 'unknown',\n confidence: 0.8,\n reason: 'Suspicious User-Agent pattern',\n userAgent,\n }\n }\n\n // If no pattern matched at all, it's likely a real browser\n if (!matchedPattern) {\n return {\n isBot: false,\n confidence: 0.1,\n reason: 'No bot pattern matched',\n userAgent,\n }\n }\n\n // We have a matched pattern, apply the rules\n\n // Check if explicitly blocked (highest priority)\n if (blockList.includes(matchedPattern.name)) {\n return {\n isBot: true,\n category: matchedPattern.category,\n name: matchedPattern.name,\n confidence: 0.95,\n reason: `Blocked bot: ${matchedPattern.name}`,\n userAgent,\n }\n }\n\n // Block all bots mode (takes priority over allow lists)\n if (blockAllBots) {\n return {\n isBot: true,\n category: matchedPattern.category,\n name: matchedPattern.name,\n confidence: 0.9,\n reason: `Bot blocked (blockAllBots mode): ${matchedPattern.name}`,\n userAgent,\n }\n }\n\n // Check if explicitly allowed\n if (allowList.includes(matchedPattern.name)) {\n return {\n isBot: true,\n category: matchedPattern.category,\n name: matchedPattern.name,\n confidence: 0.95,\n reason: `Allowed bot: ${matchedPattern.name}`,\n userAgent,\n }\n }\n\n // Check category allowlist\n if (allowCategories.includes(matchedPattern.category)) {\n return {\n isBot: true,\n category: matchedPattern.category,\n name: matchedPattern.name,\n confidence: 0.9,\n reason: `Allowed category: ${matchedPattern.category}`,\n userAgent,\n }\n }\n\n // Pattern's default behavior\n return {\n isBot: true,\n category: matchedPattern.category,\n name: matchedPattern.name,\n confidence: 0.85,\n reason: matchedPattern.allowed\n ? `Allowed bot: ${matchedPattern.name}`\n : `Blocked bot: ${matchedPattern.name}`,\n userAgent,\n }\n}\n\n/**\n * Check if User-Agent appears suspicious\n */\nexport function isSuspiciousUA(userAgent: string): boolean {\n // Too short\n if (userAgent.length < 10) {\n return true\n }\n\n // Only numbers or random characters\n if (/^[0-9a-f]{8,}$/i.test(userAgent)) {\n return true\n }\n\n // Missing typical browser indicators\n const hasBrowserIndicator = /Mozilla|Chrome|Safari|Firefox|Edge|Opera|MSIE|Trident/i.test(userAgent)\n const hasOSIndicator = /Windows|Mac|Linux|Android|iOS|iPhone|iPad/i.test(userAgent)\n\n // If it looks like a browser but missing OS, it's suspicious\n if (hasBrowserIndicator && !hasOSIndicator && userAgent.length < 50) {\n return true\n }\n\n // Very old or fake versions\n if (/Chrome\\/[0-4]\\./i.test(userAgent) || /Firefox\\/[0-3]\\./i.test(userAgent)) {\n return true\n }\n\n return false\n}\n\n/**\n * Check if a specific bot is allowed\n */\nexport function isBotAllowed(\n botName: string,\n options: UserAgentOptions = {}\n): boolean {\n const {\n blockAllBots = false,\n allowCategories = DEFAULT_ALLOWED_CATEGORIES,\n allowList = DEFAULT_ALLOWED_BOTS,\n blockList = [],\n } = options\n\n // Explicitly blocked (highest priority)\n if (blockList.includes(botName)) {\n return false\n }\n\n // Block all mode (takes priority over allow lists)\n if (blockAllBots) {\n return false\n }\n\n // Explicitly allowed\n if (allowList.includes(botName)) {\n return true\n }\n\n // Check category\n const pattern = KNOWN_BOT_PATTERNS.find(p => p.name === botName)\n if (pattern && allowCategories.includes(pattern.category)) {\n return true\n }\n\n // Default to pattern's setting\n return pattern?.allowed ?? false\n}\n\n/**\n * Get all known bot patterns for a category\n */\nexport function getBotsByCategory(category: BotCategory): BotPattern[] {\n return KNOWN_BOT_PATTERNS.filter(p => p.category === category)\n}\n\n/**\n * Create a custom bot pattern\n */\nexport function createBotPattern(\n name: string,\n pattern: RegExp | string,\n category: BotCategory,\n allowed: boolean = false,\n description?: string\n): BotPattern {\n return {\n name,\n pattern: typeof pattern === 'string' ? new RegExp(pattern, 'i') : pattern,\n category,\n allowed,\n description,\n }\n}\n","/**\n * Honeypot Protection for Bot Detection\n * @module nextjs-secure/bot\n */\n\nimport type { NextRequest } from 'next/server'\nimport type { HoneypotOptions, BotDetectionResult } from './types'\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\n/**\n * Default honeypot field names that look legitimate\n */\nexport const DEFAULT_HONEYPOT_FIELDS = [\n '_hp_email',\n '_hp_name',\n '_hp_website',\n '_hp_phone',\n '_hp_address',\n 'email_confirm',\n 'website_url',\n 'fax_number',\n]\n\n/**\n * Default honeypot options\n */\nexport const DEFAULT_HONEYPOT_OPTIONS: Required<Omit<HoneypotOptions, 'validate'>> & Pick<HoneypotOptions, 'validate'> = {\n fieldName: '_hp_email',\n additionalFields: [],\n checkIn: ['body', 'query'],\n validate: undefined,\n}\n\n// ============================================================================\n// Honeypot Detection\n// ============================================================================\n\n/**\n * Check for honeypot field values in request\n */\nexport async function checkHoneypot(\n req: NextRequest,\n options: HoneypotOptions = {}\n): Promise<BotDetectionResult> {\n const {\n fieldName = DEFAULT_HONEYPOT_OPTIONS.fieldName,\n additionalFields = DEFAULT_HONEYPOT_OPTIONS.additionalFields,\n checkIn = DEFAULT_HONEYPOT_OPTIONS.checkIn,\n validate,\n } = options\n\n const allFields = [fieldName, ...additionalFields]\n const filledFields: string[] = []\n\n // Check query parameters\n if (checkIn.includes('query')) {\n const url = new URL(req.url)\n for (const field of allFields) {\n const value = url.searchParams.get(field)\n if (value !== null && value !== '') {\n filledFields.push(`query:${field}`)\n }\n }\n }\n\n // Check request body (for POST/PUT/PATCH)\n if (checkIn.includes('body') && hasBody(req)) {\n try {\n const body = await getRequestBody(req)\n if (body && typeof body === 'object') {\n for (const field of allFields) {\n const value = (body as Record<string, unknown>)[field]\n if (value !== undefined && value !== null && value !== '') {\n // Custom validation if provided\n if (validate && !validate(value)) {\n continue\n }\n filledFields.push(`body:${field}`)\n }\n }\n }\n } catch {\n // Ignore body parsing errors\n }\n }\n\n // Check headers\n if (checkIn.includes('headers')) {\n for (const field of allFields) {\n const headerName = `x-${field.replace(/_/g, '-')}`\n const value = req.headers.get(headerName)\n if (value !== null && value !== '') {\n filledFields.push(`header:${headerName}`)\n }\n }\n }\n\n // Bot detected if any honeypot field is filled\n if (filledFields.length > 0) {\n return {\n isBot: true,\n category: 'spam',\n confidence: 0.95,\n reason: `Honeypot triggered: ${filledFields.join(', ')}`,\n ip: getClientIP(req),\n }\n }\n\n return {\n isBot: false,\n confidence: 0,\n reason: 'Honeypot check passed',\n }\n}\n\n// ============================================================================\n// Honeypot Middleware\n// ============================================================================\n\n/**\n * Create honeypot middleware\n */\nexport function withHoneypot<T = unknown>(\n handler: (req: NextRequest, ctx: T) => Response | Promise<Response>,\n options: HoneypotOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return async (req: NextRequest, ctx: T): Promise<Response> => {\n const result = await checkHoneypot(req, options)\n\n if (result.isBot) {\n // Return 403 but make it look like a success to confuse bots\n return new Response(\n JSON.stringify({\n success: false,\n error: 'Request rejected',\n }),\n {\n status: 403,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n\n return handler(req, ctx)\n }\n}\n\n// ============================================================================\n// Honeypot HTML Generator\n// ============================================================================\n\n/**\n * Generate honeypot field HTML\n * These fields should be hidden with CSS, not display:none\n * Bots often ignore display:none but fill visible fields\n */\nexport function generateHoneypotHTML(options: HoneypotOptions = {}): string {\n const {\n fieldName = DEFAULT_HONEYPOT_OPTIONS.fieldName,\n additionalFields = [],\n } = options\n\n const allFields = [fieldName, ...additionalFields]\n\n const fields = allFields.map(field => {\n // Use various hiding techniques that bots might not detect\n const style = getRandomHidingStyle()\n const labelText = humanizeFieldName(field)\n\n return `\n <div style=\"${style}\" aria-hidden=\"true\" tabindex=\"-1\">\n <label for=\"${field}\">${labelText}</label>\n <input\n type=\"text\"\n id=\"${field}\"\n name=\"${field}\"\n autocomplete=\"off\"\n tabindex=\"-1\"\n />\n </div>`\n }).join('\\n')\n\n return `<!-- Honeypot fields - Do not fill these -->\\n${fields}`\n}\n\n/**\n * Generate CSS for honeypot fields\n */\nexport function generateHoneypotCSS(options: HoneypotOptions = {}): string {\n const {\n fieldName = DEFAULT_HONEYPOT_OPTIONS.fieldName,\n additionalFields = [],\n } = options\n\n const allFields = [fieldName, ...additionalFields]\n const selectors = allFields.map(f => `#${f}`).join(', ')\n\n return `\n/* Honeypot field hiding */\n${selectors} {\n position: absolute !important;\n left: -9999px !important;\n top: -9999px !important;\n opacity: 0 !important;\n height: 0 !important;\n width: 0 !important;\n z-index: -1 !important;\n pointer-events: none !important;\n}\n`.trim()\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if request has a body\n */\nfunction hasBody(req: NextRequest): boolean {\n const method = req.method.toUpperCase()\n return ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)\n}\n\n/**\n * Get request body (cached to avoid consuming stream)\n */\nasync function getRequestBody(req: NextRequest): Promise<unknown> {\n try {\n const contentType = req.headers.get('content-type') || ''\n\n if (contentType.includes('application/json')) {\n const cloned = req.clone()\n return await cloned.json()\n }\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const cloned = req.clone()\n const text = await cloned.text()\n return Object.fromEntries(new URLSearchParams(text))\n }\n\n if (contentType.includes('multipart/form-data')) {\n const cloned = req.clone()\n const formData = await cloned.formData()\n const obj: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n obj[key] = value\n })\n return obj\n }\n\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n 'unknown'\n )\n}\n\n/**\n * Get random hiding style to make detection harder\n */\nfunction getRandomHidingStyle(): string {\n const styles = [\n 'position: absolute; left: -9999px; top: -9999px;',\n 'position: fixed; left: -100vw; visibility: hidden;',\n 'opacity: 0; height: 0; width: 0; overflow: hidden;',\n 'clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;',\n 'transform: scale(0); position: absolute;',\n ]\n return styles[Math.floor(Math.random() * styles.length)]\n}\n\n/**\n * Convert field name to human-readable label\n */\nfunction humanizeFieldName(field: string): string {\n return field\n .replace(/^_hp_/, '')\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase())\n}\n","/**\n * Behavior Analysis for Bot Detection\n * @module nextjs-secure/bot\n */\n\nimport type { NextRequest } from 'next/server'\nimport type {\n BehaviorOptions,\n BehaviorStore,\n BehaviorAnalysisResult,\n RequestRecord,\n BotDetectionResult,\n} from './types'\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\n/**\n * Default behavior analysis options\n */\nexport const DEFAULT_BEHAVIOR_OPTIONS: Required<Omit<BehaviorOptions, 'store' | 'identifier'>> & Pick<BehaviorOptions, 'store' | 'identifier'> = {\n minRequestInterval: 100,\n maxRequestsPerSecond: 10,\n windowMs: 60000,\n store: undefined,\n identifier: undefined,\n patterns: {\n sequentialAccess: true,\n regularTiming: true,\n missingHeaders: true,\n },\n}\n\n// ============================================================================\n// In-Memory Behavior Store\n// ============================================================================\n\n/**\n * In-memory behavior tracking store with LRU eviction\n */\nexport class MemoryBehaviorStore implements BehaviorStore {\n private records: Map<string, RequestRecord[]> = new Map()\n private maxIdentifiers: number\n private accessOrder: string[] = []\n\n constructor(options: { maxIdentifiers?: number } = {}) {\n this.maxIdentifiers = options.maxIdentifiers || 10000\n }\n\n async record(identifier: string, timestamp: number, path: string): Promise<void> {\n // LRU eviction\n if (!this.records.has(identifier) && this.records.size >= this.maxIdentifiers) {\n const oldest = this.accessOrder.shift()\n if (oldest) {\n this.records.delete(oldest)\n }\n }\n\n // Update access order\n const idx = this.accessOrder.indexOf(identifier)\n if (idx > -1) {\n this.accessOrder.splice(idx, 1)\n }\n this.accessOrder.push(identifier)\n\n // Add record\n const records = this.records.get(identifier) || []\n records.push({ timestamp, path })\n this.records.set(identifier, records)\n }\n\n async getHistory(identifier: string, windowMs: number): Promise<RequestRecord[]> {\n const records = this.records.get(identifier) || []\n const cutoff = Date.now() - windowMs\n\n // Filter and cleanup old records\n const filtered = records.filter(r => r.timestamp > cutoff)\n if (filtered.length !== records.length) {\n this.records.set(identifier, filtered)\n }\n\n return filtered\n }\n\n async cleanup(maxAge: number): Promise<void> {\n const cutoff = Date.now() - maxAge\n\n for (const [identifier, records] of this.records.entries()) {\n const filtered = records.filter(r => r.timestamp > cutoff)\n if (filtered.length === 0) {\n this.records.delete(identifier)\n const idx = this.accessOrder.indexOf(identifier)\n if (idx > -1) {\n this.accessOrder.splice(idx, 1)\n }\n } else {\n this.records.set(identifier, filtered)\n }\n }\n }\n\n /**\n * Get store statistics\n */\n getStats(): { identifiers: number; totalRecords: number } {\n let totalRecords = 0\n for (const records of this.records.values()) {\n totalRecords += records.length\n }\n return {\n identifiers: this.records.size,\n totalRecords,\n }\n }\n\n /**\n * Clear all records\n */\n clear(): void {\n this.records.clear()\n this.accessOrder = []\n }\n}\n\n// ============================================================================\n// Behavior Analysis\n// ============================================================================\n\n/**\n * Analyze request behavior for bot patterns\n */\nexport async function analyzeBehavior(\n req: NextRequest,\n history: RequestRecord[],\n options: BehaviorOptions = {}\n): Promise<BehaviorAnalysisResult> {\n const {\n minRequestInterval = DEFAULT_BEHAVIOR_OPTIONS.minRequestInterval,\n maxRequestsPerSecond = DEFAULT_BEHAVIOR_OPTIONS.maxRequestsPerSecond,\n patterns = DEFAULT_BEHAVIOR_OPTIONS.patterns,\n } = options\n\n const reasons: string[] = []\n let score = 0\n\n const now = Date.now()\n const requestCount = history.length\n\n // Calculate intervals between requests\n const intervals: number[] = []\n for (let i = 1; i < history.length; i++) {\n intervals.push(history[i].timestamp - history[i - 1].timestamp)\n }\n\n // Average interval\n const avgInterval = intervals.length > 0\n ? intervals.reduce((a, b) => a + b, 0) / intervals.length\n : Infinity\n\n // 1. Check request rate\n const oneSecondAgo = now - 1000\n const requestsLastSecond = history.filter(r => r.timestamp > oneSecondAgo).length\n\n if (requestsLastSecond > maxRequestsPerSecond) {\n score += 0.3\n reasons.push(`High request rate: ${requestsLastSecond}/s (max: ${maxRequestsPerSecond})`)\n }\n\n // 2. Check minimum interval\n const hasRapidRequests = intervals.some(i => i < minRequestInterval)\n if (hasRapidRequests) {\n score += 0.25\n reasons.push(`Rapid requests detected: interval < ${minRequestInterval}ms`)\n }\n\n // 3. Check for regular timing (bots often have very consistent intervals)\n if (patterns?.regularTiming && intervals.length >= 5) {\n const variance = calculateVariance(intervals)\n const coefficientOfVariation = Math.sqrt(variance) / avgInterval\n\n // Very low variance indicates automated requests\n if (coefficientOfVariation < 0.1) {\n score += 0.2\n reasons.push('Suspiciously regular request timing')\n }\n }\n\n // 4. Check for sequential URL patterns\n if (patterns?.sequentialAccess && history.length >= 5) {\n const paths = history.map(r => r.path)\n if (isSequentialPattern(paths)) {\n score += 0.15\n reasons.push('Sequential URL access pattern detected')\n }\n }\n\n // 5. Check missing typical browser headers\n if (patterns?.missingHeaders) {\n const missingScore = checkMissingHeaders(req)\n if (missingScore > 0) {\n score += missingScore\n reasons.push('Missing typical browser headers')\n }\n }\n\n // Normalize score to 0-1 range\n score = Math.min(1, score)\n\n return {\n suspicious: score >= 0.5,\n score,\n reasons,\n requestCount,\n avgInterval,\n }\n}\n\n/**\n * Check behavior and return bot detection result\n */\nexport async function checkBehavior(\n req: NextRequest,\n options: BehaviorOptions = {}\n): Promise<BotDetectionResult> {\n const {\n store = new MemoryBehaviorStore(),\n windowMs = DEFAULT_BEHAVIOR_OPTIONS.windowMs,\n identifier: getIdentifier,\n } = options\n\n // Get identifier\n const identifier = getIdentifier\n ? await getIdentifier(req)\n : getClientIP(req)\n\n // Get history\n const history = await store.getHistory(identifier, windowMs)\n\n // Record current request\n const now = Date.now()\n const path = new URL(req.url).pathname\n await store.record(identifier, now, path)\n\n // Analyze behavior (with the new record included)\n const updatedHistory = [...history, { timestamp: now, path }]\n const analysis = await analyzeBehavior(req, updatedHistory, options)\n\n return {\n isBot: analysis.suspicious,\n confidence: analysis.score,\n reason: analysis.reasons.join('; ') || 'Behavior analysis passed',\n ip: identifier,\n }\n}\n\n// ============================================================================\n// Behavior Middleware\n// ============================================================================\n\n/**\n * Global behavior store instance\n */\nlet globalBehaviorStore: MemoryBehaviorStore | undefined\n\n/**\n * Get or create global behavior store\n */\nexport function getGlobalBehaviorStore(): MemoryBehaviorStore {\n if (!globalBehaviorStore) {\n globalBehaviorStore = new MemoryBehaviorStore()\n }\n return globalBehaviorStore\n}\n\n/**\n * Create behavior analysis middleware\n */\nexport function withBehaviorAnalysis<T = unknown>(\n handler: (req: NextRequest, ctx: T) => Response | Promise<Response>,\n options: BehaviorOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n // Use provided store or global store\n const store = options.store || getGlobalBehaviorStore()\n const mergedOptions = { ...options, store }\n\n return async (req: NextRequest, ctx: T): Promise<Response> => {\n const result = await checkBehavior(req, mergedOptions)\n\n if (result.isBot && result.confidence >= 0.5) {\n return new Response(\n JSON.stringify({\n error: 'Too Many Requests',\n message: 'Unusual request pattern detected',\n retryAfter: 60,\n }),\n {\n status: 429,\n headers: {\n 'Content-Type': 'application/json',\n 'Retry-After': '60',\n },\n }\n )\n }\n\n return handler(req, ctx)\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n 'unknown'\n )\n}\n\n/**\n * Calculate variance of numbers\n */\nfunction calculateVariance(numbers: number[]): number {\n if (numbers.length === 0) return 0\n const mean = numbers.reduce((a, b) => a + b, 0) / numbers.length\n const squaredDiffs = numbers.map(n => Math.pow(n - mean, 2))\n return squaredDiffs.reduce((a, b) => a + b, 0) / numbers.length\n}\n\n/**\n * Detect sequential URL patterns\n */\nfunction isSequentialPattern(paths: string[]): boolean {\n // Check for numeric sequences in paths\n const numbers = paths.map(p => {\n const match = p.match(/(\\d+)/)\n return match ? parseInt(match[1], 10) : null\n }).filter((n): n is number => n !== null)\n\n if (numbers.length < 3) return false\n\n // Check if numbers are sequential\n let sequential = 0\n for (let i = 1; i < numbers.length; i++) {\n if (numbers[i] === numbers[i - 1] + 1) {\n sequential++\n }\n }\n\n return sequential >= numbers.length * 0.6\n}\n\n/**\n * Check for missing typical browser headers\n */\nfunction checkMissingHeaders(req: NextRequest): number {\n let score = 0\n\n // Typical browser headers\n const typicalHeaders = [\n 'accept',\n 'accept-language',\n 'accept-encoding',\n ]\n\n for (const header of typicalHeaders) {\n if (!req.headers.get(header)) {\n score += 0.05\n }\n }\n\n // Check for suspicious accept header\n const accept = req.headers.get('accept')\n if (accept && !accept.includes('text/html') && !accept.includes('application/json') && !accept.includes('*/*')) {\n score += 0.05\n }\n\n // Check for missing referer on non-entry pages\n const referer = req.headers.get('referer')\n const path = new URL(req.url).pathname\n if (!referer && path !== '/' && !path.includes('/api/')) {\n score += 0.03\n }\n\n return score\n}\n","/**\n * CAPTCHA Integration for Bot Detection\n * @module nextjs-secure/bot\n *\n * Supports:\n * - Google reCAPTCHA v2 & v3\n * - hCaptcha\n * - Cloudflare Turnstile\n */\n\nimport type { NextRequest } from 'next/server'\nimport type { CaptchaOptions, CaptchaResult, CaptchaProvider, BotDetectionResult } from './types'\n\n// ============================================================================\n// CAPTCHA Verification URLs\n// ============================================================================\n\nconst CAPTCHA_VERIFY_URLS: Record<CaptchaProvider, string> = {\n recaptcha: 'https://www.google.com/recaptcha/api/siteverify',\n hcaptcha: 'https://hcaptcha.com/siteverify',\n turnstile: 'https://challenges.cloudflare.com/turnstile/v0/siteverify',\n}\n\n/**\n * Default token field names per provider\n */\nconst DEFAULT_TOKEN_FIELDS: Record<CaptchaProvider, string> = {\n recaptcha: 'g-recaptcha-response',\n hcaptcha: 'h-captcha-response',\n turnstile: 'cf-turnstile-response',\n}\n\n// ============================================================================\n// CAPTCHA Verification\n// ============================================================================\n\n/**\n * Verify CAPTCHA token with provider\n */\nexport async function verifyCaptcha(\n token: string,\n options: CaptchaOptions\n): Promise<CaptchaResult> {\n const { provider, secretKey, action } = options\n\n const verifyUrl = CAPTCHA_VERIFY_URLS[provider]\n\n // Build form data\n const formData = new URLSearchParams()\n formData.append('secret', secretKey)\n formData.append('response', token)\n\n try {\n const response = await fetch(verifyUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: formData.toString(),\n })\n\n if (!response.ok) {\n return {\n success: false,\n errorCodes: [`HTTP ${response.status}`],\n }\n }\n\n const data = await response.json()\n\n // Parse response based on provider\n return parseCaptchaResponse(data, provider, action)\n } catch (error) {\n return {\n success: false,\n errorCodes: ['verification-failed', String(error)],\n }\n }\n}\n\n/**\n * Parse CAPTCHA verification response\n */\nfunction parseCaptchaResponse(\n data: Record<string, unknown>,\n provider: CaptchaProvider,\n expectedAction?: string\n): CaptchaResult {\n switch (provider) {\n case 'recaptcha':\n return parseRecaptchaResponse(data, expectedAction)\n case 'hcaptcha':\n return parseHCaptchaResponse(data)\n case 'turnstile':\n return parseTurnstileResponse(data)\n default:\n return {\n success: false,\n errorCodes: ['unknown-provider'],\n }\n }\n}\n\n/**\n * Parse reCAPTCHA response\n */\nfunction parseRecaptchaResponse(\n data: Record<string, unknown>,\n expectedAction?: string\n): CaptchaResult {\n const result: CaptchaResult = {\n success: data.success === true,\n score: typeof data.score === 'number' ? data.score : undefined,\n action: typeof data.action === 'string' ? data.action : undefined,\n hostname: typeof data.hostname === 'string' ? data.hostname : undefined,\n challengeTs: typeof data.challenge_ts === 'string' ? data.challenge_ts : undefined,\n errorCodes: Array.isArray(data['error-codes']) ? data['error-codes'] as string[] : undefined,\n }\n\n // For reCAPTCHA v3, verify action matches if specified\n if (result.success && expectedAction && result.action !== expectedAction) {\n result.success = false\n result.errorCodes = ['action-mismatch']\n }\n\n return result\n}\n\n/**\n * Parse hCaptcha response\n */\nfunction parseHCaptchaResponse(data: Record<string, unknown>): CaptchaResult {\n return {\n success: data.success === true,\n hostname: typeof data.hostname === 'string' ? data.hostname : undefined,\n challengeTs: typeof data.challenge_ts === 'string' ? data.challenge_ts : undefined,\n errorCodes: Array.isArray(data['error-codes']) ? data['error-codes'] as string[] : undefined,\n }\n}\n\n/**\n * Parse Turnstile response\n */\nfunction parseTurnstileResponse(data: Record<string, unknown>): CaptchaResult {\n return {\n success: data.success === true,\n hostname: typeof data.hostname === 'string' ? data.hostname : undefined,\n challengeTs: typeof data.challenge_ts === 'string' ? data.challenge_ts : undefined,\n action: typeof data.action === 'string' ? data.action : undefined,\n errorCodes: Array.isArray(data['error-codes']) ? data['error-codes'] as string[] : undefined,\n }\n}\n\n// ============================================================================\n// CAPTCHA Token Extraction\n// ============================================================================\n\n/**\n * Extract CAPTCHA token from request\n */\nexport async function extractCaptchaToken(\n req: NextRequest,\n options: CaptchaOptions\n): Promise<string | null> {\n const { provider, tokenField } = options\n const fieldName = tokenField || DEFAULT_TOKEN_FIELDS[provider]\n\n // Try query parameters first\n const url = new URL(req.url)\n const queryToken = url.searchParams.get(fieldName)\n if (queryToken) {\n return queryToken\n }\n\n // Try request body\n if (hasBody(req)) {\n try {\n const body = await getRequestBody(req)\n if (body && typeof body === 'object') {\n const bodyToken = (body as Record<string, unknown>)[fieldName]\n if (typeof bodyToken === 'string') {\n return bodyToken\n }\n }\n } catch {\n // Ignore body parsing errors\n }\n }\n\n // Try headers\n const headerToken = req.headers.get(`x-${fieldName}`)\n if (headerToken) {\n return headerToken\n }\n\n return null\n}\n\n// ============================================================================\n// CAPTCHA Check\n// ============================================================================\n\n/**\n * Check CAPTCHA and return bot detection result\n */\nexport async function checkCaptcha(\n req: NextRequest,\n options: CaptchaOptions\n): Promise<BotDetectionResult> {\n const { threshold = 0.5, skip } = options\n\n // Check skip condition\n if (skip && await skip(req)) {\n return {\n isBot: false,\n confidence: 0,\n reason: 'CAPTCHA check skipped',\n }\n }\n\n // Extract token\n const token = await extractCaptchaToken(req, options)\n\n if (!token) {\n return {\n isBot: true,\n confidence: 0.9,\n reason: 'CAPTCHA token missing',\n ip: getClientIP(req),\n }\n }\n\n // Verify token\n const result = await verifyCaptcha(token, options)\n\n if (!result.success) {\n return {\n isBot: true,\n confidence: 0.95,\n reason: `CAPTCHA verification failed: ${result.errorCodes?.join(', ') || 'unknown'}`,\n ip: getClientIP(req),\n }\n }\n\n // For reCAPTCHA v3, check score threshold\n if (result.score !== undefined && result.score < threshold) {\n return {\n isBot: true,\n confidence: 1 - result.score,\n reason: `CAPTCHA score too low: ${result.score} (threshold: ${threshold})`,\n ip: getClientIP(req),\n }\n }\n\n return {\n isBot: false,\n confidence: result.score !== undefined ? 1 - result.score : 0.1,\n reason: 'CAPTCHA verification passed',\n }\n}\n\n// ============================================================================\n// CAPTCHA Middleware\n// ============================================================================\n\n/**\n * Create CAPTCHA verification middleware\n */\nexport function withCaptcha<T = unknown>(\n handler: (req: NextRequest, ctx: T) => Response | Promise<Response>,\n options: CaptchaOptions\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return async (req: NextRequest, ctx: T): Promise<Response> => {\n const result = await checkCaptcha(req, options)\n\n if (result.isBot) {\n return new Response(\n JSON.stringify({\n error: 'CAPTCHA Required',\n message: result.reason,\n code: 'CAPTCHA_FAILED',\n }),\n {\n status: 403,\n headers: { 'Content-Type': 'application/json' },\n }\n )\n }\n\n return handler(req, ctx)\n }\n}\n\n// ============================================================================\n// CAPTCHA HTML Generators\n// ============================================================================\n\n/**\n * Generate reCAPTCHA v2 checkbox HTML\n */\nexport function generateRecaptchaV2(siteKey: string, options: {\n theme?: 'light' | 'dark'\n size?: 'normal' | 'compact'\n} = {}): string {\n const { theme = 'light', size = 'normal' } = options\n\n return `\n<script src=\"https://www.google.com/recaptcha/api.js\" async defer></script>\n<div class=\"g-recaptcha\" data-sitekey=\"${siteKey}\" data-theme=\"${theme}\" data-size=\"${size}\"></div>\n`.trim()\n}\n\n/**\n * Generate reCAPTCHA v3 HTML\n */\nexport function generateRecaptchaV3(siteKey: string, action: string = 'submit'): string {\n return `\n<script src=\"https://www.google.com/recaptcha/api.js?render=${siteKey}\"></script>\n<script>\n function getRecaptchaToken() {\n return new Promise((resolve, reject) => {\n grecaptcha.ready(() => {\n grecaptcha.execute('${siteKey}', { action: '${action}' })\n .then(resolve)\n .catch(reject);\n });\n });\n }\n</script>\n`.trim()\n}\n\n/**\n * Generate hCaptcha HTML\n */\nexport function generateHCaptcha(siteKey: string, options: {\n theme?: 'light' | 'dark'\n size?: 'normal' | 'compact'\n} = {}): string {\n const { theme = 'light', size = 'normal' } = options\n\n return `\n<script src=\"https://js.hcaptcha.com/1/api.js\" async defer></script>\n<div class=\"h-captcha\" data-sitekey=\"${siteKey}\" data-theme=\"${theme}\" data-size=\"${size}\"></div>\n`.trim()\n}\n\n/**\n * Generate Cloudflare Turnstile HTML\n */\nexport function generateTurnstile(siteKey: string, options: {\n theme?: 'light' | 'dark' | 'auto'\n size?: 'normal' | 'compact'\n} = {}): string {\n const { theme = 'auto', size = 'normal' } = options\n\n return `\n<script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>\n<div class=\"cf-turnstile\" data-sitekey=\"${siteKey}\" data-theme=\"${theme}\" data-size=\"${size}\"></div>\n`.trim()\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if request has a body\n */\nfunction hasBody(req: NextRequest): boolean {\n const method = req.method.toUpperCase()\n return ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)\n}\n\n/**\n * Get request body\n */\nasync function getRequestBody(req: NextRequest): Promise<unknown> {\n try {\n const contentType = req.headers.get('content-type') || ''\n\n if (contentType.includes('application/json')) {\n const cloned = req.clone()\n return await cloned.json()\n }\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n const cloned = req.clone()\n const text = await cloned.text()\n return Object.fromEntries(new URLSearchParams(text))\n }\n\n if (contentType.includes('multipart/form-data')) {\n const cloned = req.clone()\n const formData = await cloned.formData()\n const obj: Record<string, unknown> = {}\n formData.forEach((value, key) => {\n obj[key] = value\n })\n return obj\n }\n\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n 'unknown'\n )\n}\n","/**\n * Bot Protection Middleware\n * @module nextjs-secure/bot\n *\n * Combined bot detection middleware that integrates:\n * - User-Agent analysis\n * - Honeypot fields\n * - Behavior analysis\n * - CAPTCHA verification\n */\n\nimport type { NextRequest } from 'next/server'\nimport type {\n BotProtectionOptions,\n BotDetectionResult,\n BotContext,\n UserAgentOptions,\n HoneypotOptions,\n BehaviorOptions,\n CaptchaOptions,\n} from './types'\nimport { analyzeUserAgent, DEFAULT_ALLOWED_CATEGORIES, DEFAULT_ALLOWED_BOTS } from './user-agent'\nimport { checkHoneypot } from './honeypot'\nimport { checkBehavior, getGlobalBehaviorStore } from './behavior'\nimport { checkCaptcha } from './captcha'\n\n// ============================================================================\n// Default Bot Response\n// ============================================================================\n\n/**\n * Default response when bot is detected\n */\nfunction defaultBotResponse(result: BotDetectionResult): Response {\n return new Response(\n JSON.stringify({\n error: 'Forbidden',\n message: result.reason || 'Request blocked',\n code: 'BOT_DETECTED',\n category: result.category,\n }),\n {\n status: 403,\n headers: {\n 'Content-Type': 'application/json',\n 'X-Bot-Detection': 'true',\n },\n }\n )\n}\n\n// ============================================================================\n// Combined Bot Detection\n// ============================================================================\n\n/**\n * Run all enabled bot detection checks\n */\nexport async function detectBot(\n req: NextRequest,\n options: BotProtectionOptions = {}\n): Promise<BotDetectionResult> {\n const results: BotDetectionResult[] = []\n\n // 1. User-Agent analysis\n if (options.userAgent !== false) {\n const uaOptions: UserAgentOptions = options.userAgent === true ? {} : (options.userAgent || {})\n const userAgent = req.headers.get('user-agent')\n const uaResult = analyzeUserAgent(userAgent, uaOptions)\n\n // Only add if detected as bot AND not allowed\n if (uaResult.isBot && !isAllowedBot(uaResult, uaOptions)) {\n results.push(uaResult)\n }\n }\n\n // 2. Honeypot check (only for POST/PUT/PATCH)\n if (options.honeypot !== false && hasBody(req)) {\n const hpOptions: HoneypotOptions = options.honeypot === true ? {} : (options.honeypot || {})\n const hpResult = await checkHoneypot(req, hpOptions)\n if (hpResult.isBot) {\n results.push(hpResult)\n }\n }\n\n // 3. Behavior analysis\n if (options.behavior !== false) {\n const behaviorOptions: BehaviorOptions = options.behavior === true ? {} : (options.behavior || {})\n // Use global store if not provided\n if (!behaviorOptions.store) {\n behaviorOptions.store = getGlobalBehaviorStore()\n }\n const behaviorResult = await checkBehavior(req, behaviorOptions)\n if (behaviorResult.isBot) {\n results.push(behaviorResult)\n }\n }\n\n // 4. CAPTCHA verification (only if configured)\n if (options.captcha) {\n const captchaResult = await checkCaptcha(req, options.captcha)\n if (captchaResult.isBot) {\n results.push(captchaResult)\n }\n }\n\n // Combine results\n if (results.length === 0) {\n return {\n isBot: false,\n confidence: 0,\n reason: 'All checks passed',\n ip: getClientIP(req),\n userAgent: req.headers.get('user-agent') || undefined,\n }\n }\n\n // Find highest confidence result\n const highestConfidence = results.reduce((prev, curr) =>\n curr.confidence > prev.confidence ? curr : prev\n )\n\n // Combine all reasons\n const allReasons = results.map(r => r.reason).filter(Boolean).join('; ')\n\n return {\n isBot: true,\n category: highestConfidence.category,\n name: highestConfidence.name,\n confidence: highestConfidence.confidence,\n reason: allReasons,\n ip: getClientIP(req),\n userAgent: req.headers.get('user-agent') || undefined,\n }\n}\n\n/**\n * Check if a detected bot is allowed\n */\nfunction isAllowedBot(result: BotDetectionResult, options: UserAgentOptions): boolean {\n const {\n allowCategories = DEFAULT_ALLOWED_CATEGORIES,\n allowList = DEFAULT_ALLOWED_BOTS,\n blockList = [],\n blockAllBots = false,\n } = options\n\n // Explicitly blocked\n if (result.name && blockList.includes(result.name)) {\n return false\n }\n\n // Block all mode\n if (blockAllBots) {\n return false\n }\n\n // Explicitly allowed by name\n if (result.name && allowList.includes(result.name)) {\n return true\n }\n\n // Allowed by category\n if (result.category && allowCategories.includes(result.category)) {\n return true\n }\n\n return false\n}\n\n// ============================================================================\n// Main Bot Protection Middleware\n// ============================================================================\n\n/**\n * Create bot protection middleware\n *\n * @example\n * ```typescript\n * import { withBotProtection } from 'nextjs-secure/bot'\n *\n * export const POST = withBotProtection(handler, {\n * userAgent: {\n * blockAllBots: false,\n * allowList: ['Googlebot', 'Bingbot'],\n * },\n * honeypot: {\n * fieldName: '_hp_email',\n * },\n * behavior: {\n * maxRequestsPerSecond: 10,\n * },\n * })\n * ```\n */\nexport function withBotProtection<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n options: BotProtectionOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n const {\n skip,\n onBot,\n log,\n mode = 'block',\n } = options\n\n return async (req: NextRequest, ctx: T): Promise<Response> => {\n // Check skip condition\n if (skip && await skip(req)) {\n return handler(req, { ...ctx, bot: undefined })\n }\n\n // Run bot detection\n const result = await detectBot(req, options)\n\n // Log if enabled\n if (log) {\n if (typeof log === 'function') {\n log(result)\n } else if (result.isBot) {\n console.log('[Bot Detection]', JSON.stringify(result))\n }\n }\n\n // Handle bot detection\n if (result.isBot) {\n if (mode === 'block') {\n // Custom response handler\n if (onBot) {\n return onBot(req, result)\n }\n return defaultBotResponse(result)\n }\n // Detect mode - continue but add bot info to context\n }\n\n // Add bot info to context and continue\n const extendedCtx: T & BotContext = {\n ...ctx,\n bot: result,\n }\n\n return handler(req, extendedCtx)\n }\n}\n\n// ============================================================================\n// Convenience Middleware Functions\n// ============================================================================\n\n/**\n * User-Agent only bot protection\n */\nexport function withUserAgentProtection<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n options: UserAgentOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return withBotProtection(handler, {\n userAgent: options,\n honeypot: false,\n behavior: false,\n })\n}\n\n/**\n * Honeypot only protection\n */\nexport function withHoneypotProtection<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n options: HoneypotOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return withBotProtection(handler, {\n userAgent: false,\n honeypot: options,\n behavior: false,\n })\n}\n\n/**\n * Behavior analysis only protection\n */\nexport function withBehaviorProtection<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n options: BehaviorOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return withBotProtection(handler, {\n userAgent: false,\n honeypot: false,\n behavior: options,\n })\n}\n\n/**\n * CAPTCHA only protection\n */\nexport function withCaptchaProtection<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n options: CaptchaOptions\n): (req: NextRequest, ctx: T) => Promise<Response> {\n return withBotProtection(handler, {\n userAgent: false,\n honeypot: false,\n behavior: false,\n captcha: options,\n })\n}\n\n// ============================================================================\n// Preset Configurations\n// ============================================================================\n\n/**\n * Preset bot protection configurations\n */\nexport const BOT_PROTECTION_PRESETS = {\n /**\n * Relaxed - Only blocks obvious bots\n */\n relaxed: {\n userAgent: {\n blockAllBots: false,\n allowCategories: ['search_engine', 'social_media', 'monitoring', 'feed_reader', 'preview', 'seo'],\n },\n honeypot: false,\n behavior: false,\n } as BotProtectionOptions,\n\n /**\n * Standard - Good balance of protection\n */\n standard: {\n userAgent: {\n blockAllBots: false,\n allowCategories: ['search_engine', 'social_media', 'monitoring'],\n },\n honeypot: true,\n behavior: {\n maxRequestsPerSecond: 10,\n },\n } as BotProtectionOptions,\n\n /**\n * Strict - Maximum protection\n */\n strict: {\n userAgent: {\n blockAllBots: false,\n allowCategories: ['search_engine'],\n blockEmptyUA: true,\n blockSuspiciousUA: true,\n },\n honeypot: {\n additionalFields: ['_hp_name', '_hp_phone'],\n },\n behavior: {\n maxRequestsPerSecond: 5,\n minRequestInterval: 200,\n },\n } as BotProtectionOptions,\n\n /**\n * API - For API endpoints\n */\n api: {\n userAgent: {\n blockAllBots: true,\n blockEmptyUA: true,\n },\n honeypot: false,\n behavior: {\n maxRequestsPerSecond: 20,\n },\n } as BotProtectionOptions,\n} as const\n\n/**\n * Create bot protection with preset\n */\nexport function withBotProtectionPreset<T = unknown>(\n handler: (req: NextRequest, ctx: T & BotContext) => Response | Promise<Response>,\n preset: keyof typeof BOT_PROTECTION_PRESETS,\n overrides: BotProtectionOptions = {}\n): (req: NextRequest, ctx: T) => Promise<Response> {\n const presetOptions = BOT_PROTECTION_PRESETS[preset]\n const mergedOptions = { ...presetOptions, ...overrides }\n return withBotProtection(handler, mergedOptions)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if request has a body\n */\nfunction hasBody(req: NextRequest): boolean {\n const method = req.method.toUpperCase()\n return ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)\n}\n\n/**\n * Get client IP from request\n */\nfunction getClientIP(req: NextRequest): string {\n return (\n req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n req.headers.get('x-real-ip') ||\n req.headers.get('cf-connecting-ip') ||\n 'unknown'\n )\n}\n","/**\n * next-secure\n *\n * Production-ready security middleware for Next.js 13+ App Router.\n *\n * @example\n * ```typescript\n * import { withRateLimit, withAuth, secure } from 'next-secure'\n *\n * // Simple rate limiting\n * export const GET = withRateLimit(\n * async (req) => Response.json({ ok: true }),\n * { limit: 100, window: '15m' }\n * )\n *\n * // Builder pattern\n * export const POST = secure()\n * .rateLimit({ limit: 10, window: '1m' })\n * .auth({ roles: ['admin'] })\n * .handle(async (req, ctx) => {\n * return Response.json({ user: ctx.user })\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// =============================================================================\n// Core\n// =============================================================================\n\nexport type {\n NextRequest,\n SecureContext,\n SecureHandler,\n Middleware,\n ErrorResponse,\n RateLimitInfo,\n Duration,\n RateLimitAlgorithm,\n RateLimitIdentifier,\n} from './core/types'\n\nexport {\n SecureError,\n RateLimitError,\n AuthenticationError,\n AuthorizationError,\n ValidationError,\n CsrfError,\n ConfigurationError,\n isSecureError,\n toSecureError,\n} from './core/errors'\n\n// =============================================================================\n// Rate Limiting\n// =============================================================================\n\nexport {\n withRateLimit,\n createRateLimiter,\n checkRateLimit,\n resetRateLimit,\n getRateLimitStatus,\n clearAllRateLimits,\n} from './middleware/rate-limit'\n\nexport type {\n RateLimitConfig,\n RateLimitStore,\n MemoryStoreOptions,\n RedisStoreOptions,\n UpstashStoreOptions,\n} from './middleware/rate-limit'\n\nexport {\n MemoryStore,\n createMemoryStore,\n getGlobalMemoryStore,\n} from './middleware/rate-limit'\n\n// =============================================================================\n// CSRF Protection\n// =============================================================================\n\nexport {\n withCSRF,\n generateCSRF,\n validateCSRF,\n createToken as createCSRFToken,\n verifyToken as verifyCSRFToken,\n tokensMatch,\n} from './middleware/csrf'\n\nexport type {\n CSRFConfig,\n CSRFCookieOptions,\n CSRFToken,\n} from './middleware/csrf'\n\n// =============================================================================\n// Security Headers\n// =============================================================================\n\nexport {\n withSecurityHeaders,\n createSecurityHeaders,\n createSecurityHeadersObject,\n buildCSP,\n buildHSTS,\n buildPermissionsPolicy,\n getPreset,\n PRESET_STRICT,\n PRESET_RELAXED,\n PRESET_API,\n} from './middleware/headers'\n\nexport type {\n ContentSecurityPolicy,\n StrictTransportSecurity,\n PermissionsPolicy,\n SecurityHeadersConfig,\n SecurityHeadersPreset,\n XFrameOptions,\n ReferrerPolicy,\n} from './middleware/headers'\n\n// =============================================================================\n// Authentication\n// =============================================================================\n\nexport {\n withJWT,\n withAPIKey,\n withSession,\n withAuth,\n withRoles,\n withOptionalAuth,\n verifyJWT,\n decodeJWT,\n extractBearerToken,\n} from './middleware/auth'\n\nexport type {\n AuthUser,\n AuthConfig,\n AuthError,\n AuthErrorCode,\n JWTConfig,\n JWTPayload,\n APIKeyConfig,\n SessionConfig,\n RBACConfig,\n} from './middleware/auth'\n\n// =============================================================================\n// Input Validation\n// =============================================================================\n\nexport {\n // Middleware\n withValidation,\n withSanitization,\n withXSSProtection,\n withSQLProtection,\n withContentType,\n withFileValidation,\n withSecureValidation,\n // Schema validation\n validate,\n validateBody,\n validateQuery,\n validateRequest,\n createValidator,\n // XSS\n sanitize,\n sanitizeObject,\n sanitizeFields,\n escapeHtml,\n stripHtml,\n detectXSS,\n // SQL\n detectSQLInjection,\n hasSQLInjection,\n sanitizeSQLInput,\n // Path\n validatePath,\n sanitizePath,\n hasPathTraversal,\n sanitizeFilename,\n // Content-Type\n validateContentType,\n isJsonRequest,\n isFormRequest,\n MIME_TYPES,\n // File\n validateFile,\n validateFiles,\n detectFileType,\n DANGEROUS_EXTENSIONS,\n} from './middleware/validation'\n\nexport type {\n ValidationError as InputValidationError,\n ValidationResult,\n ValidationConfig,\n ValidatedContext,\n SanitizeConfig,\n SanitizeMode,\n SQLDetection,\n SQLProtectionConfig,\n PathValidationConfig,\n PathValidationResult,\n ContentTypeConfig,\n FileValidationConfig,\n FileValidationError,\n FileInfo,\n FieldRule,\n FieldType,\n CustomSchema,\n} from './middleware/validation'\n\n// =============================================================================\n// Audit Logging\n// =============================================================================\n\nexport {\n // Middleware\n withAuditLog,\n createAuditMiddleware,\n withRequestId,\n withTiming,\n // Stores\n MemoryStore as AuditMemoryStore,\n createMemoryStore as createAuditMemoryStore,\n ConsoleStore,\n createConsoleStore,\n ExternalStore,\n createExternalStore,\n createDatadogStore,\n MultiStore,\n createMultiStore,\n // Formatters\n JSONFormatter,\n TextFormatter,\n CLFFormatter,\n StructuredFormatter,\n createJSONFormatter,\n createTextFormatter,\n createCLFFormatter,\n createStructuredFormatter,\n // Redaction\n DEFAULT_PII_FIELDS,\n mask,\n redactObject,\n createRedactor,\n redactHeaders,\n redactQuery,\n redactEmail,\n redactCreditCard,\n redactPhone,\n redactIP,\n // Security Events\n SecurityEventTracker,\n createSecurityTracker,\n trackSecurityEvent,\n} from './middleware/audit'\n\nexport type {\n LogLevel,\n SecurityEventType,\n LogEntry,\n RequestLogEntry,\n SecurityEventEntry,\n AuditLogEntry,\n LogStore,\n LogQueryOptions,\n LogFormatter,\n PIIConfig,\n AuditConfig,\n SecurityEventConfig,\n ConsoleStoreOptions,\n MemoryStoreOptions as AuditMemoryStoreOptions,\n ExternalStoreOptions,\n} from './middleware/audit'\n\n// =============================================================================\n// Bot Detection\n// =============================================================================\n\nexport {\n // Main middleware\n withBotProtection,\n withUserAgentProtection,\n withHoneypotProtection,\n withBehaviorProtection,\n withCaptchaProtection,\n withBotProtectionPreset,\n detectBot,\n BOT_PROTECTION_PRESETS,\n // User-Agent\n analyzeUserAgent,\n isSuspiciousUA,\n isBotAllowed,\n getBotsByCategory,\n createBotPattern,\n KNOWN_BOT_PATTERNS,\n DEFAULT_ALLOWED_CATEGORIES,\n DEFAULT_ALLOWED_BOTS,\n // Honeypot\n checkHoneypot,\n withHoneypot,\n generateHoneypotHTML,\n generateHoneypotCSS,\n DEFAULT_HONEYPOT_FIELDS,\n // Behavior\n MemoryBehaviorStore,\n analyzeBehavior,\n checkBehavior,\n getGlobalBehaviorStore,\n withBehaviorAnalysis,\n // CAPTCHA\n verifyCaptcha,\n checkCaptcha,\n withCaptcha,\n generateRecaptchaV2,\n generateRecaptchaV3,\n generateHCaptcha,\n generateTurnstile,\n} from './middleware/bot'\n\nexport type {\n BotCategory,\n BotDetectionResult,\n BotPattern,\n UserAgentOptions,\n HoneypotOptions,\n BehaviorOptions,\n BehaviorStore,\n BehaviorAnalysisResult,\n CaptchaProvider,\n CaptchaOptions,\n CaptchaResult,\n BotProtectionOptions,\n BotContext,\n} from './middleware/bot'\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nexport {\n parseDuration,\n formatDuration,\n nowInSeconds,\n nowInMs,\n sleep,\n} from './utils/time'\n\nexport {\n getClientIp,\n normalizeIp,\n isValidIp,\n isPrivateIp,\n isLocalhost,\n anonymizeIp,\n getGeoInfo,\n} from './utils/ip'\n\n// =============================================================================\n// Version\n// =============================================================================\n\n/**\n * Package version\n */\nexport const VERSION = '0.7.0'\n"]}