Skip to content

P1: fix(auth): clear the OTP after resending - #220

Open
aspiers wants to merge 2 commits into
mainfrom
split-pr165/clear-code-on-resend
Open

P1: fix(auth): clear the OTP after resending#220
aspiers wants to merge 2 commits into
mainfrom
split-pr165/clear-code-on-resend

Conversation

@aspiers

@aspiers aspiers commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Clear the previously entered verification code after a successful resend. The fresh code now starts with an empty control focused at its first position.

Changes

  • Reset OTP state after resend succeeds
  • Focus the first entry position
  • Add focused render coverage

Testing

  • pnpm format:check
  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm test:coverage

Screenshots

Before: a successful resend left stale digits in the OTP boxes.

Before: resend retains stale digits

After: the old digits are cleared, focus returns to the first box, and the success banner confirms the new code. The preview responses were controlled to isolate successful resend.

After: cleared OTP after resend

Notes

Summary by CodeRabbit

  • Bug Fixes

    • Resending a sign-in code now clears previously entered digits.
    • Focus automatically returns to the first code entry box, allowing immediate entry of the new code.
  • Tests

    • Added coverage confirming expired-code recovery resets the verification form correctly.

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
epds-demo Ready Ready Preview Jul 30, 2026 9:46pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@aspiers, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0065e6b-be04-4e73-8ed6-3d63ab636ee6

📥 Commits

Reviewing files that changed from the base of the PR and between 619ae08 and d73d017.

📒 Files selected for processing (1)
  • e2e/step-definitions/auth.steps.ts
📝 Walkthrough

Walkthrough

The resend-code handler now clears previously entered OTP digits and focuses the first input. The passwordless authentication scenario adds coverage for partially entered expired codes and verifies the reset state after a fresh code is sent.

Changes

OTP resend reset

Layer / File(s) Summary
Reset OTP state after resend
packages/auth-service/src/routes/login-page.ts
Successful code resends clear all OTP inputs and focus the first slot.
Verify expired-code recovery
e2e/step-definitions/auth.steps.ts, features/passwordless-authentication.feature, .changeset/clear-otp-boxes-on-resend.md
End-to-end steps enter two OTP digits and verify that resend leaves every box empty with focus on the first box; the changeset records the behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: kzoeps

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: clearing the OTP input after a successful resend.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch split-pr165/clear-code-on-resend

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@railway-app

railway-app Bot commented Jul 30, 2026

Copy link
Copy Markdown

🚅 Deployed to the ePDS-pr-220 environment in ePDS

Service Status Web Updated (UTC)
@certified-app/demo ✅ Success (View Logs) Web Jul 30, 2026 at 9:46 pm
@certified-app/demo untrusted ✅ Success (View Logs) Web Jul 30, 2026 at 9:46 pm
@certified-app/auth-service ✅ Success (View Logs) Web Jul 30, 2026 at 9:45 pm
@certified-app/pds-core ✅ Success (View Logs) Web Jul 30, 2026 at 9:45 pm

@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d73d017

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coveralls-official

coveralls-official Bot commented Jul 30, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 30584642228

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage remained the same at 57.281%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 3 coverage regressions across 1 file.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

3 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
packages/auth-service/src/routes/account-login.ts 3 0.0%

Coverage Stats

Coverage Status
Relevant Lines: 3069
Covered Lines: 1753
Line Coverage: 57.12%
Relevant Branches: 1910
Covered Branches: 1099
Branch Coverage: 57.54%
Branches in Coverage %: Yes
Coverage Strength: 6.06 hits per line

💛 - Coveralls

@aspiers aspiers changed the title fix(auth): clear the OTP after resending P1: fix(auth): clear the OTP after resending Jul 30, 2026
Comment thread packages/auth-service/src/__tests__/login-page.test.ts Outdated
@blacksmith-sh

This comment has been minimized.

@aspiers
aspiers force-pushed the split-pr165/clear-code-on-resend branch from 50f4a5e to 619ae08 Compare July 30, 2026 16:17
@railway-app
railway-app Bot temporarily deployed to ePDS / ePDS-pr-220 July 30, 2026 16:50 Destroyed
@aspiers
aspiers marked this pull request as ready for review July 30, 2026 16:53
Copilot AI review requested due to automatic review settings July 30, 2026 16:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
e2e/step-definitions/auth.steps.ts (1)

628-635: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the old digits before testing the reset.

This makes the scenario prove that the boxes contained the old OTP prefix before resend; otherwise a regression that clears or ignores input before resend could still pass the final empty-state assertion.

Proposed test strengthening
     await otpBoxes.nth(0).fill('1')
     await otpBoxes.nth(1).fill('2')
+    await expect(otpBoxes.nth(0)).toHaveValue('1')
+    await expect(otpBoxes.nth(1)).toHaveValue('2')
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/step-definitions/auth.steps.ts` around lines 628 - 635, Update the step
definition “the user enters two digits from the old OTP” to assert that the
first two OTP boxes contain the entered old digits after filling them. Keep the
existing fill behavior and ensure the assertions run before the resend/reset
action.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@e2e/step-definitions/auth.steps.ts`:
- Around line 628-635: Update the step definition “the user enters two digits
from the old OTP” to assert that the first two OTP boxes contain the entered old
digits after filling them. Keep the existing fill behavior and ensure the
assertions run before the resend/reset action.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a80ed2d-8632-428c-bd64-317aa077a525

📥 Commits

Reviewing files that changed from the base of the PR and between 7bce175 and 619ae08.

📒 Files selected for processing (4)
  • .changeset/clear-otp-boxes-on-resend.md
  • e2e/step-definitions/auth.steps.ts
  • features/passwordless-authentication.feature
  • packages/auth-service/src/routes/login-page.ts

The "boxes are empty after resend" assertion only proves the reset
happened if the boxes held something beforehand. Without this check a
regression that cleared or ignored input *before* resend would still
satisfy the final empty-state assertion.

Suggested by CodeRabbit in review of #220.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 21:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@aspiers

aspiers commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

(reply generated by Claude Opus 5 via Claude Code)

@coderabbitai re: the nitpick on e2e/step-definitions/auth.steps.ts (the "assert the old digits before testing the reset" suggestion) — agreed and applied in d73d017.

Your reasoning is right: without it, a regression that cleared or ignored input before the resend would still satisfy the final empty-state assertion, so the scenario wouldn't actually be proving the reset.

await otpBoxes.nth(0).fill('1')
await otpBoxes.nth(1).fill('2')
// Prove the digits actually landed, so the later empty-box assertion
// demonstrates that resend cleared them rather than that they were
// never entered.
await expect(otpBoxes.nth(0)).toHaveValue('1')
await expect(otpBoxes.nth(1)).toHaveValue('2')

@aspiers

aspiers commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

(reply generated by Claude Opus 5 via Claude Code)

Re: the Blacksmith report of Cucumber/Expired OTP is rejected, resend recovers the flow failing — that result is stale, and for the record it was a real bug rather than the known flake in #214.

It ran against 50f4a5e, an earlier version of the commit that has since been amended and force-pushed away (it is no longer an ancestor of this branch). The failure was:

Error: expect(locator).toHaveCount(expected) failed
  Expected: 8
  - unexpected value "6"

Cause: my new step asserted toHaveCount(testEnv.otpLength). e2e/support/env.ts:33 defaults otpLength to 8 when OTP_LENGTH is unset in the e2e runner's environment, but the auth service under test renders 6 boxes — so the assertion compared an env-derived default against the real DOM.

Fix, already in 619ae08: assert against the length of the OTP actually captured from the mail trap, which is by definition the number of boxes to expect:

await expect(otpBoxes).toHaveCount(this.otpCode.length)

This mirrors the existing guard at auth.steps.ts:55, which likewise prefers the live box count over testEnv.otpLength.

E2E tests pass on 619ae08 (run 30560777504), and all checks are currently green on the branch tip.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@aspiers Thanks — that closes the coverage gap nicely. The pre-resend value assertions ensure the scenario proves that resend clears existing input, rather than merely observing an already-empty state.

🐇 ✅


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants