From 8b2c14e480ec7f858da8ef1dc8d5769cbfc4191a Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Tue, 13 Oct 2026 10:27:33 +0200 Subject: [PATCH] fix: block browser back from leaving onboarding React Navigation 7.2+ dispatches GO_BACK instead of RESET on browser back, bypassing OnboardingGuard. --- src/libs/Navigation/guards/OnboardingGuard.ts | 4 +++- .../Navigation/guards/OnboardingGuard.test.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/guards/OnboardingGuard.ts b/src/libs/Navigation/guards/OnboardingGuard.ts index c7a731798167..1a2960ca9a81 100644 --- a/src/libs/Navigation/guards/OnboardingGuard.ts +++ b/src/libs/Navigation/guards/OnboardingGuard.ts @@ -150,7 +150,9 @@ function isCurrentlyOnTwoFactorSetupRoute(state: NavigationState): boolean { } function shouldPreventReset(state: NavigationState, action: NavigationAction) { - if (action.type !== CONST.NAVIGATION_ACTIONS.RESET || !action?.payload) { + // Browser back that pops the last history entry dispatches GO_BACK instead of RESET, and it reaches the root only when it would leave onboarding + const isGoBack = action.type === CONST.NAVIGATION.ACTION_TYPE.GO_BACK; + if (!isGoBack && (action.type !== CONST.NAVIGATION_ACTIONS.RESET || !action?.payload)) { return false; } diff --git a/tests/unit/Navigation/guards/OnboardingGuard.test.ts b/tests/unit/Navigation/guards/OnboardingGuard.test.ts index 990fa7d497ad..5dfcb87f27e0 100644 --- a/tests/unit/Navigation/guards/OnboardingGuard.test.ts +++ b/tests/unit/Navigation/guards/OnboardingGuard.test.ts @@ -139,6 +139,24 @@ describe('OnboardingGuard', () => { expect(result.reason).toBe('Cannot reset to non-onboarding screen while on onboarding'); } }); + + it('should BLOCK GO_BACK action when user is on onboarding', () => { + // Given a user who is currently on the onboarding purpose screen and has not yet completed onboarding + const onboardingState: NavigationState = { + key: 'root', + index: 0, + routeNames: [SCREENS.ONBOARDING.PURPOSE], + routes: [{key: 'purpose', name: SCREENS.ONBOARDING.PURPOSE}], + stale: false, + type: 'root', + }; + + // When the browser back button pops the last history entry, which React Navigation dispatches as GO_BACK + const result = OnboardingGuard.evaluate(onboardingState, {type: CONST.NAVIGATION.ACTION_TYPE.GO_BACK}, authenticatedContext); + + // Then the action should be blocked because going back from onboarding would close the modal without finishing it + expect(result.type).toBe('BLOCK'); + }); }); describe('skip onboarding conditions', () => {