From 2fb92b7816d8900419981d996cfd7c6a4e00e013 Mon Sep 17 00:00:00 2001 From: ajnart <49837342+ajnart@users.noreply.github.com> Date: Fri, 3 Jul 2026 22:59:08 +0200 Subject: [PATCH] fix(workshop): harden store auth refresh --- .opencode/changelog/2026-07-03.md | 9 ++++++ apps/docs/src/components/store/useStore.ts | 35 +++++++++++++++++----- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.opencode/changelog/2026-07-03.md b/.opencode/changelog/2026-07-03.md index 866b9e783..114755375 100644 --- a/.opencode/changelog/2026-07-03.md +++ b/.opencode/changelog/2026-07-03.md @@ -17,3 +17,12 @@ - **Tests**: `pnpm --filter @homarr/docs typecheck`, `pnpm --filter @homarr/docs lint`, `pnpm --filter nextjs typecheck`, and `pnpm exec vitest run apps/docs/src/lib/store-schema.spec.ts` passed; docs lint still reports pre-existing warnings outside this fix set. - **Docs**: Updated `apps/store/README.md` with admin bootstrap variables. - **Risks**: PocketBase image pin assumes `ghcr.io/muchobien/pocketbase:0.26.2` remains the intended runtime version for this new store service. + +## PR #5984 Final Review Stability Fix + +- **Why**: Address CodeRabbit's remaining outside-diff stability comments before the final push. +- **What**: Updated `useStore` to await PocketBase auth refresh before loading workshop data and to return `null` from `requireUserId` on auth failures, allowing vote lock cleanup to run. +- **Files**: `apps/docs/src/components/store/useStore.ts`, `.opencode/changelog/2026-07-03.md`. +- **Tests**: `pnpm --filter @homarr/docs typecheck`, `pnpm --filter @homarr/docs lint`, and `pnpm exec vitest run apps/docs/src/lib/store-schema.spec.ts` passed; docs lint still reports pre-existing warnings outside this fix. +- **Docs**: Changelog updated only. +- **Risks**: Low; the change preserves existing auth refresh behavior but sequences initial loading after auth state is known. diff --git a/apps/docs/src/components/store/useStore.ts b/apps/docs/src/components/store/useStore.ts index f9d5e6a5e..add84d2d8 100644 --- a/apps/docs/src/components/store/useStore.ts +++ b/apps/docs/src/components/store/useStore.ts @@ -66,15 +66,28 @@ export const useStore = (storeUrl: string) => { }, [pb, refreshVotes]); useEffect(() => { - if (pb.authStore.isValid) - pb.collection("users") - .authRefresh() - .catch(() => pb.authStore.clear()); - void refresh(); - return pb.authStore.onChange(() => { + let cancelled = false; + const unsubscribe = pb.authStore.onChange(() => { setUser(pb.authStore.record); if (!pb.authStore.isValid) setVotes({}); }); + + const load = async () => { + if (pb.authStore.isValid) { + try { + await pb.collection("users").authRefresh(); + } catch { + pb.authStore.clear(); + } + } + if (!cancelled) await refresh(); + }; + + void load(); + return () => { + cancelled = true; + unsubscribe(); + }; }, [pb, refresh]); const ensureAuth = useCallback(async () => { @@ -93,7 +106,15 @@ export const useStore = (storeUrl: string) => { const requireUserId = useCallback( async (action: string) => { - if (!(await ensureAuth())) { + let authenticated = false; + try { + authenticated = await ensureAuth(); + } catch (caught) { + setError(errorMessage(caught, `Sign in to ${action}`)); + return null; + } + + if (!authenticated) { setError(`Sign in to ${action}`); return null; }