Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-sso-browser-dismissal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/expo': patch
---

Fix SSO/OAuth browser not being dismissed after authentication completes. On some platforms the in-app browser would remain open in the background after a successful flow, causing subsequent sign-in attempts to fail or appear frozen. `WebBrowser.dismissBrowser()` is now called unconditionally after `openAuthSessionAsync` resolves in both `useSSO` and `useOAuth`.
16 changes: 10 additions & 6 deletions packages/expo/src/hooks/useOAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,17 @@ export function useOAuth(useOAuthParams: UseOAuthFlowParams) {

const { externalVerificationRedirectURL } = signIn.firstFactorVerification;

const authSessionResult = await WebBrowserModule.openAuthSessionAsync(
// @ts-ignore
externalVerificationRedirectURL.toString(),
oauthRedirectUrl,
);
let authSessionResult: WebBrowser.WebBrowserAuthSessionResult;
try {
authSessionResult = await WebBrowserModule.openAuthSessionAsync(
// @ts-ignore
externalVerificationRedirectURL.toString(),
oauthRedirectUrl,
);
} finally {
WebBrowserModule.dismissBrowser();
}

// @ts-expect-error
const { type, url } = authSessionResult || {};

// TODO: Check all the possible AuthSession results
Expand Down
19 changes: 14 additions & 5 deletions packages/expo/src/hooks/useSSO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,20 @@ export function useSSO() {
return errorThrower.throw('Missing external verification redirect URL for SSO flow');
}

const authSessionResult = await WebBrowserModule.openAuthSessionAsync(
externalVerificationRedirectURL.toString(),
redirectUrl,
authSessionOptions,
);
let authSessionResult: WebBrowser.WebBrowserAuthSessionResult;
try {
authSessionResult = await WebBrowserModule.openAuthSessionAsync(
externalVerificationRedirectURL.toString(),
redirectUrl,
authSessionOptions,
);
} finally {
// Ensure the browser is always dismissed after the auth session completes or fails.
// Without this, the browser can remain open in the background on some platforms,
// causing subsequent SSO attempts to fail or the browser to appear frozen.
WebBrowserModule.dismissBrowser();
}

if (authSessionResult.type !== 'success' || !authSessionResult.url) {
return {
createdSessionId: null,
Expand Down
Loading