Skip to content

Commit

Permalink
Refactor implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
LauraBeatris committed Jan 14, 2025
1 parent 0cfdb3a commit 9dfbd23
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .changeset/selfish-worms-switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
'@clerk/clerk-expo': minor
---

Introduces support for SSO with SAML
Introduce support for SSO with SAML

- Introduce `useSSO` hook to support a wider range of SSO flow types
- Deprecated `useOAuth` in favor of new `useSSO` hook
- Deprecate `useOAuth` in favor of new `useSSO` hook
Original file line number Diff line number Diff line change
Expand Up @@ -7,102 +7,93 @@ import { errorThrower } from '../utils/errors';

export type UseSSOParams = {
strategy: OAuthStrategy | EnterpriseSSOStrategy;
redirectUrl?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
redirectUrl?: string;
};

export type StartSSOParams = {
redirectUrl?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
identifier?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
redirectUrl?: string;
};

export type StartSSOFlowReturnType = {
createdSessionId: string;
/**
* Session ID created upon sign-in completion, or null if incomplete.
* If incomplete, use signIn or signUp for next steps like MFA.
*/
createdSessionId: string | null;
setActive?: SetActive;
signIn?: SignInResource;
signUp?: SignUpResource;
authSessionResult?: WebBrowser.WebBrowserAuthSessionResult;
};

export function useSSO(useSSOParams: UseSSOParams) {
const { strategy } = useSSOParams || {};
if (!strategy) {
return errorThrower.throw('Missing strategy');
}

const { signIn, setActive, isLoaded: isSignInLoaded } = useSignIn();
const { signUp, isLoaded: isSignUpLoaded } = useSignUp();

async function startFlow(startSSOFlowParams?: StartSSOParams): Promise<StartSSOFlowReturnType> {
if (!isSignInLoaded || !isSignUpLoaded) {
return {
createdSessionId: '',
createdSessionId: null,
signIn,
signUp,
setActive,
};
}

// Create a redirect url for the current platform and environment.
//
// This redirect URL needs to be whitelisted for your Clerk production instance via
// https://clerk.com/docs/reference/backend-api/tag/Redirect-URLs#operation/CreateRedirectURL
//
// For more information go to:
// https://docs.expo.dev/versions/latest/sdk/auth-session/#authsessionmakeredirecturi
const oauthRedirectUrl =
let createdSessionId = signIn.createdSessionId;

const redirectUrl =
startSSOFlowParams?.redirectUrl ||
useSSOParams.redirectUrl ||
AuthSession.makeRedirectUri({
path: 'sso-native-callback',
});

await signIn.create({ strategy, redirectUrl: oauthRedirectUrl, identifier: startSSOFlowParams?.identifier });
await signIn.create({
strategy: useSSOParams.strategy,
redirectUrl,
identifier: startSSOFlowParams?.identifier,
});

const { externalVerificationRedirectURL } = signIn.firstFactorVerification;

if (!externalVerificationRedirectURL) {
return errorThrower.throw('Missing external verification redirect URL for SSO flow');
return errorThrower.throw(
'Missing external verification redirect URL for SSO flow. This indicates an API issue - please contact support for assistance.',
);
}

const authSessionResult = await WebBrowser.openAuthSessionAsync(
externalVerificationRedirectURL.toString(),
oauthRedirectUrl,
redirectUrl,
);

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

// TODO: Check all the possible AuthSession results
// https://docs.expo.dev/versions/latest/sdk/auth-session/#returns-7
if (type !== 'success') {
if (authSessionResult.type !== 'success' || !authSessionResult.url) {
return {
authSessionResult,
createdSessionId: '',
createdSessionId,
setActive,
signIn,
signUp,
};
}

const params = new URL(url).searchParams;
const params = new URL(authSessionResult.url).searchParams;
const rotatingTokenNonce = params.get('rotating_token_nonce');
if (!rotatingTokenNonce) {
return errorThrower.throw(
'Missing rotating_token_nonce in SSO callback. This indicates an API issue - please contact support for assistance.',
);
}

const rotatingTokenNonce = params.get('rotating_token_nonce') || '';
await signIn.reload({ rotatingTokenNonce });

const { status, firstFactorVerification } = signIn;

let createdSessionId = '';

if (status === 'complete') {
createdSessionId = signIn.createdSessionId!;
} else if (firstFactorVerification.status === 'transferable') {
if (signIn.firstFactorVerification.status === 'transferable') {
await signUp.create({
transfer: true,
unsafeMetadata: startSSOFlowParams?.unsafeMetadata || useSSOParams.unsafeMetadata,
});
createdSessionId = signUp.createdSessionId || '';
createdSessionId = signUp.createdSessionId;
}

return {
Expand Down

0 comments on commit 9dfbd23

Please sign in to comment.