serverless-event-orchestrator 1.3.0 → 1.3.2
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/dist/identity/extractor.js +1 -1
- package/dist/identity/extractor.js.map +1 -1
- package/dist/tenant/helpers.d.ts +4 -0
- package/dist/tenant/helpers.d.ts.map +1 -1
- package/dist/tenant/helpers.js +24 -8
- package/dist/tenant/helpers.js.map +1 -1
- package/package.json +1 -1
- package/src/identity/extractor.ts +1 -1
- package/src/tenant/helpers.ts +25 -8
- package/tests/middleware/init-tenant-context.test.ts +1 -1
- package/tests/tenant/helpers.test.ts +67 -2
|
@@ -69,7 +69,7 @@ function extractIdentity(event, autoExtract = false) {
|
|
|
69
69
|
return undefined;
|
|
70
70
|
}
|
|
71
71
|
return {
|
|
72
|
-
userId: claims.
|
|
72
|
+
userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
|
|
73
73
|
email: claims.email,
|
|
74
74
|
groups: parseGroups(claims['cognito:groups'] || claims.groups),
|
|
75
75
|
issuer: claims.iss,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":";;AA0DA,0CAuBC;AAwCD,8CAMC;AAQD,wCAKC;AAQD,kCAIC;AAQD,oCAIC;AAlKD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,SAAS,aAAa,CAAC,UAAe;IACpC,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAElC,mEAAmE;IACnE,IAAI,UAAU,CAAC,MAAM,IAAI,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/D,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,yDAAyD;IACzD,IAAI,UAAU,CAAC,GAAG,EAAE,MAAM,IAAI,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxE,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED,wDAAwD;IACxD,IAAI,UAAU,CAAC,MAAM,IAAI,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/D,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,2EAA2E;IAC3E,8EAA8E;IAC9E,IAAI,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,GAAQ;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC7F,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,KAAU,EAAE,cAAuB,KAAK;IACtE,MAAM,UAAU,GAAG,KAAK,EAAE,cAAc,EAAE,UAAU,CAAC;IACrD,IAAI,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAEvC,kGAAkG;IAClG,IAAI,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,KAAK,EAAE,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC;QAClF,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":"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"}
|
package/dist/tenant/helpers.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { TenantInfo } from './types.js';
|
|
|
3
3
|
* Builds a TenantInfo from TenantClaims in the JWT.
|
|
4
4
|
* Used by initTenantContext middleware in serverless-event-orchestrator.
|
|
5
5
|
*
|
|
6
|
+
* Supports claims with or without the `custom:` prefix:
|
|
7
|
+
* - `custom:tenantId` (Cognito user pool custom attributes)
|
|
8
|
+
* - `tenantId` (Cognito Pre Token Generation V2 added claims)
|
|
9
|
+
*
|
|
6
10
|
* @param claims - Partial claims object from JWT (event.context.identity.claims)
|
|
7
11
|
* @returns TenantInfo if all required fields are present, undefined otherwise
|
|
8
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tenant/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/tenant/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa7C;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,UAAU,GAAG,SAAS,CA2BxF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC1C,UAAU,GAAG,SAAS,CAwBxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB9E"}
|
package/dist/tenant/helpers.js
CHANGED
|
@@ -4,18 +4,34 @@ exports.tenantInfoFromClaims = tenantInfoFromClaims;
|
|
|
4
4
|
exports.tenantInfoFromHeaders = tenantInfoFromHeaders;
|
|
5
5
|
exports.tenantInfoToHeaders = tenantInfoToHeaders;
|
|
6
6
|
const types_js_1 = require("./types.js");
|
|
7
|
+
/**
|
|
8
|
+
* Resolves a claim value by checking both `custom:{key}` and `{key}` formats.
|
|
9
|
+
* Cognito Pre Token Generation V2 adds claims WITHOUT the `custom:` prefix,
|
|
10
|
+
* while Cognito user pool custom attributes use the `custom:` prefix.
|
|
11
|
+
* This helper supports both conventions transparently.
|
|
12
|
+
*/
|
|
13
|
+
function getClaim(claims, key) {
|
|
14
|
+
return claims[`custom:${key}`] ?? claims[key];
|
|
15
|
+
}
|
|
7
16
|
/**
|
|
8
17
|
* Builds a TenantInfo from TenantClaims in the JWT.
|
|
9
18
|
* Used by initTenantContext middleware in serverless-event-orchestrator.
|
|
10
19
|
*
|
|
20
|
+
* Supports claims with or without the `custom:` prefix:
|
|
21
|
+
* - `custom:tenantId` (Cognito user pool custom attributes)
|
|
22
|
+
* - `tenantId` (Cognito Pre Token Generation V2 added claims)
|
|
23
|
+
*
|
|
11
24
|
* @param claims - Partial claims object from JWT (event.context.identity.claims)
|
|
12
25
|
* @returns TenantInfo if all required fields are present, undefined otherwise
|
|
13
26
|
*/
|
|
14
27
|
function tenantInfoFromClaims(claims) {
|
|
15
|
-
const tenantId = claims
|
|
16
|
-
const tenantType = claims
|
|
17
|
-
const userId = claims
|
|
18
|
-
const countryCode = claims
|
|
28
|
+
const tenantId = getClaim(claims, 'tenantId');
|
|
29
|
+
const tenantType = getClaim(claims, 'tenantType');
|
|
30
|
+
const userId = getClaim(claims, 'userId') || claims['sub'];
|
|
31
|
+
const countryCode = getClaim(claims, 'countryCode');
|
|
32
|
+
const personProfileId = getClaim(claims, 'personProfileId');
|
|
33
|
+
const orgProfileId = getClaim(claims, 'orgProfileId');
|
|
34
|
+
const hasCRM = getClaim(claims, 'hasCRM');
|
|
19
35
|
if (!tenantId || !tenantType || !userId || !countryCode) {
|
|
20
36
|
return undefined;
|
|
21
37
|
}
|
|
@@ -26,11 +42,11 @@ function tenantInfoFromClaims(claims) {
|
|
|
26
42
|
tenantId,
|
|
27
43
|
tenantType,
|
|
28
44
|
userId,
|
|
29
|
-
personProfileId
|
|
30
|
-
orgProfileId
|
|
45
|
+
personProfileId,
|
|
46
|
+
orgProfileId,
|
|
31
47
|
countryCode,
|
|
32
|
-
plan: (0, types_js_1.isPlan)(claims
|
|
33
|
-
hasCRM
|
|
48
|
+
plan: (0, types_js_1.isPlan)(getClaim(claims, 'plan')) ? getClaim(claims, 'plan') : undefined,
|
|
49
|
+
hasCRM,
|
|
34
50
|
};
|
|
35
51
|
}
|
|
36
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tenant/helpers.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/tenant/helpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serverless-event-orchestrator",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
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",
|
|
@@ -73,7 +73,7 @@ export function extractIdentity(event: any, autoExtract: boolean = false): Ident
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
return {
|
|
76
|
-
userId: claims.
|
|
76
|
+
userId: claims.userId || claims.user_id || claims['cognito:username'] || claims.sub,
|
|
77
77
|
email: claims.email,
|
|
78
78
|
groups: parseGroups(claims['cognito:groups'] || claims.groups),
|
|
79
79
|
issuer: claims.iss,
|
package/src/tenant/helpers.ts
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
import type { TenantInfo } from './types.js';
|
|
2
2
|
import { isTenantType, isPlan, TENANT_HEADERS } from './types.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Resolves a claim value by checking both `custom:{key}` and `{key}` formats.
|
|
6
|
+
* Cognito Pre Token Generation V2 adds claims WITHOUT the `custom:` prefix,
|
|
7
|
+
* while Cognito user pool custom attributes use the `custom:` prefix.
|
|
8
|
+
* This helper supports both conventions transparently.
|
|
9
|
+
*/
|
|
10
|
+
function getClaim(claims: Record<string, any>, key: string): any {
|
|
11
|
+
return claims[`custom:${key}`] ?? claims[key];
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
/**
|
|
5
15
|
* Builds a TenantInfo from TenantClaims in the JWT.
|
|
6
16
|
* Used by initTenantContext middleware in serverless-event-orchestrator.
|
|
7
17
|
*
|
|
18
|
+
* Supports claims with or without the `custom:` prefix:
|
|
19
|
+
* - `custom:tenantId` (Cognito user pool custom attributes)
|
|
20
|
+
* - `tenantId` (Cognito Pre Token Generation V2 added claims)
|
|
21
|
+
*
|
|
8
22
|
* @param claims - Partial claims object from JWT (event.context.identity.claims)
|
|
9
23
|
* @returns TenantInfo if all required fields are present, undefined otherwise
|
|
10
24
|
*/
|
|
11
25
|
export function tenantInfoFromClaims(claims: Record<string, any>): TenantInfo | undefined {
|
|
12
|
-
const tenantId = claims
|
|
13
|
-
const tenantType = claims
|
|
14
|
-
const userId = claims
|
|
15
|
-
const countryCode = claims
|
|
26
|
+
const tenantId = getClaim(claims, 'tenantId');
|
|
27
|
+
const tenantType = getClaim(claims, 'tenantType');
|
|
28
|
+
const userId = getClaim(claims, 'userId') || claims['sub'];
|
|
29
|
+
const countryCode = getClaim(claims, 'countryCode');
|
|
30
|
+
const personProfileId = getClaim(claims, 'personProfileId');
|
|
31
|
+
const orgProfileId = getClaim(claims, 'orgProfileId');
|
|
32
|
+
const hasCRM = getClaim(claims, 'hasCRM');
|
|
16
33
|
|
|
17
34
|
if (!tenantId || !tenantType || !userId || !countryCode) {
|
|
18
35
|
return undefined;
|
|
@@ -26,11 +43,11 @@ export function tenantInfoFromClaims(claims: Record<string, any>): TenantInfo |
|
|
|
26
43
|
tenantId,
|
|
27
44
|
tenantType,
|
|
28
45
|
userId,
|
|
29
|
-
personProfileId
|
|
30
|
-
orgProfileId
|
|
46
|
+
personProfileId,
|
|
47
|
+
orgProfileId,
|
|
31
48
|
countryCode,
|
|
32
|
-
plan: isPlan(claims
|
|
33
|
-
hasCRM
|
|
49
|
+
plan: isPlan(getClaim(claims, 'plan')) ? getClaim(claims, 'plan') : undefined,
|
|
50
|
+
hasCRM,
|
|
34
51
|
};
|
|
35
52
|
}
|
|
36
53
|
|
|
@@ -60,7 +60,7 @@ describe('initTenantContext', () => {
|
|
|
60
60
|
expect(result.context.tenantInfo?.tenantType).toBe('ORG');
|
|
61
61
|
expect(result.context.tenantInfo?.countryCode).toBe('CO');
|
|
62
62
|
expect(result.context.tenantInfo?.plan).toBe('PRO');
|
|
63
|
-
expect(result.context.tenantInfo?.hasCRM).toBe(true);
|
|
63
|
+
expect(result.context.tenantInfo?.hasCRM).toBe('true');
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
it('initializes TenantContext (AsyncLocalStorage)', async () => {
|
|
@@ -47,7 +47,7 @@ describe('tenantInfoFromClaims', () => {
|
|
|
47
47
|
personProfileId: 'person_001',
|
|
48
48
|
orgProfileId: 'org_abc',
|
|
49
49
|
plan: 'PRO',
|
|
50
|
-
hasCRM: true,
|
|
50
|
+
hasCRM: 'true',
|
|
51
51
|
});
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -67,7 +67,7 @@ describe('tenantInfoFromClaims', () => {
|
|
|
67
67
|
|
|
68
68
|
it('hasCRM is false if claim is not "true"', () => {
|
|
69
69
|
const result = tenantInfoFromClaims({ ...validClaims, 'custom:hasCRM': 'false' });
|
|
70
|
-
expect(result?.hasCRM).toBe(false);
|
|
70
|
+
expect(result?.hasCRM).toBe('false');
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it('plan is undefined if claim is not a valid Plan', () => {
|
|
@@ -85,6 +85,71 @@ describe('tenantInfoFromClaims', () => {
|
|
|
85
85
|
const result = tenantInfoFromClaims(claims);
|
|
86
86
|
expect(result?.userId).toBe('cognito-sub-123');
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
describe('without custom: prefix (Cognito Pre Token Generation V2)', () => {
|
|
90
|
+
const v2Claims = {
|
|
91
|
+
tenantId: 'org_abc',
|
|
92
|
+
tenantType: 'ORG',
|
|
93
|
+
userId: 'user_001',
|
|
94
|
+
countryCode: 'CO',
|
|
95
|
+
personProfileId: 'person_001',
|
|
96
|
+
orgProfileId: 'org_abc',
|
|
97
|
+
plan: 'PRO',
|
|
98
|
+
hasCRM: 'true',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
it('builds complete TenantInfo from claims without custom: prefix', () => {
|
|
102
|
+
const result = tenantInfoFromClaims(v2Claims);
|
|
103
|
+
expect(result).toEqual({
|
|
104
|
+
tenantId: 'org_abc',
|
|
105
|
+
tenantType: 'ORG',
|
|
106
|
+
userId: 'user_001',
|
|
107
|
+
countryCode: 'CO',
|
|
108
|
+
personProfileId: 'person_001',
|
|
109
|
+
orgProfileId: 'org_abc',
|
|
110
|
+
plan: 'PRO',
|
|
111
|
+
hasCRM: 'true',
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('returns undefined if tenantId is missing (no prefix)', () => {
|
|
116
|
+
const { tenantId: _, ...claims } = v2Claims;
|
|
117
|
+
expect(tenantInfoFromClaims(claims)).toBeUndefined();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('returns undefined if tenantType is invalid (no prefix)', () => {
|
|
121
|
+
expect(tenantInfoFromClaims({ ...v2Claims, tenantType: 'INVALID' })).toBeUndefined();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('prefers custom: prefix over unprefixed when both exist', () => {
|
|
125
|
+
const mixedClaims = {
|
|
126
|
+
'custom:tenantId': 'from_custom',
|
|
127
|
+
tenantId: 'from_plain',
|
|
128
|
+
'custom:tenantType': 'ORG',
|
|
129
|
+
tenantType: 'PERSON',
|
|
130
|
+
'custom:userId': 'user_custom',
|
|
131
|
+
userId: 'user_plain',
|
|
132
|
+
'custom:countryCode': 'CO',
|
|
133
|
+
countryCode: 'US',
|
|
134
|
+
};
|
|
135
|
+
const result = tenantInfoFromClaims(mixedClaims);
|
|
136
|
+
expect(result?.tenantId).toBe('from_custom');
|
|
137
|
+
expect(result?.tenantType).toBe('ORG');
|
|
138
|
+
expect(result?.userId).toBe('user_custom');
|
|
139
|
+
expect(result?.countryCode).toBe('CO');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('uses sub as fallback for userId without prefix', () => {
|
|
143
|
+
const claims = {
|
|
144
|
+
tenantId: 'org_abc',
|
|
145
|
+
tenantType: 'ORG',
|
|
146
|
+
sub: 'cognito-sub-123',
|
|
147
|
+
countryCode: 'CO',
|
|
148
|
+
};
|
|
149
|
+
const result = tenantInfoFromClaims(claims);
|
|
150
|
+
expect(result?.userId).toBe('cognito-sub-123');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
88
153
|
});
|
|
89
154
|
|
|
90
155
|
describe('tenantInfoFromHeaders / tenantInfoToHeaders', () => {
|