feat: better ratelimiting (#2520)

Replace hono-rate-limiter with a Prisma/PostgreSQL bucketed counter
approach that works correctly across multiple instances without sticky
sessions.

- Add RateLimit model with composite PK (key, action, bucket) and atomic
upsert
- Create rate limit factory with window parsing, bucket computation, and
fail-open
- Define auth-tier and API-tier rate limit instances
- Add Hono middleware, rateLimitResponse helper, and tRPC
assertRateLimit helper
- Wire rate limit headers through AppError constructor (was declared but
never assigned)
- Apply rate limits to auth routes (email-password, passkey), tRPC
routes
  (2FA email, link org account), API routes, and file upload endpoints
- Add cleanup cron job for expired rate limit rows (batched delete every
15 min)
- Remove hono-rate-limiter dependency
This commit is contained in:
Lucas Smith
2026-02-20 12:23:02 +11:00
committed by GitHub
parent 006b1d0a57
commit 653ab3678a
21 changed files with 1218 additions and 62 deletions
-10
View File
@@ -143,7 +143,6 @@
"content-disposition": "^1.0.1",
"framer-motion": "^12.23.24",
"hono": "4.11.4",
"hono-rate-limiter": "^0.4.2",
"hono-react-router-adapter": "^0.6.5",
"input-otp": "^1.4.2",
"isbot": "^5.1.32",
@@ -25094,15 +25093,6 @@
"node": ">=16.9.0"
}
},
"node_modules/hono-rate-limiter": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/hono-rate-limiter/-/hono-rate-limiter-0.4.2.tgz",
"integrity": "sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw==",
"license": "MIT",
"peerDependencies": {
"hono": "^4.1.1"
}
},
"node_modules/hono-react-router-adapter": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/hono-react-router-adapter/-/hono-react-router-adapter-0.6.5.tgz",