// Import necessary modules require('dotenv').config(); // Load environment variables from .env file first const express = require('express'); const https = require('https'); const fs = require('fs'); const path = require('path'); const cors = require('cors'); const morgan = require('morgan'); const helmet = require('helmet'); const { initializeDatabase } = require('./src/db/db'); const { createInitialAdminUser } = require('./src/controllers/userController'); // Import function to create initial admin // const setupCronJobs = require('./src/utils/backupScheduler'); // Optional: For scheduled backups // --- Middleware --- const errorHandler = require('./src/middleware/errorMiddleware'); const { authenticateToken } = require('./src/middleware/authMiddleware'); // Import auth middleware // --- Routers --- const authRoutes = require('./src/routes/authRoutes'); const tournamentRoutes = require('./src/routes/tournamentRoutes'); const playerRoutes = require('./src/routes/playerRoutes'); const matchRoutes = require('./src/routes/matchRoutes'); const userRoutes = require('./src/routes/userRoutes'); // Add other routers as needed // --- Configuration --- const PORT = process.env.PORT || 3000; // --- Initialize Express App --- const app = express(); // --- Security Middleware --- app.use(helmet()); // Set various security HTTP headers app.use(cors()); // Enable Cross-Origin Resource Sharing // --- Logging Middleware --- app.use(morgan('dev')); // Log HTTP requests in development format // --- Body Parsing Middleware --- app.use(express.json()); // Parse JSON request bodies app.use(express.urlencoded({ extended: true })); // Parse URL-encoded request bodies // --- Static Files --- // Serve static files (HTML, CSS, JS) from the 'public' directory app.use(express.static(path.join(__dirname, 'public'))); // --- API Routes --- // Public Routes (or routes where auth is handled internally/conditionally) app.use('/api/auth', authRoutes); app.use('/api/tournaments', tournamentRoutes); // GET is public, POST/PUT/DELETE require auth (handled in router) app.use('/api/players', playerRoutes); // GET is public, POST/PUT/DELETE require auth (handled in router) app.use('/api/matches', matchRoutes); // GET is public, POST/PUT/DELETE require auth (handled in router) // Protected Routes (require authentication for all methods) app.use('/api/users', authenticateToken, userRoutes); // All user management requires login // --- Root Route (Optional Redirect or Info) --- app.get('/', (req, res) => { // Redirect to spectator view or show an info page res.redirect('/spectator.html'); }); // --- Error Handling Middleware --- // This should be the last middleware added app.use(errorHandler); // --- HTTPS Options --- // Load SSL certificate and key // Ensure key.pem and cert.pem are generated (e.g., using `npm run generate-cert`) let httpsOptions = {}; try { httpsOptions = { key: fs.readFileSync(path.join(__dirname, 'key.pem')), cert: fs.readFileSync(path.join(__dirname, 'cert.pem')), }; } catch (err) { console.error("---------------------------------------------------------"); console.error("ERROR: Could not load SSL certificate files (key.pem, cert.pem)."); console.error("Please generate them using 'npm run generate-cert'."); console.error("Falling back to HTTP (Not recommended for production)."); console.error("---------------------------------------------------------"); // Optionally exit if HTTPS is strictly required // process.exit(1); } // --- Start Server --- const startServer = async () => { try { // Initialize Database (create tables if they don't exist) await initializeDatabase(); console.log('Database initialized successfully.'); // Create initial admin user if no users exist await createInitialAdminUser(); // Optional: Schedule database backups // if (process.env.BACKUP_PATH && process.env.BACKUP_INTERVAL_MINUTES) { // setupCronJobs(); // } else { // console.log('Database backup scheduling is not configured (BACKUP_PATH or BACKUP_INTERVAL_MINUTES missing in .env).'); // } // Start HTTPS server if certificates are loaded if (httpsOptions.key && httpsOptions.cert) { https.createServer(httpsOptions, app).listen(PORT, () => { console.log(`Server running in HTTPS mode on https://localhost:${PORT}`); }); } else { // Fallback to HTTP if certificates are missing app.listen(PORT, () => { console.log(`Server running in HTTP mode on http://localhost:${PORT}`); console.warn("WARNING: Running without HTTPS. Use 'npm run generate-cert' and ensure key.pem/cert.pem exist for HTTPS."); }); } } catch (error) { console.error('Failed to start server:', error); process.exit(1); // Exit if server fails to start } }; startServer();