From 1c2dd4f1ddd7f6cf9d4126d32ae2d62ffa6f3c67 Mon Sep 17 00:00:00 2001 From: viettranx Date: Fri, 27 Mar 2026 12:07:14 +0700 Subject: [PATCH] fix(gateway): resolve tenant switch mismatch for non-owner users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-owner tenant switch set only tenant_hint in localStorage, but WS Path 1 non-owner and HTTP client only read tenant_id — causing silent fallback to MasterTenantID. Frontend: always set TENANT_ID on switch; keep TENANT_HINT for pairing compat. Backend: WS Path 1 non-owner now falls back to TenantHint before deprecated TenantScope. --- internal/gateway/router.go | 5 ++++- ui/web/src/components/layout/topbar.tsx | 9 ++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/gateway/router.go b/internal/gateway/router.go index 4b51c59c..2c62717b 100644 --- a/internal/gateway/router.go +++ b/internal/gateway/router.go @@ -145,7 +145,10 @@ func (r *MethodRouter) handleConnect(ctx context.Context, client *Client, req *p // Non-owner with gateway token: resolve tenant via hint or membership hint := params.TenantID if hint == "" { - hint = params.TenantScope + hint = params.TenantHint + } + if hint == "" { + hint = params.TenantScope // deprecated } tid, errCode := r.resolveTenantHint(ctx, hint, params.UserID) if errCode != "" { diff --git a/ui/web/src/components/layout/topbar.tsx b/ui/web/src/components/layout/topbar.tsx index 8f859d72..dc451f69 100644 --- a/ui/web/src/components/layout/topbar.tsx +++ b/ui/web/src/components/layout/topbar.tsx @@ -131,11 +131,10 @@ function UserMenu() { const tenantLabel = currentTenant?.name || currentTenantName || ""; const handleSwitchTenant = (_tenantId: string, slug: string) => { - // Owner: narrow scope to specific tenant - // Non-owner: use tenant_hint for pairing - if (isOwner) { - localStorage.setItem(LOCAL_STORAGE_KEYS.TENANT_ID, slug); - } else { + // Always set TENANT_ID so WS and HTTP both resolve the correct tenant. + localStorage.setItem(LOCAL_STORAGE_KEYS.TENANT_ID, slug); + // Non-owner: also set TENANT_HINT for browser pairing backward compat (Path 3a). + if (!isOwner) { localStorage.setItem(LOCAL_STORAGE_KEYS.TENANT_HINT, slug); } window.location.reload();