serverless-event-orchestrator 1.3.2 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@ A lightweight, type-safe event dispatcher and middleware orchestrator for AWS La
10
10
  - **Multi-Trigger Support**: Handle HTTP (API Gateway), SQS, EventBridge, and Lambda invocations with a single handler
11
11
  - **Segmented Routing**: Organize routes by security context (`public`, `private`, `backoffice`, `internal`)
12
12
  - **Path Parameters**: Built-in support for dynamic routes like `/users/{id}`
13
- - **Identity Aware**: Automatic Cognito User Pool validation per segment and optional JWT extraction from headers
13
+ - **Identity Aware**: Cryptographic JWT signature verification via `aws-jwt-verify`, Cognito User Pool validation per segment
14
14
  - **Middleware Support**: Global and per-segment middleware chains
15
15
  - **Zero Config CORS**: Built-in CORS handling with sensible defaults
16
16
  - **Response Utilities**: Standardized response helpers (success, error, etc.)
@@ -111,10 +111,17 @@ const routes: SegmentedHttpRouter = {
111
111
  export const handler = async (event: any) => {
112
112
  return dispatchEvent(event, { apigateway: routes }, {
113
113
  debug: process.env.DEBUG === 'true',
114
- userPools: {
115
- private: process.env.USER_POOL_ID,
116
- backoffice: process.env.ADMIN_POOL_ID
117
- }
114
+ autoExtractIdentity: true,
115
+ jwtVerification: {
116
+ private: {
117
+ userPoolId: process.env.USER_POOL_ID!,
118
+ clientId: null,
119
+ },
120
+ backoffice: {
121
+ userPoolId: process.env.ADMIN_POOL_ID!,
122
+ clientId: null,
123
+ },
124
+ },
118
125
  });
119
126
  };
120
127
  ```
@@ -239,29 +246,68 @@ customErrorResponse(MyErrorCodes.QUOTA_EXCEEDED, 'API quota exceeded', codeToSta
239
246
 
240
247
  ## Identity & Security
241
248
 
242
- Extract and validate Cognito claims:
249
+ ### JWT Signature Verification (v2.0+)
250
+
251
+ JWTs from the `Authorization` header are cryptographically verified against Cognito's JWKS endpoint using [`aws-jwt-verify`](https://github.com/awslabs/aws-jwt-verify). This prevents accepting fabricated tokens with arbitrary claims.
243
252
 
244
253
  ```typescript
245
- import {
246
- extractIdentity,
247
- hasAnyGroup,
248
- hasAllGroups,
249
- validateIssuer
254
+ export const handler = async (event: any) => {
255
+ return dispatchEvent(event, { apigateway: routes }, {
256
+ autoExtractIdentity: true,
257
+ jwtVerification: {
258
+ // Verify tokens for private routes against the Portal User Pool
259
+ private: {
260
+ userPoolId: process.env.COGNITO_PORTAL_USER_POOL_ID!,
261
+ clientId: null, // null = skip client ID check
262
+ },
263
+ // Verify tokens for backoffice routes against the Backoffice User Pool
264
+ backoffice: {
265
+ userPoolId: process.env.COGNITO_BACKOFFICE_USER_POOL_ID!,
266
+ clientId: null,
267
+ },
268
+ },
269
+ });
270
+ };
271
+ ```
272
+
273
+ **How it works:**
274
+
275
+ - If `event.requestContext.authorizer.claims` exists (API Gateway authorizer), those claims are used directly (already verified by API Gateway)
276
+ - If no authorizer claims exist and `autoExtractIdentity` + `jwtVerification` are configured, the `Authorization` header JWT is verified cryptographically
277
+ - If verification fails, the dispatcher returns **401 Unauthorized**
278
+ - Public and internal segments don't require `jwtVerification`
279
+ - JWKS keys are cached at the module level (persists across Lambda warm starts)
280
+
281
+ **`JwtVerificationPoolConfig` options:**
282
+
283
+ | Property | Type | Description |
284
+ |----------|------|-------------|
285
+ | `userPoolId` | `string` | Cognito User Pool ID (e.g., `us-east-1_ABC123`) |
286
+ | `clientId` | `string \| string[] \| null` | App Client ID(s). `null` to skip client ID verification |
287
+ | `tokenUse` | `'id' \| 'access' \| null` | Expected token type. `null` to accept either |
288
+
289
+ ### Working with Identity in Handlers
290
+
291
+ ```typescript
292
+ import {
293
+ hasAnyGroup,
294
+ hasAllGroups
250
295
  } from 'serverless-event-orchestrator';
251
296
 
252
297
  const myHandler = async (event: NormalizedEvent) => {
253
298
  const identity = event.context.identity;
254
-
299
+
255
300
  // Access user info
256
301
  console.log(identity?.userId); // Cognito sub
257
302
  console.log(identity?.email); // User email
258
303
  console.log(identity?.groups); // Cognito groups
259
-
304
+ console.log(identity?.claims); // All JWT claims
305
+
260
306
  // Check groups
261
307
  if (hasAnyGroup(identity, ['Admins', 'Moderators'])) {
262
308
  // User has admin or moderator role
263
309
  }
264
-
310
+
265
311
  if (hasAllGroups(identity, ['Premium', 'Verified'])) {
266
312
  // User has both premium and verified status
267
313
  }
@@ -296,14 +342,19 @@ const config: OrchestratorConfig = {
296
342
  // Enable debug logging
297
343
  debug: process.env.NODE_ENV !== 'production',
298
344
 
299
- // Automatically extract identity from Authorization header if no authorizer is present
300
- // Useful when you don't use Cognito Authorizers in API Gateway
345
+ // Extract identity from Authorization header JWT
301
346
  autoExtractIdentity: true,
302
-
303
- // User Pool validation per segment
304
- userPools: {
305
- private: 'us-east-1_ABC123',
306
- backoffice: 'us-east-1_XYZ789'
347
+
348
+ // JWT signature verification per segment (v2.0+)
349
+ jwtVerification: {
350
+ private: {
351
+ userPoolId: 'us-east-1_ABC123',
352
+ clientId: null,
353
+ },
354
+ backoffice: {
355
+ userPoolId: 'us-east-1_XYZ789',
356
+ clientId: null,
357
+ },
307
358
  },
308
359
 
309
360
  // Global middleware (runs for all routes)
@@ -354,7 +405,8 @@ export const handler = async (event: any) => {
354
405
 
355
406
  | Function | Description |
356
407
  |----------|-------------|
357
- | `extractIdentity(event)` | Extracts Cognito claims from event |
408
+ | `extractIdentity(event, options?)` | Extracts and verifies Cognito claims (async) |
409
+ | `verifyJwt(token, poolConfig)` | Verifies a JWT against Cognito JWKS |
358
410
  | `validateIssuer(identity, userPoolId)` | Validates token issuer |
359
411
  | `hasAnyGroup(identity, groups)` | Checks if user has any of the groups |
360
412
  | `hasAllGroups(identity, groups)` | Checks if user has all groups |
@@ -372,6 +424,7 @@ import type {
372
424
  IdentityContext,
373
425
  RouteConfig,
374
426
  OrchestratorConfig,
427
+ JwtVerificationPoolConfig,
375
428
  MiddlewareFn
376
429
  } from 'serverless-event-orchestrator';
377
430
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,cAAc,EASd,kBAAkB,EAEnB,MAAM,mBAAmB,CAAC;AAO3B;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,CAMrD;AA8RD;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,kBAAuB,GAC9B,OAAO,CAAC,GAAG,CAAC,CA8Kd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,kBAAuB;sBAE5C,GAAG,UAAU,cAAc;;EAGhD"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,cAAc,EASd,kBAAkB,EAEnB,MAAM,mBAAmB,CAAC;AAQ3B;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,CAMrD;AA+RD;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,kBAAuB,GAC9B,OAAO,CAAC,GAAG,CAAC,CAwLd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,kBAAuB;sBAE5C,GAAG,UAAU,cAAc;;EAGhD"}
@@ -114,8 +114,8 @@ function findRouteInSegmentsWithActualPath(router, method, routePattern, actualP
114
114
  /**
115
115
  * Normalizes an API Gateway event into a standard format
116
116
  */
117
- function normalizeApiGatewayEvent(event, segment, extractedParams, autoExtract = false) {
118
- const identity = (0, extractor_js_1.extractIdentity)(event, autoExtract);
117
+ async function normalizeApiGatewayEvent(event, segment, extractedParams, autoExtract = false, jwtVerificationConfig) {
118
+ const identity = await (0, extractor_js_1.extractIdentity)(event, { autoExtract, jwtVerificationConfig });
119
119
  // Safely extract pathParameters from event (handle null/undefined)
120
120
  const eventPathParams = event.pathParameters && typeof event.pathParameters === 'object'
121
121
  ? { ...event.pathParameters }
@@ -330,9 +330,17 @@ async function dispatchEvent(event, routes, config = {}) {
330
330
  if (debug) {
331
331
  console.log('[SEO] Route matched:', routeMatch.segment, 'Params:', routeMatch.params);
332
332
  }
333
- // Normalize event
334
- let normalized = normalizeApiGatewayEvent(event, routeMatch.segment, routeMatch.params, config.autoExtractIdentity);
335
- // Validate User Pool
333
+ // Normalize event (with JWT verification if configured for this segment)
334
+ const jwtVerificationConfig = config.jwtVerification?.[routeMatch.segment];
335
+ let normalized = await normalizeApiGatewayEvent(event, routeMatch.segment, routeMatch.params, config.autoExtractIdentity, jwtVerificationConfig);
336
+ // If JWT verification is configured but identity is missing, return 401
337
+ if (jwtVerificationConfig && !normalized.context.identity) {
338
+ if (debug) {
339
+ console.log('[SEO] JWT verification failed — no valid identity for segment:', routeMatch.segment);
340
+ }
341
+ return applyCorsToResponse((0, response_js_1.unauthorizedResponse)('Invalid or missing authentication token'));
342
+ }
343
+ // Validate User Pool (legacy issuer-only check)
336
344
  if (!validateSegmentUserPool(normalized, routeMatch.segment, config)) {
337
345
  if (debug) {
338
346
  console.log('[SEO] User Pool validation failed for segment:', routeMatch.segment);
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,22 @@
1
- import { IdentityContext } from '../types/routes.js';
1
+ import { IdentityContext, JwtVerificationPoolConfig } from '../types/routes.js';
2
2
  /**
3
- * Extracts identity information from the event's authorizer context or Authorization header
3
+ * Options for extractIdentity when using JWT verification
4
+ */
5
+ export interface ExtractIdentityOptions {
6
+ autoExtract?: boolean;
7
+ jwtVerificationConfig?: JwtVerificationPoolConfig;
8
+ }
9
+ /**
10
+ * Extracts identity information from the event's authorizer context or Authorization header.
11
+ * When jwtVerificationConfig is provided, JWT signatures are cryptographically verified
12
+ * against the Cognito JWKS endpoint. Without it, identity is only extracted from
13
+ * API Gateway authorizer claims (already verified by API Gateway).
14
+ *
4
15
  * @param event - Raw API Gateway event
5
- * @param autoExtract - Whether to automatically extract from Authorization header if authorizer is missing
16
+ * @param optionsOrAutoExtract - Boolean for backwards compatibility, or ExtractIdentityOptions
6
17
  * @returns Identity context or undefined if not authenticated
7
18
  */
8
- export declare function extractIdentity(event: any, autoExtract?: boolean): IdentityContext | undefined;
19
+ export declare function extractIdentity(event: any, optionsOrAutoExtract?: boolean | ExtractIdentityOptions): Promise<IdentityContext | undefined>;
9
20
  /**
10
21
  * Extracts the User Pool ID from the issuer URL
11
22
  * @param issuer - Cognito issuer URL (e.g., https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx)
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAoDrD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,GAAE,OAAe,GAAG,eAAe,GAAG,SAAS,CAuBrG;AAmCD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAMhF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAKzG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAInG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAIrG"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGhF;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;CACnD;AAoDD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,oBAAoB,CAAC,EAAE,OAAO,GAAG,sBAAsB,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAuC/I;AAgDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAMhF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAKzG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAInG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAIrG"}
@@ -5,6 +5,7 @@ exports.extractUserPoolId = extractUserPoolId;
5
5
  exports.validateIssuer = validateIssuer;
6
6
  exports.hasAnyGroup = hasAnyGroup;
7
7
  exports.hasAllGroups = hasAllGroups;
8
+ const jwt_verifier_js_1 = require("./jwt-verifier.js");
8
9
  /**
9
10
  * Extracts identity context from API Gateway authorizer claims
10
11
  * Supports multiple API Gateway formats:
@@ -50,31 +51,48 @@ function hasIdentityProperties(obj) {
50
51
  return identityKeys.some(key => key in obj);
51
52
  }
52
53
  /**
53
- * Extracts identity information from the event's authorizer context or Authorization header
54
+ * Extracts identity information from the event's authorizer context or Authorization header.
55
+ * When jwtVerificationConfig is provided, JWT signatures are cryptographically verified
56
+ * against the Cognito JWKS endpoint. Without it, identity is only extracted from
57
+ * API Gateway authorizer claims (already verified by API Gateway).
58
+ *
54
59
  * @param event - Raw API Gateway event
55
- * @param autoExtract - Whether to automatically extract from Authorization header if authorizer is missing
60
+ * @param optionsOrAutoExtract - Boolean for backwards compatibility, or ExtractIdentityOptions
56
61
  * @returns Identity context or undefined if not authenticated
57
62
  */
58
- function extractIdentity(event, autoExtract = false) {
63
+ async function extractIdentity(event, optionsOrAutoExtract) {
64
+ const options = typeof optionsOrAutoExtract === 'boolean'
65
+ ? { autoExtract: optionsOrAutoExtract }
66
+ : optionsOrAutoExtract ?? {};
67
+ const { autoExtract = false, jwtVerificationConfig } = options;
59
68
  const authorizer = event?.requestContext?.authorizer;
60
- let claims = extractClaims(authorizer);
61
- // If no authorizer claims found and autoExtract is enabled, try decoding the Authorization header
62
- if (!claims && autoExtract) {
69
+ const claims = extractClaims(authorizer);
70
+ // If authorizer claims exist, API Gateway already verified the token use them directly
71
+ if (claims) {
72
+ return buildIdentity(claims);
73
+ }
74
+ // If autoExtract is enabled, extract identity from Authorization header
75
+ if (autoExtract) {
63
76
  const authHeader = event?.headers?.authorization || event?.headers?.Authorization;
64
77
  if (authHeader) {
65
- claims = decodeJwtFromHeader(authHeader);
78
+ // If jwtVerificationConfig is provided, verify signature cryptographically
79
+ if (jwtVerificationConfig) {
80
+ const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
81
+ const verifiedClaims = await (0, jwt_verifier_js_1.verifyJwt)(token, jwtVerificationConfig);
82
+ if (verifiedClaims) {
83
+ return buildIdentity(verifiedClaims);
84
+ }
85
+ // Verification failed → return undefined (caller will return 401)
86
+ return undefined;
87
+ }
88
+ // No jwtVerificationConfig → decode-only fallback (no signature verification)
89
+ const decoded = decodeJwtFromHeader(authHeader);
90
+ if (decoded) {
91
+ return buildIdentity(decoded);
92
+ }
66
93
  }
67
94
  }
68
- if (!claims) {
69
- return undefined;
70
- }
71
- return {
72
- userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
73
- email: claims.email,
74
- groups: parseGroups(claims['cognito:groups'] || claims.groups),
75
- issuer: claims.iss,
76
- claims,
77
- };
95
+ return undefined;
78
96
  }
79
97
  /**
80
98
  * Decodes a JWT from the Authorization header without validating signature
@@ -96,6 +114,18 @@ function decodeJwtFromHeader(authHeader) {
96
114
  return undefined;
97
115
  }
98
116
  }
117
+ /**
118
+ * Builds an IdentityContext from raw claims
119
+ */
120
+ function buildIdentity(claims) {
121
+ return {
122
+ userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
123
+ email: claims.email,
124
+ groups: parseGroups(claims['cognito:groups'] || claims.groups),
125
+ issuer: claims.iss,
126
+ claims,
127
+ };
128
+ }
99
129
  /**
100
130
  * Parses Cognito groups from claims
101
131
  * Groups can come as a string or array depending on configuration
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  export * from './extractor.js';
2
+ export { verifyJwt } from './jwt-verifier.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
@@ -14,5 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.verifyJwt = void 0;
17
18
  __exportStar(require("./extractor.js"), exports);
19
+ var jwt_verifier_js_1 = require("./jwt-verifier.js");
20
+ Object.defineProperty(exports, "verifyJwt", { enumerable: true, get: function () { return jwt_verifier_js_1.verifyJwt; } });
18
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,qDAA8C;AAArC,4GAAA,SAAS,OAAA"}
@@ -0,0 +1,7 @@
1
+ import type { JwtVerificationPoolConfig } from '../types/routes.js';
2
+ /**
3
+ * Verifies a JWT token against a Cognito User Pool's JWKS.
4
+ * Returns the verified payload (claims) or undefined if verification fails.
5
+ */
6
+ export declare function verifyJwt(token: string, poolConfig: JwtVerificationPoolConfig): Promise<Record<string, any> | undefined>;
7
+ //# sourceMappingURL=jwt-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-verifier.d.ts","sourceRoot":"","sources":["../../src/identity/jwt-verifier.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAuBpE;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC,CAS1C"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyJwt = verifyJwt;
4
+ const aws_jwt_verify_1 = require("aws-jwt-verify");
5
+ /**
6
+ * Module-level cache of CognitoJwtVerifier instances keyed by userPoolId.
7
+ * Persists across Lambda warm invocations. Each verifier internally caches JWKS.
8
+ */
9
+ const verifierCache = new Map();
10
+ function getVerifier(poolConfig) {
11
+ const cacheKey = poolConfig.userPoolId;
12
+ if (!verifierCache.has(cacheKey)) {
13
+ const verifier = aws_jwt_verify_1.CognitoJwtVerifier.create({
14
+ userPoolId: poolConfig.userPoolId,
15
+ clientId: poolConfig.clientId ?? null,
16
+ tokenUse: poolConfig.tokenUse ?? null,
17
+ });
18
+ verifierCache.set(cacheKey, verifier);
19
+ }
20
+ return verifierCache.get(cacheKey);
21
+ }
22
+ /**
23
+ * Verifies a JWT token against a Cognito User Pool's JWKS.
24
+ * Returns the verified payload (claims) or undefined if verification fails.
25
+ */
26
+ async function verifyJwt(token, poolConfig) {
27
+ try {
28
+ const verifier = getVerifier(poolConfig);
29
+ const payload = await verifier.verify(token);
30
+ return payload;
31
+ }
32
+ catch (error) {
33
+ console.error('[SEO] JWT verification failed:', error?.message || error);
34
+ return undefined;
35
+ }
36
+ }
37
+ //# sourceMappingURL=jwt-verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-verifier.js","sourceRoot":"","sources":["../../src/identity/jwt-verifier.ts"],"names":[],"mappings":";;AA4BA,8BAYC;AAxCD,mDAAoD;AAGpD;;;GAGG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwD,CAAC;AAEtF,SAAS,WAAW,CAAC,UAAqC;IACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC;IAEvC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,mCAAkB,CAAC,MAAM,CAAC;YACzC,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,IAAI;YACrC,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,IAAI;SACtC,CAAC,CAAC;QACH,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;AACtC,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,UAAqC;IAErC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,OAAyC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,CAAC;QACzE,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,11 +7,13 @@
7
7
  */
8
8
  export { dispatchEvent, detectEventType, createOrchestrator } from './dispatcher.js';
9
9
  export { EventType, RouteSegment, } from './types/event-type.enum.js';
10
- export { HttpMethod, MiddlewareFn, RouteConfig, CorsConfig, RateLimitConfig, HttpRouter, SegmentedHttpRouter, SegmentConfig, AdvancedSegmentedRouter, EventBridgeRoutes, LambdaRoutes, SqsRoutes, DispatchRoutes, IdentityContext, RouteMatch, NormalizedEvent, OrchestratorConfig, } from './types/routes.js';
10
+ export { HttpMethod, MiddlewareFn, RouteConfig, CorsConfig, RateLimitConfig, HttpRouter, SegmentedHttpRouter, SegmentConfig, AdvancedSegmentedRouter, EventBridgeRoutes, LambdaRoutes, SqsRoutes, DispatchRoutes, IdentityContext, RouteMatch, NormalizedEvent, OrchestratorConfig, JwtVerificationPoolConfig, } from './types/routes.js';
11
11
  export { HttpStatus, StandardResponse, HttpResponse, DefaultResponseCode, createStandardResponse, successResponse, createdResponse, badRequestResponse, unauthorizedResponse, forbiddenResponse, notFoundResponse, conflictResponse, validationErrorResponse, internalErrorResponse, customErrorResponse, } from './http/response.js';
12
12
  export { parseJsonBody, parseQueryParams, withJsonBodyParser, } from './http/body-parser.js';
13
13
  export { isPreflightRequest, createPreflightResponse, applyCorsHeaders, withCors, } from './http/cors.js';
14
14
  export { extractIdentity, extractUserPoolId, validateIssuer, hasAnyGroup, hasAllGroups, } from './identity/extractor.js';
15
+ export type { ExtractIdentityOptions } from './identity/extractor.js';
16
+ export { verifyJwt } from './identity/jwt-verifier.js';
15
17
  export { matchPath, patternToRegex, hasPathParameters, normalizePath, } from './utils/path-matcher.js';
16
18
  export { normalizeHeaders, getHeader, getCorsHeaders, } from './utils/headers.js';
17
19
  export { TenantContext } from './tenant/TenantContext.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrF,OAAO,EACL,SAAS,EACT,YAAY,GACb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,YAAY,GACb,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,YAAY,EACV,UAAU,EACV,UAAU,EACV,IAAI,EACJ,cAAc,EACd,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,YAAY,EACZ,MAAM,EACN,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrF,OAAO,EACL,SAAS,EACT,YAAY,GACb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,YAAY,GACb,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGvD,OAAO,EACL,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,YAAY,EACV,UAAU,EACV,UAAU,EACV,IAAI,EACJ,cAAc,EACd,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,YAAY,EACZ,MAAM,EACN,cAAc,GACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * Cognito User Pool validation, and built-in infrastructure middlewares.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.crmGuard = exports.tenantGuard = exports.initTenantContext = exports.tenantInfoToHeaders = exports.tenantInfoFromHeaders = exports.tenantInfoFromClaims = exports.TENANT_HEADERS = exports.isPlan = exports.isTenantType = exports.TenantContext = exports.getCorsHeaders = exports.getHeader = exports.normalizeHeaders = exports.normalizePath = exports.hasPathParameters = exports.patternToRegex = exports.matchPath = exports.hasAllGroups = exports.hasAnyGroup = exports.validateIssuer = exports.extractUserPoolId = exports.extractIdentity = exports.withCors = exports.applyCorsHeaders = exports.createPreflightResponse = exports.isPreflightRequest = exports.withJsonBodyParser = exports.parseQueryParams = exports.parseJsonBody = exports.customErrorResponse = exports.internalErrorResponse = exports.validationErrorResponse = exports.conflictResponse = exports.notFoundResponse = exports.forbiddenResponse = exports.unauthorizedResponse = exports.badRequestResponse = exports.createdResponse = exports.successResponse = exports.createStandardResponse = exports.DefaultResponseCode = exports.HttpStatus = exports.RouteSegment = exports.EventType = exports.createOrchestrator = exports.detectEventType = void 0;
10
+ exports.crmGuard = exports.tenantGuard = exports.initTenantContext = exports.tenantInfoToHeaders = exports.tenantInfoFromHeaders = exports.tenantInfoFromClaims = exports.TENANT_HEADERS = exports.isPlan = exports.isTenantType = exports.TenantContext = exports.getCorsHeaders = exports.getHeader = exports.normalizeHeaders = exports.normalizePath = exports.hasPathParameters = exports.patternToRegex = exports.matchPath = exports.verifyJwt = exports.hasAllGroups = exports.hasAnyGroup = exports.validateIssuer = exports.extractUserPoolId = exports.extractIdentity = exports.withCors = exports.applyCorsHeaders = exports.createPreflightResponse = exports.isPreflightRequest = exports.withJsonBodyParser = exports.parseQueryParams = exports.parseJsonBody = exports.customErrorResponse = exports.internalErrorResponse = exports.validationErrorResponse = exports.conflictResponse = exports.notFoundResponse = exports.forbiddenResponse = exports.unauthorizedResponse = exports.badRequestResponse = exports.createdResponse = exports.successResponse = exports.createStandardResponse = exports.DefaultResponseCode = exports.HttpStatus = exports.RouteSegment = exports.EventType = exports.createOrchestrator = exports.detectEventType = void 0;
11
11
  // Core dispatcher
12
12
  var dispatcher_js_1 = require("./dispatcher.js");
13
13
  Object.defineProperty(exports, "dispatchEvent", { enumerable: true, get: function () { return dispatcher_js_1.dispatchEvent; } });
@@ -48,6 +48,8 @@ Object.defineProperty(exports, "extractUserPoolId", { enumerable: true, get: fun
48
48
  Object.defineProperty(exports, "validateIssuer", { enumerable: true, get: function () { return extractor_js_1.validateIssuer; } });
49
49
  Object.defineProperty(exports, "hasAnyGroup", { enumerable: true, get: function () { return extractor_js_1.hasAnyGroup; } });
50
50
  Object.defineProperty(exports, "hasAllGroups", { enumerable: true, get: function () { return extractor_js_1.hasAllGroups; } });
51
+ var jwt_verifier_js_1 = require("./identity/jwt-verifier.js");
52
+ Object.defineProperty(exports, "verifyJwt", { enumerable: true, get: function () { return jwt_verifier_js_1.verifyJwt; } });
51
53
  // Path utilities
52
54
  var path_matcher_js_1 = require("./utils/path-matcher.js");
53
55
  Object.defineProperty(exports, "matchPath", { enumerable: true, get: function () { return path_matcher_js_1.matchPath; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,kBAAkB;AAClB,iDAAqF;AAA5E,8GAAA,aAAa,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAE3D,QAAQ;AACR,iEAGoC;AAFlC,+GAAA,SAAS,OAAA;AACT,kHAAA,YAAY,OAAA;AAuBd,iBAAiB;AACjB,kDAgB4B;AAf1B,yGAAA,UAAU,OAAA;AAGV,kHAAA,mBAAmB,OAAA;AACnB,qHAAA,sBAAsB,OAAA;AACtB,8GAAA,eAAe,OAAA;AACf,8GAAA,eAAe,OAAA;AACf,iHAAA,kBAAkB,OAAA;AAClB,mHAAA,oBAAoB,OAAA;AACpB,gHAAA,iBAAiB,OAAA;AACjB,+GAAA,gBAAgB,OAAA;AAChB,+GAAA,gBAAgB,OAAA;AAChB,sHAAA,uBAAuB,OAAA;AACvB,oHAAA,qBAAqB,OAAA;AACrB,kHAAA,mBAAmB,OAAA;AAGrB,wDAI+B;AAH7B,+GAAA,aAAa,OAAA;AACb,kHAAA,gBAAgB,OAAA;AAChB,oHAAA,kBAAkB,OAAA;AAGpB,0CAKwB;AAJtB,6GAAA,kBAAkB,OAAA;AAClB,kHAAA,uBAAuB,OAAA;AACvB,2GAAA,gBAAgB,OAAA;AAChB,mGAAA,QAAQ,OAAA;AAGV,qBAAqB;AACrB,wDAMiC;AAL/B,+GAAA,eAAe,OAAA;AACf,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,2GAAA,WAAW,OAAA;AACX,4GAAA,YAAY,OAAA;AAGd,iBAAiB;AACjB,2DAKiC;AAJ/B,4GAAA,SAAS,OAAA;AACT,iHAAA,cAAc,OAAA;AACd,oHAAA,iBAAiB,OAAA;AACjB,gHAAA,aAAa,OAAA;AAGf,mBAAmB;AACnB,iDAI4B;AAH1B,8GAAA,gBAAgB,OAAA;AAChB,uGAAA,SAAS,OAAA;AACT,4GAAA,cAAc,OAAA;AAGhB,iBAAiB;AACjB,8DAA0D;AAAjD,iHAAA,aAAa,OAAA;AAUtB,8CAI2B;AAHzB,wGAAA,YAAY,OAAA;AACZ,kGAAA,MAAM,OAAA;AACN,0GAAA,cAAc,OAAA;AAGhB,kDAI6B;AAH3B,kHAAA,oBAAoB,OAAA;AACpB,mHAAA,qBAAqB,OAAA;AACrB,iHAAA,mBAAmB,OAAA;AAGrB,oBAAoB;AACpB,kDAI+B;AAH7B,6GAAA,iBAAiB,OAAA;AACjB,uGAAA,WAAW,OAAA;AACX,oGAAA,QAAQ,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,kBAAkB;AAClB,iDAAqF;AAA5E,8GAAA,aAAa,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAE3D,QAAQ;AACR,iEAGoC;AAFlC,+GAAA,SAAS,OAAA;AACT,kHAAA,YAAY,OAAA;AAwBd,iBAAiB;AACjB,kDAgB4B;AAf1B,yGAAA,UAAU,OAAA;AAGV,kHAAA,mBAAmB,OAAA;AACnB,qHAAA,sBAAsB,OAAA;AACtB,8GAAA,eAAe,OAAA;AACf,8GAAA,eAAe,OAAA;AACf,iHAAA,kBAAkB,OAAA;AAClB,mHAAA,oBAAoB,OAAA;AACpB,gHAAA,iBAAiB,OAAA;AACjB,+GAAA,gBAAgB,OAAA;AAChB,+GAAA,gBAAgB,OAAA;AAChB,sHAAA,uBAAuB,OAAA;AACvB,oHAAA,qBAAqB,OAAA;AACrB,kHAAA,mBAAmB,OAAA;AAGrB,wDAI+B;AAH7B,+GAAA,aAAa,OAAA;AACb,kHAAA,gBAAgB,OAAA;AAChB,oHAAA,kBAAkB,OAAA;AAGpB,0CAKwB;AAJtB,6GAAA,kBAAkB,OAAA;AAClB,kHAAA,uBAAuB,OAAA;AACvB,2GAAA,gBAAgB,OAAA;AAChB,mGAAA,QAAQ,OAAA;AAGV,qBAAqB;AACrB,wDAMiC;AAL/B,+GAAA,eAAe,OAAA;AACf,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,2GAAA,WAAW,OAAA;AACX,4GAAA,YAAY,OAAA;AAKd,8DAAuD;AAA9C,4GAAA,SAAS,OAAA;AAElB,iBAAiB;AACjB,2DAKiC;AAJ/B,4GAAA,SAAS,OAAA;AACT,iHAAA,cAAc,OAAA;AACd,oHAAA,iBAAiB,OAAA;AACjB,gHAAA,aAAa,OAAA;AAGf,mBAAmB;AACnB,iDAI4B;AAH1B,8GAAA,gBAAgB,OAAA;AAChB,uGAAA,SAAS,OAAA;AACT,4GAAA,cAAc,OAAA;AAGhB,iBAAiB;AACjB,8DAA0D;AAAjD,iHAAA,aAAa,OAAA;AAUtB,8CAI2B;AAHzB,wGAAA,YAAY,OAAA;AACZ,kGAAA,MAAM,OAAA;AACN,0GAAA,cAAc,OAAA;AAGhB,kDAI6B;AAH3B,kHAAA,oBAAoB,OAAA;AACpB,mHAAA,qBAAqB,OAAA;AACrB,iHAAA,mBAAmB,OAAA;AAGrB,oBAAoB;AACpB,kDAI+B;AAH7B,6GAAA,iBAAiB,OAAA;AACjB,uGAAA,WAAW,OAAA;AACX,oGAAA,QAAQ,OAAA"}
@@ -134,6 +134,17 @@ export interface NormalizedEvent {
134
134
  tenantInfo?: TenantInfo;
135
135
  };
136
136
  }
137
+ /**
138
+ * JWT verification configuration for a Cognito User Pool
139
+ */
140
+ export interface JwtVerificationPoolConfig {
141
+ /** Cognito User Pool ID (e.g., "us-east-1_ABC123") */
142
+ userPoolId: string;
143
+ /** App Client ID(s). Pass null to skip client ID verification. */
144
+ clientId?: string | string[] | null;
145
+ /** Expected token use. Pass null to accept either. Defaults to null. */
146
+ tokenUse?: 'id' | 'access' | null;
147
+ }
137
148
  /**
138
149
  * Orchestrator configuration options
139
150
  */
@@ -143,7 +154,8 @@ export interface OrchestratorConfig {
143
154
  */
144
155
  debug?: boolean;
145
156
  /**
146
- * User Pool ID mappings for segment-based validation
157
+ * User Pool ID mappings for segment-based validation (issuer string only).
158
+ * @deprecated Use jwtVerification instead for cryptographic signature verification.
147
159
  */
148
160
  userPools?: {
149
161
  [K in RouteSegment]?: string;
@@ -165,5 +177,13 @@ export interface OrchestratorConfig {
165
177
  * Automatically extract identity from Authorization header if no authorizer is present
166
178
  */
167
179
  autoExtractIdentity?: boolean;
180
+ /**
181
+ * JWT signature verification configuration.
182
+ * When provided for a segment, JWTs from the Authorization header
183
+ * are cryptographically verified against the Cognito JWKS endpoint.
184
+ */
185
+ jwtVerification?: {
186
+ [K in RouteSegment]?: JwtVerificationPoolConfig;
187
+ };
168
188
  }
169
189
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/types/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/types/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1F;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAClD,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;KACtB,CAAC,IAAI,UAAU,CAAC,CAAC,EAAE;QAClB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;KAC7B;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;IACpC,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;IACrC,UAAU,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;IACxC,QAAQ,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAEpF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAEjF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,UAAU,GAAG,mBAAmB,GAAG,uBAAuB,CAAC;IACxE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,GAAG,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxC,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE;QACP,OAAO,EAAE,YAAY,CAAC;QACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;QAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,SAAS,CAAC,EAAE;SACT,CAAC,IAAI,YAAY,CAAC,CAAC,EAAE,MAAM;KAC7B,CAAC;IAEF;;OAEG;IACH,gBAAgB,CAAC,EAAE,YAAY,EAAE,CAAC;IAElC;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC;QACtB,UAAU,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;QACvC,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;KAC3C,CAAC;IAEF;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,eAAe,CAAC,EAAE;SACf,CAAC,IAAI,YAAY,CAAC,CAAC,EAAE,yBAAyB;KAChD,CAAC;CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-event-orchestrator",
3
- "version": "1.3.2",
3
+ "version": "2.0.1",
4
4
  "description": "A lightweight, type-safe event dispatcher and middleware orchestrator for AWS Lambda. Designed for hexagonal architectures with support for segmented routing (public, private, backoffice), Cognito User Pool validation, and built-in infrastructure middlewares.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -62,6 +62,9 @@
62
62
  "url": "https://github.com/carlosmora01/serverless-event-orchestrator/issues"
63
63
  },
64
64
  "homepage": "https://github.com/carlosmora01/serverless-event-orchestrator#readme",
65
+ "dependencies": {
66
+ "aws-jwt-verify": "^5.1.1"
67
+ },
65
68
  "devDependencies": {
66
69
  "@types/jest": "^29.5.0",
67
70
  "@types/node": "^20.0.0",
package/src/dispatcher.ts CHANGED
@@ -16,7 +16,8 @@ import { matchPath, normalizePath } from './utils/path-matcher.js';
16
16
  import { normalizeHeaders } from './utils/headers.js';
17
17
  import { parseJsonBody, parseQueryParams } from './http/body-parser.js';
18
18
  import { extractIdentity, validateIssuer } from './identity/extractor.js';
19
- import { forbiddenResponse, badRequestResponse, notFoundResponse } from './http/response.js';
19
+ import type { JwtVerificationPoolConfig } from './types/routes.js';
20
+ import { forbiddenResponse, badRequestResponse, notFoundResponse, unauthorizedResponse } from './http/response.js';
20
21
 
21
22
  /**
22
23
  * Detects the type of AWS event
@@ -139,13 +140,14 @@ function findRouteInSegmentsWithActualPath(
139
140
  /**
140
141
  * Normalizes an API Gateway event into a standard format
141
142
  */
142
- function normalizeApiGatewayEvent(
143
+ async function normalizeApiGatewayEvent(
143
144
  event: any,
144
145
  segment: RouteSegment,
145
146
  extractedParams: Record<string, string>,
146
- autoExtract: boolean = false
147
- ): NormalizedEvent {
148
- const identity = extractIdentity(event, autoExtract);
147
+ autoExtract: boolean = false,
148
+ jwtVerificationConfig?: JwtVerificationPoolConfig
149
+ ): Promise<NormalizedEvent> {
150
+ const identity = await extractIdentity(event, { autoExtract, jwtVerificationConfig });
149
151
 
150
152
  // Safely extract pathParameters from event (handle null/undefined)
151
153
  const eventPathParams: Record<string, string> = event.pathParameters && typeof event.pathParameters === 'object'
@@ -401,15 +403,25 @@ export async function dispatchEvent(
401
403
  console.log('[SEO] Route matched:', routeMatch.segment, 'Params:', routeMatch.params);
402
404
  }
403
405
 
404
- // Normalize event
405
- let normalized = normalizeApiGatewayEvent(
406
+ // Normalize event (with JWT verification if configured for this segment)
407
+ const jwtVerificationConfig = config.jwtVerification?.[routeMatch.segment];
408
+ let normalized = await normalizeApiGatewayEvent(
406
409
  event,
407
410
  routeMatch.segment,
408
411
  routeMatch.params,
409
- config.autoExtractIdentity
412
+ config.autoExtractIdentity,
413
+ jwtVerificationConfig
410
414
  );
411
-
412
- // Validate User Pool
415
+
416
+ // If JWT verification is configured but identity is missing, return 401
417
+ if (jwtVerificationConfig && !normalized.context.identity) {
418
+ if (debug) {
419
+ console.log('[SEO] JWT verification failed — no valid identity for segment:', routeMatch.segment);
420
+ }
421
+ return applyCorsToResponse(unauthorizedResponse('Invalid or missing authentication token'));
422
+ }
423
+
424
+ // Validate User Pool (legacy issuer-only check)
413
425
  if (!validateSegmentUserPool(normalized, routeMatch.segment, config)) {
414
426
  if (debug) {
415
427
  console.log('[SEO] User Pool validation failed for segment:', routeMatch.segment);
@@ -1,4 +1,13 @@
1
- import { IdentityContext } from '../types/routes.js';
1
+ import { IdentityContext, JwtVerificationPoolConfig } from '../types/routes.js';
2
+ import { verifyJwt } from './jwt-verifier.js';
3
+
4
+ /**
5
+ * Options for extractIdentity when using JWT verification
6
+ */
7
+ export interface ExtractIdentityOptions {
8
+ autoExtract?: boolean;
9
+ jwtVerificationConfig?: JwtVerificationPoolConfig;
10
+ }
2
11
 
3
12
  /**
4
13
  * Extracts identity context from API Gateway authorizer claims
@@ -51,34 +60,54 @@ function hasIdentityProperties(obj: any): boolean {
51
60
  }
52
61
 
53
62
  /**
54
- * Extracts identity information from the event's authorizer context or Authorization header
63
+ * Extracts identity information from the event's authorizer context or Authorization header.
64
+ * When jwtVerificationConfig is provided, JWT signatures are cryptographically verified
65
+ * against the Cognito JWKS endpoint. Without it, identity is only extracted from
66
+ * API Gateway authorizer claims (already verified by API Gateway).
67
+ *
55
68
  * @param event - Raw API Gateway event
56
- * @param autoExtract - Whether to automatically extract from Authorization header if authorizer is missing
69
+ * @param optionsOrAutoExtract - Boolean for backwards compatibility, or ExtractIdentityOptions
57
70
  * @returns Identity context or undefined if not authenticated
58
71
  */
59
- export function extractIdentity(event: any, autoExtract: boolean = false): IdentityContext | undefined {
72
+ export async function extractIdentity(event: any, optionsOrAutoExtract?: boolean | ExtractIdentityOptions): Promise<IdentityContext | undefined> {
73
+ const options: ExtractIdentityOptions = typeof optionsOrAutoExtract === 'boolean'
74
+ ? { autoExtract: optionsOrAutoExtract }
75
+ : optionsOrAutoExtract ?? {};
76
+
77
+ const { autoExtract = false, jwtVerificationConfig } = options;
78
+
60
79
  const authorizer = event?.requestContext?.authorizer;
61
- let claims = extractClaims(authorizer);
62
-
63
- // If no authorizer claims found and autoExtract is enabled, try decoding the Authorization header
64
- if (!claims && autoExtract) {
80
+ const claims = extractClaims(authorizer);
81
+
82
+ // If authorizer claims exist, API Gateway already verified the token use them directly
83
+ if (claims) {
84
+ return buildIdentity(claims);
85
+ }
86
+
87
+ // If autoExtract is enabled, extract identity from Authorization header
88
+ if (autoExtract) {
65
89
  const authHeader = event?.headers?.authorization || event?.headers?.Authorization;
66
90
  if (authHeader) {
67
- claims = decodeJwtFromHeader(authHeader);
91
+ // If jwtVerificationConfig is provided, verify signature cryptographically
92
+ if (jwtVerificationConfig) {
93
+ const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
94
+ const verifiedClaims = await verifyJwt(token, jwtVerificationConfig);
95
+ if (verifiedClaims) {
96
+ return buildIdentity(verifiedClaims);
97
+ }
98
+ // Verification failed → return undefined (caller will return 401)
99
+ return undefined;
100
+ }
101
+
102
+ // No jwtVerificationConfig → decode-only fallback (no signature verification)
103
+ const decoded = decodeJwtFromHeader(authHeader);
104
+ if (decoded) {
105
+ return buildIdentity(decoded);
106
+ }
68
107
  }
69
108
  }
70
-
71
- if (!claims) {
72
- return undefined;
73
- }
74
-
75
- return {
76
- userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
77
- email: claims.email,
78
- groups: parseGroups(claims['cognito:groups'] || claims.groups),
79
- issuer: claims.iss,
80
- claims,
81
- };
109
+
110
+ return undefined;
82
111
  }
83
112
 
84
113
  /**
@@ -94,7 +123,7 @@ function decodeJwtFromHeader(authHeader: string): Record<string, any> | undefine
94
123
  const payload = parts[1];
95
124
  const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
96
125
  const jsonPayload = Buffer.from(base64, 'base64').toString('utf8');
97
-
126
+
98
127
  return JSON.parse(jsonPayload);
99
128
  } catch (error) {
100
129
  console.error('[SEO] Error decoding JWT from header:', error);
@@ -102,6 +131,19 @@ function decodeJwtFromHeader(authHeader: string): Record<string, any> | undefine
102
131
  }
103
132
  }
104
133
 
134
+ /**
135
+ * Builds an IdentityContext from raw claims
136
+ */
137
+ function buildIdentity(claims: Record<string, any>): IdentityContext {
138
+ return {
139
+ userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
140
+ email: claims.email,
141
+ groups: parseGroups(claims['cognito:groups'] || claims.groups),
142
+ issuer: claims.iss,
143
+ claims,
144
+ };
145
+ }
146
+
105
147
  /**
106
148
  * Parses Cognito groups from claims
107
149
  * Groups can come as a string or array depending on configuration
@@ -1 +1,2 @@
1
1
  export * from './extractor.js';
2
+ export { verifyJwt } from './jwt-verifier.js';
@@ -0,0 +1,41 @@
1
+ import { CognitoJwtVerifier } from 'aws-jwt-verify';
2
+ import type { JwtVerificationPoolConfig } from '../types/routes.js';
3
+
4
+ /**
5
+ * Module-level cache of CognitoJwtVerifier instances keyed by userPoolId.
6
+ * Persists across Lambda warm invocations. Each verifier internally caches JWKS.
7
+ */
8
+ const verifierCache = new Map<string, ReturnType<typeof CognitoJwtVerifier.create>>();
9
+
10
+ function getVerifier(poolConfig: JwtVerificationPoolConfig) {
11
+ const cacheKey = poolConfig.userPoolId;
12
+
13
+ if (!verifierCache.has(cacheKey)) {
14
+ const verifier = CognitoJwtVerifier.create({
15
+ userPoolId: poolConfig.userPoolId,
16
+ clientId: poolConfig.clientId ?? null,
17
+ tokenUse: poolConfig.tokenUse ?? null,
18
+ });
19
+ verifierCache.set(cacheKey, verifier);
20
+ }
21
+
22
+ return verifierCache.get(cacheKey)!;
23
+ }
24
+
25
+ /**
26
+ * Verifies a JWT token against a Cognito User Pool's JWKS.
27
+ * Returns the verified payload (claims) or undefined if verification fails.
28
+ */
29
+ export async function verifyJwt(
30
+ token: string,
31
+ poolConfig: JwtVerificationPoolConfig
32
+ ): Promise<Record<string, any> | undefined> {
33
+ try {
34
+ const verifier = getVerifier(poolConfig);
35
+ const payload = await verifier.verify(token);
36
+ return payload as unknown as Record<string, any>;
37
+ } catch (error: any) {
38
+ console.error('[SEO] JWT verification failed:', error?.message || error);
39
+ return undefined;
40
+ }
41
+ }
package/src/index.ts CHANGED
@@ -33,6 +33,7 @@ export {
33
33
  RouteMatch,
34
34
  NormalizedEvent,
35
35
  OrchestratorConfig,
36
+ JwtVerificationPoolConfig,
36
37
  } from './types/routes.js';
37
38
 
38
39
  // HTTP utilities
@@ -76,6 +77,10 @@ export {
76
77
  hasAllGroups,
77
78
  } from './identity/extractor.js';
78
79
 
80
+ export type { ExtractIdentityOptions } from './identity/extractor.js';
81
+
82
+ export { verifyJwt } from './identity/jwt-verifier.js';
83
+
79
84
  // Path utilities
80
85
  export {
81
86
  matchPath,
@@ -151,6 +151,18 @@ export interface NormalizedEvent {
151
151
  };
152
152
  }
153
153
 
154
+ /**
155
+ * JWT verification configuration for a Cognito User Pool
156
+ */
157
+ export interface JwtVerificationPoolConfig {
158
+ /** Cognito User Pool ID (e.g., "us-east-1_ABC123") */
159
+ userPoolId: string;
160
+ /** App Client ID(s). Pass null to skip client ID verification. */
161
+ clientId?: string | string[] | null;
162
+ /** Expected token use. Pass null to accept either. Defaults to null. */
163
+ tokenUse?: 'id' | 'access' | null;
164
+ }
165
+
154
166
  /**
155
167
  * Orchestrator configuration options
156
168
  */
@@ -161,7 +173,8 @@ export interface OrchestratorConfig {
161
173
  debug?: boolean;
162
174
 
163
175
  /**
164
- * User Pool ID mappings for segment-based validation
176
+ * User Pool ID mappings for segment-based validation (issuer string only).
177
+ * @deprecated Use jwtVerification instead for cryptographic signature verification.
165
178
  */
166
179
  userPools?: {
167
180
  [K in RouteSegment]?: string;
@@ -186,4 +199,13 @@ export interface OrchestratorConfig {
186
199
  * Automatically extract identity from Authorization header if no authorizer is present
187
200
  */
188
201
  autoExtractIdentity?: boolean;
202
+
203
+ /**
204
+ * JWT signature verification configuration.
205
+ * When provided for a segment, JWTs from the Authorization header
206
+ * are cryptographically verified against the Cognito JWKS endpoint.
207
+ */
208
+ jwtVerification?: {
209
+ [K in RouteSegment]?: JwtVerificationPoolConfig;
210
+ };
189
211
  }
@@ -8,17 +8,17 @@ import {
8
8
  import { IdentityContext } from '../src/types/routes';
9
9
 
10
10
  describe('extractIdentity', () => {
11
- it('should return undefined when no claims present', () => {
11
+ it('should return undefined when no claims present', async () => {
12
12
  const event = { requestContext: {} };
13
- expect(extractIdentity(event)).toBeUndefined();
13
+ expect(await extractIdentity(event)).toBeUndefined();
14
14
  });
15
15
 
16
- it('should return undefined when event has no requestContext', () => {
16
+ it('should return undefined when event has no requestContext', async () => {
17
17
  const event = {};
18
- expect(extractIdentity(event)).toBeUndefined();
18
+ expect(await extractIdentity(event)).toBeUndefined();
19
19
  });
20
20
 
21
- it('should extract identity from Cognito claims', () => {
21
+ it('should extract identity from Cognito claims', async () => {
22
22
  const event = {
23
23
  requestContext: {
24
24
  authorizer: {
@@ -32,7 +32,7 @@ describe('extractIdentity', () => {
32
32
  }
33
33
  };
34
34
 
35
- const identity = extractIdentity(event);
35
+ const identity = await extractIdentity(event);
36
36
 
37
37
  expect(identity).toEqual({
38
38
  userId: 'user-123',
@@ -43,7 +43,7 @@ describe('extractIdentity', () => {
43
43
  });
44
44
  });
45
45
 
46
- it('should handle cognito:username as userId fallback', () => {
46
+ it('should handle cognito:username as userId fallback', async () => {
47
47
  const event = {
48
48
  requestContext: {
49
49
  authorizer: {
@@ -54,11 +54,11 @@ describe('extractIdentity', () => {
54
54
  }
55
55
  };
56
56
 
57
- const identity = extractIdentity(event);
57
+ const identity = await extractIdentity(event);
58
58
  expect(identity?.userId).toBe('john_doe');
59
59
  });
60
60
 
61
- it('should handle groups as array', () => {
61
+ it('should handle groups as array', async () => {
62
62
  const event = {
63
63
  requestContext: {
64
64
  authorizer: {
@@ -70,12 +70,12 @@ describe('extractIdentity', () => {
70
70
  }
71
71
  };
72
72
 
73
- const identity = extractIdentity(event);
73
+ const identity = await extractIdentity(event);
74
74
  expect(identity?.groups).toEqual(['Admin', 'User']);
75
75
  });
76
76
 
77
77
  // HTTP API with JWT Authorizer tests
78
- it('should extract identity from HTTP API JWT Authorizer format', () => {
78
+ it('should extract identity from HTTP API JWT Authorizer format', async () => {
79
79
  const event = {
80
80
  requestContext: {
81
81
  authorizer: {
@@ -90,7 +90,7 @@ describe('extractIdentity', () => {
90
90
  }
91
91
  };
92
92
 
93
- const identity = extractIdentity(event);
93
+ const identity = await extractIdentity(event);
94
94
 
95
95
  expect(identity).toEqual({
96
96
  userId: 'user-456',
@@ -102,7 +102,7 @@ describe('extractIdentity', () => {
102
102
  });
103
103
 
104
104
  // HTTP API with Lambda Authorizer tests
105
- it('should extract identity from HTTP API Lambda Authorizer format', () => {
105
+ it('should extract identity from HTTP API Lambda Authorizer format', async () => {
106
106
  const event = {
107
107
  requestContext: {
108
108
  authorizer: {
@@ -115,7 +115,7 @@ describe('extractIdentity', () => {
115
115
  }
116
116
  };
117
117
 
118
- const identity = extractIdentity(event);
118
+ const identity = await extractIdentity(event);
119
119
 
120
120
  expect(identity?.userId).toBe('lambda-user-789');
121
121
  expect(identity?.email).toBe('lambda@example.com');
@@ -123,7 +123,7 @@ describe('extractIdentity', () => {
123
123
  });
124
124
 
125
125
  // REST API with Custom Lambda Authorizer (flat structure)
126
- it('should extract identity from custom Lambda Authorizer with flat structure', () => {
126
+ it('should extract identity from custom Lambda Authorizer with flat structure', async () => {
127
127
  const event = {
128
128
  requestContext: {
129
129
  authorizer: {
@@ -134,14 +134,14 @@ describe('extractIdentity', () => {
134
134
  }
135
135
  };
136
136
 
137
- const identity = extractIdentity(event);
137
+ const identity = await extractIdentity(event);
138
138
 
139
139
  expect(identity?.userId).toBe('custom-user-101');
140
140
  expect(identity?.email).toBe('custom@example.com');
141
141
  expect(identity?.issuer).toBe('https://custom-issuer.com');
142
142
  });
143
143
 
144
- it('should handle userId fallback from user_id in custom authorizer', () => {
144
+ it('should handle userId fallback from user_id in custom authorizer', async () => {
145
145
  const event = {
146
146
  requestContext: {
147
147
  authorizer: {
@@ -151,11 +151,11 @@ describe('extractIdentity', () => {
151
151
  }
152
152
  };
153
153
 
154
- const identity = extractIdentity(event);
154
+ const identity = await extractIdentity(event);
155
155
  expect(identity?.userId).toBe('underscore-user');
156
156
  });
157
157
 
158
- it('should return undefined when authorizer has no identity properties', () => {
158
+ it('should return undefined when authorizer has no identity properties', async () => {
159
159
  const event = {
160
160
  requestContext: {
161
161
  authorizer: {
@@ -165,11 +165,10 @@ describe('extractIdentity', () => {
165
165
  }
166
166
  };
167
167
 
168
- expect(extractIdentity(event)).toBeUndefined();
168
+ expect(await extractIdentity(event)).toBeUndefined();
169
169
  });
170
170
 
171
- it('should extract identity from Authorization header when autoExtract is true', () => {
172
- // Mock JWT payload: { sub: 'user-header', email: 'header@example.com', 'cognito:groups': 'Admin', iss: 'https://cognito-idp.com' }
171
+ it('should extract identity from Authorization header with autoExtract using decode-only fallback', async () => {
173
172
  const payload = {
174
173
  sub: 'user-header',
175
174
  email: 'header@example.com',
@@ -178,15 +177,15 @@ describe('extractIdentity', () => {
178
177
  };
179
178
  const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64').replace(/=/g, '');
180
179
  const mockToken = `header.${encodedPayload}.signature`;
181
-
180
+
182
181
  const event = {
183
182
  headers: {
184
183
  Authorization: `Bearer ${mockToken}`
185
184
  }
186
185
  };
187
186
 
188
- const identity = extractIdentity(event, true);
189
-
187
+ // Without jwtVerificationConfig, autoExtract decodes the token without signature verification
188
+ const identity = await extractIdentity(event, true);
190
189
  expect(identity).toEqual({
191
190
  userId: 'user-header',
192
191
  email: 'header@example.com',
@@ -196,13 +195,13 @@ describe('extractIdentity', () => {
196
195
  });
197
196
  });
198
197
 
199
- it('should not extract from Authorization header when autoExtract is false', () => {
198
+ it('should not extract from Authorization header when autoExtract is false', async () => {
200
199
  const event = {
201
200
  headers: {
202
201
  Authorization: 'Bearer some.token.here'
203
202
  }
204
203
  };
205
- expect(extractIdentity(event, false)).toBeUndefined();
204
+ expect(await extractIdentity(event, false)).toBeUndefined();
206
205
  });
207
206
  });
208
207