fix(ui): Address Greptile review feedback on proxy switcher

- Fix removeConnection to use setProxyBaseUrl(null) instead of
  setProxyBaseUrl(defaultConn.url), consistent with switchConnection
- Replace hardcoded "Admin" role for remote proxies with actual role
  fetched from /user/info endpoint on the remote proxy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Krrish Dholakia 2026-03-02 13:59:16 -08:00
parent 22f2055841
commit 0f2a416b6f
2 changed files with 45 additions and 6 deletions

View file

@ -1,11 +1,11 @@
"use client";
import { getProxyBaseUrl } from "@/components/networking";
import { getProxyBaseUrl, getGlobalLitellmHeaderName } from "@/components/networking";
import { clearTokenCookies, getCookie } from "@/utils/cookieUtils";
import { checkTokenValidity, decodeToken } from "@/utils/jwtUtils";
import { useProxyConnection } from "@/contexts/ProxyConnectionContext";
import { useRouter } from "next/navigation";
import { useEffect, useMemo } from "react";
import { useEffect, useMemo, useState } from "react";
import { useUIConfig } from "./uiConfig/useUIConfig";
function formatUserRole(userRole: string) {
@ -52,6 +52,42 @@ const useAuthorized = () => {
const isRemoteAuthorized = isRemoteProxy && !!activeConnection?.apiKey;
const isAuthorized = isRemoteAuthorized || (isTokenValid && !uiConfig?.admin_ui_disabled);
// Fetch actual user info from remote proxy to get the real role
const [remoteUserInfo, setRemoteUserInfo] = useState<{
user_role: string | null;
user_id: string | null;
user_email: string | null;
}>({ user_role: null, user_id: null, user_email: null });
useEffect(() => {
if (!isRemoteProxy || !activeConnection?.apiKey) return;
const fetchRemoteUserInfo = async () => {
try {
const url = `${getProxyBaseUrl()}/user/info`;
const response = await fetch(url, {
method: "GET",
headers: {
[getGlobalLitellmHeaderName()]: `Bearer ${activeConnection.apiKey}`,
"Content-Type": "application/json",
},
});
if (response.ok) {
const data = await response.json();
setRemoteUserInfo({
user_role: data?.user_role ?? null,
user_id: data?.user_id ?? null,
user_email: data?.user_email ?? null,
});
}
} catch {
// Silently fail — role will fall back to "Admin"
}
};
fetchRemoteUserInfo();
}, [isRemoteProxy, activeConnection?.apiKey]); // eslint-disable-line react-hooks/exhaustive-deps
// Single useEffect for all redirect logic
useEffect(() => {
if (isLoading) return;
@ -74,9 +110,11 @@ const useAuthorized = () => {
isAuthorized,
token: isAuthorized ? token : null,
accessToken: effectiveAccessToken,
userId: isRemoteProxy ? null : (decoded?.user_id ?? null),
userEmail: isRemoteProxy ? null : (decoded?.user_email ?? null),
userRole: isRemoteProxy ? "Admin" : formatUserRole(decoded?.user_role),
userId: isRemoteProxy ? (remoteUserInfo.user_id ?? null) : (decoded?.user_id ?? null),
userEmail: isRemoteProxy ? (remoteUserInfo.user_email ?? null) : (decoded?.user_email ?? null),
userRole: isRemoteProxy
? formatUserRole(remoteUserInfo.user_role ?? "proxy_admin")
: formatUserRole(decoded?.user_role),
premiumUser: decoded?.premium_user ?? null,
disabledPersonalKeyCreation: decoded?.disabled_non_admin_personal_key_creation ?? null,
showSSOBanner: isRemoteProxy ? false : decoded?.login_method === "username_password",

View file

@ -160,7 +160,8 @@ export const ProxyConnectionProvider: React.FC<ProxyConnectionProviderProps> = (
const defaultConn = connections.find((c) => c.isDefault);
if (defaultConn) {
saveActiveId(defaultConn.id);
setProxyBaseUrl(defaultConn.url);
// Clear the override so getProxyBaseUrl() falls back to window.location.origin
setProxyBaseUrl(null);
window.location.reload();
}
}