feat(admin): list currently rate-limited entities, resolved to users #331
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/BUNYIP-315-admin-rate-limits-list"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Add a read-only GET /v1/admin/rate-limits (AdminUser-guarded) that returns every currently-active throttle across both rate-limit sources, each resolved to a user where possible.
Unifies the two places rate-limit state lives:
Supporting changes, all single-source-of-truth: add a key_kind field to every RateLimitConfig preset plus a KeyKind/KeySubject taxonomy and by_action/subject helpers; promote the feedback_submit config from a handler-local literal to a preset so its cap/window resolve from one place; extract the 2FA key prefix into TWO_FACTOR_KEY_PREFIX shared by the totp handler and the read path; add RateLimitRepository::list_active and TokenRepository::list_email_{verification,change}_over_limit; make resend_retry_after_secs pub.
The unified list is paginated in memory like list_users. Unit-tested at the pure-logic level for an email-keyed action, an IP-keyed action, the 2fa_verify_user: prefix case, the active-window/cap gate, and an email-verification synthesized entry.
#BUNYIP-315
Add a read-only GET /v1/admin/rate-limits (AdminUser-guarded) that returns every currently-active throttle across both rate-limit sources, each resolved to a user where possible. Unifies the two places rate-limit state lives: - The rate_limits table (login, registration, the OCI/OAuth presets, the per-account 2FA failure counter). Each row's opaque key is interpreted per its action's new KeyKind: email-keyed and user-id-keyed rows resolve to a user (id + email) via UserRepository, the 2fa_verify_user: prefix is stripped to recover the user id, and IP-keyed rows expose the IP with no user. A row is surfaced only when its window is still open and its count is at or over the cap; cap and window come from the RateLimitConfig presets via the new by_action lookup, never re-hardcoded, and retry_after is computed from window_start via RateLimit::active_retry_after. - The email-verify / email-change resend limiters (BUNYIP-313), which count rows outside the rate_limits table. Users at or over the shared RESEND_LIMIT_MAX within the rolling window are synthesized into entries under the pseudo-actions email_verification / email_change, reusing the shared constants and resend_retry_after_secs so retry_after matches the enforcement path exactly. Supporting changes, all single-source-of-truth: add a key_kind field to every RateLimitConfig preset plus a KeyKind/KeySubject taxonomy and by_action/subject helpers; promote the feedback_submit config from a handler-local literal to a preset so its cap/window resolve from one place; extract the 2FA key prefix into TWO_FACTOR_KEY_PREFIX shared by the totp handler and the read path; add RateLimitRepository::list_active and TokenRepository::list_email_{verification,change}_over_limit; make resend_retry_after_secs pub. The unified list is paginated in memory like list_users. Unit-tested at the pure-logic level for an email-keyed action, an IP-keyed action, the 2fa_verify_user: prefix case, the active-window/cap gate, and an email-verification synthesized entry. #BUNYIP-315