import axios, { AxiosError } from "axios" let refreshPromise: Promise | null = null let waitForPromise: boolean = false export const useAuth = () => { const refreshToken = useCookie("refreshToken", { sameSite: "lax", }) const sessionToken = useCookie("sessionToken", { sameSite: "lax", }) const signin = async ( email: string, password: string, remember: boolean = false ) => { try { const res = await cfetch( "/auth/signin", { method: "POST", data: { email, password, }, }, false ) refreshToken.value = res.data.refreshToken await refreshSessionToken() await navigateTo("/") } catch (e) { if (axios.isAxiosError(e) && e.response?.data?.message) { throw new Error(e.response.data.message) } throw new Error("Failed to sign in") } } const signup = async (name: string, email: string, password: string) => {} const signout = () => {} const refreshSessionToken = async () => { if (waitForPromise) { // Force it to wait up to 50 ms for it to set refreshPromise, hopefully less for (let i = 0; i < 10; i++) { if (refreshPromise != null) { break } await new Promise((r) => setTimeout(r, 5)) } } waitForPromise = true if (refreshPromise != null) { waitForPromise = false return refreshPromise } refreshPromise = cfetch( "/auth/session", { data: { refreshToken: refreshToken.value, }, method: "POST", }, false ) .then((res) => { const token = res.data.sessionToken sessionToken.value = token refreshPromise = null return token }) .catch((e) => { refreshPromise = null sessionToken.value = null return null }) return refreshPromise } return { refreshToken, sessionToken, signin, signup, signout, refreshSessionToken, } }