config->get('plugins.api.cors.enabled', true)) { return $response; } $origin = $request->getHeaderLine('Origin'); if (!$origin) { return $response; } $allowedOrigins = (array) $this->config->get('plugins.api.cors.origins', ['*']); if (in_array('*', $allowedOrigins, true)) { $response = $response->withHeader('Access-Control-Allow-Origin', '*'); } elseif (in_array($origin, $allowedOrigins, true)) { $response = $response ->withHeader('Access-Control-Allow-Origin', $origin) ->withHeader('Vary', 'Origin'); } else { return $response; } $credentials = $this->config->get('plugins.api.cors.credentials', false); if ($credentials) { $response = $response->withHeader('Access-Control-Allow-Credentials', 'true'); } $exposeHeaders = (array) $this->config->get('plugins.api.cors.expose_headers', []); // Always expose X-Invalidates so the client can read cache invalidation tags if (!in_array('X-Invalidates', $exposeHeaders)) { $exposeHeaders[] = 'X-Invalidates'; } $response = $response->withHeader('Access-Control-Expose-Headers', implode(', ', $exposeHeaders)); return $response; } public function createPreflightResponse(): ResponseInterface { $headers = []; $allowedOrigins = (array) $this->config->get('plugins.api.cors.origins', ['*']); $origin = $_SERVER['HTTP_ORIGIN'] ?? '*'; if (in_array('*', $allowedOrigins, true)) { $headers['Access-Control-Allow-Origin'] = '*'; } elseif (in_array($origin, $allowedOrigins, true)) { $headers['Access-Control-Allow-Origin'] = $origin; $headers['Vary'] = 'Origin'; } $methods = (array) $this->config->get('plugins.api.cors.methods', ['GET', 'POST', 'PATCH', 'DELETE', 'OPTIONS']); $headers['Access-Control-Allow-Methods'] = implode(', ', $methods); $allowHeaders = (array) $this->config->get('plugins.api.cors.headers', []); if ($allowHeaders) { $headers['Access-Control-Allow-Headers'] = implode(', ', $allowHeaders); } $maxAge = $this->config->get('plugins.api.cors.max_age', 86400); $headers['Access-Control-Max-Age'] = (string) $maxAge; $credentials = $this->config->get('plugins.api.cors.credentials', false); if ($credentials) { $headers['Access-Control-Allow-Credentials'] = 'true'; } $headers['Content-Length'] = '0'; return new Response(204, $headers); } }