From ebab3405b12d2ebb1e7314383365c83bdf5b11d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Fri, 6 Mar 2026 12:56:47 +0100 Subject: [PATCH] fix: forward session token in admin SSR load functions Admin list queries (users, videos, articles) were using getGraphQLClient without auth credentials, causing silent 403s on server-side loads. Now extract session_token cookie and pass it to getAuthClient so the backend sees the admin session on SSR requests. Co-Authored-By: Claude Sonnet 4.6 --- packages/frontend/src/lib/services.ts | 14 +++++++++----- .../src/routes/admin/articles/+page.server.ts | 5 +++-- .../src/routes/admin/articles/[id]/+page.server.ts | 5 +++-- .../src/routes/admin/users/+page.server.ts | 5 +++-- .../src/routes/admin/videos/+page.server.ts | 5 +++-- .../src/routes/admin/videos/[id]/+page.server.ts | 5 +++-- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/frontend/src/lib/services.ts b/packages/frontend/src/lib/services.ts index 2b6c195..dab33b3 100644 --- a/packages/frontend/src/lib/services.ts +++ b/packages/frontend/src/lib/services.ts @@ -1033,11 +1033,13 @@ const ADMIN_LIST_USERS_QUERY = gql` export async function adminListUsers( opts: { role?: string; search?: string; limit?: number; offset?: number } = {}, fetchFn?: typeof globalThis.fetch, + token?: string, ) { return loggedApiCall( "adminListUsers", async () => { - const data = await getGraphQLClient(fetchFn).request<{ + const client = token ? getAuthClient(token, fetchFn) : getGraphQLClient(fetchFn); + const data = await client.request<{ adminListUsers: { total: number; items: User[] }; }>(ADMIN_LIST_USERS_QUERY, opts); return data.adminListUsers; @@ -1142,9 +1144,10 @@ const ADMIN_LIST_VIDEOS_QUERY = gql` } `; -export async function adminListVideos(fetchFn?: typeof globalThis.fetch) { +export async function adminListVideos(fetchFn?: typeof globalThis.fetch, token?: string) { return loggedApiCall("adminListVideos", async () => { - const data = await getGraphQLClient(fetchFn).request<{ adminListVideos: Video[] }>( + const client = token ? getAuthClient(token, fetchFn) : getGraphQLClient(fetchFn); + const data = await client.request<{ adminListVideos: Video[] }>( ADMIN_LIST_VIDEOS_QUERY, ); return data.adminListVideos; @@ -1318,9 +1321,10 @@ const ADMIN_LIST_ARTICLES_QUERY = gql` } `; -export async function adminListArticles(fetchFn?: typeof globalThis.fetch) { +export async function adminListArticles(fetchFn?: typeof globalThis.fetch, token?: string) { return loggedApiCall("adminListArticles", async () => { - const data = await getGraphQLClient(fetchFn).request<{ adminListArticles: Article[] }>( + const client = token ? getAuthClient(token, fetchFn) : getGraphQLClient(fetchFn); + const data = await client.request<{ adminListArticles: Article[] }>( ADMIN_LIST_ARTICLES_QUERY, ); return data.adminListArticles; diff --git a/packages/frontend/src/routes/admin/articles/+page.server.ts b/packages/frontend/src/routes/admin/articles/+page.server.ts index e3bf579..d944816 100644 --- a/packages/frontend/src/routes/admin/articles/+page.server.ts +++ b/packages/frontend/src/routes/admin/articles/+page.server.ts @@ -1,6 +1,7 @@ import { adminListArticles } from "$lib/services"; -export async function load({ fetch }) { - const articles = await adminListArticles(fetch).catch(() => []); +export async function load({ fetch, cookies }) { + const token = cookies.get("session_token") || ""; + const articles = await adminListArticles(fetch, token).catch(() => []); return { articles }; } diff --git a/packages/frontend/src/routes/admin/articles/[id]/+page.server.ts b/packages/frontend/src/routes/admin/articles/[id]/+page.server.ts index c9de57b..4ac994f 100644 --- a/packages/frontend/src/routes/admin/articles/[id]/+page.server.ts +++ b/packages/frontend/src/routes/admin/articles/[id]/+page.server.ts @@ -1,8 +1,9 @@ import { adminListArticles } from "$lib/services"; import { error } from "@sveltejs/kit"; -export async function load({ params, fetch }) { - const articles = await adminListArticles(fetch).catch(() => []); +export async function load({ params, fetch, cookies }) { + const token = cookies.get("session_token") || ""; + const articles = await adminListArticles(fetch, token).catch(() => []); const article = articles.find((a) => a.id === params.id); if (!article) throw error(404, "Article not found"); return { article }; diff --git a/packages/frontend/src/routes/admin/users/+page.server.ts b/packages/frontend/src/routes/admin/users/+page.server.ts index 1895b77..3b9dff5 100644 --- a/packages/frontend/src/routes/admin/users/+page.server.ts +++ b/packages/frontend/src/routes/admin/users/+page.server.ts @@ -1,12 +1,13 @@ import { adminListUsers } from "$lib/services"; -export async function load({ fetch, url }) { +export async function load({ fetch, url, cookies }) { + const token = cookies.get("session_token") || ""; const role = url.searchParams.get("role") || undefined; const search = url.searchParams.get("search") || undefined; const offset = parseInt(url.searchParams.get("offset") || "0", 10); const limit = 50; - const result = await adminListUsers({ role, search, limit, offset }, fetch).catch(() => ({ + const result = await adminListUsers({ role, search, limit, offset }, fetch, token).catch(() => ({ items: [], total: 0, })); diff --git a/packages/frontend/src/routes/admin/videos/+page.server.ts b/packages/frontend/src/routes/admin/videos/+page.server.ts index 6869280..17a5f79 100644 --- a/packages/frontend/src/routes/admin/videos/+page.server.ts +++ b/packages/frontend/src/routes/admin/videos/+page.server.ts @@ -1,6 +1,7 @@ import { adminListVideos } from "$lib/services"; -export async function load({ fetch }) { - const videos = await adminListVideos(fetch).catch(() => []); +export async function load({ fetch, cookies }) { + const token = cookies.get("session_token") || ""; + const videos = await adminListVideos(fetch, token).catch(() => []); return { videos }; } diff --git a/packages/frontend/src/routes/admin/videos/[id]/+page.server.ts b/packages/frontend/src/routes/admin/videos/[id]/+page.server.ts index 4cfbf38..631ff54 100644 --- a/packages/frontend/src/routes/admin/videos/[id]/+page.server.ts +++ b/packages/frontend/src/routes/admin/videos/[id]/+page.server.ts @@ -1,9 +1,10 @@ import { adminListVideos, getModels } from "$lib/services"; import { error } from "@sveltejs/kit"; -export async function load({ params, fetch }) { +export async function load({ params, fetch, cookies }) { + const token = cookies.get("session_token") || ""; const [allVideos, models] = await Promise.all([ - adminListVideos(fetch).catch(() => []), + adminListVideos(fetch, token).catch(() => []), getModels(fetch).catch(() => []), ]);