Skip to content

Commit

Permalink
Deprecate useOAuth in favor of useSSO
Browse files Browse the repository at this point in the history
  • Loading branch information
LauraBeatris committed Jan 14, 2025
1 parent 865c3a3 commit 4f5378f
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 13 deletions.
4 changes: 2 additions & 2 deletions .changeset/selfish-worms-switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

Introduces support for SSO with SAML

- Rename `useOAuth` to `useSso` to support a wider range of protocols
- Update default redirect URI to from `oauth-native-callback` to `sso-native-callback`
- Introduce `useSSO` hook to support a wider range of SSO flow types
- Deprecated `useOAuth` in favor of new `useSSO` hook
3 changes: 2 additions & 1 deletion packages/expo/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export {
useUser,
} from '@clerk/clerk-react';

export * from './useSso';
export * from './useSSO';
export * from './useOAuth';
export * from './useAuth';
119 changes: 119 additions & 0 deletions packages/expo/src/hooks/useOAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useSignIn, useSignUp } from '@clerk/clerk-react';
import type { OAuthStrategy, SetActive, SignInResource, SignUpResource } from '@clerk/types';
import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';

import { errorThrower } from '../utils/errors';

export type UseOAuthFlowParams = {
strategy: OAuthStrategy;
redirectUrl?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
};

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

export type StartOAuthFlowReturnType = {
createdSessionId: string;
setActive?: SetActive;
signIn?: SignInResource;
signUp?: SignUpResource;
authSessionResult?: WebBrowser.WebBrowserAuthSessionResult;
};

/**
* @deprecated Use `useSSO` instead
*/
export function useOAuth(useOAuthParams: UseOAuthFlowParams) {
const { strategy } = useOAuthParams || {};
if (!strategy) {
return errorThrower.throw('Missing oauth strategy');
}

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

async function startOAuthFlow(startOAuthFlowParams?: StartOAuthFlowParams): Promise<StartOAuthFlowReturnType> {
if (!isSignInLoaded || !isSignUpLoaded) {
return {
createdSessionId: '',
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 =
startOAuthFlowParams?.redirectUrl ||
useOAuthParams.redirectUrl ||
AuthSession.makeRedirectUri({
path: 'oauth-native-callback',
});

await signIn.create({ strategy, redirectUrl: oauthRedirectUrl });

const { externalVerificationRedirectURL } = signIn.firstFactorVerification;

const authSessionResult = await WebBrowser.openAuthSessionAsync(
// @ts-ignore
externalVerificationRedirectURL.toString(),
oauthRedirectUrl,
);

// @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') {
return {
authSessionResult,
createdSessionId: '',
setActive,
signIn,
signUp,
};
}

const params = new URL(url).searchParams;

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') {
await signUp.create({
transfer: true,
unsafeMetadata: startOAuthFlowParams?.unsafeMetadata || useOAuthParams.unsafeMetadata,
});
createdSessionId = signUp.createdSessionId || '';
}

return {
authSessionResult,
createdSessionId,
setActive,
signIn,
signUp,
};
}

return {
startOAuthFlow,
};
}
20 changes: 10 additions & 10 deletions packages/expo/src/hooks/useSso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,36 @@ import * as WebBrowser from 'expo-web-browser';

import { errorThrower } from '../utils/errors';

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

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

export type StartSsoFlowReturnType = {
export type StartSSOFlowReturnType = {
createdSessionId: string;
setActive?: SetActive;
signIn?: SignInResource;
signUp?: SignUpResource;
authSessionResult?: WebBrowser.WebBrowserAuthSessionResult;
};

export function useSso(useSsoParams: UseSsoParams) {
const { strategy } = useSsoParams || {};
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> {
async function startFlow(startSSOFlowParams?: StartSSOParams): Promise<StartSSOFlowReturnType> {
if (!isSignInLoaded || !isSignUpLoaded) {
return {
createdSessionId: '',
Expand All @@ -52,13 +52,13 @@ export function useSso(useSsoParams: UseSsoParams) {
// For more information go to:
// https://docs.expo.dev/versions/latest/sdk/auth-session/#authsessionmakeredirecturi
const oauthRedirectUrl =
startSsoFlowParams?.redirectUrl ||
useSsoParams.redirectUrl ||
startSSOFlowParams?.redirectUrl ||
useSSOParams.redirectUrl ||
AuthSession.makeRedirectUri({
path: 'sso-native-callback',
});

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

const { externalVerificationRedirectURL } = signIn.firstFactorVerification;

Expand Down Expand Up @@ -100,7 +100,7 @@ export function useSso(useSsoParams: UseSsoParams) {
} else if (firstFactorVerification.status === 'transferable') {
await signUp.create({
transfer: true,
unsafeMetadata: startSsoFlowParams?.unsafeMetadata || useSsoParams.unsafeMetadata,
unsafeMetadata: startSSOFlowParams?.unsafeMetadata || useSSOParams.unsafeMetadata,
});
createdSessionId = signUp.createdSessionId || '';
}
Expand Down

0 comments on commit 4f5378f

Please sign in to comment.