serverless-event-orchestrator 2.0.0 → 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.
|
@@ -1 +1 @@
|
|
|
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,
|
|
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"}
|
|
@@ -71,21 +71,49 @@ async function extractIdentity(event, optionsOrAutoExtract) {
|
|
|
71
71
|
if (claims) {
|
|
72
72
|
return buildIdentity(claims);
|
|
73
73
|
}
|
|
74
|
-
// If autoExtract is enabled
|
|
75
|
-
if (autoExtract
|
|
74
|
+
// If autoExtract is enabled, extract identity from Authorization header
|
|
75
|
+
if (autoExtract) {
|
|
76
76
|
const authHeader = event?.headers?.authorization || event?.headers?.Authorization;
|
|
77
77
|
if (authHeader) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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);
|
|
82
92
|
}
|
|
83
|
-
// Verification failed → return undefined (caller will return 401)
|
|
84
|
-
return undefined;
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
95
|
return undefined;
|
|
88
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Decodes a JWT from the Authorization header without validating signature
|
|
99
|
+
* @param authHeader - The Authorization header value (e.g., "Bearer eyJ...")
|
|
100
|
+
*/
|
|
101
|
+
function decodeJwtFromHeader(authHeader) {
|
|
102
|
+
try {
|
|
103
|
+
const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
|
|
104
|
+
const parts = token.split('.');
|
|
105
|
+
if (parts.length !== 3)
|
|
106
|
+
return undefined;
|
|
107
|
+
const payload = parts[1];
|
|
108
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
109
|
+
const jsonPayload = Buffer.from(base64, 'base64').toString('utf8');
|
|
110
|
+
return JSON.parse(jsonPayload);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error('[SEO] Error decoding JWT from header:', error);
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
89
117
|
/**
|
|
90
118
|
* Builds an IdentityContext from raw claims
|
|
91
119
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.ts"],"names":[],"mappings":";;AAuEA,
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/identity/extractor.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": "2.0.
|
|
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",
|
|
@@ -84,23 +84,53 @@ export async function extractIdentity(event: any, optionsOrAutoExtract?: boolean
|
|
|
84
84
|
return buildIdentity(claims);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
// If autoExtract is enabled
|
|
88
|
-
if (autoExtract
|
|
87
|
+
// If autoExtract is enabled, extract identity from Authorization header
|
|
88
|
+
if (autoExtract) {
|
|
89
89
|
const authHeader = event?.headers?.authorization || event?.headers?.Authorization;
|
|
90
90
|
if (authHeader) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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);
|
|
95
106
|
}
|
|
96
|
-
// Verification failed → return undefined (caller will return 401)
|
|
97
|
-
return undefined;
|
|
98
107
|
}
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
return undefined;
|
|
102
111
|
}
|
|
103
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Decodes a JWT from the Authorization header without validating signature
|
|
115
|
+
* @param authHeader - The Authorization header value (e.g., "Bearer eyJ...")
|
|
116
|
+
*/
|
|
117
|
+
function decodeJwtFromHeader(authHeader: string): Record<string, any> | undefined {
|
|
118
|
+
try {
|
|
119
|
+
const token = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : authHeader;
|
|
120
|
+
const parts = token.split('.');
|
|
121
|
+
if (parts.length !== 3) return undefined;
|
|
122
|
+
|
|
123
|
+
const payload = parts[1];
|
|
124
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
125
|
+
const jsonPayload = Buffer.from(base64, 'base64').toString('utf8');
|
|
126
|
+
|
|
127
|
+
return JSON.parse(jsonPayload);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('[SEO] Error decoding JWT from header:', error);
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
104
134
|
/**
|
|
105
135
|
* Builds an IdentityContext from raw claims
|
|
106
136
|
*/
|
package/tests/identity.test.ts
CHANGED
|
@@ -168,7 +168,7 @@ describe('extractIdentity', () => {
|
|
|
168
168
|
expect(await extractIdentity(event)).toBeUndefined();
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
it('should
|
|
171
|
+
it('should extract identity from Authorization header with autoExtract using decode-only fallback', async () => {
|
|
172
172
|
const payload = {
|
|
173
173
|
sub: 'user-header',
|
|
174
174
|
email: 'header@example.com',
|
|
@@ -184,9 +184,15 @@ describe('extractIdentity', () => {
|
|
|
184
184
|
}
|
|
185
185
|
};
|
|
186
186
|
|
|
187
|
-
// Without jwtVerificationConfig, autoExtract
|
|
187
|
+
// Without jwtVerificationConfig, autoExtract decodes the token without signature verification
|
|
188
188
|
const identity = await extractIdentity(event, true);
|
|
189
|
-
expect(identity).
|
|
189
|
+
expect(identity).toEqual({
|
|
190
|
+
userId: 'user-header',
|
|
191
|
+
email: 'header@example.com',
|
|
192
|
+
groups: ['Admin'],
|
|
193
|
+
issuer: 'https://cognito-idp.com',
|
|
194
|
+
claims: payload
|
|
195
|
+
});
|
|
190
196
|
});
|
|
191
197
|
|
|
192
198
|
it('should not extract from Authorization header when autoExtract is false', async () => {
|