test(auth): password-reset redeem coverage (PMS-659) #458
Loading…
Reference in a new issue
No description provided.
Delete branch "test/PMS-659-password-reset-coverage"
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?
What
Adds automated coverage for the legacy password-reset redeem flow (PMS-659 verification). Five integration tests in
tests/auth.rs.Why
PMS-659 verifies the reset flow and its protections. The redeem half (redemption, expiry, single-use, session revocation, no-enumeration) had almost no coverage. The emailed token is
{user_id}.{secret}with only the Argon2 hash ofsecretstored, so the secret cannot be read back from the DB andrequest_password_resetreturns nothing; the tests mint a token row with a known secret (craft_reset_token) to drive the redeem endpoint.Tests
reset_password_changes_password_and_revokes_sessions- a valid reset changes the password (old fails, new logs in), stamps the tokenused_at, and revokes alluser_sessions(logout_all).reset_password_rejects_expired_token- theexpires_at > NOW()guard.reset_password_token_is_single_use- a second redeem of the same token fails.reset_password_rejects_malformed_and_wrong_secret- a bad token shape and a wrong secret both 400.forgot_password_unknown_email_issues_no_token- 2xx and zero tokens (no user enumeration).Full
cargo test --test authpasses (27/27) against Postgres.Verification findings (PMS-659)
The reset flow itself is sound: user-bound token, Argon2-hashed at rest, 24h expiry, single-use, all pending tokens invalidated on redeem, sessions revoked (
logout_all). Login is rate-limited (IP 20/min + email 5/min). Two gaps found, filed as linked issues:/auth/forgot-passwordis not rate-limited (login is), so reset-email bombing is unguarded.Note: the legacy password login has no persistent lockout; it relies on the per-(IP, email) rate limit instead (hard lockout enables victim-lockout DoS). MFA has its own lockout (
mfa_failed_codes_lock_account).#PMS-659
PMS-659 verification found the reset redeem path (redemption, expiry, single-use, session revocation, no-enumeration) had almost no automated coverage. Add five integration tests to tests/auth.rs. Because the emailed token is `{user_id}.{secret}` and only the Argon2 hash of the secret is stored, the tests mint a token row with a known secret (`craft_reset_token`) to exercise the redeem half that the request-side test cannot reach. Coverage: a valid reset changes the password and revokes the user's sessions (logout_all), rejects an expired token, enforces single-use, rejects malformed and wrong-secret tokens, and confirms forgot-password issues no token for an unknown email (no enumeration). Two defects found during verification are filed separately: forgot-password is not rate-limited (PMS-680) and a reset does not invalidate already-issued access tokens within their 1h TTL (PMS-681). #PMS-659 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>