feat(server): make CORS middleware configurable (#5123) * feat(server): make CORS middleware configurable Add detailed configuration options for CORS in config.yaml, including origin, methods, headers, credentials, and max age. Update server initialization to apply these settings dynamically instead of using hardcoded values. * fix(server): Fix default value and conditional logic issues in CORS configuration - Changed the default value of `cors.maxAge` from `null` to `0`. - Simplified the conditional check logic for `allowedHeaders`, removing duplicate checks for `corsAllowedHeaders` being `null`. * fix(server): Fix CORS exposed headers configuration logic - Removed redundant conditional checks. now directly validates array length when `corsExposedHeaders` has a truthy value * Improve types + simplify checks * fix(cors): align maxAge default with original behavior * Adjust default array values * Remove debug log --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

10e08f0e3df3bd22a00a017db772cd8b0258ecc3

awaae <108462724+awaae001@users.noreply.github.com>

Signed
2 files changed, +45 -6Ignore whitespace
default/config.yaml+19 -0
@@ -71,6 +71,25 @@ basicAuthUser:
7171 password: "password"
7272# Enables CORS proxy middleware
7373enableCorsProxy: false
74+# CORS settings (applied to all routes)
75+cors:
76+ # Enable or disable CORS middleware
77+ enabled: true
78+ # Allowed origins. Use "null" to match the default browser file origin.
79+ # You can set "*" to allow any origin, or a list of allowed origins.
80+ origin:
81+ - "null"
82+ # Allowed methods
83+ methods:
84+ - "OPTIONS"
85+ # Allowed request headers (optional)
86+ allowedHeaders: []
87+ # Exposed response headers (optional)
88+ exposedHeaders: []
89+ # Allow credentials (cookies, authorization headers)
90+ credentials: false
91+ # Preflight cache max age in seconds (optional)
92+ maxAge: null
7493# -- REQUEST PROXY CONFIGURATION --
7594requestProxy:
7695 # If a proxy is enabled, all outgoing HTTP/HTTPS requests will be routed through it.
src/server-main.js+26 -6
@@ -103,12 +103,32 @@ app.use(bodyParser.json({ limit: '500mb' }));
103103app.use(bodyParser.urlencoded({ extended: true, limit: '500mb' }));
104104
105105// CORS Settings //
106-const CORS = cors({
106+const corsEnabled = getConfigValue('cors.enabled', true, 'boolean');
107- origin: 'null',
107+if (corsEnabled) {
108- methods: ['OPTIONS'],
108+ const corsOrigin = getConfigValue('cors.origin', 'null');
109-});
109+ const corsMethods = getConfigValue('cors.methods', ['OPTIONS']);
110-
110+ const corsAllowedHeaders = getConfigValue('cors.allowedHeaders', []);
111-app.use(CORS);
111+ const corsExposedHeaders = getConfigValue('cors.exposedHeaders', []);
112+ const corsCredentials = getConfigValue('cors.credentials', false, 'boolean');
113+ const corsMaxAge = getConfigValue('cors.maxAge', null, 'number');
114+
115+ /** @type {cors.CorsOptions} */
116+ const corsOptions = {
117+ origin: corsOrigin,
118+ methods: corsMethods,
119+ credentials: corsCredentials,
120+ };
121+ if (Array.isArray(corsAllowedHeaders) && corsAllowedHeaders.length > 0) {
122+ corsOptions.allowedHeaders = corsAllowedHeaders;
123+ }
124+ if (Array.isArray(corsExposedHeaders) && corsExposedHeaders.length > 0) {
125+ corsOptions.exposedHeaders = corsExposedHeaders;
126+ }
127+ if (corsMaxAge !== null && Number.isInteger(corsMaxAge)) {
128+ corsOptions.maxAge = corsMaxAge;
129+ }
130+ app.use(cors(corsOptions));
131+}
112132
113133if (cliArgs.listen && cliArgs.basicAuthMode) {
114134 app.use(basicAuthMiddleware);