v0.1.19 — Security: add stricter rate limiting to waitlist.join public endpoint
Release v0.1.19: Stricter Rate Limiting for Public Waitlist
What changed
- Added
waitlist_jointier to rate limits: 5 requests per hour per IP (vs 30/min for general tRPC mutations) - Middleware now detects
waitlist.joinrequests and enforces the hourly limit before the general tRPC tier - tRPC procedure applies two independent checks: per-IP and per-project+IP hourly limits
- 31 new test assertions covering tier values, URL pattern matching, and sliding-window behavior
Why it matters
The waitlist.join endpoint is unauthenticated and publicly accessible. The previous 30 req/min tier was too permissive — an automated script could flood a product's waitlist with thousands of fake emails per day. This patch tightens the limit to 5/hour and enforces it at two independent layers so no code path can bypass protection.
Technical notes
- Defense-in-depth: middleware checks the hourly limit first; the procedure re-checks it independently so server actions, tests, and internal callers are still protected
- Per-project+IP key prevents an attacker from cycling through projects while staying under the global IP limit
- Responses return
429 Too Many RequestswithRetry-After: 3600header - No database schema changes; no breaking changes to the public API
Release Notes
PR #427 was reviewed, squash-merged into main (commit 1d5b8ae), and a release was attempted for v0.1.19. The merge succeeded cleanly. The GitHub release creation returned a "tag already exists" error, meaning the v0.1.19 tag was pre-existing in the repository — the code changes from PR #427 are live on main. The release is a security patch adding defense-in-depth rate limiting (5 req/hour per IP) to the public waitlist.join tRPC endpoint at both the Next.js middleware layer and inside the tRPC procedure, with 31 new test assertions and no breaking changes.