import { describe, expect, test } from "vitest"; import { FixedWindowRateLimiter, createOAuthRouteRateLimiter } from "../src/web/rate-limit.js"; describe("OAuth process rate limits", () => { test("bounds keys, rejects excess requests, and recovers after the window", () => { let now = 1_000; const limiter = new FixedWindowRateLimiter({ maxRequests: 2, windowMs: 10_000, maxKeys: 2, now: () => now, }); expect(limiter.check("a").allowed).toBe(true); expect(limiter.check("a").allowed).toBe(true); expect(limiter.check("a")).toMatchObject({ allowed: false, retryAfterSeconds: 10 }); expect(limiter.check("b").allowed).toBe(true); expect(limiter.check("c").allowed).toBe(false); now += 10_001; expect(limiter.check("c").allowed).toBe(true); }); test("applies both per-client and global OAuth route ceilings", () => { const limiter = createOAuthRouteRateLimiter(() => 1_000); for (let request = 0; request < 6; request += 1) { expect(limiter.login("198.51.100.1").allowed).toBe(true); } expect(limiter.login("198.51.100.1").allowed).toBe(false); expect(limiter.login("198.51.100.2").allowed).toBe(true); for (let request = 0; request < 12; request += 1) { expect(limiter.callback("198.51.100.3").allowed).toBe(true); } expect(limiter.callback("198.51.100.3").allowed).toBe(false); }); });