Skip to content

feat: Redis-backed sliding window throttling with @Throttle decorator#882

Merged
nafiuishaaq merged 3 commits into
MentoNest:mainfrom
Shecodes174:feat/redis-throttling
Jun 27, 2026
Merged

feat: Redis-backed sliding window throttling with @Throttle decorator#882
nafiuishaaq merged 3 commits into
MentoNest:mainfrom
Shecodes174:feat/redis-throttling

Conversation

@Shecodes174

@Shecodes174 Shecodes174 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

closes #696

Summary

Implements Redis-backed rate limiting with a custom @Throttle() decorator and ThrottlerGuard that uses a sliding window algorithm.

New files: src/common/throttler/

File Purpose
throttle.decorator.ts @Throttle(limit, ttl) and @SkipThrottle() decorators
throttler.service.ts Sliding window via Redis ZADD/ZCARD/ZREMRANGEBYSCORE
throttler.guard.ts CanActivate guard — IP tracking (unauth) / userId tracking (auth)
throttler.module.ts NestJS module exporting service + guard
throttler.spec.ts 12 unit tests

Acceptance criteria

  • 429 Too Many Requests when limit exceeded
  • Per-route limits: @Throttle(10, 60) = 10 req/60s
  • Redis sliding window with atomic ZADD + TTL
  • Global defaults: 100 req/min authenticated, 20 req/min unauthenticated
  • Retry-After header returned on 429
  • IP-based tracking for unauthenticated endpoints
  • User ID-based tracking for authenticated endpoints
  • Trusted IP bypass via THROTTLE_TRUSTED_IPS env var (comma-separated)

Auth endpoint limits

  • GET /auth/nonce/:walletAddress@Throttle(5, 60)
  • POST /auth/login@Throttle(10, 60)
  • POST /auth/refresh@Throttle(20, 60)

Configuration

THROTTLE_TRUSTED_IPS=10.0.0.1,10.0.0.2   # optional whitelist

Tests

15/15 pass (12 throttler + 3 auth controller)

- Add src/common/throttler/ module:
  - throttle.decorator.ts: @Throttle(limit, ttl) and @SkipThrottle()
  - throttler.service.ts: sliding window via Redis ZADD/ZCARD/ZREMRANGEBYSCORE
  - throttler.guard.ts: IP-based (unauthenticated) + userId-based (authenticated)
    tracking, trusted IP whitelist (THROTTLE_TRUSTED_IPS env), Retry-After header
  - throttler.module.ts: exports ThrottlerService + ThrottlerGuard

- Register ThrottlerGuard globally via APP_GUARD in AppModule
- Auth endpoints: @Throttle(5,60) nonce, @Throttle(10,60) login, @Throttle(20,60) refresh
- Global defaults: 100 req/min authenticated, 20 req/min unauthenticated
- Remove old inline enforceRateLimit from AuthController

- Also includes normalizeWalletAddress utility (wallet.utils.ts) and
  pre-existing merge conflict fixes from feat/normalize-wallet-address

Tests: 12/12 throttler, 3/3 auth controller (15 total)
@drips-wave

drips-wave Bot commented Jun 26, 2026

Copy link
Copy Markdown

@Shecodes174 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@nafiuishaaq nafiuishaaq merged commit 6ee5382 into MentoNest:main Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API rate limiting with Redis

2 participants