From f9ccd18f15ecf5bf3aed702da63a24ecfb1d0d28 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Mon, 9 Mar 2026 13:51:04 -0700 Subject: [PATCH] fix(rnotes): add auth headers to all REST API calls folk-notes-app was missing Authorization headers on all fetch calls, causing 403 errors on non-demo spaces. Now uses getAccessToken() from rstack-identity consistently. Co-Authored-By: Claude Opus 4.6 --- modules/rnotes/components/folk-notes-app.ts | 16 ++++++++++++---- modules/rnotes/mod.ts | 4 ++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/rnotes/components/folk-notes-app.ts b/modules/rnotes/components/folk-notes-app.ts index 66d5555..78fc6b6 100644 --- a/modules/rnotes/components/folk-notes-app.ts +++ b/modules/rnotes/components/folk-notes-app.ts @@ -12,6 +12,7 @@ import * as Automerge from '@automerge/automerge'; import { notebookSchema } from '../schemas'; import type { DocumentId } from '../../../shared/local-first/document'; +import { getAccessToken } from '../../../shared/components/rstack-identity'; import { Editor } from '@tiptap/core'; import StarterKit from '@tiptap/starter-kit'; import Link from '@tiptap/extension-link'; @@ -654,12 +655,19 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF return match ? match[0] : ""; } + private authHeaders(extra?: Record): Record { + const headers: Record = { ...extra }; + const token = getAccessToken(); + if (token) headers["Authorization"] = `Bearer ${token}`; + return headers; + } + private async loadNotebooks() { this.loading = true; this.render(); try { const base = this.getApiBase(); - const res = await fetch(`${base}/api/notebooks`); + const res = await fetch(`${base}/api/notebooks`, { headers: this.authHeaders() }); const data = await res.json(); this.notebooks = data.notebooks || []; } catch { @@ -686,7 +694,7 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF private async loadNotebookREST(id: string) { try { const base = this.getApiBase(); - const res = await fetch(`${base}/api/notebooks/${id}`); + const res = await fetch(`${base}/api/notebooks/${id}`, { headers: this.authHeaders() }); this.selectedNotebook = await res.json(); } catch { this.error = "Failed to load notebook"; @@ -730,7 +738,7 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF } try { const base = this.getApiBase(); - const res = await fetch(`${base}/api/notes?q=${encodeURIComponent(query)}`); + const res = await fetch(`${base}/api/notes?q=${encodeURIComponent(query)}`, { headers: this.authHeaders() }); const data = await res.json(); this.searchResults = data.notes || []; } catch { @@ -744,7 +752,7 @@ Gear: EUR 400 (10%)

Maya is tracking expenses in rF const base = this.getApiBase(); const res = await fetch(`${base}/api/notebooks`, { method: "POST", - headers: { "Content-Type": "application/json" }, + headers: this.authHeaders({ "Content-Type": "application/json" }), body: JSON.stringify({ title: "Untitled Notebook" }), }); const nb = await res.json(); diff --git a/modules/rnotes/mod.ts b/modules/rnotes/mod.ts index a5c13bd..75e1be3 100644 --- a/modules/rnotes/mod.ts +++ b/modules/rnotes/mod.ts @@ -1009,8 +1009,8 @@ routes.get("/", (c) => { modules: getModuleInfoList(), theme: "dark", body: ``, - scripts: ``, - styles: ``, + scripts: ``, + styles: ``, })); });