Skip to content

Commit

Permalink
chore(expo): Make useOAuth base implementation to be the native one
Browse files Browse the repository at this point in the history
  • Loading branch information
octoper committed Jun 12, 2024
1 parent 04bc38b commit b84424e
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 124 deletions.
117 changes: 0 additions & 117 deletions packages/expo/src/hooks/useOAuth/useOAuth.native.ts

This file was deleted.

116 changes: 109 additions & 7 deletions packages/expo/src/hooks/useOAuth/useOAuth.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,117 @@
import type { OAuthStrategy } from '@clerk/types';
import { Platform } from 'react-native';

import { errorThrower } from '../../utils/errors';
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';

export type UseOAuthFlowParams = {
strategy: OAuthStrategy;
redirectUrl?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
};
export function useOAuth(_useOAuthParams: UseOAuthFlowParams) {
if (Platform.OS === 'web') {
throw errorThrower.throw('useOAuth hook is not supported in Web');

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

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

export function useOAuth(useOAuthParams: UseOAuthFlowParams) {
const { strategy } = useOAuthParams || {};
if (!strategy) {
throw new Error('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,
);

console.log('authSessionResult', authSessionResult);

// @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') {
console.log('signIn', signIn);
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,
};
}
15 changes: 15 additions & 0 deletions packages/expo/src/hooks/useOAuth/useOAuth.web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { OAuthStrategy } from '@clerk/types';
import { Platform } from 'react-native';

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

export type UseOAuthFlowParams = {
strategy: OAuthStrategy;
redirectUrl?: string;
unsafeMetadata?: SignUpUnsafeMetadata;
};
export function useOAuth(_useOAuthParams: UseOAuthFlowParams) {
if (Platform.OS === 'web') {
throw errorThrower.throw('useOAuth hook is not supported in Web');
}
}

0 comments on commit b84424e

Please sign in to comment.