Fix rate limiting: handle Redis unavailability gracefully to prevent email failures

This commit is contained in:
TheMaddax 2025-09-11 10:48:42 -06:00
parent 788ce88288
commit 265b439449

View file

@ -39,24 +39,36 @@ export class RateLimit {
}
async check(config: RateLimitConfig): Promise<RateLimitResult> {
const ip = await this.getIP()
const key = this.getKey(ip)
const now = Math.floor(Date.now() / 1000)
const windowStart = now - (now % config.interval)
const windowKey = `${key}:${windowStart}`
try {
const ip = await this.getIP()
const key = this.getKey(ip)
const now = Math.floor(Date.now() / 1000)
const windowStart = now - (now % config.interval)
const windowKey = `${key}:${windowStart}`
const pipeline = this.redis.pipeline()
pipeline.incr(windowKey)
pipeline.expire(windowKey, config.interval)
const pipeline = this.redis.pipeline()
pipeline.incr(windowKey)
pipeline.expire(windowKey, config.interval)
const [count] = await pipeline.exec()
const remaining = Math.max(0, config.limit - (count as number))
const [count] = await pipeline.exec()
const remaining = Math.max(0, config.limit - (count as number))
return {
success: (count as number) <= config.limit,
limit: config.limit,
remaining,
reset: windowStart + config.interval
return {
success: (count as number) <= config.limit,
limit: config.limit,
remaining,
reset: windowStart + config.interval
}
} catch (error) {
console.warn('Redis unavailable, allowing request (rate limiting disabled):', error)
// Fallback: allow the request when Redis is unavailable
// TODO: Fix Redis connection or create new instance
return {
success: true,
limit: config.limit,
remaining: config.limit - 1,
reset: Math.floor(Date.now() / 1000) + config.interval
}
}
}
}
@ -73,4 +85,4 @@ export async function rateLimit(
): Promise<RateLimitResult> {
const limiter = new RateLimit()
return limiter.check(config)
}
}