fix: static files before routes, fix CSP for assets and Cloudflare, SPA fallback safety
Build Institutional Trader / build-and-deploy (push) Successful in 1m57s Details

This commit is contained in:
Deep Koluguri 2026-06-24 19:17:43 -04:00
parent 78b408057c
commit 7344d5a2b1
2 changed files with 23 additions and 11 deletions

View File

@ -9,10 +9,15 @@ export const setupSecurity = (app) => {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com'],
scriptSrcElem: ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com'],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'", 'https:', 'wss:'],
workerSrc: ["'self'", 'blob:'],
fontSrc: ["'self'", 'https:', 'data:'],
},
},
crossOriginEmbedderPolicy: false,
}));
// CORS

View File

@ -46,6 +46,17 @@ setupSecurity(app);
// Body parsing
app.use(express.json());
// Serve static frontend files in production
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const frontendPath = path.join(__dirname, '../../public');
// Static files MUST come before the wildcard catch-all
app.use(express.static(frontendPath, {
maxAge: '1d',
etag: true,
}));
// Routes
app.use('/api/options', optionsFlowRouter);
app.use('/api/analysis', dailyAnalysisRouter);
@ -61,19 +72,15 @@ app.use('/api/market', marketAnalysisRouter);
app.use('/api/backtest', backtestRouter);
app.use('/health', healthRouter);
// Serve static frontend files in production
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const frontendPath = path.join(__dirname, '../../public');
app.use(express.static(frontendPath));
// Fallback all other routes to React's index.html
// SPA fallback — only for non-API, non-asset routes
app.get('*', (req, res, next) => {
if (req.path.startsWith('/api/') || req.path.startsWith('/health')) {
if (req.path.startsWith('/api/') || req.path.startsWith('/health') || req.path.startsWith('/assets/')) {
return next();
}
res.sendFile(path.join(frontendPath, 'index.html'));
const indexPath = path.join(frontendPath, 'index.html');
res.sendFile(indexPath, (err) => {
if (err) next(err);
});
});
// Error handler (must be last)