From 5b87f7d7cb095ac186162e8a8f3967182aa8023b Mon Sep 17 00:00:00 2001 From: Santhi Prakash <38608178+santhiprakash@users.noreply.github.com> Date: Tue, 8 Sep 2026 17:51:00 +0530 Subject: [PATCH] fix(hub): always clear auth store when encountring 4xx after token expires (#2310) Co-authored-by: henrygd --- internal/site/src/lib/api.ts | 20 ++++++++++++++++++-- internal/site/src/lib/systemsManager.ts | 7 +------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/internal/site/src/lib/api.ts b/internal/site/src/lib/api.ts index 79f4b127..55245b4e 100644 --- a/internal/site/src/lib/api.ts +++ b/internal/site/src/lib/api.ts @@ -4,7 +4,7 @@ import { basePath } from "@/components/router" import { toast } from "@/components/ui/use-toast" import type { ChartTimes, UserSettings } from "@/types" import { $alerts, $allSystemsById, $allSystemsByName, $userSettings } from "./stores" -import { chartTimeData } from "./utils" +import { chartTimeData, debounce } from "./utils" /** PocketBase JS Client */ export const pb = new PocketBase(basePath) @@ -12,7 +12,7 @@ export const pb = new PocketBase(basePath) export const isAdmin = () => pb.authStore.record?.role === "admin" export const isReadOnlyUser = () => pb.authStore.record?.role === "readonly" -export const verifyAuth = () => { +const verifyAuth = () => { pb.collection("users") .authRefresh() .catch(() => { @@ -25,6 +25,22 @@ export const verifyAuth = () => { }) } +const verifyAuthDebounced = debounce(verifyAuth, 100) + +// verify the session whenever any API request returns a 4xx response (e.g. an +// expired JWT). The auth-refresh endpoint is excluded to avoid a loop, since +// it returns 401 itself when the token is no longer valid. +pb.afterSend = (response, data) => { + if ( + (response.status === 401 || response.status === 403) && + pb.authStore.token && + !response.url.includes("auth-refresh") + ) { + verifyAuthDebounced() + } + return data +} + /** Logs the user out by clearing the auth store and unsubscribing from realtime updates. */ export function logOut() { $allSystemsByName.set({}) diff --git a/internal/site/src/lib/systemsManager.ts b/internal/site/src/lib/systemsManager.ts index 2ee58602..f3c87fbf 100644 --- a/internal/site/src/lib/systemsManager.ts +++ b/internal/site/src/lib/systemsManager.ts @@ -1,6 +1,6 @@ /** biome-ignore-all lint/suspicious/noAssignInExpressions: it's fine :) */ import type { PreinitializedMapStore } from "nanostores" -import { pb, verifyAuth } from "@/lib/api" +import { pb } from "@/lib/api" import { $allSystemsById, $allSystemsByName, @@ -167,11 +167,6 @@ export async function subscribe() { export async function refresh() { try { const records = await fetchSystems() - if (!records.length) { - // No systems found, verify authentication - verifyAuth() - return - } for (const record of records) { add(record) }