Skip to content

fix: validate reset passwords, revoke sessions and other reset tokens - #1348

Merged
thlpkee20-wq merged 2 commits into
RevoraOrg:masterfrom
Oluwasegun6921:security/issue-1293-security-password-reset-resetpassword-skips
Oct 22, 2026
Merged

thlpkee20-wq merged 2 commits into
RevoraOrg:masterfrom
Oluwasegun6921:security/issue-1293-security-password-reset-resetpassword-skips

Conversation

@Oluwasegun6921

Copy link
Copy Markdown
Contributor

Overview

This PR hardens PasswordResetService.resetPassword so a password reset enforces the same strength rules as registration, revokes the user's existing sessions, and invalidates any other outstanding reset tokens — all within the existing transaction. The route now surfaces validation failures as 400 and distinguishes them from an invalid/expired token.

Related Issue

Changes

🔒 Password Reset Hardening

  • [MODIFY] src/services/passwordResetService.ts

    • Calls validatePasswordStrength(newPassword) before opening the transaction, so a weak password never touches the token.
    • Inside the existing transaction, revokes all active sessions for row.user_id (UPDATE sessions SET revoked_at = NOW() WHERE user_id = $1 AND revoked_at IS NULL).
    • Inside the same transaction, marks all other unused reset tokens for the user as used, so a second emailed link is rejected.
    • Return type now distinguishes outcomes (e.g. { ok: false, reason }) so callers can tell a validation failure from an invalid token.
  • [MODIFY] src/routes/passwordReset.ts

    • Maps the validation-failure reason to a 400 response; invalid/expired token keeps its existing handling.

🧪 Tests

  • [MODIFY] src/services/passwordResetService.test.ts

    • Weak password is rejected and leaves the token unused.
    • After a successful reset, previously issued sessions are revoked and a second outstanding reset token is rejected.
    • Regression test for session survival that fails on master.
  • [MODIFY] src/routes/passwordReset.test.ts

    • Weak password returns 400 and leaves the token unused.
    • Successful reset path returns success; invalid token path is unchanged.

Verification Results

npm test -- src/services/passwordResetService.test.ts src/routes/passwordReset.test.ts
✅ passwordResetService tests passed
✅ passwordReset route tests passed
Acceptance Criteria Status
A weak password returns 400 and leaves the token unused ✅ Strength validation runs before the transaction; route maps to 400
After a reset, a previously issued session gets 401 ✅ All active sessions revoked in the reset transaction
A second outstanding reset token is rejected ✅ Other unused tokens marked used in the same transaction
Tests in passwordResetService.test.ts and passwordReset.test.ts ✅ Added for both files
Regression test for session survival that fails on master ✅ Added in service tests
CI stays green ✅ No type errors or disabled checks

Closes #1293

@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@Oluwasegun6921 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Oluwasegun6921
Oluwasegun6921 force-pushed the security/issue-1293-security-password-reset-resetpassword-skips branch from 8316ba4 to d01ca0f Compare October 22, 2026 06:52
Strips the payload this branch picked up (deleted api.js, truncated eslint.config.js, unhooked package.json). No functional change to the branch's own work.
@thlpkee20-wq
thlpkee20-wq merged commit d883b7a into RevoraOrg:master Oct 22, 2026
1 check failed
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.

security(password-reset): resetPassword skips strength validation and leaves existing sessions and other reset tokens valid

2 participants