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:
parent
05e41d2ccc
commit
c6fad3f923
2 changed files with 72 additions and 1 deletions
|
|
@ -1,7 +1,11 @@
|
|||
import { useCallback, useMemo } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DebugInspectorOAuthClientProvider } from "../lib/auth";
|
||||
import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
|
||||
import {
|
||||
auth,
|
||||
discoverOAuthMetadata,
|
||||
} from "@modelcontextprotocol/sdk/client/auth.js";
|
||||
import { OAuthMetadataSchema } from "@modelcontextprotocol/sdk/shared/auth.js";
|
||||
import { AlertCircle } from "lucide-react";
|
||||
import { AuthDebuggerState } from "../lib/auth-types";
|
||||
import { OAuthFlowProgress } from "./OAuthFlowProgress";
|
||||
|
|
@ -123,6 +127,14 @@ const AuthDebugger = ({
|
|||
const serverAuthProvider = new DebugInspectorOAuthClientProvider(
|
||||
serverUrl,
|
||||
);
|
||||
// First discover OAuth metadata separately so we can save it
|
||||
const metadata = await discoverOAuthMetadata(serverUrl);
|
||||
if (!metadata) {
|
||||
throw new Error("Failed to discover OAuth metadata");
|
||||
}
|
||||
const parsedMetadata = await OAuthMetadataSchema.parseAsync(metadata);
|
||||
serverAuthProvider.saveServerMetadata(parsedMetadata);
|
||||
|
||||
await auth(serverAuthProvider, { serverUrl: serverUrl });
|
||||
updateAuthState({
|
||||
statusMessage: {
|
||||
|
|
|
|||
|
|
@ -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", () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue