From cebad27b38682b589a0ada464796ba63749237af Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Sun, 22 Mar 2026 18:15:17 -0700 Subject: [PATCH] fix(auth): pass JWT secret to all SDK verify calls + add auth header to rpubs generate evaluateSpaceAccess and authenticateWSUpgrade were calling the SDK without the secret option, forcing remote verification. Also adds auth header to rpubs editor generate fetch (was getting 401 on private spaces). Co-Authored-By: Claude Opus 4.6 --- modules/rpubs/components/folk-pubs-editor.ts | 7 ++++++- server/index.ts | 16 +++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/modules/rpubs/components/folk-pubs-editor.ts b/modules/rpubs/components/folk-pubs-editor.ts index 3274454..42a6243 100644 --- a/modules/rpubs/components/folk-pubs-editor.ts +++ b/modules/rpubs/components/folk-pubs-editor.ts @@ -747,9 +747,14 @@ export class FolkPubsEditor extends HTMLElement { this.render(); try { + const authHeaders: Record = {}; + try { + const s = JSON.parse(localStorage.getItem("encryptid_session") || "{}"); + if (s?.accessToken) authHeaders["Authorization"] = `Bearer ${s.accessToken}`; + } catch {} const res = await fetch(`/${this._spaceSlug}/rpubs/api/generate`, { method: "POST", - headers: { "Content-Type": "application/json" }, + headers: { "Content-Type": "application/json", ...authHeaders }, body: JSON.stringify({ content, title: titleInput?.value?.trim() || undefined, diff --git a/server/index.ts b/server/index.ts index 45e22f9..0f2addc 100644 --- a/server/index.ts +++ b/server/index.ts @@ -42,6 +42,11 @@ import type { SpaceAuthConfig } from "@encryptid/sdk/server"; import { verifyToken, extractToken } from "./auth"; import type { EncryptIDClaims } from "./auth"; +const spaceAuthOpts = () => ({ + getSpaceConfig, + ...(process.env.JWT_SECRET ? { secret: process.env.JWT_SECRET } : {}), +}); + // ── Module system ── import { registerModule, getAllModules, getModuleInfoList, getModule } from "../shared/module"; import { canvasModule } from "../modules/rspace/mod"; @@ -583,7 +588,7 @@ app.post("/api/communities/demo/reset", async (c) => { app.get("/api/communities/:slug/shapes", async (c) => { const slug = c.req.param("slug"); const token = extractToken(c.req.raw.headers); - const access = await evaluateSpaceAccess(slug, token, "GET", { getSpaceConfig }); + const access = await evaluateSpaceAccess(slug, token, "GET", spaceAuthOpts()); if (!access.allowed) return c.json({ error: access.reason }, access.claims ? 403 : 401); @@ -602,7 +607,7 @@ app.post("/api/communities/:slug/shapes", async (c) => { if (!isInternalCall) { const token = extractToken(c.req.raw.headers); - const access = await evaluateSpaceAccess(slug, token, "POST", { getSpaceConfig }); + const access = await evaluateSpaceAccess(slug, token, "POST", spaceAuthOpts()); if (!access.allowed) return c.json({ error: access.reason }, access.claims ? 403 : 401); if (access.readOnly) return c.json({ error: "Write access required to add shapes" }, 403); } @@ -632,7 +637,7 @@ app.patch("/api/communities/:slug/shapes/:shapeId", async (c) => { if (!isInternalCall) { const token = extractToken(c.req.raw.headers); - const access = await evaluateSpaceAccess(slug, token, "PATCH", { getSpaceConfig }); + const access = await evaluateSpaceAccess(slug, token, "PATCH", spaceAuthOpts()); if (!access.allowed) return c.json({ error: access.reason }, access.claims ? 403 : 401); } @@ -676,7 +681,7 @@ app.get("/api/space-access/:slug", async (c) => { app.get("/api/communities/:slug", async (c) => { const slug = c.req.param("slug"); const token = extractToken(c.req.raw.headers); - const access = await evaluateSpaceAccess(slug, token, "GET", { getSpaceConfig }); + const access = await evaluateSpaceAccess(slug, token, "GET", spaceAuthOpts()); if (!access.allowed) return c.json({ error: access.reason }, access.claims ? 403 : 401); @@ -2670,7 +2675,8 @@ const server = Bun.serve({ const communitySlug = url.pathname.split("/")[2]; if (communitySlug) { const spaceConfig = await getSpaceConfig(communitySlug); - const claims = await authenticateWSUpgrade(req); + const wsAuthOpts = process.env.JWT_SECRET ? { secret: process.env.JWT_SECRET } : {}; + const claims = await authenticateWSUpgrade(req, wsAuthOpts); let readOnly = false; let spaceRole: WSData['spaceRole'] = null;