@@ -206,13 +206,13 @@ describe('OAuthProvider', () => {
206
206
return new Response ( 'Users API response' , { status : 200 } ) ;
207
207
}
208
208
}
209
-
209
+
210
210
class DocumentsApiHandler extends WorkerEntrypoint {
211
211
fetch ( request : Request ) {
212
212
return new Response ( 'Documents API response' , { status : 200 } ) ;
213
213
}
214
214
}
215
-
215
+
216
216
// Create provider with multi-handler configuration
217
217
const providerWithMultiHandler = new OAuthProvider ( {
218
218
apiHandlers : {
@@ -225,96 +225,96 @@ describe('OAuthProvider', () => {
225
225
clientRegistrationEndpoint : '/oauth/register' , // Important for registering clients in the test
226
226
scopesSupported : [ 'read' , 'write' ] ,
227
227
} ) ;
228
-
228
+
229
229
// Create a client and get an access token
230
230
const clientData = {
231
231
redirect_uris : [ 'https://client.example.com/callback' ] ,
232
232
client_name : 'Test Client' ,
233
233
token_endpoint_auth_method : 'client_secret_basic' ,
234
234
} ;
235
-
235
+
236
236
const registerRequest = createMockRequest (
237
237
'https://example.com/oauth/register' ,
238
238
'POST' ,
239
239
{ 'Content-Type' : 'application/json' } ,
240
240
JSON . stringify ( clientData )
241
241
) ;
242
-
242
+
243
243
const registerResponse = await providerWithMultiHandler . fetch ( registerRequest , mockEnv , mockCtx ) ;
244
244
const client = await registerResponse . json ( ) ;
245
245
const clientId = client . client_id ;
246
246
const clientSecret = client . client_secret ;
247
247
const redirectUri = 'https://client.example.com/callback' ;
248
-
248
+
249
249
// Get an auth code
250
250
const authRequest = createMockRequest (
251
251
`https://example.com/authorize?response_type=code&client_id=${ clientId } ` +
252
- `&redirect_uri=${ encodeURIComponent ( redirectUri ) } ` +
253
- `&scope=read%20write&state=xyz123`
252
+ `&redirect_uri=${ encodeURIComponent ( redirectUri ) } ` +
253
+ `&scope=read%20write&state=xyz123`
254
254
) ;
255
-
255
+
256
256
const authResponse = await providerWithMultiHandler . fetch ( authRequest , mockEnv , mockCtx ) ;
257
257
const location = authResponse . headers . get ( 'Location' ) ! ;
258
258
const code = new URL ( location ) . searchParams . get ( 'code' ) ! ;
259
-
259
+
260
260
// Exchange for tokens
261
261
const params = new URLSearchParams ( ) ;
262
262
params . append ( 'grant_type' , 'authorization_code' ) ;
263
263
params . append ( 'code' , code ) ;
264
264
params . append ( 'redirect_uri' , redirectUri ) ;
265
265
params . append ( 'client_id' , clientId ) ;
266
266
params . append ( 'client_secret' , clientSecret ) ;
267
-
267
+
268
268
const tokenRequest = createMockRequest (
269
269
'https://example.com/oauth/token' ,
270
270
'POST' ,
271
271
{ 'Content-Type' : 'application/x-www-form-urlencoded' } ,
272
272
params . toString ( )
273
273
) ;
274
-
274
+
275
275
const tokenResponse = await providerWithMultiHandler . fetch ( tokenRequest , mockEnv , mockCtx ) ;
276
276
const tokens = await tokenResponse . json ( ) ;
277
277
const accessToken = tokens . access_token ;
278
-
278
+
279
279
// Make requests to different API routes
280
280
const usersApiRequest = createMockRequest ( 'https://example.com/api/users/profile' , 'GET' , {
281
281
Authorization : `Bearer ${ accessToken } ` ,
282
282
} ) ;
283
-
283
+
284
284
const documentsApiRequest = createMockRequest ( 'https://example.com/api/documents/list' , 'GET' , {
285
285
Authorization : `Bearer ${ accessToken } ` ,
286
286
} ) ;
287
-
287
+
288
288
// Request to Users API should be handled by UsersApiHandler
289
289
const usersResponse = await providerWithMultiHandler . fetch ( usersApiRequest , mockEnv , mockCtx ) ;
290
290
expect ( usersResponse . status ) . toBe ( 200 ) ;
291
291
expect ( await usersResponse . text ( ) ) . toBe ( 'Users API response' ) ;
292
-
292
+
293
293
// Request to Documents API should be handled by DocumentsApiHandler
294
294
const documentsResponse = await providerWithMultiHandler . fetch ( documentsApiRequest , mockEnv , mockCtx ) ;
295
295
expect ( documentsResponse . status ) . toBe ( 200 ) ;
296
296
expect ( await documentsResponse . text ( ) ) . toBe ( 'Documents API response' ) ;
297
297
} ) ;
298
-
298
+
299
299
it ( 'should throw an error when both single-handler and multi-handler configs are provided' , ( ) => {
300
300
expect ( ( ) => {
301
301
new OAuthProvider ( {
302
302
apiRoute : '/api/' ,
303
303
apiHandler : {
304
- fetch : ( ) => Promise . resolve ( new Response ( ) )
304
+ fetch : ( ) => Promise . resolve ( new Response ( ) ) ,
305
305
} ,
306
306
apiHandlers : {
307
307
'/api/users/' : {
308
- fetch : ( ) => Promise . resolve ( new Response ( ) )
309
- }
308
+ fetch : ( ) => Promise . resolve ( new Response ( ) ) ,
309
+ } ,
310
310
} ,
311
311
defaultHandler : testDefaultHandler ,
312
312
authorizeEndpoint : '/authorize' ,
313
313
tokenEndpoint : '/oauth/token' ,
314
314
} ) ;
315
315
} ) . toThrow ( 'Cannot use both apiRoute/apiHandler and apiHandlers' ) ;
316
316
} ) ;
317
-
317
+
318
318
it ( 'should throw an error when neither single-handler nor multi-handler config is provided' , ( ) => {
319
319
expect ( ( ) => {
320
320
new OAuthProvider ( {
@@ -494,6 +494,23 @@ describe('OAuthProvider', () => {
494
494
expect ( grants . keys . length ) . toBe ( 1 ) ;
495
495
} ) ;
496
496
497
+ it ( 'should reject authorization request with invalid redirect URI' , async ( ) => {
498
+ // Create an authorization request with an invalid redirect URI
499
+ const invalidRedirectUri = 'https://attacker.example.com/callback' ;
500
+ const authRequest = createMockRequest (
501
+ `https://example.com/authorize?response_type=code&client_id=${ clientId } ` +
502
+ `&redirect_uri=${ encodeURIComponent ( invalidRedirectUri ) } ` +
503
+ `&scope=read%20write&state=xyz123`
504
+ ) ;
505
+
506
+ // Expect the request to be rejected
507
+ await expect ( oauthProvider . fetch ( authRequest , mockEnv , mockCtx ) ) . rejects . toThrow ( 'Invalid redirect URI' ) ;
508
+
509
+ // Verify no grant was created
510
+ const grants = await mockEnv . OAUTH_KV . list ( { prefix : 'grant:' } ) ;
511
+ expect ( grants . keys . length ) . toBe ( 0 ) ;
512
+ } ) ;
513
+
497
514
// Add more tests for auth code flow...
498
515
} ) ;
499
516
0 commit comments