mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
86400s max-age cached old preflight results in browsers for 24h — any CORS header change left users broken until the cache expired. 3600 (1h) is safer. Also sync api/_cors.js with server/cors.ts — it was missing X-Widget-Key and X-Pro-Key, which are needed for widget-agent cross-origin requests.
53 lines
2.0 KiB
JavaScript
53 lines
2.0 KiB
JavaScript
const ALLOWED_ORIGIN_PATTERNS = [
|
|
/^https:\/\/(.*\.)?worldmonitor\.app$/,
|
|
/^https:\/\/worldmonitor-[a-z0-9-]+-elie-[a-z0-9]+\.vercel\.app$/,
|
|
/^https?:\/\/tauri\.localhost(:\d+)?$/,
|
|
/^https?:\/\/[a-z0-9-]+\.tauri\.localhost(:\d+)?$/i,
|
|
/^tauri:\/\/localhost$/,
|
|
/^asset:\/\/localhost$/,
|
|
// Only allow bare localhost/127.0.0.1 in non-production (matches server/cors.ts)
|
|
...(process.env.NODE_ENV === 'production' ? [] : [
|
|
/^https?:\/\/localhost(:\d+)?$/,
|
|
/^https?:\/\/127\.0\.0\.1(:\d+)?$/,
|
|
]),
|
|
];
|
|
|
|
function isAllowedOrigin(origin) {
|
|
return Boolean(origin) && ALLOWED_ORIGIN_PATTERNS.some((pattern) => pattern.test(origin));
|
|
}
|
|
|
|
export function getCorsHeaders(req, methods = 'GET, OPTIONS') {
|
|
const origin = req.headers.get('origin') || '';
|
|
const allowOrigin = isAllowedOrigin(origin) ? origin : 'https://worldmonitor.app';
|
|
return {
|
|
'Access-Control-Allow-Origin': allowOrigin,
|
|
'Access-Control-Allow-Methods': methods,
|
|
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-WorldMonitor-Key, X-Widget-Key, X-Pro-Key',
|
|
'Access-Control-Max-Age': '3600',
|
|
'Vary': 'Origin',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* CORS headers for public cacheable responses (seeded data, no per-user variation).
|
|
* Uses ACAO: * so Vercel edge stores ONE cache entry per URL instead of one per
|
|
* unique Origin. Eliminates Vary: Origin cache fragmentation that multiplies
|
|
* origin hits by the number of distinct client origins.
|
|
*
|
|
* Safe to use when isDisallowedOrigin() has already blocked unauthorized origins.
|
|
*/
|
|
export function getPublicCorsHeaders(methods = 'GET, OPTIONS') {
|
|
return {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Methods': methods,
|
|
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-WorldMonitor-Key, X-Widget-Key, X-Pro-Key',
|
|
'Access-Control-Max-Age': '3600',
|
|
};
|
|
}
|
|
|
|
export function isDisallowedOrigin(req) {
|
|
const origin = req.headers.get('origin');
|
|
if (!origin) return false;
|
|
return !isAllowedOrigin(origin);
|
|
}
|