@re-auth/http-adapters
Version:
HTTP protocol adapters for ReAuth - framework-agnostic integration with Express, Fastify, and Hono
1 lines • 14.9 kB
Source Map (JSON)
{"version":3,"sources":["../../src/middleware/security.ts"],"names":[],"mappings":"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","file":"security.cjs","sourcesContent":["import type {\n CorsConfig,\n RateLimitConfig,\n SecurityConfig,\n ValidationConfig,\n MiddlewareFunction,\n} from '../types';\n\n/**\n * CORS middleware factory\n */\nexport function createCorsMiddleware(\n config: CorsConfig = {},\n): MiddlewareFunction {\n const {\n origin = '*',\n credentials = false,\n allowedHeaders = ['Content-Type', 'Authorization'],\n exposedHeaders = [],\n methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],\n preflightContinue = false,\n optionsSuccessStatus = 204,\n } = config;\n\n return (req: any, res: any, next: any) => {\n // Handle origin\n if (typeof origin === 'string') {\n res.header('Access-Control-Allow-Origin', origin);\n } else if (typeof origin === 'boolean') {\n res.header('Access-Control-Allow-Origin', origin ? '*' : 'false');\n } else if (Array.isArray(origin)) {\n const requestOrigin = req.headers.origin;\n if (requestOrigin && origin.includes(requestOrigin)) {\n res.header('Access-Control-Allow-Origin', requestOrigin);\n }\n } else if (typeof origin === 'function') {\n const requestOrigin = req.headers.origin;\n origin(requestOrigin, (err, allow) => {\n if (err) {\n return next(err);\n }\n if (allow) {\n res.header('Access-Control-Allow-Origin', requestOrigin || '*');\n }\n });\n }\n\n // Handle credentials\n if (credentials) {\n res.header('Access-Control-Allow-Credentials', 'true');\n }\n\n // Handle methods\n res.header('Access-Control-Allow-Methods', methods.join(', '));\n\n // Handle headers\n if (allowedHeaders.length > 0) {\n res.header('Access-Control-Allow-Headers', allowedHeaders.join(', '));\n }\n\n if (exposedHeaders.length > 0) {\n res.header('Access-Control-Expose-Headers', exposedHeaders.join(', '));\n }\n\n // Handle preflight\n if (req.method === 'OPTIONS') {\n if (!preflightContinue) {\n res.status(optionsSuccessStatus).end();\n return;\n }\n }\n\n next();\n };\n}\n\n/**\n * Rate limiting middleware factory\n */\nexport function createRateLimitMiddleware(\n config: RateLimitConfig = {},\n): MiddlewareFunction {\n const {\n windowMs = 15 * 60 * 1000, // 15 minutes\n max = 100,\n message = 'Too many requests, please try again later.',\n standardHeaders = true,\n legacyHeaders = false,\n skipSuccessfulRequests = false,\n skipFailedRequests = false,\n keyGenerator = (req: any) => req.ip || 'anonymous',\n } = config;\n\n const requests = new Map<string, { count: number; resetTime: number }>();\n\n return (req: any, res: any, next: any) => {\n const key = keyGenerator(req);\n const now = Date.now();\n const resetTime = now + windowMs;\n\n // Clean up expired entries\n for (const [k, v] of requests.entries()) {\n if (v.resetTime <= now) {\n requests.delete(k);\n }\n }\n\n // Get or create request info\n let requestInfo = requests.get(key);\n if (!requestInfo || requestInfo.resetTime <= now) {\n requestInfo = { count: 0, resetTime };\n requests.set(key, requestInfo);\n }\n\n // Check rate limit\n if (requestInfo.count >= max) {\n if (standardHeaders) {\n res.header('X-RateLimit-Limit', max.toString());\n res.header('X-RateLimit-Remaining', '0');\n res.header(\n 'X-RateLimit-Reset',\n new Date(requestInfo.resetTime).toISOString(),\n );\n }\n\n if (legacyHeaders) {\n res.header('X-Rate-Limit-Limit', max.toString());\n res.header('X-Rate-Limit-Remaining', '0');\n res.header(\n 'X-Rate-Limit-Reset',\n new Date(requestInfo.resetTime).toISOString(),\n );\n }\n\n return res.status(429).json({\n success: false,\n error: {\n code: 'RATE_LIMIT_EXCEEDED',\n message,\n },\n meta: {\n timestamp: new Date().toISOString(),\n },\n });\n }\n\n // Increment counter\n requestInfo.count++;\n\n // Set headers\n if (standardHeaders) {\n res.header('X-RateLimit-Limit', max.toString());\n res.header('X-RateLimit-Remaining', (max - requestInfo.count).toString());\n res.header(\n 'X-RateLimit-Reset',\n new Date(requestInfo.resetTime).toISOString(),\n );\n }\n\n if (legacyHeaders) {\n res.header('X-Rate-Limit-Limit', max.toString());\n res.header(\n 'X-Rate-Limit-Remaining',\n (max - requestInfo.count).toString(),\n );\n res.header(\n 'X-Rate-Limit-Reset',\n new Date(requestInfo.resetTime).toISOString(),\n );\n }\n\n next();\n };\n}\n\n/**\n * Security headers middleware factory\n */\nexport function createSecurityMiddleware(\n config: SecurityConfig = {},\n): MiddlewareFunction {\n const { helmet = true } = config;\n\n return (req: any, res: any, next: any) => {\n if (helmet) {\n // Basic security headers\n res.header('X-Content-Type-Options', 'nosniff');\n res.header('X-Frame-Options', 'DENY');\n res.header('X-XSS-Protection', '1; mode=block');\n res.header('Referrer-Policy', 'strict-origin-when-cross-origin');\n res.header(\n 'Permissions-Policy',\n 'geolocation=(), microphone=(), camera=()',\n );\n\n // HSTS for HTTPS\n if (req.secure || req.headers['x-forwarded-proto'] === 'https') {\n res.header(\n 'Strict-Transport-Security',\n 'max-age=31536000; includeSubDomains',\n );\n }\n }\n\n next();\n };\n}\n\n/**\n * Input validation middleware factory\n */\nexport function createValidationMiddleware(\n config: ValidationConfig = {},\n): MiddlewareFunction {\n const {\n validateInput = true,\n maxPayloadSize = 1024 * 1024, // 1MB\n allowedFields = [],\n sanitizeFields = ['email', 'username', 'name'],\n } = config;\n\n return (req: any, res: any, next: any) => {\n if (!validateInput) {\n return next();\n }\n\n // Check payload size\n const contentLength = parseInt(req.headers['content-length'] || '0', 10);\n if (contentLength > maxPayloadSize) {\n return res.status(413).json({\n success: false,\n error: {\n code: 'PAYLOAD_TOO_LARGE',\n message: `Payload too large. Maximum size is ${maxPayloadSize} bytes.`,\n },\n meta: {\n timestamp: new Date().toISOString(),\n },\n });\n }\n\n // Sanitize input\n if (req.body && typeof req.body === 'object') {\n for (const field of sanitizeFields) {\n if (req.body[field] && typeof req.body[field] === 'string') {\n // Basic sanitization - remove HTML tags and trim\n req.body[field] = req.body[field].replace(/<[^>]*>/g, '').trim();\n }\n }\n\n // Filter allowed fields if specified\n if (allowedFields.length > 0) {\n const filtered: any = {};\n for (const field of allowedFields) {\n if (req.body[field] !== undefined) {\n filtered[field] = req.body[field];\n }\n }\n req.body = filtered;\n }\n }\n\n next();\n };\n}\n\n/**\n * Create all security middleware\n */\nexport function createSecurityMiddlewares(config: {\n cors?: CorsConfig;\n rateLimit?: RateLimitConfig;\n security?: SecurityConfig;\n validation?: ValidationConfig;\n}): MiddlewareFunction[] {\n const middlewares: MiddlewareFunction[] = [];\n\n if (config.security) {\n middlewares.push(createSecurityMiddleware(config.security));\n }\n\n if (config.cors) {\n middlewares.push(createCorsMiddleware(config.cors));\n }\n\n if (config.rateLimit) {\n middlewares.push(createRateLimitMiddleware(config.rateLimit));\n }\n\n if (config.validation) {\n middlewares.push(createValidationMiddleware(config.validation));\n }\n\n return middlewares;\n}\n"]}