Files
2026-09-11 02:46:56 +02:00

64 lines
2.1 KiB
TypeScript

import type { Core } from '@strapi/strapi';
/**
* Origins that are always allowed outside production: the React Router dev
* server (Vite) on both hostnames it is commonly reached on.
*/
const DEV_ORIGINS = [
'http://localhost:5173',
'http://127.0.0.1:5173',
];
/**
* The default Strapi middleware stack, in order, with CORS configured for the
* SHARP-ER web app.
*
* Order matters: `strapi::errors` must wrap everything after it, `strapi::cors`
* must run before routing so pre-flight requests are answered, and
* `strapi::public` stays last so it only handles what nothing else claimed.
*/
const config = ({ env }: Core.Config.Shared.ConfigParams): Core.Config.Middlewares => {
const isProduction = env('NODE_ENV', 'development') === 'production';
/**
* Production origins come from the environment, e.g.
* CORS_ORIGINS=https://sharper.ly,https://www.sharper.ly
* Outside production the local dev server is allowed as well.
*/
const configuredOrigins = env.array('CORS_ORIGINS', []) as string[];
const origin = Array.from(
new Set([...(isProduction ? [] : DEV_ORIGINS), ...configuredOrigins].filter(Boolean))
);
return [
'strapi::logger',
'strapi::errors',
// If uploads move to S3/CDN, add the bucket host to img-src and media-src
// here - see the S3 notes in config/plugins.ts.
'strapi::security',
{
name: 'strapi::cors',
config: {
// An empty list blocks every cross-origin browser request, which is the
// safe default if CORS_ORIGINS was forgotten in production.
origin,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
// The web app sends the locale it wants and reads pagination metadata.
expose: ['Content-Range', 'Content-Length'],
credentials: true,
maxAge: 31536000,
keepHeadersOnError: false,
},
},
'strapi::poweredBy',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
];
};
export default config;