From 7ad5666b9af5f51225cc3ba284fb3f2924a6ebbe Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Tue, 24 Mar 2026 12:38:01 -0700 Subject: [PATCH] fix: enforce enabledModules check on module root path The sub-path middleware (/:space/:moduleId/*) already blocked disabled modules, but the root path (/:space/:moduleId) didn't. Now both paths consistently check enabledModules before allowing access. Co-Authored-By: Claude Opus 4.6 --- server/index.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/server/index.ts b/server/index.ts index 1f3bec6..8a2922b 100644 --- a/server/index.ts +++ b/server/index.ts @@ -2374,11 +2374,24 @@ for (const mod of getAllModules()) { return next(); }); - // Onboarding: show landing page for empty modules (root page only) + // Onboarding + enabledModules check for root path (root page only) if (mod.id !== "rspace") { app.use(`/:space/${mod.id}`, async (c, next) => { const space = c.req.param("space"); - if (!space || space === "demo" || space === "api" || space.includes(".")) return next(); + if (!space || space === "api" || space.includes(".")) return next(); + + // Block disabled modules (same check as sub-path middleware) + await loadCommunity(space); + const spaceDoc = getDocumentData(space); + if (spaceDoc?.meta?.enabledModules && !spaceDoc.meta.enabledModules.includes(mod.id)) { + const accept = c.req.header("Accept") || ""; + if (accept.includes("text/html")) { + return c.redirect(`/${space}/rspace`); + } + return c.json({ error: "Module not enabled for this space" }, 404); + } + + if (space === "demo") return next(); if (c.req.method !== "GET") return next(); const path = c.req.path; const root = `/${space}/${mod.id}`;