diff --git a/client/eslint.config.js b/client/eslint.config.js index c689c75d..79a552ea 100644 --- a/client/eslint.config.js +++ b/client/eslint.config.js @@ -23,10 +23,6 @@ export default tseslint.config( "warn", { allowConstantExport: true }, ], - "@typescript-eslint/no-unused-vars": [ - "error", - { argsIgnorePattern: "^_" }, - ], }, }, ); diff --git a/client/src/App.tsx b/client/src/App.tsx index 1454811a..4c35b0ec 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -154,7 +154,14 @@ const App = () => { return migrateFromLegacyAuth(legacyToken, legacyHeaderName); } - return []; + // Default to Authorization: Bearer as the most common case + return [ + { + name: "Authorization", + value: "Bearer ", + enabled: true, + }, + ]; }); const [pendingSampleRequests, setPendingSampleRequests] = useState< @@ -243,8 +250,6 @@ const App = () => { args, sseUrl, env, - bearerToken, - headerName, customHeaders, oauthClientId, oauthScope, @@ -334,11 +339,19 @@ const App = () => { }, [transportType]); useEffect(() => { - localStorage.setItem("lastBearerToken", bearerToken); + if (bearerToken) { + localStorage.setItem("lastBearerToken", bearerToken); + } else { + localStorage.removeItem("lastBearerToken"); + } }, [bearerToken]); useEffect(() => { - localStorage.setItem("lastHeaderName", headerName); + if (headerName) { + localStorage.setItem("lastHeaderName", headerName); + } else { + localStorage.removeItem("lastHeaderName"); + } }, [headerName]); useEffect(() => { @@ -858,10 +871,6 @@ const App = () => { setEnv={setEnv} config={config} setConfig={setConfig} - bearerToken={bearerToken} - setBearerToken={setBearerToken} - headerName={headerName} - setHeaderName={setHeaderName} customHeaders={customHeaders} setCustomHeaders={setCustomHeaders} oauthClientId={oauthClientId} diff --git a/client/src/components/Sidebar.tsx b/client/src/components/Sidebar.tsx index 9806624f..c0c61fbe 100644 --- a/client/src/components/Sidebar.tsx +++ b/client/src/components/Sidebar.tsx @@ -53,12 +53,7 @@ interface SidebarProps { setSseUrl: (url: string) => void; env: Record; setEnv: (env: Record) => void; - // Legacy auth props (for backward compatibility) - bearerToken: string; - setBearerToken: (token: string) => void; - headerName?: string; - setHeaderName?: (name: string) => void; - // New custom headers support + // Custom headers support customHeaders: CustomHeadersType; setCustomHeaders: (headers: CustomHeadersType) => void; oauthClientId: string; @@ -86,10 +81,6 @@ const Sidebar = ({ setSseUrl, env, setEnv, - bearerToken: _bearerToken, - setBearerToken: _setBearerToken, - headerName: _headerName, - setHeaderName: _setHeaderName, customHeaders, setCustomHeaders, oauthClientId, diff --git a/client/src/components/__tests__/Sidebar.test.tsx b/client/src/components/__tests__/Sidebar.test.tsx index b6797d38..3a23daaf 100644 --- a/client/src/components/__tests__/Sidebar.test.tsx +++ b/client/src/components/__tests__/Sidebar.test.tsx @@ -1,10 +1,4 @@ -import { - render, - screen, - fireEvent, - act, - waitFor, -} from "@testing-library/react"; +import { render, screen, fireEvent, act } from "@testing-library/react"; import "@testing-library/jest-dom"; import { describe, it, beforeEach, jest } from "@jest/globals"; import Sidebar from "../Sidebar"; @@ -54,10 +48,6 @@ describe("Sidebar", () => { setOauthScope: jest.fn(), env: {}, setEnv: jest.fn(), - bearerToken: "", - setBearerToken: jest.fn(), - headerName: "", - setHeaderName: jest.fn(), customHeaders: [], setCustomHeaders: jest.fn(), onConnect: jest.fn(), diff --git a/client/src/lib/hooks/__tests__/useConnection.test.tsx b/client/src/lib/hooks/__tests__/useConnection.test.tsx index 8047bed8..a94f2386 100644 --- a/client/src/lib/hooks/__tests__/useConnection.test.tsx +++ b/client/src/lib/hooks/__tests__/useConnection.test.tsx @@ -649,9 +649,17 @@ describe("useConnection", () => { }); test("preserves server Authorization header when proxy auth is configured", async () => { + const customHeaders: CustomHeaders = [ + { + name: "Authorization", + value: "Bearer server-auth-token", + enabled: true, + }, + ]; + const propsWithBothAuth = { ...defaultProps, - bearerToken: "server-auth-token", + customHeaders, config: { ...DEFAULT_INSPECTOR_CONFIG, MCP_PROXY_AUTH_TOKEN: { @@ -811,14 +819,18 @@ describe("useConnection", () => { expect(headers).not.toHaveProperty("X-Disabled"); }); - test("migrates from legacy bearerToken and headerName", async () => { - const propsWithLegacyAuth = { + test("handles migrated legacy auth via custom headers", async () => { + // Simulate what App.tsx would do - migrate legacy auth to custom headers + const customHeaders: CustomHeaders = [ + { name: "X-Custom-Auth", value: "legacy-token", enabled: true }, + ]; + + const propsWithMigratedAuth = { ...defaultProps, - bearerToken: "legacy-token", - headerName: "X-Custom-Auth", + customHeaders, }; - const { result } = renderHook(() => useConnection(propsWithLegacyAuth)); + const { result } = renderHook(() => useConnection(propsWithMigratedAuth)); await act(async () => { await result.current.connect(); diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 04778157..f47f0d15 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -57,7 +57,7 @@ import { import { getMCPServerRequestTimeout } from "@/utils/configUtils"; import { InspectorConfig } from "../configurationTypes"; import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; -import { CustomHeaders, migrateFromLegacyAuth } from "../types/customHeaders"; +import { CustomHeaders } from "../types/customHeaders"; interface UseConnectionOptions { transportType: "stdio" | "sse" | "streamable-http"; @@ -65,10 +65,7 @@ interface UseConnectionOptions { args: string; sseUrl: string; env: Record; - // Legacy auth support (for backward compatibility) - bearerToken?: string; - headerName?: string; - // New custom headers support + // Custom headers support customHeaders?: CustomHeaders; oauthClientId?: string; oauthScope?: string; @@ -90,8 +87,6 @@ export function useConnection({ args, sseUrl, env, - bearerToken, - headerName, customHeaders, oauthClientId, oauthScope, @@ -384,16 +379,8 @@ export function useConnection({ // Create an auth provider with the current server URL const serverAuthProvider = new InspectorOAuthClientProvider(sseUrl); - // Handle custom headers (new approach) or legacy auth (backward compatibility) - let finalHeaders: CustomHeaders = []; - - if (customHeaders && customHeaders.length > 0) { - // Use new custom headers approach - finalHeaders = customHeaders; - } else if (bearerToken || headerName) { - // Migrate from legacy auth approach - finalHeaders = migrateFromLegacyAuth(bearerToken, headerName); - } + // Use custom headers (migration is handled in App.tsx) + let finalHeaders: CustomHeaders = customHeaders || []; // Add OAuth token if available and no custom headers are set if (finalHeaders.length === 0) { diff --git a/client/src/lib/types/customHeaders.ts b/client/src/lib/types/customHeaders.ts index 3443727a..46e7237d 100644 --- a/client/src/lib/types/customHeaders.ts +++ b/client/src/lib/types/customHeaders.ts @@ -58,9 +58,7 @@ export const migrateFromLegacyAuth = ( bearerToken?: string, headerName?: string, ): CustomHeaders => { - if (!bearerToken) { - return []; - } - - return [createHeaderFromBearerToken(bearerToken, headerName)]; + return bearerToken + ? [createHeaderFromBearerToken(bearerToken, headerName)] + : []; };