From 1f0ecd696dac812d692d2f9afe157403dd29fdc5 Mon Sep 17 00:00:00 2001 From: Sanidhya Kumar Verma Date: Wed, 4 Sep 2024 11:38:47 +0000 Subject: [PATCH] OAuth implemented --- components/oauth.tsx | 27 ++++++++++++++++--- lib/auth.ts | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/components/oauth.tsx b/components/oauth.tsx index c07b184..a6bc887 100644 --- a/components/oauth.tsx +++ b/components/oauth.tsx @@ -1,15 +1,36 @@ -import { Image, Text, View } from "react-native"; +import { useOAuth } from "@clerk/clerk-expo"; +import { useCallback } from "react"; +import { Alert, Image, Text, View } from "react-native"; import { icons } from "@/constants"; import { CustomButton } from "./custom-button"; +import { googleOAuth } from "@/lib/auth"; +import { router } from "expo-router"; type OAuthProps = { title: string; }; export const OAuth = ({ title }: OAuthProps) => { - const handleGoogleSignIn = () => {}; + const { startOAuthFlow } = useOAuth({ strategy: "oauth_google" }); + + const handleGoogleOAuth = useCallback(async () => { + try { + const result = await googleOAuth(startOAuthFlow); + + if (result?.code === "session_exists") { + router.replace("/(root)/(tabs)/home"); + } + + Alert.alert( + result?.success ? "Success" : "Error", + result?.message || "You are Logged In!", + ); + } catch (err) { + console.error("OAuth error", err); + } + }, [startOAuthFlow]); return ( @@ -34,7 +55,7 @@ export const OAuth = ({ title }: OAuthProps) => { )} bgVariant="outline" textVariant="primary" - onPress={handleGoogleSignIn} + onPress={handleGoogleOAuth} /> ); diff --git a/lib/auth.ts b/lib/auth.ts index cb1ba6b..8f45769 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,5 +1,12 @@ +import type { + StartOAuthFlowParams, + StartOAuthFlowReturnType, +} from "@clerk/clerk-expo"; +import * as Linking from "expo-linking"; import * as SecureStore from "expo-secure-store"; +import { fetchAPI } from "./fetch"; + export interface TokenCache { getToken: (key: string) => Promise; saveToken: (key: string, token: string) => Promise; @@ -32,3 +39,60 @@ export const tokenCache = { } }, }; + +type StartOAuthFlowType = ( + startOAuthFlowParams?: StartOAuthFlowParams, +) => Promise; + +export const googleOAuth = async (startOAuthFlow: StartOAuthFlowType) => { + try { + const { createdSessionId, signUp, setActive } = await startOAuthFlow({ + redirectUrl: Linking.createURL("/(root)/(tabs)/home", { + scheme: "ryde", // match with scheme in app.json + }), + }); + + if (createdSessionId) { + if (setActive) { + await setActive!({ session: createdSessionId }); + + if (signUp && signUp.createdUserId) { + await fetchAPI("/(api)/user", { + method: "POST", + body: JSON.stringify({ + name: `${signUp.firstName} ${signUp.lastName}`, + email: signUp.emailAddress, + clerkId: signUp.createdUserId, + }), + }); + } + + return { + success: true, + code: "success", + message: "You are logged in.", + }; + } + + return { + success: false, + code: "failed", + message: "An error occured.", + }; + } else { + // Use signIn or signUp for next steps such as MFA + } + } catch (err) { + console.log("[OAUTH]: ", err); + + return { + success: false, + code: ( + err as { + code?: string; + } + )?.code, + message: "Internal Server Error.", + }; + } +};