@@ -13,8 +13,7 @@ import { handler as endsWithHandler } from './endsWith';
13
13
import { handler as allLowerCaseHandler } from './alllowercase' ;
14
14
import { handler as modelWhitelistHandler } from './modelWhitelist' ;
15
15
import { handler as characterCountHandler } from './characterCount' ;
16
-
17
- import { z } from 'zod' ;
16
+ import { handler as jwtHandler } from './jwt' ;
18
17
import { PluginContext , PluginParameters } from '../types' ;
19
18
20
19
describe ( 'Regex Matcher Plugin' , ( ) => {
@@ -2315,3 +2314,156 @@ describe('endsWith handler', () => {
2315
2314
} ) ;
2316
2315
} ) ;
2317
2316
} ) ;
2317
+
2318
+ describe ( 'jwt handler' , ( ) => {
2319
+ const mockEventType = 'beforeRequestHook' ;
2320
+
2321
+ it ( 'should validate a valid JWT token' , async ( ) => {
2322
+ const context : PluginContext = {
2323
+ headers : {
2324
+ Authorization :
2325
+ 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' ,
2326
+ } ,
2327
+ } ;
2328
+ const parameters : PluginParameters = {
2329
+ jwksUri : 'https://www.googleapis.com/oauth2/v3/certs' ,
2330
+ headerKey : 'Authorization' ,
2331
+ } ;
2332
+
2333
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2334
+
2335
+ expect ( result . error ) . toBe ( null ) ;
2336
+ expect ( result . verdict ) . toBe ( true ) ;
2337
+ expect ( result . data ) . toMatchObject ( {
2338
+ verdict : true ,
2339
+ explanation : 'JWT token validation succeeded' ,
2340
+ payload : expect . any ( Object ) ,
2341
+ } ) ;
2342
+ } ) ;
2343
+
2344
+ it ( 'should handle missing authorization header' , async ( ) => {
2345
+ const context : PluginContext = {
2346
+ headers : { } ,
2347
+ } ;
2348
+ const parameters : PluginParameters = {
2349
+ jwksUri : 'https://www.googleapis.com/oauth2/v3/certs' ,
2350
+ } ;
2351
+
2352
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2353
+
2354
+ expect ( result . error ) . not . toBe ( null ) ;
2355
+ expect ( result . verdict ) . toBe ( false ) ;
2356
+ expect ( result . data ) . toMatchObject ( {
2357
+ verdict : false ,
2358
+ explanation : 'JWT validation error: Missing authorization header' ,
2359
+ } ) ;
2360
+ } ) ;
2361
+
2362
+ it ( 'should handle invalid authorization header format' , async ( ) => {
2363
+ const context : PluginContext = {
2364
+ headers : {
2365
+ Authorization : 'InvalidFormat' ,
2366
+ } ,
2367
+ } ;
2368
+ const parameters : PluginParameters = {
2369
+ jwksUri : 'https://www.googleapis.com/oauth2/v3/certs' ,
2370
+ } ;
2371
+
2372
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2373
+
2374
+ expect ( result . error ) . not . toBe ( null ) ;
2375
+ expect ( result . verdict ) . toBe ( false ) ;
2376
+ expect ( result . data ) . toMatchObject ( {
2377
+ verdict : false ,
2378
+ explanation : 'JWT validation error: Invalid authorization header format' ,
2379
+ } ) ;
2380
+ } ) ;
2381
+
2382
+ it ( 'should handle missing JWKS URI' , async ( ) => {
2383
+ const context : PluginContext = {
2384
+ headers : {
2385
+ Authorization : 'Bearer valid.token.here' ,
2386
+ } ,
2387
+ } ;
2388
+ const parameters : PluginParameters = { } ;
2389
+
2390
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2391
+
2392
+ expect ( result . error ) . not . toBe ( null ) ;
2393
+ expect ( result . verdict ) . toBe ( false ) ;
2394
+ expect ( result . data ) . toMatchObject ( {
2395
+ verdict : false ,
2396
+ explanation : 'JWT validation error: Missing JWKS URI' ,
2397
+ } ) ;
2398
+ } ) ;
2399
+
2400
+ it ( 'should use custom header key from parameters' , async ( ) => {
2401
+ const context : PluginContext = {
2402
+ headers : {
2403
+ 'X-Custom-Auth' :
2404
+ 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' ,
2405
+ } ,
2406
+ } ;
2407
+ const parameters : PluginParameters = {
2408
+ jwksUri : 'https://www.googleapis.com/oauth2/v3/certs' ,
2409
+ headerKey : 'X-Custom-Auth' ,
2410
+ } ;
2411
+
2412
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2413
+
2414
+ expect ( result . error ) . toBe ( null ) ;
2415
+ expect ( result . verdict ) . toBe ( true ) ;
2416
+ expect ( result . data ) . toMatchObject ( {
2417
+ verdict : true ,
2418
+ explanation : 'JWT token validation succeeded' ,
2419
+ payload : expect . any ( Object ) ,
2420
+ } ) ;
2421
+ } ) ;
2422
+
2423
+ it ( 'should use environment variables when parameters not provided' , async ( ) => {
2424
+ process . env . JWT_AUTH_HEADER = 'X-Env-Auth' ;
2425
+ process . env . JWT_JWKS_URI = 'https://www.googleapis.com/oauth2/v3/certs' ;
2426
+
2427
+ const context : PluginContext = {
2428
+ headers : {
2429
+ 'X-Env-Auth' :
2430
+ 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' ,
2431
+ } ,
2432
+ } ;
2433
+ const parameters : PluginParameters = { } ;
2434
+
2435
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2436
+
2437
+ expect ( result . error ) . toBe ( null ) ;
2438
+ expect ( result . verdict ) . toBe ( true ) ;
2439
+ expect ( result . data ) . toMatchObject ( {
2440
+ verdict : true ,
2441
+ explanation : 'JWT token validation succeeded' ,
2442
+ payload : expect . any ( Object ) ,
2443
+ } ) ;
2444
+
2445
+ // Clean up
2446
+ delete process . env . JWT_AUTH_HEADER ;
2447
+ delete process . env . JWT_JWKS_URI ;
2448
+ } ) ;
2449
+
2450
+ it ( 'should handle invalid JWKS URI' , async ( ) => {
2451
+ const context : PluginContext = {
2452
+ headers : {
2453
+ Authorization : 'Bearer valid.token.here' ,
2454
+ } ,
2455
+ } ;
2456
+ const parameters : PluginParameters = {
2457
+ jwksUri : 'https://invalid-jwks-uri.example.com/keys' ,
2458
+ } ;
2459
+
2460
+ const result = await jwtHandler ( context , parameters , mockEventType ) ;
2461
+
2462
+ expect ( result . error ) . not . toBe ( null ) ;
2463
+ expect ( result . verdict ) . toBe ( false ) ;
2464
+ expect ( result . data ) . toMatchObject ( {
2465
+ verdict : false ,
2466
+ explanation : expect . stringContaining ( 'JWT validation error' ) ,
2467
+ } ) ;
2468
+ } ) ;
2469
+ } ) ;
0 commit comments