import express, { Request, Response, NextFunction } from 'express'; import dotenv from 'dotenv'; import cookieParser from 'cookie-parser'; import passport from './src/routes/passport'; import { logger } from './src/services/logger'; // Import routers import authRouter from './src/routes/auth'; import publicRouter from './src/routes/public'; import userRouter from './src/routes/user'; import adminRouter from './src/routes/admin'; import aiRouter from './src/routes/ai'; // Load environment variables from a .env file at the root of your project dotenv.config(); const app = express(); // --- Core Middleware --- app.use(express.json()); // Middleware to parse JSON request bodies app.use(cookieParser()); // Middleware to parse cookies app.use(passport.initialize()); // Initialize Passport // --- Logging Middleware --- const getDurationInMilliseconds = (start: [number, number]): number => { const NS_PER_SEC = 1e9; const NS_TO_MS = 1e6; const diff = process.hrtime(start); return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS; }; const requestLogger = (req: Request, res: Response, next: NextFunction) => { const start = process.hrtime(); const { method, originalUrl } = req; res.on('finish', () => { const user = req.user as { id?: string } | undefined; const durationInMilliseconds = getDurationInMilliseconds(start); const { statusCode } = res; const userIdentifier = user?.id ? ` (User: ${user.id})` : ''; const logMessage = `${method} ${originalUrl} ${statusCode} ${durationInMilliseconds.toFixed(2)}ms${userIdentifier}`; if (statusCode >= 500) logger.error(logMessage); else if (statusCode >= 400) logger.warn(logMessage); else logger.info(logMessage); }); next(); }; app.use(requestLogger); // Use the logging middleware for all requests // --- Security Warning --- if ((process.env.JWT_SECRET || 'your_super_secret_jwt_key_change_this') === 'your_super_secret_jwt_key_change_this') { logger.warn('Security Warning: JWT_SECRET is using a default, insecure value. Please set a strong secret in your .env file.'); } // --- API Routes --- app.use('/api', publicRouter); app.use('/api/auth', authRouter); app.use('/api', userRouter); // Contains protected user routes app.use('/api/admin', adminRouter); app.use('/api/ai', aiRouter); // --- Error Handling and Server Startup --- // Basic error handling middleware app.use((err: Error, req: Request, res: Response, next: NextFunction) => { logger.error('Unhandled application error:', { error: err.stack }); // The 'next' parameter is required for Express to identify this as an error-handling middleware. // We log it here to satisfy the 'no-unused-vars' lint rule, as it's not called in this terminal handler. logger.info('Terminal error handler invoked. The "next" function is part of the required signature.', { next: String(next) }); if (!res.headersSent) { res.status(500).json({ message: 'Something broke!' }); } }); const PORT = process.env.PORT || 3001; app.listen(PORT, () => { logger.info(`Authentication server started on port ${PORT}`); });