type SessionResponse = { sessionToken: string expireAt: string } export const useAuth = () => { const sessionToken = useCookie("sessionToken", { sameSite: "lax", maxAge: 60 * 60, }) let refreshPromise: Promise | null = null const signin = async (email: string, password: string, remember = false) => { try { await $fetch("/api/auth/signin", { method: "POST", body: { email, password, remember: Boolean(remember) }, }) if (!(await refreshSessionToken())) throw new Error("Unable to create session") await navigateTo("/") } catch (error: any) { throw new Error(error?.data?.message || error?.statusMessage || "Failed to sign in") } } const signup = async (name: string, email: string, password: string) => { try { await $fetch("/api/auth/register", { method: "POST", body: { name, email, password }, }) if (!(await refreshSessionToken())) throw new Error("Unable to create session") await navigateTo("/") } catch (error: any) { throw new Error(error?.data?.message || error?.statusMessage || "Failed to sign up") } } const signout = async () => { try { await $fetch("/api/auth/signout", { method: "POST" }) } finally { sessionToken.value = null } } const refreshSessionToken = async (): Promise => { if (refreshPromise) return refreshPromise refreshPromise = $fetch("/api/auth/session", { method: "POST", }) .then((response) => { sessionToken.value = response.sessionToken return response.sessionToken }) .catch(() => { sessionToken.value = null return null }) .finally(() => { refreshPromise = null }) return refreshPromise } return { sessionToken, signin, signup, signout, refreshSessionToken, } }