File
Blob: src/worker/middleware/rate-limit.ts
| 1 | import type { AppContext } from "@/worker/types"; |
| 2 | import { hashNullable } from "@/worker/util/request-context"; |
| 3 | import { jsonError } from "@/worker/util/response"; |
| 4 | |
| 5 | export type RateLimitBinding = "RL_AUTH" | "RL_DAV_AUTH" | "RL_REPORT"; |
| 6 | |
| 7 | export async function rateLimitKey(parts: (string | null | undefined)[]): Promise<string> { |
| 8 | return (await hashNullable(parts.filter((part): part is string => !!part).join(":"))) ?? "unknown"; |
| 9 | } |
| 10 | |
| 11 | export async function enforceRateLimit( |
| 12 | c: AppContext, |
| 13 | binding: RateLimitBinding, |
| 14 | keyParts: (string | null | undefined)[], |
| 15 | ): Promise<Response | null> { |
| 16 | if (import.meta.env.DEV) return null; |
| 17 | const key = await rateLimitKey(keyParts); |
| 18 | const { success } = await c.env[binding].limit({ key }); |
| 19 | return success ? null : jsonError("rate_limited", "Too many requests.", 429); |
| 20 | } |