Add Redis rate limiting for forgot-password

Summary

  • Add RateLimiterService using the existing Redis instance (host redis, DB 9) with fixed-window counters
  • Enforce configurable per-email and per-IP limits on forgot-password before user lookup
  • Keep the existing 5-minute per-user DB cooldown (generated_at)
  • Keep clear UX messages for unknown / banned / suspended accounts
  • Use a uniform denial message for rate-limit and cooldown denials: Too many requests. Please try again later.
  • Add config + env knobs, unit/controller tests, and ignore .phpunit.cache/

The previous 5-minute cooldown only applied to known accounts after a reset was issued. Requests with arbitrary email addresses could still generate unnecessary load on the email queue and SMTP pipeline. This adds request-layer protection without requiring new infrastructure.

Behavior

Case Result
Over email/IP Redis limit Error: Too many requests…
Within 5 minutes of last reset (known user) Error: Too many requests…
Unknown email Error: Email address does not exist…
Banned / suspended Existing banned / inactivity messages
Active user, allowed Success + enqueue resetPassword

Config (defaults)

Knob Default Env
Email max / window 5 / 3600s RATE_LIMIT_FORGOT_EMAIL_MAX, RATE_LIMIT_FORGOT_EMAIL_WINDOW
IP max / window 20 / 3600s RATE_LIMIT_FORGOT_IP_MAX, RATE_LIMIT_FORGOT_IP_WINDOW
Fail open if Redis down true RATE_LIMIT_FAIL_OPEN

Files

  • src/Service/RateLimiterService.php
  • src/Controller/ForgotController.php
  • config/app.php, config/.env.example, .gitignore
  • Tests: RateLimiterServiceTest, ForgotControllerTest, Redis fakes

Test plan

  • ./vendor/bin/phpunit tests/TestCase/Service/RateLimiterServiceTest.php
  • ./vendor/bin/phpunit tests/TestCase/Controller/ForgotControllerTest.php (app container)
  • Manual: 6th submit for same email → Too many requests…
  • Manual: unknown email (after clearing Redis limits) → Email address does not exist…
  • Manual: real account, 2nd request within 5 minutes → Too many requests…
  • Manual: successful reset still enqueues email job

Merge request reports

Loading
Loading