Skip to content

Commit 409c2f4

Browse files
committed
fix(settings): cached passwordless Sync signin on mobile stuck on sign-in page
For passwordless Sync accounts on mobile (Firefox iOS), the cached signin page was stuck after clicking "Sign in" because performNavigation was false and no webchannel messages were sent. Allow in-webview navigation to the set-password page for these accounts.
1 parent d82cf8c commit 409c2f4

2 files changed

Lines changed: 41 additions & 2 deletions

File tree

packages/fxa-settings/src/pages/Signin/index.test.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,41 @@ describe('Signin component', () => {
11821182
handleNavigationSpy.mockRestore();
11831183
});
11841184

1185+
it('allows navigation for cached Sync passwordless user on mobile', async () => {
1186+
const ensureCanLinkSpy = jest.spyOn(
1187+
SigninUtils,
1188+
'ensureCanLinkAcountOrRedirect'
1189+
).mockResolvedValue(true);
1190+
const handleNavigationSpy = jest.spyOn(
1191+
SigninUtils,
1192+
'handleNavigation'
1193+
);
1194+
const cachedSigninHandler = jest
1195+
.fn()
1196+
.mockReturnValueOnce(CACHED_SIGNIN_HANDLER_RESPONSE);
1197+
const integration = createMockSigninOAuthNativeSyncIntegration({
1198+
isMobile: true,
1199+
});
1200+
render({
1201+
integration,
1202+
sessionToken: MOCK_SESSION_TOKEN,
1203+
hasPassword: false,
1204+
hasLinkedAccount: false,
1205+
cachedSigninHandler,
1206+
});
1207+
1208+
await submit();
1209+
await waitFor(() => {
1210+
expect(handleNavigationSpy).toHaveBeenCalledWith(
1211+
expect.objectContaining({
1212+
performNavigation: true,
1213+
})
1214+
);
1215+
});
1216+
ensureCanLinkSpy.mockRestore();
1217+
handleNavigationSpy.mockRestore();
1218+
});
1219+
11851220
it('shows merge warning for cached Sync passwordless signin when user accepts', async () => {
11861221
const ensureCanLinkSpy = jest.spyOn(
11871222
SigninUtils,

packages/fxa-settings/src/pages/Signin/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,13 @@ const Signin = ({
199199
: '',
200200
finishOAuthFlowHandler,
201201
queryParams: location.search,
202-
performNavigation: !integration.isFirefoxMobileClient(),
202+
// Passwordless Sync accounts (OTP or third-party auth) need to navigate
203+
// to set_password within the webview, even on mobile clients. No webchannel
204+
// messages are sent (deferred until after password creation), so the webview
205+
// must handle navigation internally.
206+
performNavigation: (isSync && !hasPassword) || !integration.isFirefoxMobileClient(),
203207
isServiceWithEmailVerification,
204-
// Sync users in the cached path are passwordless (third-party auth);
208+
// Sync users in the cached path are passwordless (third-party auth or OTP);
205209
// defer web channel messages until after password creation.
206210
handleFxaLogin: !isSync,
207211
handleFxaOAuthLogin: !isSync,

0 commit comments

Comments
 (0)