diff --git a/apps/mana/apps/web/src/lib/modules/news/api.ts b/apps/mana/apps/web/src/lib/modules/news/api.ts index ff5f4132d..49b3f046c 100644 --- a/apps/mana/apps/web/src/lib/modules/news/api.ts +++ b/apps/mana/apps/web/src/lib/modules/news/api.ts @@ -25,7 +25,11 @@ import { authStore } from '$lib/stores/auth.svelte'; import { getManaApiUrl } from '$lib/api/config'; async function authHeader(): Promise> { - const token = await authStore.getAccessToken(); + // getValidToken (not getAccessToken) — runs the token through the + // tokenManager so it refreshes if expired. getAccessToken just reads + // localStorage and returns null/stale, which is what made the first + // pass at this fix still 401. sync.ts uses the same getValidToken. + const token = await authStore.getValidToken(); return token ? { Authorization: `Bearer ${token}` } : {}; } diff --git a/apps/mana/apps/web/src/lib/modules/news/queries.ts b/apps/mana/apps/web/src/lib/modules/news/queries.ts index 580e05838..9b689a8f0 100644 --- a/apps/mana/apps/web/src/lib/modules/news/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/news/queries.ts @@ -69,13 +69,21 @@ export function toCategory(local: LocalCategory): Category { } export function toPreferences(local: LocalPreferences): Preferences { + // Force the array fields back to arrays even if decryption left an + // encrypted blob string in place (vault locked at boot). Without this + // guard `{#each prefs.selectedTopics}` iterates the encrypted string + // char-by-char and crashes `TOPIC_LABELS[topic].emoji` on render. return { id: local.id, - selectedTopics: local.selectedTopics ?? [], - blockedSources: local.blockedSources ?? [], - preferredLanguages: local.preferredLanguages ?? ['de', 'en'], - topicWeights: local.topicWeights ?? {}, - sourceWeights: local.sourceWeights ?? {}, + selectedTopics: Array.isArray(local.selectedTopics) ? local.selectedTopics : [], + blockedSources: Array.isArray(local.blockedSources) ? local.blockedSources : [], + preferredLanguages: Array.isArray(local.preferredLanguages) + ? local.preferredLanguages + : ['de', 'en'], + topicWeights: + local.topicWeights && typeof local.topicWeights === 'object' ? local.topicWeights : {}, + sourceWeights: + local.sourceWeights && typeof local.sourceWeights === 'object' ? local.sourceWeights : {}, onboardingCompleted: local.onboardingCompleted ?? false, }; }