Skip to content

[$250] Registered label has changed to true even though the second authentication is fail #82044

Closed

Description

@lanitochka17

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: v9.3.16-4
Reproducible in staging?: Yes
Reproducible in production?: N/A - new feature, doesn't exist in prod
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #79473
Email or phone of affected tester (no customers): N/A
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Android 13 / Xiaomi Poco F5, iOS 15.8.3 / iPhone 7 Plus
App Component: Other

Action Performed:

  1. Open the Expensify native app
  2. Navigate to the Settings > Troubleshoot
  3. Tap the "Test" button next to the "Biometrics (Not registered)" text
  4. Fill the magic code input
  5. Tap on the "Got it" button
  6. Authenticate the correct fingerprint in the first authentication
  7. Authenticate the incorrect fingerprint in the second authentication
  8. Close the fingerprint modal
  9. Tap on the "Got it" button

Expected Result:

Registered label should not be changed to true, the Biometrics status should be Not Registered

Actual Result:

Registered label has changed to true even though the second authentication is fail
Note:

  • In Troubleshoot, the Biometrics status changes to Registered
  • In Security > Face/fingerprint & passkeys, there is a Revoke access button

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome / Safari

Screenshots/Videos

Bug7073748_1770738057464.81937_-_PR79473_-_Registered_label_has_changed_to_true_even_though_the_second_authentication_is_fail.mp4

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @Pujan92
Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~022021321407118902864
  • Upwork Job ID: 2021321407118902864
  • Last Price Increase: 2026-02-10

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    ExternalAdded to denote the issue can be worked on by a contributor
    on Feb 10, 2026
  2. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Feb 10, 2026
  3. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Feb 10, 2026
  4. melvin-bot commented on Feb 10, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #79473

  5. melvin-bot commented on Feb 10, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  6. melvin-bot commented on Feb 10, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @Pujan92 (External)

  7. melvin-bot commented on Feb 10, 2026

    @melvin-bot

    Triggered auto assignment to @dylanexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

  8. changed the title [-]Registered label has changed to true even though the second authentication is fail[/-] [+][$250] Registered label has changed to true even though the second authentication is fail[/+] on Feb 10, 2026
  9. melvin-bot commented on Feb 10, 2026

    @melvin-bot
  10. github-actions commented on Feb 10, 2026

    @github-actions
    Contributor

    👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  11. OSBotify commented on Feb 10, 2026

    @OSBotify
    Contributor

    🔍 Investigation Summary

    Classification: Frontend bug
    Causing PR: #79473 - "[ECUK In-App 3DS] Implement MultifactorAuthenticationContext, useNativeBiometrics & helpers" by @JakubKorytko (High confidence)
    Related Issues: None

    Recommendation: REVERT

    This PR introduced a new biometric authentication system that has a logic flaw in how registration status is tracked and displayed. The bug occurs because the "Registered" label reflects whether credentials exist on the server (after first authentication), rather than the overall authentication flow success state.

    Labels: Keeping DeployBlockerCash (this is an App PR that needs to be reverted to fix the issue)

    📋 Detailed Analysis

    Evidence

    The bug report clearly states that PR #79473 is the cause, and my investigation confirms this. The PR was merged on Feb 6, 2026, and the bug appears on staging but not production (new feature).

    The test steps show:

    1. First authentication succeeds (registration completes)
    2. Second authentication fails (wrong fingerprint)
    3. Expected: Status should remain "Not Registered"
    4. Actual: Status shows "Registered"

    Verification

    I examined the key files modified in PR #79473:

    File: src/components/MultifactorAuthentication/Context/Main.tsx (line 215)

    dispatch({type: 'SET_REGISTRATION_COMPLETE', payload: true});

    This sets registration as complete after the first successful authentication.

    File: src/selectors/Account.ts (line 12)

    const hasBiometricsRegisteredSelector = (data: OnyxEntry<Account>) => 
        data?.multifactorAuthenticationPublicKeyIDs && 
        data.multifactorAuthenticationPublicKeyIDs.length > 0;

    This determines "Registered" status based solely on whether public key IDs exist in the Account object.

    File: src/components/TestToolMenu.tsx (line 35)

    const [hasBiometricsRegistered = false] = useOnyx(ONYXKEYS.ACCOUNT, {
        canBeMissing: true, 
        selector: hasBiometricsRegisteredSelector
    });

    This displays the "Registered" status in the Troubleshoot menu.

    Root Cause

    The biometric authentication flow has two phases:

    1. Registration: Generate and store keys, send public key to server
    2. Authorization: Verify the user can authenticate with those keys

    The bug occurs because:

    • After the first authentication succeeds, multifactorAuthenticationPublicKeyIDs is populated with the registered key
    • The "Registered" status is determined by checking if this array has any items
    • When the second authentication fails, the key ID remains in the array (registration was successful)
    • Therefore, the UI shows "Registered" even though the authorization step failed

    The expected behavior for a test scenario should be that if ANY part of the authentication flow fails, the overall registration should not be marked as complete. The current implementation conflates "has registered credentials" with "authentication flow completed successfully."

  12. added and removed
    DeployBlockerCashThis issue or pull request should block deployment
    on Feb 10, 2026
  13. lakchote commented on Feb 10, 2026

    @lakchote
    Contributor

    Demoting, it's a new feature

  14. rafecolton commented on Feb 10, 2026

    @rafecolton
    Member

    This is actually not a bug, the feature is working exactly how it is supposed to. Once the first authentication succeeds, you are registered. The second one just tests authentication. If authentication succeeds, you see the unlock illustration, and if not, you see the error page. (The error page is generic for now because we haven't implemented scenario-specific ones.)

  15. rafecolton commented on Feb 10, 2026

    @rafecolton
    Member

    @lanitochka17 can you please point me to where the testing guidelines are written for this so @joekaufmanexpensify or I can update them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2EngineeringExternalAdded to denote the issue can be worked on by a contributorHelp WantedApply this label when an issue is open to proposals by contributors

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions