fix: quick oauth flow could not transition to token_request due to missing server metadata (#407)

* fix: quick oauth flow could not transition to token_request due to missing server metadata

* chore: prettier fix
This commit is contained in:
Kamal Fariz Mahyuddin 2025-05-16 08:22:39 -07:00 • committed by GitHub
commit c6fad3f923
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -48,6 +48,7 @@ import {
registerClient,
startAuthorization,
exchangeAuthorization,
auth,
} from "@modelcontextprotocol/sdk/client/auth.js";
import { OAuthMetadata } from "@modelcontextprotocol/sdk/shared/auth.js";
@ -64,6 +65,7 @@ const mockStartAuthorization = startAuthorization as jest.MockedFunction<
const mockExchangeAuthorization = exchangeAuthorization as jest.MockedFunction<
typeof exchangeAuthorization
>;
const mockAuth = auth as jest.MockedFunction<typeof auth>;
const sessionStorageMock = {
getItem: jest.fn(),
@ -186,6 +188,63 @@ describe("AuthDebugger", () => {
},
});
});
it("should start quick OAuth flow and properly fetch and save metadata", async () => {
// Setup the auth mock
mockAuth.mockResolvedValue("AUTHORIZED");
const updateAuthState = jest.fn();
await act(async () => {
renderAuthDebugger({ updateAuthState });
});
await act(async () => {
fireEvent.click(screen.getByText("Quick OAuth Flow"));
});
// Should first discover and save OAuth metadata
expect(mockDiscoverOAuthMetadata).toHaveBeenCalledWith(
"https://example.com",
);
// Then should call auth with the server provider
expect(mockAuth).toHaveBeenCalled();
// Check that updateAuthState was called with the right info message
expect(updateAuthState).toHaveBeenCalledWith(
expect.objectContaining({
statusMessage: {
type: "info",
message: "Starting OAuth authentication process...",
},
}),
);
});
it("should show error when quick OAuth flow fails to discover metadata", async () => {
mockDiscoverOAuthMetadata.mockRejectedValue(
new Error("Metadata discovery failed"),
);
const updateAuthState = jest.fn();
await act(async () => {
renderAuthDebugger({ updateAuthState });
});
await act(async () => {
fireEvent.click(screen.getByText("Quick OAuth Flow"));
});
// Check that updateAuthState was called with an error message
expect(updateAuthState).toHaveBeenCalledWith(
expect.objectContaining({
statusMessage: {
type: "error",
message: expect.stringContaining("Failed to start OAuth flow"),
},
}),
);
});
});
describe("Session Storage Integration", () => {