Compare commits

...

2 commits

Author SHA1 Message Date
advplyr
030e43f382 Support disabled rate limiter by setting max to 0, add logs when rate limit is changed from default
Some checks are pending
Integration Test / build and test (push) Waiting to run
Run Unit Tests / Run Unit Tests (push) Waiting to run
2025-07-12 10:51:07 -05:00
advplyr
f081a7fdc1 Update rate limiter to use requestIp as key, pass in configurable error message 2025-07-12 10:32:35 -05:00

View file

@ -1,10 +1,14 @@
const { rateLimit, RateLimitRequestHandler } = require('express-rate-limit')
const Logger = require('../Logger')
const requestIp = require('../libs/requestIp')
/**
* Factory for creating authentication rate limiters
*/
class RateLimiterFactory {
static DEFAULT_WINDOW_MS = 10 * 60 * 1000 // 10 minutes
static DEFAULT_MAX = 40 // 40 attempts
constructor() {
this.authRateLimiter = null
}
@ -18,17 +22,30 @@ class RateLimiterFactory {
return this.authRateLimiter
}
let windowMs = 10 * 60 * 1000 // 10 minutes default
// Disable by setting max to 0
if (process.env.RATE_LIMIT_AUTH_MAX === '0') {
this.authRateLimiter = (req, res, next) => next()
Logger.info(`[RateLimiterFactory] Authentication rate limiting disabled by ENV variable`)
return this.authRateLimiter
}
let windowMs = RateLimiterFactory.DEFAULT_WINDOW_MS
if (parseInt(process.env.RATE_LIMIT_AUTH_WINDOW) > 0) {
windowMs = parseInt(process.env.RATE_LIMIT_AUTH_WINDOW)
if (windowMs !== RateLimiterFactory.DEFAULT_WINDOW_MS) {
Logger.info(`[RateLimiterFactory] Authentication rate limiting window set to ${windowMs}ms by ENV variable`)
}
}
let max = 40 // 40 attempts default
let max = RateLimiterFactory.DEFAULT_MAX
if (parseInt(process.env.RATE_LIMIT_AUTH_MAX) > 0) {
max = parseInt(process.env.RATE_LIMIT_AUTH_MAX)
if (max !== RateLimiterFactory.DEFAULT_MAX) {
Logger.info(`[RateLimiterFactory] Authentication rate limiting max set to ${max} by ENV variable`)
}
}
let message = 'Too many requests, please try again later.'
let message = 'Too many authentication requests'
if (process.env.RATE_LIMIT_AUTH_MESSAGE) {
message = process.env.RATE_LIMIT_AUTH_MESSAGE
}
@ -36,18 +53,22 @@ class RateLimiterFactory {
this.authRateLimiter = rateLimit({
windowMs,
max,
message,
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req) => {
// Override keyGenerator to handle proxy IPs
return requestIp.getClientIp(req) || req.ip
},
handler: (req, res) => {
const userAgent = req.get('User-Agent') || 'Unknown'
const endpoint = req.path
const method = req.method
const ip = requestIp.getClientIp(req) || req.ip
Logger.warn(`[RateLimiter] Rate limit exceeded - IP: ${req.ip}, Endpoint: ${method} ${endpoint}, User-Agent: ${userAgent}`)
Logger.warn(`[RateLimiter] Rate limit exceeded - IP: ${ip}, Endpoint: ${method} ${endpoint}, User-Agent: ${userAgent}`)
res.status(429).json({
error: 'Too many authentication attempts, please try again later.'
error: message
})
}
})