import rateLimit from 'express-rate-limit'; import helmet from 'helmet'; import csrf from 'csurf'; import config from '../config.js'; // Rate limiter for general API requests export const apiLimiter = rateLimit({ windowMs: config.rateLimit.windowMs, max: config.rateLimit.maxRequests, message: 'Too many requests, please try again later', standardHeaders: true, legacyHeaders: false, }); // Stricter rate limiter for auth endpoints export const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, message: 'Too many login attempts, please try again later', skipSuccessfulRequests: true, }); // Security headers middleware export function securityHeaders(req, res, next) { helmet()(req, res, next); } // CSRF protection export const csrfProtection = csrf({ cookie: false }); // Request logging export function requestLogger(req, res, next) { const start = Date.now(); res.on('finish', () => { const duration = Date.now() - start; console.log( `[${new Date().toISOString()}] ${req.method} ${req.path} - ${res.statusCode} - ${duration}ms` ); }); next(); } // Error handler middleware export function errorHandler(err, req, res, next) { console.error('Error:', err); if (err.code === 'EBADCSRFTOKEN') { return res.status(403).json({ error: 'Invalid CSRF token' }); } if (err.message && err.message.includes('OIDC')) { return res.status(401).json({ error: 'Authentication failed' }); } res.status(err.status || 500).json({ error: err.message || 'Internal server error', }); } // Middleware to attach CSRF token to response export function attachCsrfToken(req, res, next) { res.locals.csrfToken = req.csrfToken(); next(); }