// server.js // Main application file for the Node.js Express server require('dotenv').config(); // Load environment variables first const express = require('express'); const path = require('path'); const cookieParser = require('cookie-parser'); const helmet = require('helmet'); // Add security headers const compression = require('compression'); // Add compression const morgan = require('morgan'); // Add request logging // Import route handlers const authRoutes = require('./routes/authRoutes'); const todoRoutes = require('./routes/todoRoutes'); const viewRoutes = require('./routes/viewRoutes'); // Initialize Express app const app = express(); const PORT = process.env.PORT || 3000; // --- Middleware --- // Add security headers app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], }, } })); // Add compression to improve performance app.use(compression()); // Add request logging app.use(morgan('dev')); // Parse JSON request bodies app.use(express.json()); // Parse URL-encoded request bodies app.use(express.urlencoded({ extended: true })); // Parse cookies (needed for JWT authentication) app.use(cookieParser()); // Serve static files (HTML, CSS, JS) from the 'public' directory // Files in 'public' will be accessible directly, e.g., /style.css, /script.js app.use(express.static(path.join(__dirname, 'public'))); // --- Routes --- // API routes app.use('/api/auth', authRoutes); // Authentication routes (login, register, logout, status) app.use('/api/todos', todoRoutes); // Todo CRUD routes (protected by auth middleware inside the router) // View routes (serving HTML pages) // These should generally be last, especially the '/' route, // to avoid conflicts with static files or API routes. app.use('/', viewRoutes); // --- Global Error Handler (Basic Example) --- app.use((err, req, res, next) => { console.error("Global Error Handler:", err.stack || err); if (res.headersSent) { return next(err); } // Send a generic JSON error response res.status(500).json({ message: 'Ein unerwarteter Serverfehler ist aufgetreten.', error: process.env.NODE_ENV === 'development' ? err.message : undefined }); }); // --- Start Server --- const server = app.listen(PORT, () => { console.log(`Server läuft auf http://localhost:${PORT}`); }); // Handle graceful shutdown process.on('SIGTERM', gracefulShutdown); process.on('SIGINT', gracefulShutdown); function gracefulShutdown() { console.log('Gracefully shutting down...'); server.close(() => { console.log('Server closed'); process.exit(0); }); // Force close after 10s if server hasn't closed gracefully setTimeout(() => { console.error('Server close timeout, forcing exit'); process.exit(1); }, 10000); }