Skip to content

Commit c164857

Browse files
MelvinBotmkhutornyi
andcommitted
Use hasAuthToken() dynamically instead of stale isAuthenticated closure
The isAuthenticated parameter is captured at call time in openReportFromDeepLink and never updates after login. When a user deep links while logged out, isAuthenticated stays false in the closure even after waitForUserSignIn resolves, so the guard added in the previous commit always evaluated to false and handleDeeplinkNavigation was never called. Switch to hasAuthToken() which reads the current auth state dynamically, fixing the deep-link-then-login flow while still preventing premature navigation before authentication. Co-authored-by: mkhutornyi <mkhutornyi@users.noreply.github.com>
1 parent 80b43c4 commit c164857

2 files changed

Lines changed: 12 additions & 11 deletions

File tree

src/libs/actions/Link.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import SCREENS from '@src/SCREENS';
3232
import {hasCompletedGuidedSetupFlowSelector} from '@src/selectors/Onboarding';
3333
import type {Beta, IntroSelected, Report} from '@src/types/onyx';
3434
import {doneCheckingPublicRoom, navigateToConciergeChat, openReport} from './Report';
35-
import {canAnonymousUserAccessRoute, isAnonymousUser, signOutAndRedirectToSignIn, waitForUserSignIn} from './Session';
35+
import {canAnonymousUserAccessRoute, hasAuthToken, isAnonymousUser, signOutAndRedirectToSignIn, waitForUserSignIn} from './Session';
3636
import {setOnboardingErrorMessage} from './Welcome';
3737

3838
let currentUserEmail = '';
@@ -364,10 +364,11 @@ function openReportFromDeepLink(
364364
}
365365
};
366366

367-
// We must check isAuthenticated before hasCompletedGuidedSetupFlowSelector because the selector
368-
// returns true for empty onboarding objects (the pre-login default state), which would cause
369-
// premature deeplink navigation before authentication completes.
370-
if ((isAuthenticated && hasCompletedGuidedSetupFlowSelector(val)) || isAnonymousUser()) {
367+
// We must check hasAuthToken() dynamically (not the stale `isAuthenticated` closure value)
368+
// before hasCompletedGuidedSetupFlowSelector because the selector returns true for empty
369+
// onboarding objects (the pre-login default state), which would cause premature deeplink
370+
// navigation before authentication completes.
371+
if ((hasAuthToken() && hasCompletedGuidedSetupFlowSelector(val)) || isAnonymousUser()) {
371372
handleDeeplinkNavigation();
372373
}
373374
});

tests/unit/OnboardingSelectorsTest.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ describe('onboardingSelectors', () => {
88
// the onboarding flow is only showed to the users with `hasCompletedGuidedSetupFlow` set to false
99
describe('hasCompletedGuidedSetupFlowSelector', () => {
1010
// Regression test: hasCompletedGuidedSetupFlowSelector returns true for empty onboarding objects (the pre-login default state).
11-
// The deeplink guard in Link.ts must combine this with an isAuthenticated check to prevent premature navigation.
12-
it('Should return true for empty onboarding (pre-login default), confirming the need for an isAuthenticated guard in deeplink navigation', () => {
11+
// The deeplink guard in Link.ts must combine this with a dynamic hasAuthToken() check to prevent premature navigation.
12+
it('Should return true for empty onboarding (pre-login default), confirming the need for an auth guard in deeplink navigation', () => {
1313
const emptyOnboarding = {} as OnyxValue<typeof ONYXKEYS.NVP_ONBOARDING>;
14-
const isAuthenticated = false;
14+
const hasToken = false; // simulates hasAuthToken() returning false before login
1515
const selectorResult = hasCompletedGuidedSetupFlowSelector(emptyOnboarding);
1616

1717
// The selector returns true for empty objects (old/migrated accounts), which is correct for its own purpose.
1818
expect(selectorResult).toBe(true);
1919

20-
// But the deeplink guard must NOT navigate when the user is not authenticated, even if the selector returns true.
21-
// This is the condition from openReportFromDeepLink: (isAuthenticated && hasCompletedGuidedSetupFlowSelector(val))
22-
expect(isAuthenticated && selectorResult).toBe(false);
20+
// But the deeplink guard must NOT navigate when the user has no auth token, even if the selector returns true.
21+
// This is the condition from openReportFromDeepLink: (hasAuthToken() && hasCompletedGuidedSetupFlowSelector(val))
22+
expect(hasToken && selectorResult).toBe(false);
2323
});
2424

2525
it('Should return true if onboarding NVP is an empty object', () => {

0 commit comments

Comments
 (0)