diff --git a/client/src/App.tsx b/client/src/App.tsx index 6c9ae333..00fa6f46 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -162,14 +162,8 @@ const App = () => { return migrateFromLegacyAuth(legacyToken, legacyHeaderName); } - // Default to Authorization: Bearer as the most common case - return [ - { - name: "Authorization", - value: "Bearer ", - enabled: true, - }, - ]; + // Default to empty array + return []; }); const [pendingSampleRequests, setPendingSampleRequests] = useState< diff --git a/client/src/lib/hooks/__tests__/useConnection.test.tsx b/client/src/lib/hooks/__tests__/useConnection.test.tsx index 4946cdda..8d8a1f8b 100644 --- a/client/src/lib/hooks/__tests__/useConnection.test.tsx +++ b/client/src/lib/hooks/__tests__/useConnection.test.tsx @@ -97,9 +97,10 @@ jest.mock("@modelcontextprotocol/sdk/client/auth.js", () => ({ })); // Mock the toast hook +const mockToast = jest.fn(); jest.mock("@/lib/hooks/useToast", () => ({ useToast: () => ({ - toast: jest.fn(), + toast: mockToast, }), })); @@ -940,6 +941,13 @@ describe("useConnection", () => { expect(headers).toHaveProperty("Authorization", "Bearer mock-token"); // Should not have the x-custom-auth-headers since Authorization is standard expect(headers).not.toHaveProperty("x-custom-auth-headers"); + + // Should show toast notification for empty Authorization header + expect(mockToast).toHaveBeenCalledWith({ + title: "Invalid Authorization Header", + description: expect.any(String), + variant: "destructive", + }); }); test("prioritizes custom headers over legacy auth", async () => { diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 70ae5acf..fa03496d 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -400,6 +400,23 @@ export function useConnection({ // Use custom headers (migration is handled in App.tsx) let finalHeaders: CustomHeaders = customHeaders || []; + // Check for empty Authorization headers and show validation error + const hasEmptyAuthHeader = finalHeaders.some( + (header) => + header.enabled && + header.name.trim().toLowerCase() === "authorization" && + (!header.value.trim() || header.value.trim() === "Bearer"), + ); + + if (hasEmptyAuthHeader) { + toast({ + title: "Invalid Authorization Header", + description: + "Authorization header is enabled but empty. Please add a token or disable the header. It will be added automatically.", + variant: "destructive", + }); + } + // Check if we need to inject OAuth token // This handles both empty headers and default "Bearer " placeholder headers const isEmptyAuthHeader = (header: CustomHeaders[number]) =>