@valentine-efagene/qshelter-common 2.0.131 → 2.0.133

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.
@@ -23,8 +23,9 @@ export interface AuthContext {
23
23
  * Extracts auth context from API Gateway authorizer or JWT token.
24
24
  *
25
25
  * Priority:
26
- * 1. Production: requestContext.authorizer (set by API Gateway Lambda Authorizer)
27
- * 2. Fallback: Decode JWT from Authorization header (LocalStack/dev/tests)
26
+ * 1. HTTP API v2 simple response: requestContext.authorizer.lambda (enableSimpleResponses=true)
27
+ * 2. REST API / HTTP API: requestContext.authorizer (enableSimpleResponses=false)
28
+ * 3. Fallback: Decode JWT from Authorization header (LocalStack/dev/tests)
28
29
  *
29
30
  * In production, the Lambda Authorizer validates the JWT and injects context.
30
31
  * In LocalStack (no authorizer), we decode the JWT directly since it contains
@@ -19,8 +19,9 @@ function decodeJwtPayload(token) {
19
19
  * Extracts auth context from API Gateway authorizer or JWT token.
20
20
  *
21
21
  * Priority:
22
- * 1. Production: requestContext.authorizer (set by API Gateway Lambda Authorizer)
23
- * 2. Fallback: Decode JWT from Authorization header (LocalStack/dev/tests)
22
+ * 1. HTTP API v2 simple response: requestContext.authorizer.lambda (enableSimpleResponses=true)
23
+ * 2. REST API / HTTP API: requestContext.authorizer (enableSimpleResponses=false)
24
+ * 3. Fallback: Decode JWT from Authorization header (LocalStack/dev/tests)
24
25
  *
25
26
  * In production, the Lambda Authorizer validates the JWT and injects context.
26
27
  * In LocalStack (no authorizer), we decode the JWT directly since it contains
@@ -31,8 +32,18 @@ function decodeJwtPayload(token) {
31
32
  */
32
33
  export function extractAuthContext(req) {
33
34
  const lambdaReq = req;
34
- // Production: API Gateway Lambda integration populates requestContext
35
35
  const authorizer = lambdaReq.requestContext?.authorizer;
36
+ // HTTP API v2 with enableSimpleResponses=true: context is under authorizer.lambda
37
+ const lambdaContext = authorizer?.lambda;
38
+ if (lambdaContext?.userId && lambdaContext?.tenantId) {
39
+ return {
40
+ userId: lambdaContext.userId,
41
+ tenantId: lambdaContext.tenantId,
42
+ email: lambdaContext.email,
43
+ roles: lambdaContext.roles ? JSON.parse(lambdaContext.roles) : [],
44
+ };
45
+ }
46
+ // REST API / HTTP API with enableSimpleResponses=false: context is directly on authorizer
36
47
  if (authorizer?.userId && authorizer?.tenantId) {
37
48
  return {
38
49
  userId: authorizer.userId,
@@ -10,7 +10,13 @@ declare global {
10
10
  tenantContext?: TenantContext;
11
11
  tenantPrisma?: TenantPrismaClient | PrismaClient;
12
12
  /**
13
- * API Gateway context added by serverless-express
13
+ * API Gateway context added by serverless-express.
14
+ *
15
+ * With HTTP API v2 and enableSimpleResponses=true, context is under:
16
+ * authorizer.lambda.{field}
17
+ *
18
+ * With REST API or enableSimpleResponses=false, context is under:
19
+ * authorizer.{field}
14
20
  */
15
21
  apiGateway?: {
16
22
  event: {
@@ -20,6 +26,12 @@ declare global {
20
26
  email?: string;
21
27
  roles?: string;
22
28
  tenantId?: string;
29
+ lambda?: {
30
+ userId?: string;
31
+ email?: string;
32
+ roles?: string;
33
+ tenantId?: string;
34
+ };
23
35
  };
24
36
  };
25
37
  };
@@ -21,7 +21,10 @@ export function createTenantMiddleware(options) {
21
21
  return function tenantMiddleware(req, res, next) {
22
22
  try {
23
23
  // 1. Try Lambda authorizer context first (production)
24
- const authorizerContext = req.apiGateway?.event?.requestContext?.authorizer;
24
+ // HTTP API v2 with enableSimpleResponses=true nests context under authorizer.lambda
25
+ const authorizer = req.apiGateway?.event?.requestContext?.authorizer;
26
+ const lambdaContext = authorizer?.lambda;
27
+ const authorizerContext = lambdaContext || authorizer;
25
28
  // 2. Fall back to x-authorizer-* headers (test/development)
26
29
  const headers = req.headers;
27
30
  const tenantId = authorizerContext?.tenantId || headers['x-authorizer-tenant-id'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valentine-efagene/qshelter-common",
3
- "version": "2.0.131",
3
+ "version": "2.0.133",
4
4
  "description": "Shared database schemas and utilities for QShelter services",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",