Show a reconnect warning when the QBO refresh token is about to expire - #101273
Conversation
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
There was a problem hiding this comment.
Did you mean to commit that? Looks like it's causing a conflict
There was a problem hiding this comment.
Nope. I reverted the reference. Thanks.
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
Nice. This is a great product change.
| } | ||
|
|
||
| let qboTokenExpiryHint; | ||
| if (qboTokenExpiryDate) { |
There was a problem hiding this comment.
Do we also need to check && canWriteAccounting here?
There was a problem hiding this comment.
Oh, that's fair. Included it and a test to cover.
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
|
🚧 francoisl has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
Explanation of Change
The QuickBooks Online connection credentials in Onyx carry
refreshTokenExpiresAt(epoch seconds, written by the backend on connect and on every Intuit refresh), but the App never read it, so a workspace whose refresh token was days from dying looked healthy until an export failed. This PR derives a warning from that value at render time, with no new Onyx state, and shows it to workspace admins when the token expires within 7 days or has already expired without a sync failing yet:The helpers live in
AccountingUtilsand are pure (nowis a parameter) so they are easy to test. Connections whose last sync already reports an authentication error are excluded because they already show the red error state. Both reconnect entry points now passisIntuitEnterpriseSuite, so an Intuit Enterprise Suite workspace reconnects with the right scopes. The backend half of this feature, a Concierge message in #admins, is in Warn admins in-app before a QBO refresh token expires; the two PRs are independent and can deploy in any order.Fixed Issues
https://github.com/Expensify/Expensify/issues/679790
Tests
Requires a workspace connected to QuickBooks Online whose
connections.quickbooksOnline.config.credentials.refreshTokenExpiresAtis within 7 days. On the dev VM, set it throughPolicyAPI::setConnectionDataor edit the policy NVP directly; the value is epoch seconds.lastSync.isAuthenticationErrorto true with an expiry within 7 days and verify only the existing red error state shows, with no hint and no green dot.npm run test -- tests/unit/AccountingUtilsTest.ts tests/unit/PolicyUtilsTest.ts tests/unit/getWorkspaceMenuItemsTest.tsand verify all suites pass.Offline tests
N/A
QA Steps
The warning cannot be triggered on staging because Intuit issues a fresh 100-day refresh token on every sync. Please regression test the surrounding flows:
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, 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
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
Before:

After:





