From c674785c82584c2bae3a6fd89e7f218f8e139c2a Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Thu, 9 Apr 2026 23:33:30 +0200 Subject: [PATCH] fix: merge global + org-scoped token scopes in OrgResolver Vendor's platform:admin scope comes from a global Logto role, which is only present in the non-org-scoped token. OrgResolver now fetches both the global token and the org-scoped token, merging their scopes. This ensures vendor users see platform:admin and land on the vendor console. Co-Authored-By: Claude Opus 4.6 (1M context) --- ui/src/auth/OrgResolver.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/ui/src/auth/OrgResolver.tsx b/ui/src/auth/OrgResolver.tsx index e60e3db..aa53373 100644 --- a/ui/src/auth/OrgResolver.tsx +++ b/ui/src/auth/OrgResolver.tsx @@ -66,12 +66,21 @@ export function OrgResolver({ children }: { children?: React.ReactNode }) { }; try { - const token = await (currentOrgId - ? getAccessToken(config.logtoResource, currentOrgId) - : getAccessToken(config.logtoResource) - ).catch(() => undefined); + // Always fetch the global (non-org) token — it contains global role scopes + // like platform:admin from the saas-vendor role. + const globalToken = await getAccessToken(config.logtoResource).catch(() => undefined); + const globalScopes = extractScopes(globalToken); - setScopes(new Set(extractScopes(token))); + // If an org is selected, also fetch org-scoped token for org-level scopes + // (tenant:manage, apps:manage, etc.) + let orgScopes: string[] = []; + if (currentOrgId) { + const orgToken = await getAccessToken(config.logtoResource, currentOrgId).catch(() => undefined); + orgScopes = extractScopes(orgToken); + } + + // Merge both scope sets + setScopes(new Set([...globalScopes, ...orgScopes])); } catch { setScopes(new Set()); }