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 const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: config.isProduction ? 10 : 50, keyGenerator, standardHeaders: true, legacyHeaders: false, trustProxy: true, // Explicitly trust proxy message: 'Too many login attempts, please try again later.', skipSuccessfulRequests: true }); // 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); }; module.exports = { apiLimiter, strictLimiter, authLimiter, tempUserLimiter, conditionalTempLimiter };