81 lines
1.9 KiB
TypeScript
81 lines
1.9 KiB
TypeScript
import { expoClient } from "@better-auth/expo/client";
|
|
import { createAuthClient } from "better-auth/react";
|
|
import { genericOAuthClient } from "better-auth/client/plugins";
|
|
import * as SecureStore from "expo-secure-store";
|
|
import {
|
|
createContext,
|
|
useContext,
|
|
useMemo,
|
|
type ReactNode,
|
|
} from "react";
|
|
|
|
type AuthClient = ReturnType<typeof createAuthClient>;
|
|
|
|
async function authFetch(input: RequestInfo | URL, init?: RequestInit) {
|
|
try {
|
|
return await fetch(input, init);
|
|
} catch (error) {
|
|
if (error instanceof Error && error.name === "AbortError") {
|
|
throw error;
|
|
}
|
|
|
|
return new Response(
|
|
JSON.stringify({
|
|
message: "Could not connect to the server.",
|
|
code: "NETWORK_ERROR",
|
|
}),
|
|
{
|
|
status: 503,
|
|
statusText: "Service Unavailable",
|
|
headers: { "content-type": "application/json" },
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
function createAppAuthClient(apiUrl: string, storagePrefix: string): AuthClient {
|
|
return createAuthClient({
|
|
baseURL: apiUrl,
|
|
fetchOptions: {
|
|
customFetchImpl: authFetch,
|
|
},
|
|
plugins: [
|
|
expoClient({
|
|
scheme: "beenvoice",
|
|
storagePrefix,
|
|
storage: SecureStore,
|
|
}),
|
|
genericOAuthClient(),
|
|
],
|
|
});
|
|
}
|
|
|
|
const AuthContext = createContext<AuthClient | null>(null);
|
|
|
|
export function AuthProvider({
|
|
apiUrl,
|
|
storagePrefix,
|
|
children,
|
|
}: {
|
|
apiUrl: string;
|
|
storagePrefix: string;
|
|
children: ReactNode;
|
|
}) {
|
|
const client = useMemo(
|
|
() => createAppAuthClient(apiUrl, storagePrefix),
|
|
[apiUrl, storagePrefix],
|
|
);
|
|
|
|
return <AuthContext.Provider value={client}>{children}</AuthContext.Provider>;
|
|
}
|
|
|
|
export function useAuthClient() {
|
|
const client = useContext(AuthContext);
|
|
if (!client) throw new Error("useAuthClient must be used within AuthProvider");
|
|
return client;
|
|
}
|
|
|
|
export function useSession() {
|
|
return useAuthClient().useSession();
|
|
}
|