import express from 'express'; import compression from 'compression'; import { handler } from './dist/server/entry.mjs'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const app = express(); const PORT = process.env.PORT || 3000; // Enable gzip/brotli compression app.use(compression()); // Set minimal secure headers for SSR responses app.use((req, res, next) => { res.setHeader('X-Content-Type-Options', 'nosniff'); res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin'); res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp'); // Gate SSR CSP to avoid breaking inline scripts unless explicitly enabled if (process.env.ENABLE_SSR_CSP === '1') { res.setHeader( 'Content-Security-Policy', "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://cdn.pixabay.com https://raw.githubusercontent.com; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" ); } next(); }); // Serve static assets from the dist/client directory app.use(express.static(path.join(__dirname, 'dist/client'))); // Handle all SSR requests with Astro's handler app.all('*', handler); app.listen(PORT, () => { const isProduction = process.env.NODE_ENV === 'production'; const domain = isProduction ? '365devnet.eu' : `localhost:${PORT}`; const protocol = isProduction ? 'https' : 'http'; console.log(`Server running with compression on ${protocol}://${domain}`); if (!isProduction) { console.log(`Development server accessible at http://localhost:${PORT}`); } });