From 495baa5935576295deadfd51bb0898b6651c837f Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 4 Mar 2026 09:57:59 -0800 Subject: [PATCH] fix: allow unauthenticated thread builder save/share operations The space role middleware was blocking all POST/PUT requests from unauthenticated users with a 403, preventing the thread builder's save draft and share buttons from working. Added publicWrite module flag to bypass the role check for modules with public API endpoints. Also fixed saveDraft() to properly surface server errors. Co-Authored-By: Claude Opus 4.6 --- modules/rsocials/mod.ts | 2 ++ server/index.ts | 2 +- shared/module.ts | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/rsocials/mod.ts b/modules/rsocials/mod.ts index 565eac4..4b66f63 100644 --- a/modules/rsocials/mod.ts +++ b/modules/rsocials/mod.ts @@ -917,6 +917,7 @@ function renderThreadBuilderPage(space: string, threadData?: ThreadData | null): }); } + if (!res.ok) throw new Error('Save failed: ' + res.status); const data = await res.json(); if (data.id) { currentThreadId = data.id; @@ -1786,6 +1787,7 @@ export const socialsModule: RSpaceModule = { description: "Federated social feed aggregator for communities", scoping: { defaultScope: 'global', userConfigurable: true }, routes, + publicWrite: true, standaloneDomain: "rsocials.online", landingPage: renderLanding, externalApp: { url: "https://social.jeffemmett.com", name: "Postiz" }, diff --git a/server/index.ts b/server/index.ts index 5c6b7c1..0195e6c 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1248,7 +1248,7 @@ for (const mod of getAllModules()) { // Resolve caller's role for write-method blocking const method = c.req.method; - if (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE") { + if (!mod.publicWrite && (method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE")) { const token = extractToken(c.req.raw.headers); let claims: EncryptIDClaims | null = null; if (token) { diff --git a/shared/module.ts b/shared/module.ts index 13b6214..2128f85 100644 --- a/shared/module.ts +++ b/shared/module.ts @@ -108,6 +108,10 @@ export interface RSpaceModule { /** Seed template/demo data for a space. Called by /template route. */ seedTemplate?: (space: string) => void; + + /** If true, write operations (POST/PUT/PATCH/DELETE) skip the space role check. + * Use for modules whose API endpoints are publicly accessible (e.g. thread builder). */ + publicWrite?: boolean; } /** Registry of all loaded modules */