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; clearToken?: (key: string) => void; } export const tokenCache = { async getToken(key: string) { try { const item = await SecureStore.getItemAsync(key); return item; } catch (error) { console.error("GET_TOKEN_CACHE: ", error); await SecureStore.deleteItemAsync(key); return null; } }, async saveToken(key: string, value: string) { try { return SecureStore.setItemAsync(key, value); } catch (err) { console.error("SAVE_TOKEN_CACHE: ", err); return; } }, }; type StartOAuthFlowType = ( startOAuthFlowParams?: StartOAuthFlowParams, ) => Promise; export const googleOAuth = async (startOAuthFlow: StartOAuthFlowType) => { try { // No explicit scheme: in Expo Go this resolves to exp://... so the // browser can redirect back into the app; in a standalone build it // automatically uses the app.json scheme ("waseel"). const { createdSessionId, signUp, setActive } = await startOAuthFlow({ redirectUrl: Linking.createURL("/(root)/(tabs)/home"), }); 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.", }; } };