Skip to content

feat: rate limiting & brute-force protection for email code / password login#22

Merged
slhmy merged 2 commits intomainfrom
copilot/add-rate-limiting-and-error-protection
Apr 15, 2026
Merged

feat: rate limiting & brute-force protection for email code / password login#22
slhmy merged 2 commits intomainfrom
copilot/add-rate-limiting-and-error-protection

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 15, 2026

SendLoginEmailCode, LoginByEmailCode, and LoginByPassword had no protection against abuse — unlimited send attempts and no lockout on repeated credential failures.

Changes

cache.RateLimiter (new redis_rate_limiter.go)

Redis-backed interface using Lua scripts for atomicity:

  • IsAllowed(ctx, key) — read-only check (no side effects)
  • Record(ctx, key) — increment failure counter; sets TTL on first call
  • Reset(ctx, key) — clear counter on successful auth

Config (config.go)

New fields with sensible defaults:

Field Default
LoginMaxAttempts 5 attempts
LoginLockoutDuration 15 min
SendCodeMaxAttempts 5 sends
SendCodeWindow 1 hour

Service (service.go)

  • loginRateLimiter applied to LoginByPassword and LoginByEmailCode: check before attempt → Record on failure → Reset on success
  • sendCodeRateLimiter applied to SendLoginEmailCode: check + Record before sending
  • Errors from the limiter fail open — a Redis outage won't lock out legitimate users
  • mailer field widened from *smtp.Mailer to mail.Sender interface (already existed in the codebase) to enable the new unit tests

Tests (service_rate_limit_test.go)

9 unit tests covering block-on-exceeded, record-on-failure, and reset-on-success for all three endpoints, using in-memory mocks (no Redis required).

@slhmy slhmy marked this pull request as ready for review April 15, 2026 07:03
@slhmy slhmy merged commit 5941468 into main Apr 15, 2026
2 checks passed
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.

2 participants