Skip to content

fix(a11y): TOTP modal validation and error handling#37049

Merged
dionisio-bot[bot] merged 7 commits intoRocketChat:developfrom
NightSkyHigh:fix/196-TOTP
Apr 27, 2026
Merged

fix(a11y): TOTP modal validation and error handling#37049
dionisio-bot[bot] merged 7 commits intoRocketChat:developfrom
NightSkyHigh:fix/196-TOTP

Conversation

@NightSkyHigh
Copy link
Copy Markdown
Contributor

@NightSkyHigh NightSkyHigh commented Sep 24, 2025

fix modal not closing when entering wrong code. fixed inline error to display correct text

WA-60
WA-33

Summary by CodeRabbit

  • Bug Fixes

    • Corrected the error message shown for invalid two-factor codes.
    • Improved handling of invalid 2FA attempts with clearer user feedback.
    • Non-2FA login errors are now surfaced more reliably.
  • Refactor

    • Modernized the 2FA and password+TOTP login flows to use async promises, improving stability and responsiveness without changing user behavior.

@NightSkyHigh NightSkyHigh requested a review from a team as a code owner September 24, 2025 10:38
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Sep 24, 2025

⚠️ No Changeset found

Latest commit: db941b2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented Sep 24, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is targeting the wrong base branch. It should target 8.5.0, but it targets 8.4.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Sep 24, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 24, 2025

Walkthrough

Shifts two-factor login flow to Promise-based handling, awaiting code submission. Updates invalid 2FA UI message key. Exposes and converts password+TOTP login to an exported Promise-returning function. Adjusts error propagation paths to resolve/reject Promises instead of relying solely on callbacks.

Changes

Cohort / File(s) Summary
UI i18n message update
apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx
Changes invalid 2FA error message key from Invalid_password to Invalid_two_factor_code; rendering logic unchanged.
2FA async control flow
apps/meteor/client/lib/2fa/overrideLoginMethod.ts, apps/meteor/client/lib/2fa/process2faReturn.ts
Refactors onCode handling to Promise-based flow; rejects on invalid TOTP, resolves on max attempts, and returns error from outer login when TOTP not required. process2faReturn now awaits onCode(...).
Login API Promise export
apps/meteor/client/meteor/overrides/login/password.ts
Introduces and exports loginWithPasswordAndTOTP(...) returning Promise<void>. Converts callback-based Accounts.callLoginMethod path to Promise, invoking callback but resolving the Promise on both success and error.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant M as TwoFactor Modal
  participant C as Client 2FA Flow (process2faReturn)
  participant L as onCode Handler
  participant A as loginWithPasswordAndTOTP
  participant S as Server

  U->>M: Enter TOTP code
  M->>C: submit(code)
  C->>L: await onCode(code, method)
  rect rgba(230,240,255,0.5)
    note right of L: Promise-based handling
    L->>A: return A(user,password,code)
    A->>S: Accounts.callLoginMethod
    S-->>A: success or error
    A-->>L: Promise resolved (success or error passthrough via callback)
  end
  alt Success
    L-->>C: resolve
    C-->>M: close / continue login
  else Invalid code
    L-->>C: reject (after toast i18n)
    C-->>M: show "Invalid_two_factor_code"
  else Max attempts reached
    L-->>C: resolve (handled case)
    C-->>M: proceed with handled state
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

A bunny taps a secret code, hop-hop, no lag, no load,
Promises bloom where callbacks slept, tidy trails now showed.
The modal whispers truer words, mistakes no longer vague,
With ears up high I parse the flow—async without the drag.
Thump! Login’s smooth—let’s ship this wag. 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ⚠️ Warning The PR title focuses on 'a11y' (accessibility) and mentions 'TOTP modal validation and error handling', but the actual changes address a functional bug where the modal doesn't close when entering an incorrect code and fix the displayed error message text. The title does not accurately reflect the primary bug fix described in the PR objectives. Update the title to reflect the main changes, such as 'fix: TOTP modal not closing when entering wrong code and correct error message display' to better align with the PR's actual objectives and changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (6)
apps/meteor/client/meteor/overrides/login/password.ts (2)

23-29: Avoid parameter reassignment; normalize into a local variable

Reassigning function parameters harms readability and can confuse TS inference. Normalize into a local and use includes:

-  if (typeof userDescriptor === 'string') {
-    if (userDescriptor.indexOf('@') === -1) {
-      userDescriptor = { username: userDescriptor };
-    } else {
-      userDescriptor = { email: userDescriptor };
-    }
-  }
+  const normalizedUser =
+    typeof userDescriptor === 'string'
+      ? userDescriptor.includes('@')
+        ? { email: userDescriptor }
+        : { username: userDescriptor }
+      : userDescriptor;

And update the usage below:

-              user: userDescriptor,
+              user: normalizedUser,

17-22: Exported API semantics changed — document or align behavior

Now that loginWithPasswordAndTOTP is exported and Promise-returning, ensure downstream consumers know it rejects on errors (see suggested fix above) or document that it only signals via the callback. Silent resolution on error will cause hard-to-debug flows.

apps/meteor/client/lib/2fa/process2faReturn.ts (2)

66-68: Type onCode to allow Promises

Since you now await onCode(...), broaden the type to reflect Promise-returning handlers:

-  onCode: (code: string, method: string) => void;
+  onCode: (code: string, method: string) => void | Promise<void>;

84-92: Return the recursive call to preserve Promise chain

Avoid a dangling Promise when you re-enter the flow:

