mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(ui): clear auth context on session invalidation; drop dead showSSOBanner
Greptile flagged that the admin_ui_disabled path cleared the token cookie but left AuthContext state populated until a hard reload. The context now exposes clearAuth(), which useAuthorized calls instead of reaching for clearTokenCookies() directly, and the decoded JWT fields are derived from the token with useMemo instead of living in their own useState slots, so nulling the token clears them for free. The userRole/userEmail reset runs in the token-sync effect rather than clearAuth itself so a stale sync queued in the same commit cannot resurrect them showSSOBanner was computed and passed through but rendered nowhere; the banner UI it fed was deleted long ago. Removed from the context, the hook, and the typed test mocks instead of restoring the login_method guard Greptile suggested, since polishing dead code is the wrong fix The admin_ui_disabled test now asserts the decoded fields are cleared after the redirect; it previously pinned the stale values, so it fails without clearAuth
This commit is contained in:
parent
3ece94bb7a
commit
24ae260c74
32 changed files with 44 additions and 162 deletions
|
|
@ -81,7 +81,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -144,7 +143,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
@ -168,7 +166,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
@ -192,7 +189,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
@ -216,7 +212,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
@ -240,7 +235,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
@ -283,7 +277,6 @@ describe("useAgents", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAgents(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ describe("useCredentials", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -129,7 +128,6 @@ describe("useCredentials", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCredentials(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -146,7 +145,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
@ -170,7 +168,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
@ -194,7 +191,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
@ -218,7 +214,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
@ -242,7 +237,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
@ -285,7 +279,6 @@ describe("useCustomers", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCustomers(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ describe("useGuardrails", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -114,7 +113,6 @@ describe("useGuardrails", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useGuardrails(), { wrapper });
|
||||
|
|
@ -138,7 +136,6 @@ describe("useGuardrails", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useGuardrails(), { wrapper });
|
||||
|
|
@ -162,7 +159,6 @@ describe("useGuardrails", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useGuardrails(), { wrapper });
|
||||
|
|
@ -186,7 +182,6 @@ describe("useGuardrails", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useGuardrails(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -182,7 +182,6 @@ describe("useKeys", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
// Reset fetch mock
|
||||
|
|
@ -273,7 +272,6 @@ describe("useKeys", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useKeys(1, 10), { wrapper });
|
||||
|
|
@ -485,7 +483,6 @@ describe("useDeletedKeys", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
// Reset fetch mock
|
||||
|
|
@ -596,7 +593,6 @@ describe("useDeletedKeys", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useDeletedKeys(1, 10), { wrapper });
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ describe("useModelsInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -164,7 +163,6 @@ describe("useModelsInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useModelsInfo(), { wrapper });
|
||||
|
|
@ -184,7 +182,6 @@ describe("useModelsInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useModelsInfo(), { wrapper });
|
||||
|
|
@ -204,7 +201,6 @@ describe("useModelsInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useModelsInfo(), { wrapper });
|
||||
|
|
@ -224,7 +220,6 @@ describe("useModelsInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useModelsInfo(), { wrapper });
|
||||
|
|
@ -258,7 +253,6 @@ describe("useModelHub", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -322,7 +316,6 @@ describe("useModelHub", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useModelHub(), { wrapper });
|
||||
|
|
@ -356,7 +349,6 @@ describe("useAllProxyModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -428,7 +420,6 @@ describe("useAllProxyModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAllProxyModels(), { wrapper });
|
||||
|
|
@ -448,7 +439,6 @@ describe("useAllProxyModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAllProxyModels(), { wrapper });
|
||||
|
|
@ -468,7 +458,6 @@ describe("useAllProxyModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useAllProxyModels(), { wrapper });
|
||||
|
|
@ -502,7 +491,6 @@ describe("useSelectedTeamModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -574,7 +562,6 @@ describe("useSelectedTeamModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSelectedTeamModels("team-1"), { wrapper });
|
||||
|
|
@ -594,7 +581,6 @@ describe("useSelectedTeamModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSelectedTeamModels("team-1"), { wrapper });
|
||||
|
|
@ -614,7 +600,6 @@ describe("useSelectedTeamModels", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSelectedTeamModels("team-1"), { wrapper });
|
||||
|
|
@ -673,7 +658,6 @@ describe("useInfiniteModelInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -802,7 +786,6 @@ describe("useInfiniteModelInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useInfiniteModelInfo(), { wrapper });
|
||||
|
|
@ -822,7 +805,6 @@ describe("useInfiniteModelInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useInfiniteModelInfo(), { wrapper });
|
||||
|
|
@ -842,7 +824,6 @@ describe("useInfiniteModelInfo", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useInfiniteModelInfo(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ describe("useOrganizations", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -145,7 +144,6 @@ describe("useOrganizations", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useOrganizations(), { wrapper });
|
||||
|
|
@ -169,7 +167,6 @@ describe("useOrganizations", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useOrganizations(), { wrapper });
|
||||
|
|
@ -193,7 +190,6 @@ describe("useOrganizations", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useOrganizations(), { wrapper });
|
||||
|
|
@ -217,7 +213,6 @@ describe("useOrganizations", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useOrganizations(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ describe("useProxyConfig", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
fetchSpy = vi.fn();
|
||||
|
|
@ -218,7 +217,6 @@ describe("useProxyConfig", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useProxyConfig(ConfigType.GENERAL_SETTINGS), { wrapper });
|
||||
|
|
@ -301,7 +299,6 @@ describe("useDeleteProxyConfigField", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
fetchSpy = vi.fn();
|
||||
|
|
@ -388,7 +385,6 @@ describe("useDeleteProxyConfigField", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useDeleteProxyConfigField(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ describe("useRouterFields", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -159,7 +158,6 @@ describe("useRouterFields", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useRouterFields(), { wrapper });
|
||||
|
|
@ -182,7 +180,6 @@ describe("useRouterFields", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useRouterFields(), { wrapper });
|
||||
|
|
@ -205,7 +202,6 @@ describe("useRouterFields", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useRouterFields(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ describe("useEditSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -113,7 +112,6 @@ describe("useEditSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useEditSSOSettings(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ describe("useSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -143,7 +142,6 @@ describe("useSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSSOSettings(), { wrapper });
|
||||
|
|
@ -164,7 +162,6 @@ describe("useSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSSOSettings(), { wrapper });
|
||||
|
|
@ -185,7 +182,6 @@ describe("useSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSSOSettings(), { wrapper });
|
||||
|
|
@ -206,7 +202,6 @@ describe("useSSOSettings", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSSOSettings(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@ describe("useStoreModelInDB", () => {
|
|||
userEmail: null,
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
} as any);
|
||||
|
||||
const { result } = renderHook(() => useStoreModelInDB(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ describe("useTags", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -146,7 +145,6 @@ describe("useTags", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTags(), { wrapper });
|
||||
|
|
@ -170,7 +168,6 @@ describe("useTags", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTags(), { wrapper });
|
||||
|
|
@ -194,7 +191,6 @@ describe("useTags", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTags(), { wrapper });
|
||||
|
|
@ -218,7 +214,6 @@ describe("useTags", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTags(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ describe("useTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -150,7 +149,6 @@ describe("useTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTeams(), { wrapper });
|
||||
|
|
@ -174,7 +172,6 @@ describe("useTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTeams(), { wrapper });
|
||||
|
|
@ -250,7 +247,6 @@ describe("useTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTeams(), { wrapper });
|
||||
|
|
@ -276,7 +272,6 @@ describe("useTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTeams(), { wrapper });
|
||||
|
|
@ -312,7 +307,6 @@ describe("useTeam", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -376,7 +370,6 @@ describe("useTeam", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useTeam("team-1"), { wrapper });
|
||||
|
|
@ -433,7 +426,6 @@ describe("useTeam", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
// Import useQueryClient to get access to query client
|
||||
|
|
@ -465,7 +457,6 @@ describe("useTeam", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const testQueryFnMissingTeamId = async () => {
|
||||
|
|
@ -651,7 +642,6 @@ describe("useDeletedTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
global.fetch = vi.fn();
|
||||
|
|
@ -719,7 +709,6 @@ describe("useDeletedTeams", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useDeletedTeams(1, 10, {}), { wrapper });
|
||||
|
|
|
|||
|
|
@ -126,7 +126,6 @@ describe("useAuthorized", () => {
|
|||
expect(result.current.userRole).toBe("Admin");
|
||||
expect(result.current.premiumUser).toBe(true);
|
||||
expect(result.current.disabledPersonalKeyCreation).toBe(false);
|
||||
expect(result.current.showSSOBanner).toBe(true);
|
||||
expect(replaceMock).not.toHaveBeenCalled();
|
||||
expect(clearTokenCookiesMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
|
@ -163,9 +162,15 @@ describe("useAuthorized", () => {
|
|||
expect(clearTokenCookiesMock).toHaveBeenCalled();
|
||||
expect(result.current.isAuthorized).toBe(false);
|
||||
expect(result.current.token).toBeNull();
|
||||
expect(result.current.accessToken).toBe("api-key-123");
|
||||
expect(result.current.userId).toBe("user-1");
|
||||
expect(result.current.userEmail).toBe("user@example.com");
|
||||
|
||||
// clearAuth must reset the context, not just the cookie, so no consumer
|
||||
// can keep acting on the revoked session until a hard reload.
|
||||
await waitFor(() => {
|
||||
expect(result.current.accessToken).toBeNull();
|
||||
});
|
||||
expect(result.current.userId).toBeNull();
|
||||
expect(result.current.userEmail).toBeNull();
|
||||
expect(result.current.userRole).toBe("Undefined Role");
|
||||
});
|
||||
|
||||
it("should redirect when token is missing", async () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { getProxyBaseUrl } from "@/components/networking";
|
||||
import { clearTokenCookies } from "@/utils/cookieUtils";
|
||||
import { buildLoginUrlWithReturn, storeReturnUrl } from "@/utils/returnUrlUtils";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useCallback, useEffect } from "react";
|
||||
|
|
@ -30,7 +29,7 @@ const useAuthorized = () => {
|
|||
accessToken,
|
||||
premiumUser,
|
||||
disabledPersonalKeyCreation,
|
||||
showSSOBanner,
|
||||
clearAuth,
|
||||
} = useAuth();
|
||||
|
||||
const isLoading = authLoading || isUIConfigLoading;
|
||||
|
|
@ -47,11 +46,11 @@ const useAuthorized = () => {
|
|||
|
||||
if (!isAuthorized) {
|
||||
if (token) {
|
||||
clearTokenCookies();
|
||||
clearAuth();
|
||||
}
|
||||
redirectToLogin();
|
||||
}
|
||||
}, [isLoading, isAuthorized, token, redirectToLogin]);
|
||||
}, [isLoading, isAuthorized, token, clearAuth, redirectToLogin]);
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
|
|
@ -63,7 +62,6 @@ const useAuthorized = () => {
|
|||
userRole,
|
||||
premiumUser: premiumUser as LegacyDecodedField,
|
||||
disabledPersonalKeyCreation: disabledPersonalKeyCreation as LegacyDecodedField,
|
||||
showSSOBanner,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ describe("useCurrentUser", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -134,7 +133,6 @@ describe("useCurrentUser", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCurrentUser(), { wrapper });
|
||||
|
|
@ -158,7 +156,6 @@ describe("useCurrentUser", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCurrentUser(), { wrapper });
|
||||
|
|
@ -182,7 +179,6 @@ describe("useCurrentUser", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCurrentUser(), { wrapper });
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ const DEFAULT_AUTH = {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
const buildUserListResponse = (page: number, totalPages: number, userCount = 2): UserListResponse => ({
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ describe("AllModelsTab", () => {
|
|||
userRole: "Admin",
|
||||
premiumUser: true,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ describe("TopKeyView", () => {
|
|||
userRole: "admin",
|
||||
premiumUser: true,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
const mockSetTopKeysLimit = vi.fn();
|
||||
|
|
|
|||
|
|
@ -517,7 +517,6 @@ describe("UsagePage", () => {
|
|||
userRole: "Admin",
|
||||
premiumUser: true,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
mockUseCurrentUser.mockReturnValue({
|
||||
data: {
|
||||
|
|
@ -651,7 +650,6 @@ describe("UsagePage", () => {
|
|||
userRole: "internal_user",
|
||||
premiumUser: true,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
renderWithProviders(<UsagePage {...defaultProps} />);
|
||||
|
|
@ -839,7 +837,6 @@ describe("UsagePage", () => {
|
|||
userRole: "Internal User",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
renderWithProviders(<UsagePage {...defaultProps} />);
|
||||
|
|
@ -865,7 +862,6 @@ describe("UsagePage", () => {
|
|||
userRole: "Internal User",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
renderWithProviders(<UsagePage {...defaultProps} />);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,6 @@ const mockAuthorizedUser = (userRole: string, userId: string, premiumUser: boole
|
|||
userRole,
|
||||
premiumUser,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
const testTeam: Team = {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ describe("CacheFieldGroup", () => {
|
|||
userRole: "Admin",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ vi.mock("@/app/(dashboard)/hooks/useAuthorized", () => ({
|
|||
userRole: "Admin",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ const { mockUseAuthorized, mockUseOrganizations } = vi.hoisted(() => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
}));
|
||||
|
||||
const mockUseOrganizations = vi.fn(() => ({
|
||||
|
|
@ -148,7 +147,6 @@ describe("Sidebar (leftnav)", () => {
|
|||
userEmail: "viewer@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
it("hides Playground from Admin Viewer (cost-incurring action)", () => {
|
||||
|
|
@ -192,7 +190,6 @@ describe("Sidebar (leftnav)", () => {
|
|||
userEmail: "orgadmin@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
mockUseOrganizations.mockReturnValueOnce({
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ describe("TeamMembersComponent", () => {
|
|||
userEmail: "test@example.com",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -322,7 +322,6 @@ const renderView = (premiumUser: boolean) => {
|
|||
token: "token_123",
|
||||
userEmail: "test@example.com",
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
return render(
|
||||
|
|
@ -353,7 +352,6 @@ describe("KeyInfoView handleKeyUpdate guardrails guard", () => {
|
|||
token: "token_123",
|
||||
userEmail: "test@example.com",
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
|
||||
render(
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ const baseAuthorized = {
|
|||
token: "test-token",
|
||||
userEmail: null,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
describe("KeyInfoView overview budget display (LIT-2845)", () => {
|
||||
|
|
|
|||
|
|
@ -143,7 +143,6 @@ describe("KeyInfoView", () => {
|
|||
token: "test-token",
|
||||
userEmail: null,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
};
|
||||
|
||||
it("should render tags", async () => {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,12 @@
|
|||
"use client";
|
||||
|
||||
import React, { createContext, useContext, useEffect, useState } from "react";
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { clearTokenCookies, getCookie } from "@/utils/cookieUtils";
|
||||
import { isJwtExpired } from "@/utils/jwtUtils";
|
||||
import { formatUserRole } from "@/utils/roles";
|
||||
import { getUiConfig, setGlobalLitellmHeaderName } from "@/components/networking";
|
||||
|
||||
function deleteCookie(name: string, path = "/") {
|
||||
document.cookie = `${name}=; Max-Age=0; Path=${path}`;
|
||||
if (name === "token") {
|
||||
clearTokenCookies();
|
||||
}
|
||||
}
|
||||
|
||||
type AuthContextValue = {
|
||||
authLoading: boolean;
|
||||
token: string | null;
|
||||
|
|
@ -23,8 +16,8 @@ type AuthContextValue = {
|
|||
accessToken: string | null;
|
||||
premiumUser: boolean;
|
||||
disabledPersonalKeyCreation: boolean;
|
||||
showSSOBanner: boolean;
|
||||
|
||||
clearAuth: () => void;
|
||||
setUserRole: React.Dispatch<React.SetStateAction<string>>;
|
||||
setUserEmail: React.Dispatch<React.SetStateAction<string | null>>;
|
||||
};
|
||||
|
|
@ -34,13 +27,22 @@ const AuthContext = createContext<AuthContextValue | null>(null);
|
|||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [authLoading, setAuthLoading] = useState(true);
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
const [userID, setUserID] = useState<string | null>(null);
|
||||
const [userRole, setUserRole] = useState(formatUserRole(""));
|
||||
const [userEmail, setUserEmail] = useState<string | null>(null);
|
||||
const [accessToken, setAccessToken] = useState<string | null>(null);
|
||||
const [premiumUser, setPremiumUser] = useState(false);
|
||||
const [disabledPersonalKeyCreation, setDisabledPersonalKeyCreation] = useState(false);
|
||||
const [showSSOBanner, setShowSSOBanner] = useState(false);
|
||||
|
||||
const decoded = useMemo<{ [k: string]: any } | null>(() => {
|
||||
if (!token || isJwtExpired(token)) return null;
|
||||
try {
|
||||
return jwtDecode(token);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}, [token]);
|
||||
|
||||
const clearAuth = useCallback(() => {
|
||||
clearTokenCookies();
|
||||
setToken(null);
|
||||
}, []);
|
||||
|
||||
// Load runtime UI config (populates proxyBaseUrl etc.) before clearing
|
||||
// authLoading, so any consumer that builds proxy-rooted URLs from authLoading=false
|
||||
|
|
@ -63,7 +65,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||
|
||||
// Clear expired/invalid token so downstream code doesn't keep trying to use it.
|
||||
if (raw && !valid) {
|
||||
deleteCookie("token", "/");
|
||||
clearTokenCookies();
|
||||
}
|
||||
|
||||
setToken(valid);
|
||||
|
|
@ -75,60 +77,42 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||
};
|
||||
}, []);
|
||||
|
||||
// Decode JWT and populate derived auth state whenever the token changes.
|
||||
// Side effects of a token change: drop tokens that fail to decode, sync the
|
||||
// mutable user fields, and apply any custom auth header. The reset branch runs
|
||||
// after any commit that nulls the token, so user fields cannot survive clearAuth
|
||||
// even if a stale sync was queued in the same commit.
|
||||
useEffect(() => {
|
||||
if (!token) {
|
||||
if (token && !decoded) {
|
||||
clearAuth();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJwtExpired(token)) {
|
||||
deleteCookie("token", "/");
|
||||
setToken(null);
|
||||
if (!decoded) {
|
||||
setUserRole(formatUserRole(""));
|
||||
setUserEmail(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let decoded: { [k: string]: any } | null = null;
|
||||
try {
|
||||
decoded = jwtDecode(token);
|
||||
} catch {
|
||||
deleteCookie("token", "/");
|
||||
setToken(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decoded) return;
|
||||
|
||||
setAccessToken(decoded.key);
|
||||
setDisabledPersonalKeyCreation(decoded.disabled_non_admin_personal_key_creation);
|
||||
setShowSSOBanner(decoded.login_method === "username_password");
|
||||
|
||||
if (decoded.user_role) {
|
||||
setUserRole(formatUserRole(decoded.user_role));
|
||||
}
|
||||
if (decoded.user_email) {
|
||||
setUserEmail(decoded.user_email);
|
||||
}
|
||||
if (decoded.premium_user) {
|
||||
setPremiumUser(decoded.premium_user);
|
||||
}
|
||||
if (decoded.auth_header_name) {
|
||||
setGlobalLitellmHeaderName(decoded.auth_header_name);
|
||||
}
|
||||
if (decoded.user_id) {
|
||||
setUserID(decoded.user_id);
|
||||
}
|
||||
}, [token]);
|
||||
}, [token, decoded, clearAuth]);
|
||||
|
||||
const value: AuthContextValue = {
|
||||
authLoading,
|
||||
token,
|
||||
userID,
|
||||
userID: decoded?.user_id ?? null,
|
||||
userRole,
|
||||
userEmail,
|
||||
accessToken,
|
||||
premiumUser,
|
||||
disabledPersonalKeyCreation,
|
||||
showSSOBanner,
|
||||
accessToken: decoded?.key ?? null,
|
||||
premiumUser: !!decoded?.premium_user,
|
||||
disabledPersonalKeyCreation: !!decoded?.disabled_non_admin_personal_key_creation,
|
||||
clearAuth,
|
||||
setUserRole,
|
||||
setUserEmail,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -147,7 +147,6 @@ vi.mock("@/app/(dashboard)/hooks/useAuthorized", () => ({
|
|||
userRole: "Admin",
|
||||
premiumUser: false,
|
||||
disabledPersonalKeyCreation: null,
|
||||
showSSOBanner: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ describe("TopKeyView", () => {
|
|||
userRole: mockProps.userRole,
|
||||
premiumUser: mockProps.premiumUser,
|
||||
disabledPersonalKeyCreation: false,
|
||||
showSSOBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue