From a15f85a08276b3824890a1c7fbd7ede015180761 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Wed, 28 May 2025 02:24:54 +0200 Subject: [PATCH] fix: refresh returning 401 not properly logging you out of client --- composables/auth.ts | 20 +++---- utils/fetchWithApi.ts | 129 +++++++++++++++++++++++------------------- 2 files changed, 79 insertions(+), 70 deletions(-) diff --git a/composables/auth.ts b/composables/auth.ts index ccb45ca..7ce077c 100644 --- a/composables/auth.ts +++ b/composables/auth.ts @@ -30,11 +30,11 @@ export const useAuth = () => { { username, password: hashedPass, device_name: "Linux Laptop" } - }) as { access_token: string, refresh_token: string }; fetch + }) as { access_token: string, refresh_token: string }; console.log("hi"); accessToken.value = res.access_token; console.log("access token:", accessToken.value); - await fetchUser(); + //await fetchUser(); } async function logout(password: string) { @@ -60,19 +60,17 @@ export const useAuth = () => { async function refresh() { console.log("refreshing"); - try { - const res = await fetchWithApi("/auth/refresh", { - method: "POST" - }) as { access_token: string }; - accessToken.value = res.access_token; - console.log("set new access token"); - } catch (error) { - console.error("refresh error:", error); - } + const res = await fetchWithApi("/auth/refresh", { + method: "POST" + }) as any; + console.log("finished refreshing:", res); + accessToken.value = res?.access_token; + console.log("set new access token"); } async function fetchUser() { if (!accessToken.value) return; + console.log("fetchuser access token:", accessToken.value); const res = await fetchWithApi("/users/me") as UserResponse; user.value = res; return user.value; diff --git a/utils/fetchWithApi.ts b/utils/fetchWithApi.ts index c0ebf2e..11856fb 100644 --- a/utils/fetchWithApi.ts +++ b/utils/fetchWithApi.ts @@ -9,63 +9,74 @@ export default async (path: string, options: NitroFetchOptions = {}) path = path.slice(0, path.lastIndexOf("/")); } console.log("formatted path:", path); - try { - const accessToken = useCookie("access_token"); - console.log("access token:", accessToken.value); - const apiBase = useCookie("api_base").value; - const apiVersion = useRuntimeConfig().public.apiVersion; - console.log("heyoooo") - console.log("apiBase:", apiBase); - if (!apiBase) { - console.log("no api base"); - return; - } - console.log("path:", path) - const { revoke, refresh } = useAuth(); - console.log("access token 2:", accessToken.value); - - let headers: HeadersInit = {}; - - if (accessToken.value) { - headers = { - ...options.headers, - "Authorization": `Bearer ${accessToken.value}` - }; - } else { - headers = { - ...options.headers - }; - } - - let reauthFailed = false; - while (!reauthFailed) { - try { - console.log("fetching:", URL.parse(apiBase + path)); - const res = await $fetch(URL.parse(apiBase + path)!.href, { - ...options, - headers, - credentials: "include" - }); - - return res; - } catch (error: any) { - if (error?.response?.status === 401) { - if (!path.startsWith("/auth/refresh")) { - try { - await refresh(); - } catch (error: any) { - if (error?.response?.status === 401) { - reauthFailed = true; - await revoke(); - return; - } - } - } - } - throw error; - } - } - } catch (error) { - console.error("error:", error); - } + const accessToken = useCookie("access_token"); + console.log("access token:", accessToken.value); + const apiBase = useCookie("api_base").value; + const apiVersion = useRuntimeConfig().public.apiVersion; + console.log("heyoooo") + console.log("apiBase:", apiBase); + if (!apiBase) { + console.log("no api base"); + return; + } + console.log("path:", path) + const { revoke, refresh } = useAuth(); + console.log("access token 2:", accessToken.value); + + let headers: HeadersInit = {}; + + if (accessToken.value) { + headers = { + ...options.headers, + "Authorization": `Bearer ${accessToken.value}` + }; + } else { + headers = { + ...options.headers + }; + } + + let reauthFailed = false; + while (!reauthFailed) { + try { + console.log("fetching:", URL.parse(apiBase + path)); + const res = await $fetch(URL.parse(apiBase + path)!.href, { + ...options, + headers, + credentials: "include" + }); + + return res; + } catch (error: any) { + console.error("Error fetching resource"); + if (error?.response?.status === 401) { + console.log("Error status is 401"); + if (!path.startsWith("/auth/refresh")) { + console.log("Path is not refresh endpoint"); + try { + console.log("Trying to refresh"); + await refresh(); + console.log("Successfully refreshed token"); + } catch (error: any) { + console.log("Failed to refresh token"); + if (error?.response?.status === 401) { + console.log("Refresh returned 401"); + reauthFailed = true; + console.log("Revoking"); + await revoke(); + console.log("Redirecting to login"); + await navigateTo("/login"); + console.log("redirected"); + return; + } + } + } else { + console.log("Path is refresh endpoint, throwing error"); + throw error; + } + } + console.log("throwing error"); + throw error; + } + } }