feat(account): throttle confirm-code sends per recipient

Add an in-memory SendLimiter enforcing a one-per-minute cooldown and a
five-per-rolling-hour cap per recipient address, checked before provisioning or
sending in RequestCode, RequestLoginCode and RequestLinkCode. It guards against
email bombing and protects the relay quota. The limiter is injected in main
(nil in tests, so the domain suite is unaffected); ErrTooManyRequests maps to
HTTP 429.
This commit is contained in:
Ilia Denisov
2026-07-03 03:02:49 +02:00
parent 3877b23894
commit 2207ac6132
7 changed files with 138 additions and 0 deletions
+3
View File
@@ -26,6 +26,9 @@ func (s *EmailService) RequestLinkCode(ctx context.Context, accountID uuid.UUID,
if err != nil {
return err
}
if !s.allowSend(addr) {
return ErrTooManyRequests
}
return s.issueCode(ctx, accountID, addr, purposeLink, s.accountLocale(ctx, accountID))
}