feat: complete CORS config-driven middleware rewrite
- cors.ts: createCorsMiddleware factory with RuntimeConfig param - Wildcard ['*'] mode: Access-Control-Allow-Origin: * (backward compatible) - Specific origins mode: reflect matching origin + Allow-Credentials - Added Access-Control-Max-Age: 86400 for preflight caching - app.ts: accept config param, use createCorsMiddleware(config) - index.ts: pass runtimeConfig to createApp - env-overrides.ts: add string[] to RuntimeConfigValue, corsOriginsEnv helper - runtime-config.ts: cors.allowedOrigins: string[] type - defaults.ts: cors.allowedOrigins: ['*'] default - .env: CORS_ALLOWED_ORIGINS=* with production example
This commit is contained in:
@@ -1,21 +1,43 @@
|
||||
import type { Request, Response, NextFunction } from "express";
|
||||
import type { RuntimeConfig } from "../types/runtime-config.js";
|
||||
|
||||
export function corsMiddleware(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): void {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
||||
res.setHeader(
|
||||
"Access-Control-Allow-Methods",
|
||||
"GET, POST, PUT, PATCH, DELETE, OPTIONS"
|
||||
);
|
||||
export function createCorsMiddleware(
|
||||
config: RuntimeConfig
|
||||
): (req: Request, res: Response, next: NextFunction) => void {
|
||||
const allowedOrigins = config.cors.allowedOrigins;
|
||||
const isWildcard =
|
||||
allowedOrigins.length === 1 && allowedOrigins[0] === "*";
|
||||
|
||||
if (req.method === "OPTIONS") {
|
||||
res.sendStatus(204);
|
||||
return;
|
||||
}
|
||||
return function corsMiddleware(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): void {
|
||||
if (isWildcard) {
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
} else {
|
||||
const origin = req.headers.origin;
|
||||
if (origin && allowedOrigins.includes(origin)) {
|
||||
res.setHeader("Access-Control-Allow-Origin", origin);
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
res.setHeader(
|
||||
"Access-Control-Allow-Headers",
|
||||
"Content-Type, Authorization"
|
||||
);
|
||||
res.setHeader(
|
||||
"Access-Control-Allow-Methods",
|
||||
"GET, POST, PUT, PATCH, DELETE, OPTIONS"
|
||||
);
|
||||
res.setHeader("Access-Control-Max-Age", "86400");
|
||||
|
||||
if (req.method === "OPTIONS") {
|
||||
res.sendStatus(204);
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user