Wifiv2 / src /middleware /rateLimiter.js
Mbonea's picture
Fix captive portal purchase throttling
58d7be4
Raw
History Blame Contribute Delete
2.24 kB
const rateLimit = require('express-rate-limit');
function normalizePhone(value) {
return String(value || '').replace(/\D/g, '');
}
// Tenant login β€” 5 failed attempts per 15 min per IP
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.' },
});
// Tenant registration β€” 3 accounts per hour per IP
const registerLimiter = rateLimit({
windowMs: 60 * 60 * 1000,
max: 3,
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many registration attempts. Try again in an hour.' },
});
// Portal purchase β€” 5 per 10 min per IP (prevents M-Pesa spam to any phone)
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.' },
});
// Forgot password β€” 3 OTP requests per 15 min per IP (prevents SMS bombing)
const forgotPasswordLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 3,
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many reset requests. Try again in 15 minutes.' },
});
// Portal auth / code entry β€” 10 per 15 min per IP (prevents code brute force)
const portalAuthLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many authorization attempts. Try again in 15 minutes.' },
});
// Phone change OTP β€” 3 requests per 30 min per IP (prevents SMS bombing new numbers)
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 };