1
1
import { useCallback , useMemo } from "react" ;
2
2
import { Button } from "@/components/ui/button" ;
3
3
import { DebugInspectorOAuthClientProvider } from "../lib/auth" ;
4
- import {
5
- auth ,
6
- discoverOAuthMetadata ,
7
- } from "@modelcontextprotocol/sdk/client/auth.js" ;
8
- import { OAuthMetadataSchema } from "@modelcontextprotocol/sdk/shared/auth.js" ;
9
4
import { AlertCircle } from "lucide-react" ;
10
5
import { AuthDebuggerState } from "../lib/auth-types" ;
11
6
import { OAuthFlowProgress } from "./OAuthFlowProgress" ;
@@ -124,22 +119,43 @@ const AuthDebugger = ({
124
119
125
120
updateAuthState ( { isInitiatingAuth : true , statusMessage : null } ) ;
126
121
try {
127
- const serverAuthProvider = new DebugInspectorOAuthClientProvider (
128
- serverUrl ,
129
- ) ;
130
- // First discover OAuth metadata separately so we can save it
131
- const metadata = await discoverOAuthMetadata ( serverUrl ) ;
132
- if ( ! metadata ) {
133
- throw new Error ( "Failed to discover OAuth metadata" ) ;
122
+ // Step through the OAuth flow using the state machine instead of the auth() function
123
+ let currentState : AuthDebuggerState = {
124
+ ...authState ,
125
+ oauthStep : "metadata_discovery" ,
126
+ authorizationUrl : null ,
127
+ latestError : null ,
128
+ } ;
129
+
130
+ const oauthMachine = new OAuthStateMachine ( serverUrl , ( updates ) => {
131
+ // Update our temporary state during the process
132
+ currentState = { ...currentState , ...updates } ;
133
+ // But don't call updateAuthState yet
134
+ } ) ;
135
+
136
+ // Manually step through each stage of the OAuth flow
137
+ while ( currentState . oauthStep !== "complete" ) {
138
+ await oauthMachine . executeStep ( currentState ) ;
139
+ // In quick mode, we'll just redirect to the authorization URL
140
+ if (
141
+ currentState . oauthStep === "authorization_code" &&
142
+ currentState . authorizationUrl
143
+ ) {
144
+ // Open the authorization URL automatically
145
+ window . location . href = currentState . authorizationUrl ;
146
+ break ;
147
+ }
134
148
}
135
- const parsedMetadata = await OAuthMetadataSchema . parseAsync ( metadata ) ;
136
- serverAuthProvider . saveServerMetadata ( parsedMetadata ) ;
137
149
138
- await auth ( serverAuthProvider , { serverUrl : serverUrl } ) ;
150
+ // After the flow completes or reaches a user-input step, update the app state
139
151
updateAuthState ( {
152
+ ...currentState ,
140
153
statusMessage : {
141
154
type : "info" ,
142
- message : "Starting OAuth authentication process..." ,
155
+ message :
156
+ currentState . oauthStep === "complete"
157
+ ? "Authentication completed successfully"
158
+ : "Please complete authentication in the opened window and enter the code" ,
143
159
} ,
144
160
} ) ;
145
161
} catch ( error ) {
@@ -153,7 +169,7 @@ const AuthDebugger = ({
153
169
} finally {
154
170
updateAuthState ( { isInitiatingAuth : false } ) ;
155
171
}
156
- } , [ serverUrl , updateAuthState ] ) ;
172
+ } , [ serverUrl , updateAuthState , authState ] ) ;
157
173
158
174
const handleClearOAuth = useCallback ( ( ) => {
159
175
if ( serverUrl ) {
0 commit comments