Files
ToDo-App_Node.js_Test/server.js

99 lines
2.8 KiB
JavaScript

// 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);
}