const express = require('express'); const cors = require('cors'); const helmet = require('helmet'); const session = require('express-session'); const path = require('path'); require('dotenv').config(); const apiRoutes = require('./routes/api'); const authRoutes = require('./routes/auth'); const { requireAdmin } = require('./middleware/auth'); const app = express(); const PORT = process.env.PORT || 3333; // Trust proxy for Docker/reverse proxy environments // Only trust Docker internal networks for better security app.set('trust proxy', ['127.0.0.1', '::1', '172.16.0.0/12', '192.168.0.0/16', '10.0.0.0/8']); // Security middleware app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'", "https://unpkg.com"], scriptSrc: ["'self'", "'unsafe-inline'", "https://unpkg.com", "https://static.cloudflareinsights.com"], imgSrc: ["'self'", "data:", "https:"], connectSrc: ["'self'", "https://cloudflareinsights.com"], }, }, })); // Middleware app.use(cors()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Session configuration app.use(session({ secret: process.env.SESSION_SECRET || 'influence-campaign-secret-key-change-in-production', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production' && process.env.HTTPS === 'true', httpOnly: true, maxAge: 24 * 60 * 60 * 1000 // 24 hours } })); app.use(express.static(path.join(__dirname, 'public'))); // Routes app.use('/api/auth', authRoutes); app.use('/api', apiRoutes); // Serve the main page app.get('/', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); }); // Serve login page app.get('/login.html', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'login.html')); }); // Serve admin panel (protected) app.get('/admin.html', requireAdmin, (req, res) => { res.sendFile(path.join(__dirname, 'public', 'admin.html')); }); // Serve the admin page (protected) app.get('/admin', requireAdmin, (req, res) => { res.sendFile(path.join(__dirname, 'public', 'admin.html')); }); // Serve campaign landing pages app.get('/campaign/:slug', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'campaign.html')); }); // Serve campaign pages app.get('/campaign/:slug', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'campaign.html')); }); // Error handling middleware app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: 'Something went wrong!', message: process.env.NODE_ENV === 'development' ? err.message : 'Internal server error' }); }); // 404 handler app.use((req, res) => { res.status(404).json({ error: 'Route not found' }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); console.log(`Environment: ${process.env.NODE_ENV}`); }); module.exports = app;