Files
TTurnier/server.js
2025-04-08 21:29:54 +02:00

127 lines
5.2 KiB
JavaScript

// 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;
const HTTPS_PORT = process.env.HTTPS_PORT || 3443; // Optional: For HTTPS port if needed
// --- 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}`);
// });
if (httpsOptions.key && httpsOptions.cert) {
https.createServer(httpsOptions, app).listen(HTTPS_PORT, () => {
console.log(`HTTPS server running on https://localhost:${HTTPS_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();