Fix Xero 2FA modal not navigating after disconnecting other accountin…#89470
Conversation
…g integration on iOS
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-05-07.at.18.02.27.movAndroid: mWeb ChromeScreen.Recording.2026-05-07.at.17.59.42.moviOS: HybridAppScreen.Recording.2026-05-07.at.17.53.13.moviOS: mWeb SafariScreen.Recording.2026-05-07.at.17.57.53.movMacOS: Chrome / SafariScreen.Recording.2026-05-07.at.17.56.16.mov |
|
🚧 @lakchote has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/lakchote in version: 9.3.69-0 🚀
Bundle Size Analysis (Sentry): |
|
I reviewed the changes in this PR. It fixes an iOS-specific bug where the 2FA modal navigation callback wasn't firing due to a timing issue with No help site changes are required. This PR doesn't add or modify any user-facing features, workflows, settings, or UI labels — it only corrects existing navigation behavior on iOS. |
|
🚀 Deployed to production by https://github.com/Beamanator in version: 9.3.69-18 🚀
|
| <RequireTwoFactorAuthenticationModal | ||
| onSubmit={() => { | ||
| setIsRequire2FAModalOpen(false); | ||
| close(() => { |
|
The bug was introduced by PR #59773 — "Fix validate code modal shows blank" by Specifically, commit |
Explanation of Change
On iOS, when a workspace was already connected to another accounting integration (e.g., Sage Intacct) and the user tried to connect Xero, tapping Enable two-factor authentication did not navigate to the 2FA setup page — the navigation only happened after the user pressed the back button.
The
RequireTwoFactorAuthenticationModal'sonSubmithandler wrapped the navigation insideModal.close(callback).close()stores its callback and only runs it later whenonModalDidClose()fires fromBaseModal.hideModal(), which on iOS is triggered by RN Modal'sonDismissevent.This flow is unique because an
AccountingConnectionConfirmationModal(the "disconnect existing integration?" prompt) is shown first and unmounts right before the 2FA modal mounts. On iOS, the unmounting confirmation modal'sonDismissevent is misattributed to the freshly mounted 2FA modal, causinghideModal()to fire prematurely as a no-op (no callback queued yet). Later, when the user taps Enable 2FA,close()stores the navigation callback and callscloseTop(), butonDismissnever fires again, so the navigation callback never runs.The fix removes the
close()wrapper insrc/components/ConnectToXeroFlow/index.native.tsxand navigates directly aftersetIsRequire2FAModalOpen(false). The modal still closes on its own viaisVisiblebecoming false, and navigation does not need to wait for the close animation. This matches how the other accounting integrations (QBO, NetSuite, Sage Intacct) handle this navigation.Fixed Issues
$ #79494
PROPOSAL: #79494 (comment)
Tests
Precondition: the workspace is already connected to another accounting integration (e.g., Sage Intacct).
Offline tests
Same as Tests.
QA Steps
Precondition: the workspace is already connected to another accounting integration (e.g., Sage Intacct).
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Kapture.2026-05-04.at.08.55.04.mp4
Android: mWeb Chrome
iOS: Native
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2026-05-04.at.08.36.52.mov
iOS: mWeb Safari
MacOS: Chrome / Safari