Repository navigation
Extract authToken from gap-deferred sign-in while OpenApp is in-flight - #97097
Conversation
|
@codex review |
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ 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". |
|
@eVoloshchak Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b2b6ffb6f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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/VideosMacOS: Chrome / SafariScreen.Recording.2026-07-28.at.19.16.52.mov |
|
We did not find an internal engineer to review this PR, trying to assign a random engineer to #96848 as well as to this PR... Please reach out for help on Slack if no one gets assigned! |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 inimaga 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! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/inimaga in version: 9.4.46-0 🚀
|
|
🤖 No help site changes required. This PR is a purely internal, client-side bug fix in There's no change to any user-facing feature, setting, tab label, button, or workflow — the only observable effect is that the app no longer gets stuck loading in this edge case. Nothing in No draft docs PR was created. @VickyStash, if you believe some user-facing behavior here should be documented that I've missed, let me know and I'll draft the help site changes. |
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.4.46-10 🚀
Bundle Size Analysis (Sentry): |
Explanation of Change
When a stale, gap-behind client returns to NewDot via an OldDot→NewDot
/transition?...&shortLivedAuthToken=...link, the app can get stuck on an endless loading spinner with every request returning 407, and the user is never logged out.Root cause is a single branch in
handleMissingOnyxUpdates(src/libs/actions/OnyxUpdateManager/index.ts):If user:
session.signedInWithShortLivedAuthTokenset as trueOpenAppwith the expired persisted authToken, which setsisLoadingApp: true.SignInWithShortLivedAuthTokenreturns200with the fresh authToken, but because the client is behind on updates, that response is gap-deferred intoONYX_UPDATES_FROM_SERVERinstead of applied inline.handleMissingOnyxUpdateswhileOpenAppis still in-flight (isLoadingApp === true), so it hits theif (isLoadingApp)early-return beforeupdateAuthTokenIfNecessaryever runs. The fresh authToken is skipped, and this pass runs only once — nothing retries it.OpenAppthen 407s (expired token) and itsisLoadingApp: falseclear is discarded on the failed-reauth path, so the loader stays up. Every subsequent read / Pusher connection 407s and is aborted by the short-lived-token reauth guard → endless loading, no logout.The deadlock:
OpenAppneeds a valid token to finish and clearisLoadingApp, but the fresh token can't be applied whileisLoadingAppis true.before1.mp4
Fix: extract the authToken even when the deferred update body is skipped. In the
if (isLoadingApp)branch, callupdateAuthTokenIfNecessary(onyxUpdatesFromServer)before the early-return. This still skips applying the update body whileOpenAppis in-flight (base state isn't ready yet — the original reason for the branch), but it lets a gap-deferredSignInWithShortLivedAuthTokenresponse hand over its fresh authToken.Once the token lands, the app's OpenApp retry succeeds and loading completes normally.
Fixed Issues
$ #96848
PROPOSAL: N/A
Tests
Pre-condition:
Login to the same account:
Onyx.merge('session', {signedInWithShortLivedAuthToken: true})Invalidateand close the app right away/transition?...&shortLivedAuthToken=...link.[OnyxUpdateManager] Found an authToken update while handling an Onyx update gap. Updating the authToken.Offline tests
Same, as in the Tests section
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Same, as in the Tests section
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, 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.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
MacOS: Chrome / Safari
after.mp4