// Copied from https://github.com/atinux/nuxthub-better-auth import { defu } from 'defu' import { createAuthClient } from 'better-auth/client' import type { InferSessionFromClient, InferUserFromClient, ClientOptions } from 'better-auth/client' import { organizationClient, jwtClient } from 'better-auth/client/plugins' import type { RouteLocationRaw } from 'vue-router' interface RuntimeAuthConfig { redirectUserTo: RouteLocationRaw | string redirectGuestTo: RouteLocationRaw | string } export function useAuth() { const url = useRequestURL() const headers = import.meta.server ? useRequestHeaders() : undefined const client = createAuthClient({ baseURL: url.origin, fetchOptions: { headers }, plugins: [organizationClient(), jwtClient()] }) const options = defu(useRuntimeConfig().public.auth as Partial, { redirectUserTo: '/', redirectGuestTo: '/login' }) const session = useState | null>('auth:session', () => null) const user = useState | null>('auth:user', () => null) const sessionFetching = import.meta.server ? ref(false) : useState('auth:sessionFetching', () => false) const jwt = useState('auth:jwt', () => null) async function fetchSession() { if (sessionFetching.value) { console.log('already fetching session') return } sessionFetching.value = true const { data } = await client.getSession({ fetchOptions: { headers } }) jwt.value = (await client.token()).data?.token ?? null session.value = data?.session || null user.value = data?.user || null sessionFetching.value = false return data } if (import.meta.client) { client.$store.listen('$sessionSignal', async (signal) => { if (!signal) return await fetchSession() }) } async function signOut({ redirectTo }: { redirectTo?: RouteLocationRaw } = {}) { const res = await client.signOut() if (res.error) { console.error('Error signing out:', res.error) return res } session.value = null user.value = null if (redirectTo) { await navigateTo(redirectTo) } return res } return { session, user, loggedIn: computed(() => !!session.value), signIn: client.signIn, signUp: client.signUp, signOut, organization: client.organization, options, fetchSession, client, jwt } }