import rateLimit, { ipKeyGenerator } from 'express-rate-limit' import type { Request } from 'express' // req.ip is already the real client IP when app.set('trust proxy', 1) is configured const getClientIpKey = (req: Request) => ipKeyGenerator(req.ip ?? '') // Strict limiter for auth endpoints — prevents brute-force and credential stuffing export const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 20, standardHeaders: 'draft-7', legacyHeaders: false, skipSuccessfulRequests: false, keyGenerator: (req) => getClientIpKey(req), message: { error: 'too_many_requests', message: 'Too many attempts, please try again later', statusCode: 429 }, }) // Standard limiter for general authenticated API endpoints export const apiLimiter = rateLimit({ windowMs: 60 * 1000, // 1 minute max: 120, standardHeaders: 'draft-7', legacyHeaders: false, keyGenerator: (req) => { const ip = getClientIpKey(req) const companyId = (req as any).companyId ?? '' const renterId = (req as any).renterId ?? '' return `${ip}:${companyId || renterId}` }, message: { error: 'too_many_requests', message: 'Rate limit exceeded', statusCode: 429 }, }) // Limiter for public marketplace and site endpoints (no auth) export const publicLimiter = rateLimit({ windowMs: 60 * 1000, max: 60, standardHeaders: 'draft-7', legacyHeaders: false, keyGenerator: (req) => getClientIpKey(req), message: { error: 'too_many_requests', message: 'Rate limit exceeded', statusCode: 429 }, }) // Tight limiter for admin endpoints export const adminLimiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, standardHeaders: 'draft-7', legacyHeaders: false, keyGenerator: (req) => getClientIpKey(req), message: { error: 'too_many_requests', message: 'Too many admin requests', statusCode: 429 }, })