fix: address PR review feedback for requestPasswordReset + resetPassword
- Timing: generate-and-discard token on all non-found paths in
requestPasswordReset to equalize CPU work with the happy path and
make timing-based email enumeration impractical
- DB layer: add is_expired bool (via SQL comparison) to ResetTokenRow
and include it in get_reset_token's SELECT, eliminating the inline
sqlx::query_scalar that bypassed the DB module in reset_password.rs
- rows_affected(): both mark_reset_token_used and update_password_hash
now return InternalError if the UPDATE affects 0 rows, preventing
silent success when a row disappears inside a transaction
- Logging: add tracing::error\! with endpoint context on the Err arm of
resolve_by_email; add did= field to insert_reset_token failure log;
add tracing::warn\! on token-reuse and expiry paths in reset_password
- Comments: fix insert_reset_token doc ("ATProto spec" → implementation
choice); reword transaction safety comment to not couple correctness
reasoning to pool size; fix get_reset_token doc to match new struct
- CLAUDE.md: update accounts.rs row to list all exported functions
- Tests: add e2e flow test (requestPasswordReset → resetPassword →
createSession), deactivated-account test, multiple-tokens-per-DID test