Menu

#39 feat(api): make the portal-auth throttle limit env-configurable

open
nobody
None
1 day ago
1 day ago
Anonymous
No

Originally created by: AshishGTH

Summary

  • Adds PORTAL_AUTH_THROTTLE_LIMIT, replacing the hardcoded limit: 5 on the portal-auth throttler bucket in app.module.ts. Unset, the limit stays 5 requests / 5 minutes per IP — no behaviour change on any existing install.
  • Read via process.env inside the existing ThrottlerModule.forRootAsync useFactory, matching the adjacent DEFAULT_THROTTLE_LIMIT line exactly rather than ConfigService: reading one value from each source in the same array literal would be worse than either choice made consistently, and the factory has no inject array to extend. ConfigModule loads .env into process.env anyway, so both read the same source.
  • The value is read once per NestFactory.create(), so it is frozen at bootstrap — a test must set it before the app is constructed and cannot vary it mid-run.
  • e2e-portal-throttle.test.ts is the only place that drives this bucket to an exact 5-then-429 boundary, so it now pins its own '5' at module top level next to THROTTLE_TEST_KEY_PREFIX, rather than silently tracking a production default someone else may tune. vitest.config.ts deliberately does not set the var suite-wide — doing so would break that assertion.
  • playwright.config.ts raises it to 100 for the harness. This is the change that addresses the actual problem: the bucket is IP-keyed, Playwright's webServer runs one API process for the whole suite, and the suite finishes well inside the 5-minute window — so the ceiling is the suite's total portal login count, not any one spec's. apps/e2e/fixtures/seed.ts already records real, intermittent 429s on unrelated spec files from exactly this.

Also in scope, both found while making the above change:

  • Documents DEFAULT_THROTTLE_LIMIT in both .env.example files. It has been read by app.module.ts since it was added and was documented in neither.
  • Corrects portal-throttler.guard.ts's doc comment, which still described the second ThrottlerModule.forRoot() call in PortalAuthModule that was removed when the competing @Global() registration bug was fixed. Comment-only, no behaviour change.

Test plan

  • [x] pnpm --filter @openestate/api build — clean
  • [x] pnpm --filter @openestate/api lint && pnpm --filter @openestate/api typecheck — both clean
  • [ ] pnpm --filter @openestate/api test -- e2e-portal-throttle could NOT be executed locally. This machine has no PostgreSQL and no Redis running (5432/6379/5433/6380 all ECONNREFUSED), so the spec's describeIf gate skipped all 3 tests — 1 skipped (1) / 3 skipped (3). That is a skip, not a pass. CI's integration-tests job is the first real execution of this spec against the change, and the first actual verification that the pinned PORTAL_AUTH_THROTTLE_LIMIT=5 still produces 5×401-then-429.
  • [ ] Note that apps/api/tsconfig.json has "include": ["src"] and lint runs eslint src, so neither of the green commands above covers test/ at all. The test-file edit is a one-line process.env assignment; vitest collecting the file cleanly (3 tests found) is the only local check it received.
  • [ ] CI: lint-typecheck-build, integration-tests, native-install, native-upgrade, e2e-playwright

🤖 Generated with Claude Code

Discussion


Log in to post a comment.