feat: add default Authorization Bearer header and clean up legacy auth

- Provide "Authorization: Bearer " as default starting header
- Remove legacy auth props from components
- Centralize migration logic and fix localStorage cleanup
- Update tests for new auth architecture
This commit is contained in:
jeetul.samaiya 2025-09-15 20:19:56 +05:30
commit e08ce8cee9
7 changed files with 45 additions and 62 deletions

View file

@ -23,10 +23,6 @@ export default tseslint.config(
"warn",
{ allowConstantExport: true },
],
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
},
},
);

View file

@ -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}

View file

@ -53,12 +53,7 @@ interface SidebarProps {
setSseUrl: (url: string) => void;
env: Record<string, string>;
setEnv: (env: Record<string, string>) => 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,

View file

@ -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(),

View file

@ -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();

View file

@ -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<string, string>;
// 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) {

View file

@ -58,9 +58,7 @@ export const migrateFromLegacyAuth = (
bearerToken?: string,
headerName?: string,
): CustomHeaders => {
if (!bearerToken) {
return [];
}
return [createHeaderFromBearerToken(bearerToken, headerName)];
return bearerToken
? [createHeaderFromBearerToken(bearerToken, headerName)]
: [];
};