const rateLimit = require('express-rate-limit'); const config = require('../config'); // Helper to extract real IP with Cloudflare support const keyGenerator = (req) => { return req.headers['cf-connecting-ip'] || req.headers['x-forwarded-for']?.split(',')[0] || req.ip; }; // General API rate limiter const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, keyGenerator, standardHeaders: true, legacyHeaders: false, trustProxy: true, // Explicitly trust proxy message: 'Too many requests, please try again later.' }); // Strict limiter for write operations const strictLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 20, keyGenerator, trustProxy: true, // Explicitly trust proxy message: 'Too many write operations, please try again later.' }); // Auth-specific limiter with admin bypass capability const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: config.isProduction ? 30 : 50, // Increased from 10 to 30 for production keyGenerator, standardHeaders: true, legacyHeaders: false, trustProxy: true, // Explicitly trust proxy message: 'Too many login attempts, please try again later.', skipSuccessfulRequests: true, skip: (req, res) => { // Skip rate limiting for authenticated admin users on certain admin endpoints return req.session?.isAdmin && req.path?.includes('/admin'); } }); // Temp user rate limiter - stricter but allows for auto-refresh const tempUserLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 50, // Allow more requests to accommodate auto-refresh (every 30 seconds = ~30 requests per 15 min) keyGenerator, standardHeaders: true, legacyHeaders: false, trustProxy: true, message: JSON.stringify({ success: false, error: 'Rate limit exceeded for temporary account. Please contact an administrator for full access.', isRateLimit: true }) }); // Conditional rate limiter that applies stricter limits to temp users const conditionalTempLimiter = (req, res, next) => { if (req.session?.userType === 'temp') { return tempUserLimiter(req, res, next); } return apiLimiter(req, res, next); }; // Admin-friendly limiter for admin operations const adminLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 200, // High limit for admin operations keyGenerator, standardHeaders: true, legacyHeaders: false, trustProxy: true, message: 'Rate limit exceeded for admin operations. Please try again later.' }); module.exports = { apiLimiter, strictLimiter, authLimiter, tempUserLimiter, conditionalTempLimiter, adminLimiter };