require('dotenv').config(); const express = require('express'); const helmet = require('helmet'); const cors = require('cors'); const rateLimit = require('express-rate-limit'); const path = require('path'); const { initializeDatabase } = require('./src/database/db'); const { startFileWatcher } = require('./src/services/fileWatcher'); const { startExpirationChecker } = require('./src/services/expirationChecker'); const logger = require('./src/utils/logger'); // Import routes const authRoutes = require('./src/routes/auth'); const eventRoutes = require('./src/routes/events'); const galleryRoutes = require('./src/routes/gallery'); const adminRoutes = require('./src/routes/admin'); const adminAuthRoutes = require('./src/routes/adminAuth'); const app = express(); const PORT = process.env.PORT || 3000; // Security middleware app.use(helmet()); // CORS configuration const corsOptions = { origin: function (origin, callback) { const allowedOrigins = [ process.env.FRONTEND_URL || 'http://localhost:3005', process.env.ADMIN_URL || 'http://localhost:3005', 'http://localhost:5173', // Vite dev server 'http://localhost:3002', // Backend server 'http://localhost:3001', // For API testing 'http://localhost:3000' // Direct backend access ]; // Allow requests with no origin (like mobile apps or curl) if (!origin || allowedOrigins.indexOf(origin) !== -1) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, credentials: true }; app.use(cors(corsOptions)); // Rate limiting const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs }); const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 5 // limit auth attempts }); app.use('/api/', limiter); app.use('/api/auth', authLimiter); // Body parsing middleware app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Static file serving for photos (protected) app.use('/photos', require('./src/middleware/photoAuth'), express.static(path.join(__dirname, 'storage/events/active'))); // Health check endpoint app.get('/api/health', (req, res) => { res.json({ status: 'ok', timestamp: new Date().toISOString() }); }); // Routes app.use('/api/auth', authRoutes); app.use('/api/events', eventRoutes); app.use('/api/gallery', galleryRoutes); app.use('/api/admin', adminRoutes); app.use('/api/admin/auth', adminAuthRoutes); // Error handling middleware app.use((err, req, res, next) => { logger.error(err.stack); res.status(500).json({ error: 'Something went wrong!' }); }); // Initialize services async function startServer() { try { // Initialize database await initializeDatabase(); // Start file watcher startFileWatcher(); // Start expiration checker startExpirationChecker(); app.listen(PORT, () => { logger.info(`Server running on port ${PORT}`); logger.info(`Admin interface: ${process.env.ADMIN_URL || 'http://localhost:3000'}`); logger.info(`Frontend: ${process.env.FRONTEND_URL || 'http://localhost:3001'}`); }); } catch (error) { logger.error('Failed to start server:', error); process.exit(1); } } startServer(); module.exports = app; // For testing