From 3152ec660c3aa51f79071f76d65fc10f96484441 Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Fri, 15 May 2026 20:28:08 +0200 Subject: [PATCH] ui: Display the authenticated userId by configured userIdClaim Signed-off-by: Marco Franssen --- helm/kagent/templates/ui-deployment.yaml | 4 ++++ ui/src/app/actions/auth.ts | 4 ++++ ui/src/components/AppInitializer.tsx | 11 +++++++++++ ui/src/contexts/AuthContext.tsx | 9 ++++++--- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/helm/kagent/templates/ui-deployment.yaml b/helm/kagent/templates/ui-deployment.yaml index 05d1b86b8..af35e6dac 100644 --- a/helm/kagent/templates/ui-deployment.yaml +++ b/helm/kagent/templates/ui-deployment.yaml @@ -64,6 +64,10 @@ spec: - name: SSO_REDIRECT_PATH value: {{ .Values.ui.auth.ssoRedirectPath | default "/oauth2/start" | quote }} {{- end }} + {{- with .Values.controller.auth.userIdClaim }} + - name: KAGENT_USER_ID_CLAIM + value: {{ . | quote }} + {{- end }} {{- with .Values.ui.additionalForwardedHeaders }} - name: KAGENT_ADDITIONAL_FORWARDED_HEADERS value: {{ join "," . | quote }} diff --git a/ui/src/app/actions/auth.ts b/ui/src/app/actions/auth.ts index 95baf5fad..60777b94c 100644 --- a/ui/src/app/actions/auth.ts +++ b/ui/src/app/actions/auth.ts @@ -28,3 +28,7 @@ export async function getCurrentUser(): Promise { return claims as CurrentUser; } + +export async function getUserIdClaim(): Promise { + return process.env.KAGENT_USER_ID_CLAIM || "sub"; +} diff --git a/ui/src/components/AppInitializer.tsx b/ui/src/components/AppInitializer.tsx index fd016a88e..e52f1ce62 100644 --- a/ui/src/components/AppInitializer.tsx +++ b/ui/src/components/AppInitializer.tsx @@ -3,6 +3,8 @@ import React, { useEffect, useState } from "react"; import { usePathname } from "next/navigation"; import { OnboardingWizard } from "./onboarding/OnboardingWizard"; +import { useAuth } from "@/contexts/AuthContext"; +import { useUserStore } from "@/lib/userStore"; const LOCAL_STORAGE_KEY = "kagent-onboarding"; @@ -10,6 +12,15 @@ export function AppInitializer({ children }: { children: React.ReactNode }) { /** `null` = not read yet (must match server + first client paint to avoid hydration mismatch) */ const [isOnboarding, setIsOnboarding] = useState(null); const pathname = usePathname(); + const { user, userIdClaim } = useAuth(); + const setUserId = useUserStore((s) => s.setUserId); + + useEffect(() => { + const identity = user?.[userIdClaim] as string | undefined; + if (identity) { + setUserId(identity); + } + }, [user, userIdClaim, setUserId]); useEffect(() => { const hasOnboarded = localStorage.getItem(LOCAL_STORAGE_KEY) === "true"; diff --git a/ui/src/contexts/AuthContext.tsx b/ui/src/contexts/AuthContext.tsx index bef4168d5..1a58cabc8 100644 --- a/ui/src/contexts/AuthContext.tsx +++ b/ui/src/contexts/AuthContext.tsx @@ -1,10 +1,11 @@ "use client"; import React, { createContext, useContext, useEffect, useState, ReactNode } from "react"; -import { getCurrentUser, CurrentUser } from "@/app/actions/auth"; +import { getCurrentUser, getUserIdClaim, CurrentUser } from "@/app/actions/auth"; interface AuthContextValue { user: CurrentUser | null; + userIdClaim: string; isLoading: boolean; error: Error | null; refetch: () => Promise; @@ -14,6 +15,7 @@ const AuthContext = createContext(undefined); export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); + const [userIdClaim, setUserIdClaim] = useState("sub"); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); @@ -21,8 +23,9 @@ export function AuthProvider({ children }: { children: ReactNode }) { setIsLoading(true); setError(null); try { - const currentUser = await getCurrentUser(); + const [currentUser, claim] = await Promise.all([getCurrentUser(), getUserIdClaim()]); setUser(currentUser); + setUserIdClaim(claim); } catch (e) { setError(e instanceof Error ? e : new Error("Failed to fetch user")); } finally { @@ -35,7 +38,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { }, []); return ( - + {children} );