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 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-22 18:15:17 -07:00
parent cc1f09b565
commit cebad27b38
2 changed files with 17 additions and 6 deletions

View File

@ -747,9 +747,14 @@ export class FolkPubsEditor extends HTMLElement {
this.render();
try {
const authHeaders: Record<string, string> = {};
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,

View File

@ -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<WSData>({
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;