Fix SLO on web#86416
Conversation
|
@AndrewGable, I'm not sure if C+ can test this PR |
|
Ping me if we need a C+ review. |
|
Do we need to wait for https://github.com/Expensify/Web-Expensify/pull/51650 to hit production? |
|
We can test on staging but I remember there were differences between staging and prod |
|
@AndrewGable, https://github.com/Expensify/Web-Expensify/pull/51650 is on production |
|
@huult can you please C+ review this? Thank you! |
|
Yes |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / Safari |
Screen.Recording.2026-04-13.at.10.02.02.mp4@AndrewGable I can’t start the portal on local dev. Could you trigger an ad-hoc build? |
|
🚧 @mjasikowski has triggered a test Expensify/App build. You can view the workflow run here. |
|
@huult, have you set up a domain on Expensify and IdP provider on your own? I think it's necessary to test this because you have to configure your IdP to redirect to adhoc address |
This comment has been minimized.
This comment has been minimized.
|
@jnowakow I’ll check and reconfigure it soon |
|
Hmm I think you won't be able to get around callback mismatch error :/ Now I remember that it's hardcoded on backend and in order to for it to work I had to modify one variable in the code. |
|
I'm not sure you'll be able to configure this for testing, I'd just review it for code quality |
| function callSAMLSignOut(params: LogOutParams, authToken: string): Promise<void | Response<never>> { | ||
| const queryString = CONFIG.IS_HYBRID_APP ? `appversion=${pkg.version}&referer=ecash&authToken=${authToken}` : `referer=ecash&authToken=${authToken}`; | ||
| return openAuthSessionAsync(`${CONFIG.EXPENSIFY.SAML_URL}/logout?${queryString}`, CONST.SAML_REDIRECT_URL) | ||
| const expectedURL = CONFIG.IS_HYBRID_APP ? CONST.SAML_REDIRECT_URL : CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL; |
There was a problem hiding this comment.
| const expectedURL = CONFIG.IS_HYBRID_APP ? CONST.SAML_REDIRECT_URL : CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL; | |
| const expectedURL = Platform.OS !== 'web' ? CONST.SAML_REDIRECT_URL : CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL; |
@jnowakow Could you help clarify why only hybrid apps use the SAML_REDIRECT_URL, while NewDot apps use the NEW_EXPENSIFY_URL?
My understanding is that web environments should use NEW_EXPENSIFY_URL, while native mobile environments should rely on SAML_REDIRECT_URL. Is that correct?
There was a problem hiding this comment.
Exactly! Web expects url staring with https:// while mobile apps expect deep link starting with expenify://
There was a problem hiding this comment.
@jnowakow Nice, let's check my suggested change. We can't use IS_HYBRID_APP to detect web vs mobile app, since IS_HYBRID_APP is specifically used to detect hybrid apps.
There was a problem hiding this comment.
Right, it make sense!
There was a problem hiding this comment.
@huult I've applied you suggestion but without negation - I think it's simpler to understand it this way
There was a problem hiding this comment.
@jnowakow Your changes look good. Could you add test cases to cover the new updates? I think it would be useful and shouldn’t take much time. After you add them, I will approve this PR.
There was a problem hiding this comment.
@huult I've updated tests. Please take a look
| const queryString = Platform.OS === 'web' ? `referer=ecash&authToken=${authToken}` : `appversion=${pkg.version}&referer=ecash&authToken=${authToken}`; | ||
| const expectedURL = Platform.OS === 'web' ? CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL : CONST.SAML_REDIRECT_URL; |
There was a problem hiding this comment.
| const queryString = Platform.OS === 'web' ? `referer=ecash&authToken=${authToken}` : `appversion=${pkg.version}&referer=ecash&authToken=${authToken}`; | |
| const expectedURL = Platform.OS === 'web' ? CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL : CONST.SAML_REDIRECT_URL; | |
| const isWeb = getPlatform() === CONST.PLATFORM.WEB; | |
| const queryString = isWeb ? `referer=ecash&authToken=${authToken}` : `appversion=${pkg.version}&referer=ecash&authToken=${authToken}`; | |
| const expectedURL = isWeb ? CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL : CONST.SAML_REDIRECT_URL; |
Please create an isWeb constant to avoid duplication.
There was a problem hiding this comment.
There's difference between mobileweb and web so it won't work. I'll go with isWeb = Platform.OS === 'web'
There was a problem hiding this comment.
@jnowakow Could you create
const isWeb = getPlatform() === CONST.PLATFORM.WEB;
outside the callSAMLSignOut function and use isWeb for the checks to avoid duplication?
There was a problem hiding this comment.
There's difference between mobileweb and web so it won't work. I'll go with isWeb = Platform.OS === 'web'
@jnowakow Could you check the getPlatform function? I noticed that in the current codebase, we don’t use Platform.OS === 'web' directly in components and pages because getPlatform already supports all the cases you need.
| mockedOpenAuthSessionAsync.mockClear(); | ||
|
|
||
| const originalPlatformOS = Platform.OS; | ||
| Platform.OS = 'web'; |
There was a problem hiding this comment.
Could you check how we mocked getPlatform previously and follow the same approach? For example:
https://github.com/Expensify/App/blob/fce5a62db323b89c987c072de195f390bef23b85/tests/unit/pages/workspace/accounting/qbd/utilsTest.ts
|
@huult I've applied your suggestions :) |
|
@AndrewGable, C+ approved the PR, please take a look when you have a moment |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 @AndrewGable 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/AndrewGable in version: 9.3.62-0 🚀
Bundle Size Analysis (Sentry): |
|
🚀 Deployed to staging by https://github.com/AndrewGable in version: 9.3.64-0 🚀
Bundle Size Analysis (Sentry): |
|
No help site changes required. This PR fixes an internal implementation detail of SSO Single Logout (SLO) on web — specifically, it adds The relevant help site articles (Set-Up-SAML-SSO.md and Troubleshoot-SAML-SSO-Login.md) cover SAML setup, configuration, and login troubleshooting. They don't document the sign-out flow itself. Since the user-visible sign-out behavior and steps remain unchanged, no documentation updates are needed. |
|
@AndrewGable @jnowakow based on this comment it seems like this did not pass QA. This is NAB so I'll check it off. |
|
🚀 Deployed to production by https://github.com/arosiclair in version: 9.3.64-31 🚀
|
@AndrewGable
Explanation of Change
During work on #76246 one thing was missed.
expo-web-browserworks differently on mobile platforms and on web. On web it needsmaybeCompleteAuthSessionto be called from pop-up to determine that single logout request has finished and it can be closed.Fixed Issues
$ #85937
PROPOSAL: N/A
Tests
Offline tests
N/A
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
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
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
SLO.mov