-    process2faReturn({
+    return process2faReturn({
       error: error as globalThis.Error | Meteor.Error | Meteor.TypedError | undefined,
       result,
       originalCallback,
       onCode,
       emailOrUsername,
     });
apps/meteor/client/lib/2fa/overrideLoginMethod.ts (2)

16-16: Remove no-op return inside callback

return error; inside the callback is ignored by the caller and has no effect.

-            callback?.(error);
-            return error;
+            callback?.(error);
+            return;

86-89: Confirm intent: Swallowing invalid-code error in Promise flow

Here, invalid-code shows a toast and calls callback?.(undefined), which signals success to the consumer. Is this intended to only clear loading states without marking failure?

If not, consider invoking callback?.(error) to propagate failure, or re-enter the 2FA flow similarly to the callback-based path.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ddfb304 and 77b8553.

📒 Files selected for processing (4)
  • apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx (1 hunks)
  • apps/meteor/client/lib/2fa/overrideLoginMethod.ts (2 hunks)
  • apps/meteor/client/lib/2fa/process2faReturn.ts (1 hunks)
  • apps/meteor/client/meteor/overrides/login/password.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/meteor/client/meteor/overrides/login/password.ts (1)
apps/meteor/client/lib/2fa/overrideLoginMethod.ts (1)
  • LoginCallback (5-5)
apps/meteor/client/lib/2fa/overrideLoginMethod.ts (1)
apps/meteor/client/lib/toast.ts (1)
  • dispatchToastMessage (22-25)
🔇 Additional comments (3)
apps/meteor/client/lib/2fa/process2faReturn.ts (1)

83-83: Good: await onCode to drive modal lifecycle

Awaiting onCode ensures the modal closes and reopens correctly on failures.

apps/meteor/client/lib/2fa/overrideLoginMethod.ts (1)

27-33: LGTM: Promise-wrapped TOTP path enables awaiting retries

Wrapping the TOTP callback path in a Promise aligns with process2faReturn’s awaited flow.

apps/meteor/client/components/TwoFactorModal/TwoFactorTotpModal.tsx (1)

54-54: LGTM — i18n key verified

The translation key "Invalid_two_factor_code" exists in packages/i18n/src/locales/*.i18n.json and is already used elsewhere in the codebase; approve.

Comment thread apps/meteor/client/lib/2fa/overrideLoginMethod.ts Outdated
Comment thread apps/meteor/client/meteor/overrides/login/password.ts Outdated
@NightSkyHigh NightSkyHigh changed the title fixed two factor modal not closing when entering wron code fix: two factor modal not closing when entering the wrong code Oct 2, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 22.72727% with 68 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.76%. Comparing base (f032e18) to head (db941b2).
⚠️ Report is 66 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37049      +/-   ##
===========================================
- Coverage    70.27%   69.76%   -0.51%     
===========================================
  Files         3284     3291       +7     
  Lines       117118   119102    +1984     
  Branches     20736    21456     +720     
===========================================
+ Hits         82308    83095     +787     
- Misses       31517    32699    +1182     
- Partials      3293     3308      +15     
Flag Coverage Δ
e2e 59.68% <22.72%> (-0.04%) ⬇️
e2e-api 47.09% <ø> (-0.21%) ⬇️
unit 70.47% <ø> (-0.66%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 9 files

You’re at about 96% of the monthly review limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/meteor/client/lib/2fa/overrideLoginMethod.ts">

<violation number="1" location="apps/meteor/client/lib/2fa/overrideLoginMethod.ts:44">
P2: Missing rejection handling on dynamic imports can leave `onCode` Promise pending indefinitely and stall 2FA modal completion.</violation>
</file>

<file name="apps/meteor/client/meteor/login/password.ts">

<violation number="1" location="apps/meteor/client/meteor/login/password.ts:52">
P2: Error handling mixes callback and Promise rejection, which can trigger unhandled rejections because the caller uses callback style and does not consume the returned Promise.</violation>
</file>

<file name="apps/meteor/client/lib/2fa/process2faReturn.ts">

<violation number="1" location="apps/meteor/client/lib/2fa/process2faReturn.ts:116">
P2: Truthiness check on `result` wrongly throws for valid falsy `onCode` return values.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/meteor/client/lib/2fa/overrideLoginMethod.ts
Comment thread apps/meteor/client/meteor/login/password.ts
Comment thread apps/meteor/client/lib/2fa/process2faReturn.ts Outdated
@juliajforesti juliajforesti changed the title fix: two factor modal not closing when entering the wrong code fix(ux): 2fa modal not closing when entering the wrong code Apr 20, 2026
@juliajforesti juliajforesti changed the title fix(ux): 2fa modal not closing when entering the wrong code fix(ux): 2fa validation a11y Apr 20, 2026
@juliajforesti juliajforesti added this to the 8.4.0 milestone Apr 20, 2026
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@dougfabris dougfabris changed the title fix(ux): 2fa validation a11y fix(a11y): TOTP modal validation and error handling Apr 20, 2026
@dougfabris dougfabris removed this from the 8.4.0 milestone Apr 20, 2026
@dougfabris dougfabris added this to the 8.5.0 milestone Apr 20, 2026
@dougfabris dougfabris added the stat: QA assured Means it has been tested and approved by a company insider label Apr 27, 2026
@dionisio-bot dionisio-bot Bot added this pull request to the merge queue Apr 27, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 27, 2026
@dougfabris dougfabris modified the milestone: 8.5.0 Apr 27, 2026
@dougfabris dougfabris added stat: QA assured Means it has been tested and approved by a company insider and removed stat: QA assured Means it has been tested and approved by a company insider labels Apr 27, 2026
@dionisio-bot dionisio-bot Bot added this pull request to the merge queue Apr 27, 2026
Merged via the queue into RocketChat:develop with commit 0d34fc1 Apr 27, 2026
79 of 82 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community stat: QA assured Means it has been tested and approved by a company insider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants