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 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-09 13:51:04 -07:00
parent 494568599f
commit f9ccd18f15
2 changed files with 14 additions and 6 deletions

View File

@ -12,6 +12,7 @@
import * as Automerge from '@automerge/automerge'; import * as Automerge from '@automerge/automerge';
import { notebookSchema } from '../schemas'; import { notebookSchema } from '../schemas';
import type { DocumentId } from '../../../shared/local-first/document'; import type { DocumentId } from '../../../shared/local-first/document';
import { getAccessToken } from '../../../shared/components/rstack-identity';
import { Editor } from '@tiptap/core'; import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit'; import StarterKit from '@tiptap/starter-kit';
import Link from '@tiptap/extension-link'; import Link from '@tiptap/extension-link';
@ -654,12 +655,19 @@ Gear: EUR 400 (10%)</code></pre><p><em>Maya is tracking expenses in rF
return match ? match[0] : ""; return match ? match[0] : "";
} }
private authHeaders(extra?: Record<string, string>): Record<string, string> {
const headers: Record<string, string> = { ...extra };
const token = getAccessToken();
if (token) headers["Authorization"] = `Bearer ${token}`;
return headers;
}
private async loadNotebooks() { private async loadNotebooks() {
this.loading = true; this.loading = true;
this.render(); this.render();
try { try {
const base = this.getApiBase(); 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(); const data = await res.json();
this.notebooks = data.notebooks || []; this.notebooks = data.notebooks || [];
} catch { } catch {
@ -686,7 +694,7 @@ Gear: EUR 400 (10%)</code></pre><p><em>Maya is tracking expenses in rF
private async loadNotebookREST(id: string) { private async loadNotebookREST(id: string) {
try { try {
const base = this.getApiBase(); 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(); this.selectedNotebook = await res.json();
} catch { } catch {
this.error = "Failed to load notebook"; this.error = "Failed to load notebook";
@ -730,7 +738,7 @@ Gear: EUR 400 (10%)</code></pre><p><em>Maya is tracking expenses in rF
} }
try { try {
const base = this.getApiBase(); 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(); const data = await res.json();
this.searchResults = data.notes || []; this.searchResults = data.notes || [];
} catch { } catch {
@ -744,7 +752,7 @@ Gear: EUR 400 (10%)</code></pre><p><em>Maya is tracking expenses in rF
const base = this.getApiBase(); const base = this.getApiBase();
const res = await fetch(`${base}/api/notebooks`, { const res = await fetch(`${base}/api/notebooks`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: this.authHeaders({ "Content-Type": "application/json" }),
body: JSON.stringify({ title: "Untitled Notebook" }), body: JSON.stringify({ title: "Untitled Notebook" }),
}); });
const nb = await res.json(); const nb = await res.json();

View File

@ -1009,8 +1009,8 @@ routes.get("/", (c) => {
modules: getModuleInfoList(), modules: getModuleInfoList(),
theme: "dark", theme: "dark",
body: `<folk-notes-app space="${space}"></folk-notes-app>`, body: `<folk-notes-app space="${space}"></folk-notes-app>`,
scripts: `<script type="module" src="/modules/rnotes/folk-notes-app.js?v=2"></script>`, scripts: `<script type="module" src="/modules/rnotes/folk-notes-app.js?v=3"></script>`,
styles: `<link rel="stylesheet" href="/modules/rnotes/notes.css?v=2">`, styles: `<link rel="stylesheet" href="/modules/rnotes/notes.css?v=3">`,
})); }));
}); });