diff --git a/ui/src/auth/useAuth.ts b/ui/src/auth/useAuth.ts index 3617b67..5ed9c7f 100644 --- a/ui/src/auth/useAuth.ts +++ b/ui/src/auth/useAuth.ts @@ -1,35 +1,11 @@ import { useLogto } from '@logto/react'; -import { useState, useEffect, useCallback } from 'react'; +import { useCallback } from 'react'; import { useOrgStore } from './useOrganization'; -interface IdTokenClaims { - sub?: string; - email?: string; - name?: string; - username?: string; - roles?: string[]; - organization_id?: string; - [key: string]: unknown; -} - export function useAuth() { - const { isAuthenticated, isLoading, getIdTokenClaims, signOut, signIn } = useLogto(); - const [claims, setClaims] = useState(null); + const { isAuthenticated, isLoading, signOut, signIn } = useLogto(); const { currentTenantId, isPlatformAdmin } = useOrgStore(); - useEffect(() => { - if (isAuthenticated) { - getIdTokenClaims().then((c) => setClaims(c as IdTokenClaims)); - } else { - setClaims(null); - } - }, [isAuthenticated, getIdTokenClaims]); - - const username = claims?.username ?? claims?.name ?? claims?.email ?? claims?.sub ?? null; - const roles = (claims?.roles as string[]) ?? []; - // tenantId is the DB UUID from the org store (set by OrgResolver after /api/me) - const tenantId = currentTenantId; - const logout = useCallback(() => { signOut(window.location.origin + '/login'); }, [signOut]); @@ -37,9 +13,7 @@ export function useAuth() { return { isAuthenticated, isLoading, - username, - roles, - tenantId, + tenantId: currentTenantId, isPlatformAdmin, logout, signIn, diff --git a/ui/src/auth/useOrganization.ts b/ui/src/auth/useOrganization.ts index 94c2030..8d12721 100644 --- a/ui/src/auth/useOrganization.ts +++ b/ui/src/auth/useOrganization.ts @@ -10,16 +10,19 @@ export interface OrgInfo { interface OrgState { currentOrgId: string | null; // Logto org ID — used for getAccessToken(resource, orgId) currentTenantId: string | null; // DB UUID — used for API calls like /api/tenants/{id} + currentOrgRoles: string[] | null; // Logto org roles for the current org (e.g. 'admin', 'member') organizations: OrgInfo[]; isPlatformAdmin: boolean; setCurrentOrg: (orgId: string | null) => void; setOrganizations: (orgs: OrgInfo[]) => void; setIsPlatformAdmin: (value: boolean) => void; + setCurrentOrgRoles: (roles: string[] | null) => void; } export const useOrgStore = create((set, get) => ({ currentOrgId: null, currentTenantId: null, + currentOrgRoles: null, organizations: [], isPlatformAdmin: false, setCurrentOrg: (orgId) => { @@ -36,4 +39,5 @@ export const useOrgStore = create((set, get) => ({ }); }, setIsPlatformAdmin: (value) => set({ isPlatformAdmin: value }), + setCurrentOrgRoles: (roles) => set({ currentOrgRoles: roles }), })); diff --git a/ui/src/components/Layout.tsx b/ui/src/components/Layout.tsx index 9bb13c1..e81eda6 100644 --- a/ui/src/components/Layout.tsx +++ b/ui/src/components/Layout.tsx @@ -100,7 +100,7 @@ function PlatformIcon() { export function Layout() { const navigate = useNavigate(); - const { username, logout, isPlatformAdmin } = useAuth(); + const { logout, isPlatformAdmin } = useAuth(); const [envSectionOpen, setEnvSectionOpen] = useState(true); const [collapsed, setCollapsed] = useState(false); @@ -166,7 +166,7 @@ export function Layout() { {/* User info + logout */} } - label={username ?? 'Account'} + label="Account" onClick={logout} /> @@ -177,7 +177,7 @@ export function Layout() { diff --git a/ui/src/hooks/usePermissions.ts b/ui/src/hooks/usePermissions.ts index a6cc005..3859511 100644 --- a/ui/src/hooks/usePermissions.ts +++ b/ui/src/hooks/usePermissions.ts @@ -1,14 +1,17 @@ -import { useAuth } from '../auth/useAuth'; +import { useOrgStore } from '../auth/useOrganization'; const ROLE_PERMISSIONS: Record = { - OWNER: ['tenant:manage', 'billing:manage', 'team:manage', 'apps:manage', 'apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug', 'settings:manage'], - ADMIN: ['team:manage', 'apps:manage', 'apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug', 'settings:manage'], - DEVELOPER: ['apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug'], - VIEWER: ['observe:read'], + 'admin': [ + 'tenant:manage', 'billing:manage', 'team:manage', 'apps:manage', + 'apps:deploy', 'secrets:manage', 'observe:read', 'observe:debug', + 'settings:manage', + ], + 'member': ['apps:deploy', 'observe:read', 'observe:debug'], }; export function usePermissions() { - const { roles } = useAuth(); + const { currentOrgRoles } = useOrgStore(); + const roles = currentOrgRoles ?? []; const permissions = new Set(); for (const role of roles) {