@@ -22,10 +22,6 @@ import { CheckCircle2, Circle, ExternalLink } from "lucide-react";
22
22
23
23
interface AuthDebuggerProps {
24
24
sseUrl : string ;
25
- bearerToken : string ;
26
- headerName : string ;
27
- setBearerToken : ( token : string ) => void ;
28
- setHeaderName : ( headerName : string ) => void ;
29
25
onBack : ( ) => void ;
30
26
}
31
27
@@ -46,20 +42,43 @@ class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
46
42
}
47
43
}
48
44
49
- const AuthDebugger = ( {
50
- sseUrl,
51
- bearerToken,
52
- headerName,
53
- setBearerToken,
54
- setHeaderName,
55
- onBack,
56
- } : AuthDebuggerProps ) => {
45
+ const validateOAuthMetadata = (
46
+ metadata : OAuthMetadata | null ,
47
+ toast : ( arg0 : object ) => void ,
48
+ ) : OAuthMetadata => {
49
+ if ( ! metadata ) {
50
+ toast ( {
51
+ title : "Error" ,
52
+ description : "Can't advance without successfully fetching metadata" ,
53
+ variant : "destructive" ,
54
+ } ) ;
55
+ throw new Error ( "OAuth metadata not found" ) ;
56
+ }
57
+ return metadata ;
58
+ } ;
59
+
60
+ const validateClientInformation = async (
61
+ provider : DebugInspectorOAuthClientProvider ,
62
+ toast : ( arg0 : object ) => void ,
63
+ ) : Promise < OAuthClientInformation > => {
64
+ const clientInformation = await provider . clientInformation ( ) ;
65
+
66
+ if ( ! clientInformation ) {
67
+ toast ( {
68
+ title : "Error" ,
69
+ description : "Can't advance without successful client registration" ,
70
+ variant : "destructive" ,
71
+ } ) ;
72
+ throw new Error ( "OAuth client information not found" ) ;
73
+ }
74
+ return clientInformation ;
75
+ } ;
76
+
77
+ const AuthDebugger = ( { sseUrl, onBack } : AuthDebuggerProps ) => {
57
78
const { toast } = useToast ( ) ;
58
79
const [ isInitiatingAuth , setIsInitiatingAuth ] = useState ( false ) ;
59
80
const [ oauthTokens , setOAuthTokens ] = useState < OAuthTokens | null > ( null ) ;
60
81
const [ loading , setLoading ] = useState ( true ) ;
61
- const [ localHeaderName , setLocalHeaderName ] = useState ( headerName ) ;
62
- const [ localBearerToken , setLocalBearerToken ] = useState ( bearerToken ) ;
63
82
const [ oauthStep , setOAuthStep ] = useState < OAuthStep > ( "not_started" ) ;
64
83
const [ oauthMetadata , setOAuthMetadata ] = useState < OAuthMetadata | null > (
65
84
null ,
@@ -82,7 +101,7 @@ const AuthDebugger = ({
82
101
const parsedTokens = await OAuthTokensSchema . parseAsync (
83
102
JSON . parse ( tokens ) ,
84
103
) ;
85
- setOauthTokens ( parsedTokens ) ;
104
+ setOAuthTokens ( parsedTokens ) ;
86
105
setOAuthStep ( "complete" ) ;
87
106
}
88
107
}
@@ -154,24 +173,30 @@ const AuthDebugger = ({
154
173
const parsedMetadata = await OAuthMetadataSchema . parseAsync ( metadata ) ;
155
174
setOAuthMetadata ( parsedMetadata ) ;
156
175
} else if ( oauthStep === "metadata_discovery" ) {
176
+ const metadata = validateOAuthMetadata ( oauthMetadata , toast ) ;
177
+
157
178
setOAuthStep ( "client_registration" ) ;
158
179
159
180
const fullInformation = await registerClient ( sseUrl , {
160
- metadata : oauthMetadata ,
181
+ metadata,
161
182
clientMetadata : provider . clientMetadata ,
162
183
} ) ;
163
184
164
185
provider . saveClientInformation ( fullInformation ) ;
165
186
} else if ( oauthStep === "client_registration" ) {
187
+ const metadata = validateOAuthMetadata ( oauthMetadata , toast ) ;
188
+ const clientInformation = await validateClientInformation (
189
+ provider ,
190
+ toast ,
191
+ ) ;
166
192
setOAuthStep ( "authorization_redirect" ) ;
167
193
// This custom implementation captures the OAuth flow step by step
168
194
// First, get or register the client
169
195
try {
170
- const clientInformation = await provider . clientInformation ( ) ;
171
196
const { authorizationUrl, codeVerifier } = await startAuthorization (
172
197
sseUrl ,
173
198
{
174
- metadata : oauthMetadata ,
199
+ metadata,
175
200
clientInformation,
176
201
redirectUrl : provider . redirectUrl ,
177
202
} ,
@@ -194,15 +219,27 @@ const AuthDebugger = ({
194
219
} ) ;
195
220
}
196
221
} else if ( oauthStep === "authorization_code" ) {
197
- // This is after we enter the code.
222
+ if ( ! authorizationCode || authorizationCode . trim ( ) === "" ) {
223
+ toast ( {
224
+ title : "Error" ,
225
+ description : "You need to provide an authorization code" ,
226
+ variant : "destructive" ,
227
+ } ) ;
228
+ return ;
229
+ }
230
+ // We have a code, continue to token request
198
231
setOAuthStep ( "token_request" ) ;
199
232
} else if ( oauthStep === "token_request" ) {
200
233
const codeVerifier = provider . codeVerifier ( ) ;
201
- const clientInformation = await provider . clientInformation ( ) ;
234
+ const metadata = validateOAuthMetadata ( oauthMetadata , toast ) ;
235
+ const clientInformation = await validateClientInformation (
236
+ provider ,
237
+ toast ,
238
+ ) ;
202
239
203
240
// const clientInformation = await provider.clientInformation();
204
241
const tokens = await exchangeAuthorization ( sseUrl , {
205
- metadata : oauthMetadata ,
242
+ metadata,
206
243
clientInformation,
207
244
authorizationCode,
208
245
codeVerifier,
@@ -279,34 +316,7 @@ const AuthDebugger = ({
279
316
}
280
317
} ;
281
318
282
- const handleSaveManualAuth = ( ) => {
283
- setBearerToken ( localBearerToken ) ;
284
- setHeaderName ( localHeaderName ) ;
285
- toast ( {
286
- title : "Settings Saved" ,
287
- description :
288
- "Your authentication settings have been saved for the next connection" ,
289
- } ) ;
290
- } ;
291
-
292
- const getOAuthStatus = ( ) => {
293
- if ( ! oauthTokens ) return "Not authenticated" ;
294
-
295
- if ( oauthTokens . expires_at ) {
296
- const now = Math . floor ( Date . now ( ) / 1000 ) ;
297
- if ( now > oauthTokens . expires_at ) {
298
- return "Token expired" ;
299
- }
300
-
301
- const timeRemaining = oauthTokens . expires_at - now ;
302
- return `Authenticated (expires in ${ Math . floor ( timeRemaining / 60 ) } minutes)` ;
303
- }
304
-
305
- return "Authenticated" ;
306
- } ;
307
319
const renderOAuthFlow = ( ) => {
308
- const provider = new DebugInspectorOAuthClientProvider ( sseUrl ) ;
309
-
310
320
const steps = [
311
321
{
312
322
key : "not_started" ,
@@ -534,17 +544,6 @@ const AuthDebugger = ({
534
544
< p > Loading authentication status...</ p >
535
545
) : (
536
546
< div className = "space-y-4" >
537
- < div className = "flex items-center justify-between" >
538
- < span className = "font-medium" > Status:</ span >
539
- < span
540
- className = {
541
- oauthTokens ? "text-green-600" : "text-amber-600"
542
- }
543
- >
544
- { getOAuthStatus ( ) }
545
- </ span >
546
- </ div >
547
-
548
547
{ oauthTokens && (
549
548
< div className = "space-y-2" >
550
549
< p className = "text-sm font-medium" > Access Token:</ p >
0 commit comments