diff --git a/src/server/index.ts b/src/server/index.ts index 888aaae..854bd12 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -174,8 +174,16 @@ db.run(` // Middleware app.use('*', cors()) app.use('*', logger()) -// CSRF protection for state-changing endpoints -app.use('*', csrf()) + +// Serve static files FIRST (before CSRF and other middleware) +app.use('/css/*', serveStatic({ root: './public' })) +app.use('/js/*', serveStatic({ root: './public' })) +app.use('/images/*', serveStatic({ root: './public' })) +app.use('/*.css', serveStatic({ root: './public' })) +app.use('/*.js', serveStatic({ root: './public' })) + +// CSRF protection - only for API routes, not static files +app.use('/api/*', csrf()) // Global error handler app.use('*', async (c, next) => { @@ -191,9 +199,6 @@ app.use('*', async (c, next) => { } }) -// Serve static files -app.use('/public/*', serveStatic({ root: './' })) - // Helper const genId = () => crypto.randomUUID() @@ -1176,8 +1181,8 @@ app.get('/api/admin/stats', requireAdmin, (c) => { app.get('/property/*', serveStatic({ path: './public/property.html' })) app.get('/admin/*', serveStatic({ path: './public/admin.html' })) -// Serve index.html for all other routes -app.get('*', serveStatic({ path: './public/index.html' })) +// SPA fallback - serve index.html for non-API, non-static routes +app.get('/*', serveStatic({ path: './public/index.html' })) // Start server const port = parseInt(process.env.PORT || '8080')