-
Notifications
You must be signed in to change notification settings - Fork 335
/
Copy pathuseOAuth.ts
120 lines (100 loc) · 3.46 KB
/
useOAuth.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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') {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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,
};
}