serverless-offline 8.6.0 → 8.7.0
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.
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = authValidateContext;
|
|
7
|
+
|
|
8
|
+
var _boom = _interopRequireDefault(require("@hapi/boom"));
|
|
9
|
+
|
|
10
|
+
var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
|
|
11
|
+
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
|
|
14
|
+
function internalServerError(message) {
|
|
15
|
+
const errorType = 'AuthorizerConfigurationException';
|
|
16
|
+
|
|
17
|
+
const error = _boom.default.internal();
|
|
18
|
+
|
|
19
|
+
error.output.payload.message = message;
|
|
20
|
+
error.output.payload.error = errorType;
|
|
21
|
+
error.output.headers['x-amzn-ErrorType'] = errorType;
|
|
22
|
+
return error;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isValidContext(context) {
|
|
26
|
+
return Object.values(context).every(i => typeof i === 'string' || typeof i === 'boolean' || typeof i === 'number');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function transform(context) {
|
|
30
|
+
Object.keys(context).forEach(i => {
|
|
31
|
+
context[i] = context[i].toString();
|
|
32
|
+
});
|
|
33
|
+
return context;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function authValidateContext(context, authFunName) {
|
|
37
|
+
if (typeof context !== 'object') {
|
|
38
|
+
return internalServerError('Authorizer response context must be an object');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!isValidContext(context)) {
|
|
42
|
+
const error = 'Authorizer response context values must be of type string, number, or boolean';
|
|
43
|
+
(0, _serverlessLog.default)(`Detected invalid value types returned in authorizer context: (λ: ${authFunName}). ${error}. ` + 'More info: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html');
|
|
44
|
+
return internalServerError(error);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return transform(context);
|
|
48
|
+
}
|
|
@@ -9,6 +9,8 @@ var _boom = _interopRequireDefault(require("@hapi/boom"));
|
|
|
9
9
|
|
|
10
10
|
var _authCanExecuteResource = _interopRequireDefault(require("../authCanExecuteResource.js"));
|
|
11
11
|
|
|
12
|
+
var _authValidateContext = _interopRequireDefault(require("./authValidateContext.js"));
|
|
13
|
+
|
|
12
14
|
var _debugLog = _interopRequireDefault(require("../../debugLog.js"));
|
|
13
15
|
|
|
14
16
|
var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
|
|
@@ -113,11 +115,9 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
|
|
|
113
115
|
|
|
114
116
|
try {
|
|
115
117
|
const result = await lambdaFunction.runHandler();
|
|
116
|
-
if (result === 'Unauthorized') return _boom.default.unauthorized('Unauthorized'); //
|
|
117
|
-
|
|
118
|
-
const policy = result; // Validate that the policy document has the principalId set
|
|
118
|
+
if (result === 'Unauthorized') return _boom.default.unauthorized('Unauthorized'); // Validate that the policy document has the principalId set
|
|
119
119
|
|
|
120
|
-
if (!
|
|
120
|
+
if (!result.principalId) {
|
|
121
121
|
if (log) {
|
|
122
122
|
log.notice(`Authorization response did not include a principalId: (λ: ${authFunName})`);
|
|
123
123
|
} else {
|
|
@@ -127,7 +127,7 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
|
|
|
127
127
|
return _boom.default.forbidden('No principalId set on the Response');
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
if (!(0, _authCanExecuteResource.default)(
|
|
130
|
+
if (!(0, _authCanExecuteResource.default)(result.policyDocument, event.methodArn)) {
|
|
131
131
|
if (log) {
|
|
132
132
|
log.notice(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`);
|
|
133
133
|
} else {
|
|
@@ -135,6 +135,18 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
return _boom.default.forbidden('User is not authorized to access this resource');
|
|
138
|
+
} // validate the resulting context, ensuring that all
|
|
139
|
+
// values are either string, number, or boolean types
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if (result.context) {
|
|
143
|
+
const validationResult = (0, _authValidateContext.default)(result.context, authFunName);
|
|
144
|
+
|
|
145
|
+
if (validationResult instanceof Error) {
|
|
146
|
+
return validationResult;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
result.context = validationResult;
|
|
138
150
|
}
|
|
139
151
|
|
|
140
152
|
if (log) {
|
|
@@ -145,17 +157,16 @@ function createAuthScheme(authorizerOptions, provider, lambda, {
|
|
|
145
157
|
|
|
146
158
|
const authorizer = {
|
|
147
159
|
integrationLatency: '42',
|
|
148
|
-
principalId:
|
|
149
|
-
...
|
|
160
|
+
principalId: result.principalId,
|
|
161
|
+
...result.context
|
|
150
162
|
}; // Set the credentials for the rest of the pipeline
|
|
151
|
-
// return resolve(
|
|
152
163
|
|
|
153
164
|
return h.authenticated({
|
|
154
165
|
credentials: {
|
|
155
166
|
authorizer,
|
|
156
|
-
context:
|
|
157
|
-
principalId:
|
|
158
|
-
usageIdentifierKey:
|
|
167
|
+
context: result.context,
|
|
168
|
+
principalId: result.principalId,
|
|
169
|
+
usageIdentifierKey: result.usageIdentifierKey
|
|
159
170
|
}
|
|
160
171
|
});
|
|
161
172
|
} catch (err) {
|
|
@@ -17,6 +17,10 @@ var id = 0;
|
|
|
17
17
|
|
|
18
18
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
19
19
|
|
|
20
|
+
const {
|
|
21
|
+
parse
|
|
22
|
+
} = JSON;
|
|
23
|
+
|
|
20
24
|
var _path = /*#__PURE__*/_classPrivateFieldLooseKey("path");
|
|
21
25
|
|
|
22
26
|
var _request = /*#__PURE__*/_classPrivateFieldLooseKey("request");
|
|
@@ -51,6 +55,26 @@ class LambdaIntegrationEvent {
|
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
create() {
|
|
58
|
+
if (process.env.AUTHORIZER) {
|
|
59
|
+
try {
|
|
60
|
+
const authorizerContext = parse(process.env.AUTHORIZER);
|
|
61
|
+
|
|
62
|
+
if (authorizerContext) {
|
|
63
|
+
_classPrivateFieldLooseBase(this, _request)[_request].auth = { ..._classPrivateFieldLooseBase(this, _request)[_request].auth,
|
|
64
|
+
credentials: {
|
|
65
|
+
authorizer: authorizerContext
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (this.log) {
|
|
71
|
+
this.log.error('Could not parse process.env.AUTHORIZER, make sure it is correct JSON');
|
|
72
|
+
} else {
|
|
73
|
+
console.error('Serverless-offline: Could not parse process.env.AUTHORIZER, make sure it is correct JSON.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
54
78
|
const velocityContext = new _VelocityContext.default(_classPrivateFieldLooseBase(this, _request)[_request], _classPrivateFieldLooseBase(this, _stage)[_stage], _classPrivateFieldLooseBase(this, _request)[_request].payload || {}, _classPrivateFieldLooseBase(this, _path)[_path]).getContext();
|
|
55
79
|
const event = (0, _renderVelocityTemplateObject.default)(_classPrivateFieldLooseBase(this, _requestTemplate)[_requestTemplate], velocityContext, this.v3Utils);
|
|
56
80
|
return event;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"dedicatedTo": "Blue, a great migrating bird.",
|
|
3
3
|
"name": "serverless-offline",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.7.0",
|
|
5
5
|
"description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/main.js",
|