From 265b4394494e85b1e0aab28287b0db6e1c0e3e8e Mon Sep 17 00:00:00 2001 From: TheMaddax Date: Thu, 11 Sep 2025 10:48:42 -0600 Subject: [PATCH] Fix rate limiting: handle Redis unavailability gracefully to prevent email failures --- src/lib/rate-limit.ts | 44 +++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/lib/rate-limit.ts b/src/lib/rate-limit.ts index da2118c..ad23097 100644 --- a/src/lib/rate-limit.ts +++ b/src/lib/rate-limit.ts @@ -39,24 +39,36 @@ export class RateLimit { } async check(config: RateLimitConfig): Promise { - 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 { const limiter = new RateLimit() return limiter.check(config) -} \ No newline at end of file +}