From fa029437a162088ff79f36872110fa4087011530 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 10 Jul 2026 22:56:12 -0700 Subject: invoices: rate-limit invoice create and update per IP Add a per-IP rate limit (30/10s) to POST /invoice and POST /invoice/:id, matching the existing GET /invoice/:id limit, to throttle automated invoice-creation floods. Co-Authored-By: Claude Opus 4.8 (1M context) --- index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'index.ts') diff --git a/index.ts b/index.ts index 0a3bfd89..808252de 100644 --- a/index.ts +++ b/index.ts @@ -48,8 +48,8 @@ app.get("/locations", locations.list); app.get("/invoice/:id", { config: { rateLimit: { max: 30, timeWindow: 10000, keyGenerator: (req) => { const ip = (req.headers["cf-connecting-ip"] as string) || req.ip; const token = (req.headers.authorization || "").slice(0, 50); return token ? `invoice:${token}` : `invoice:${ip}`; } } } }, invoices.get); app.get("/invoices", auth, invoices.list); -app.post("/invoice", optional, invoices.create); -app.post("/invoice/:id", optional, invoices.update); +app.post("/invoice", { ...optional, config: { rateLimit: { max: 30, timeWindow: 10000, keyGenerator: (req) => `invoicecreate:${(req.headers["cf-connecting-ip"] as string) || req.ip}` } } }, invoices.create); +app.post("/invoice/:id", { ...optional, config: { rateLimit: { max: 30, timeWindow: 10000, keyGenerator: (req) => `invoiceupdate:${(req.headers["cf-connecting-ip"] as string) || req.ip}` } } }, invoices.update); app.post("/sign", auth, invoices.sign); app.get("/assetlinks.json", (_, res) => res.sendFile("assetlinks.json")); -- cgit v1.2.3