diff --git a/src/lib/__tests__/rateLimit.test.ts b/src/lib/__tests__/rateLimit.test.ts index 864a312..966ded2 100644 --- a/src/lib/__tests__/rateLimit.test.ts +++ b/src/lib/__tests__/rateLimit.test.ts @@ -35,6 +35,14 @@ describe("RateLimiter", () => { }); describe("In-memory Fallback", () => { + it("throws in production when fallback is triggered", async () => { + const limiter = new RateLimiter(2, 1000); + const key = "test-key-prod"; + vi.stubEnv('NODE_ENV', 'production'); + await expect(limiter.check(key)).rejects.toThrow("Redis must be configured in production for secure rate limiting."); + vi.stubEnv('NODE_ENV', 'test'); + }); + it("allows requests below the limit", async () => { const limiter = new RateLimiter(2, 1000); const key = "test-key"; diff --git a/src/lib/rateLimit.ts b/src/lib/rateLimit.ts index 4ea5c6e..5183169 100644 --- a/src/lib/rateLimit.ts +++ b/src/lib/rateLimit.ts @@ -32,6 +32,10 @@ export class RateLimiter { return { success, reset }; } + if (process.env.NODE_ENV === "production") { + throw new Error("Redis must be configured in production for secure rate limiting."); + } + // Fallback to in-memory caching const now = Date.now(); this.cleanup(now); // Lazy cleanup