diff --git a/backend/src/server.ts b/backend/src/server.ts index 79d4710..1955c86 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -23,12 +23,15 @@ import dynamicRoutes from './routes/dynamic'; const app: Express = express(); +// Trust proxy if behind reverse proxy (nginx, apache, etc) +app.set('trust proxy', true); + // Middleware app.use(helmet({ contentSecurityPolicy: config.nodeEnv === 'production' ? { directives: { defaultSrc: ["'self'"], - scriptSrc: ["'self'", "'unsafe-inline'", "blob:"], + scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "blob:"], workerSrc: ["'self'", "blob:"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:", "blob:"], @@ -36,6 +39,9 @@ app.use(helmet({ connectSrc: ["'self'"], }, } : false, + crossOriginOpenerPolicy: false, + crossOriginResourcePolicy: false, + crossOriginEmbedderPolicy: false, })); app.use(cors()); app.use(express.json()); @@ -96,12 +102,22 @@ app.use('/api/v1', dynamicRoutes); // Serve frontend static files in production if (config.nodeEnv === 'production') { const frontendPath = path.join(__dirname, '../../frontend/dist'); - app.use(express.static(frontendPath)); + console.log(`📁 Serving static files from: ${frontendPath}`); + + app.use(express.static(frontendPath, { + maxAge: '1d', + etag: true, + setHeaders: (res) => { + res.setHeader('Cache-Control', 'public, max-age=86400'); + } + })); // SPA fallback - all non-API routes serve index.html app.get('*', (req: Request, res: Response) => { if (!req.path.startsWith('/api/') && !req.path.startsWith('/api-docs') && req.path !== '/health') { - res.sendFile(path.join(frontendPath, 'index.html')); + const indexPath = path.join(frontendPath, 'index.html'); + console.log(`📄 Serving index.html for route: ${req.path}`); + res.sendFile(indexPath); } else { res.status(404).json({ error: 'API route not found' }); }