| const rateLimit = require('express-rate-limit'); |
|
|
| function normalizePhone(value) { |
| return String(value || '').replace(/\D/g, ''); |
| } |
|
|
| |
| const loginLimiter = rateLimit({ |
| windowMs: 15 * 60 * 1000, |
| max: 5, |
| skipSuccessfulRequests: true, |
| standardHeaders: true, |
| legacyHeaders: false, |
| message: { error: 'Too many login attempts. Try again in 15 minutes.' }, |
| }); |
|
|
| |
| const registerLimiter = rateLimit({ |
| windowMs: 60 * 60 * 1000, |
| max: 3, |
| standardHeaders: true, |
| legacyHeaders: false, |
| message: { error: 'Too many registration attempts. Try again in an hour.' }, |
| }); |
|
|
| |
| const purchaseLimiter = rateLimit({ |
| windowMs: 10 * 60 * 1000, |
| max: 5, |
| standardHeaders: true, |
| legacyHeaders: false, |
| keyGenerator: req => { |
| const siteId = req.params?.siteId || 'unknown-site'; |
| const phone = normalizePhone(req.body?.phone) || req.ip || 'unknown-phone'; |
| return `${siteId}:${phone}`; |
| }, |
| message: { error: 'Too many purchase attempts. Please wait before trying again.' }, |
| }); |
|
|
| |
| const forgotPasswordLimiter = rateLimit({ |
| windowMs: 15 * 60 * 1000, |
| max: 3, |
| standardHeaders: true, |
| legacyHeaders: false, |
| message: { error: 'Too many reset requests. Try again in 15 minutes.' }, |
| }); |
|
|
| |
| const portalAuthLimiter = rateLimit({ |
| windowMs: 15 * 60 * 1000, |
| max: 10, |
| standardHeaders: true, |
| legacyHeaders: false, |
| message: { error: 'Too many authorization attempts. Try again in 15 minutes.' }, |
| }); |
|
|
| |
| const phoneOtpLimiter = rateLimit({ |
| windowMs: 30 * 60 * 1000, |
| max: 3, |
| standardHeaders: true, |
| legacyHeaders: false, |
| message: { error: 'Too many verification requests. Try again in 30 minutes.' }, |
| }); |
|
|
| module.exports = { loginLimiter, registerLimiter, forgotPasswordLimiter, purchaseLimiter, portalAuthLimiter, phoneOtpLimiter }; |
|
|