import express, { Application } from 'express'; import cors from 'cors'; import helmet from 'helmet'; import compression from 'compression'; import { config } from './config'; import { logger } from './utils/logger'; import { errorHandler } from './middleware/errorHandler'; import { requestLogger } from './middleware/requestLogger'; import voteRoutes from './routes/vote.routes'; import adminRoutes from './routes/admin.routes'; import scanRoutes from './routes/scan.routes'; export const app: Application = express(); // CORS - must be before helmet app.use( cors({ origin: function (origin, callback) { // Allow requests with no origin (like mobile apps or curl) if (!origin) return callback(null, true); const allowedOrigins = [ 'http://localhost:5173', 'http://localhost:5174', 'http://192.168.1.5:5173', 'http://192.168.1.5:5174', ]; if (allowedOrigins.includes(origin)) { callback(null, true); } else { console.log('CORS blocked origin:', origin); callback(null, true); // Allow all for development } }, credentials: true, }) ); // Security middleware app.use(helmet()); // Compression app.use(compression()); // Body parsing app.use(express.json({ limit: '1mb' })); app.use(express.urlencoded({ extended: true })); // Request logging app.use(requestLogger); // Health check app.get('/health', (_req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // API routes app.use('/api/vote', voteRoutes); app.use('/api/admin', adminRoutes); app.use('/api/scan', scanRoutes); // 404 handler app.use((_req, res) => { res.status(404).json({ error: 'Not Found' }); }); // Error handler app.use(errorHandler); export { logger };