fix: API Helmet — allow cross-origin for frontend consumption
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 11s
Deploy / Build API Image (push) Failing after 18s
Deploy / Build AI Services Image (push) Failing after 9s
E2E Tests / Playwright E2E (push) Failing after 11s
Deploy / Smoke Test Staging (push) Has been skipped
CI / E2E Tests (push) Has been skipped
Deploy / Build Web Image (push) Failing after 8s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped

crossOriginResourcePolicy: 'same-origin' blocks browser fetch from
platform.goodgo.vn to api.goodgo.vn. Changed to 'cross-origin'.
Also disabled crossOriginEmbedderPolicy which conflicts with CORS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-04-14 23:53:50 +07:00
parent b9ad280192
commit a394bb3139

View File

@@ -61,13 +61,14 @@ async function bootstrap() {
// ── Security Headers (Helmet) ──
app.use(
helmet({
// CSP relaxed for API — responses are consumed cross-origin by the web frontend
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
styleSrc: ["'self'", "'unsafe-inline'", 'https://cdn.jsdelivr.net'],
imgSrc: ["'self'", 'data:', 'https:', 'blob:'],
connectSrc: ["'self'", 'https://cdn.jsdelivr.net'],
connectSrc: ["'self'", 'https://cdn.jsdelivr.net', 'https://api.goodgo.vn'],
fontSrc: ["'self'", 'data:'],
objectSrc: ["'none'"],
frameSrc: ["'none'"],
@@ -75,9 +76,10 @@ async function bootstrap() {
formAction: ["'self'"],
},
},
crossOriginEmbedderPolicy: true,
crossOriginOpenerPolicy: true,
crossOriginResourcePolicy: { policy: 'same-origin' },
// Must allow cross-origin for API consumed by platform.goodgo.vn
crossOriginEmbedderPolicy: false,
crossOriginOpenerPolicy: false,
crossOriginResourcePolicy: { policy: 'cross-origin' },
frameguard: { action: 'deny' },
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },