From 522f6eb2a58bae321a39206f5bfeb991b6fcfeab Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Wed, 27 May 2026 17:43:32 +0000 Subject: [PATCH] fix(broadcast): correct org-root CTE for non-root senders (#1959) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The org-root lookup CTE in workspace_broadcast.go carried `id AS root_id` from the recursive seed, so a non-root workspace resolved its org root to itself instead of its actual topmost ancestor. This caused broadcasts from child workspaces to under-deliver (missed siblings and other org members). Port the corrected CTE shape from org_scope.go (#1954): - Seed selects only `id, parent_id` (no carried root_id alias) - Final SELECT uses `id AS root_id` on the parentless row This is an availability fix, not a security leak — recipients were still org-scoped, just under-scoped to the sender itself when the sender was not the org root. Fixes #1959 --- workspace-server/internal/handlers/workspace_broadcast.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/workspace-server/internal/handlers/workspace_broadcast.go b/workspace-server/internal/handlers/workspace_broadcast.go index 27ce7a8ea..b213cfdfe 100644 --- a/workspace-server/internal/handlers/workspace_broadcast.go +++ b/workspace-server/internal/handlers/workspace_broadcast.go @@ -85,15 +85,15 @@ func (h *BroadcastHandler) Broadcast(c *gin.Context) { var orgRootID string err = db.DB.QueryRowContext(ctx, ` WITH RECURSIVE org_chain AS ( - SELECT id, parent_id, id AS root_id + SELECT id, parent_id FROM workspaces WHERE id = $1 UNION ALL - SELECT w.id, w.parent_id, c.root_id + SELECT w.id, w.parent_id FROM workspaces w JOIN org_chain c ON w.id = c.parent_id ) - SELECT root_id FROM org_chain WHERE parent_id IS NULL LIMIT 1 + SELECT id AS root_id FROM org_chain WHERE parent_id IS NULL LIMIT 1 `, senderID).Scan(&orgRootID) if err != nil { log.Printf("Broadcast: org root lookup for %s: %v", senderID, err) -- 2.52.0