serverless-offline 8.7.0 → 9.0.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.
- package/README.md +91 -95
- package/package.json +41 -69
- package/src/ServerlessOffline.js +412 -0
- package/src/config/commandOptions.js +155 -0
- package/src/config/constants.js +22 -0
- package/{dist → src}/config/defaultOptions.js +8 -17
- package/src/config/index.js +4 -0
- package/src/config/supportedRuntimes.js +47 -0
- package/src/events/authCanExecuteResource.js +35 -0
- package/src/events/authFunctionNameExtractor.js +75 -0
- package/src/events/authMatchPolicyResource.js +71 -0
- package/src/events/authValidateContext.js +51 -0
- package/src/events/http/Endpoint.js +135 -0
- package/src/events/http/Http.js +50 -0
- package/src/events/http/HttpEventDefinition.js +20 -0
- package/src/events/http/HttpServer.js +1277 -0
- package/src/events/http/OfflineEndpoint.js +33 -0
- package/src/events/http/authJWTSettingsExtractor.js +70 -0
- package/src/events/http/createAuthScheme.js +176 -0
- package/src/events/http/createJWTAuthScheme.js +106 -0
- package/src/events/http/index.js +1 -0
- package/src/events/http/javaHelpers.js +102 -0
- package/src/events/http/lambda-events/LambdaIntegrationEvent.js +57 -0
- package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +233 -0
- package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +190 -0
- package/src/events/http/lambda-events/VelocityContext.js +147 -0
- package/src/events/http/lambda-events/index.js +4 -0
- package/src/events/http/lambda-events/renderVelocityTemplateObject.js +93 -0
- package/{dist → src}/events/http/parseResources.js +73 -78
- package/src/events/http/payloadSchemaValidator.js +13 -0
- package/{dist → src}/events/http/templates/offline-default.req.vm +0 -0
- package/{dist → src}/events/http/templates/offline-default.res.vm +0 -0
- package/src/events/schedule/Schedule.js +131 -0
- package/src/events/schedule/ScheduleEvent.js +18 -0
- package/src/events/schedule/ScheduleEventDefinition.js +21 -0
- package/src/events/schedule/index.js +1 -0
- package/src/events/websocket/HttpServer.js +69 -0
- package/src/events/websocket/WebSocket.js +52 -0
- package/src/events/websocket/WebSocketClients.js +462 -0
- package/src/events/websocket/WebSocketEventDefinition.js +18 -0
- package/src/events/websocket/WebSocketServer.js +73 -0
- package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +16 -0
- package/src/events/websocket/http-routes/_catchAll/index.js +1 -0
- package/src/events/websocket/http-routes/connections/ConnectionsController.js +28 -0
- package/src/events/websocket/http-routes/connections/connectionsRoutes.js +70 -0
- package/src/events/websocket/http-routes/connections/index.js +1 -0
- package/src/events/websocket/http-routes/index.js +2 -0
- package/src/events/websocket/index.js +1 -0
- package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +65 -0
- package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +68 -0
- package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +31 -0
- package/src/events/websocket/lambda-events/WebSocketEvent.js +29 -0
- package/src/events/websocket/lambda-events/WebSocketRequestContext.js +67 -0
- package/src/events/websocket/lambda-events/index.js +4 -0
- package/src/index.js +12 -0
- package/src/lambda/HttpServer.js +108 -0
- package/src/lambda/Lambda.js +68 -0
- package/src/lambda/LambdaContext.js +33 -0
- package/src/lambda/LambdaFunction.js +308 -0
- package/src/lambda/LambdaFunctionPool.js +109 -0
- package/src/lambda/__tests__/LambdaContext.test.js +30 -0
- package/src/lambda/__tests__/LambdaFunction.test.js +196 -0
- package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsJSONObject.fixture.js +47 -0
- package/src/lambda/__tests__/fixtures/Lambda/LambdaFunctionThatReturnsNativeString.fixture.js +46 -0
- package/src/lambda/__tests__/fixtures/Lambda/package.json +3 -0
- package/src/lambda/__tests__/fixtures/lambdaFunction.fixture.js +145 -0
- package/src/lambda/__tests__/fixtures/package.json +3 -0
- package/src/lambda/__tests__/routes/invocations/InvocationsController.test.js +42 -0
- package/src/lambda/handler-runner/HandlerRunner.js +136 -0
- package/src/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +72 -0
- package/src/lambda/handler-runner/child-process-runner/childProcessHelper.js +42 -0
- package/src/lambda/handler-runner/child-process-runner/index.js +1 -0
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +417 -0
- package/src/lambda/handler-runner/docker-runner/DockerImage.js +35 -0
- package/src/lambda/handler-runner/docker-runner/DockerRunner.js +63 -0
- package/src/lambda/handler-runner/docker-runner/index.js +1 -0
- package/src/lambda/handler-runner/go-runner/GoRunner.js +166 -0
- package/src/lambda/handler-runner/go-runner/index.js +1 -0
- package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +125 -0
- package/src/lambda/handler-runner/in-process-runner/index.js +1 -0
- package/src/lambda/handler-runner/index.js +1 -0
- package/src/lambda/handler-runner/java-runner/JavaRunner.js +114 -0
- package/src/lambda/handler-runner/java-runner/index.js +1 -0
- package/src/lambda/handler-runner/python-runner/PythonRunner.js +138 -0
- package/src/lambda/handler-runner/python-runner/index.js +1 -0
- package/{dist → src}/lambda/handler-runner/python-runner/invoke.py +0 -0
- package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +107 -0
- package/src/lambda/handler-runner/ruby-runner/index.js +1 -0
- package/{dist → src}/lambda/handler-runner/ruby-runner/invoke.rb +0 -0
- package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +70 -0
- package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -0
- package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +29 -0
- package/src/lambda/index.js +1 -0
- package/src/lambda/routes/index.js +2 -0
- package/src/lambda/routes/invocations/InvocationsController.js +102 -0
- package/src/lambda/routes/invocations/index.js +1 -0
- package/src/lambda/routes/invocations/invocationsRoute.js +77 -0
- package/src/lambda/routes/invoke-async/InvokeAsyncController.js +20 -0
- package/src/lambda/routes/invoke-async/index.js +1 -0
- package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +33 -0
- package/src/utils/__tests__/createUniqueId.test.js +18 -0
- package/src/utils/__tests__/formatToClfTime.test.js +14 -0
- package/src/utils/__tests__/generateHapiPath.test.js +46 -0
- package/src/utils/__tests__/lowerCaseKeys.test.js +30 -0
- package/src/utils/__tests__/parseHeaders.test.js +13 -0
- package/src/utils/__tests__/parseMultiValueHeaders.test.js +24 -0
- package/src/utils/__tests__/parseMultiValueQueryStringParameters.test.js +159 -0
- package/src/utils/__tests__/parseQueryStringParameters.test.js +15 -0
- package/src/utils/__tests__/splitHandlerPathAndName.test.js +54 -0
- package/src/utils/__tests__/unflatten.test.js +32 -0
- package/src/utils/checkDockerDaemon.js +19 -0
- package/src/utils/checkGoVersion.js +16 -0
- package/src/utils/createApiKey.js +5 -0
- package/src/utils/createUniqueId.js +5 -0
- package/src/utils/detectExecutable.js +11 -0
- package/{dist → src}/utils/formatToClfTime.js +6 -14
- package/src/utils/generateHapiPath.js +26 -0
- package/src/utils/getHttpApiCorsConfig.js +28 -0
- package/src/utils/index.js +42 -0
- package/src/utils/jsonPath.js +13 -0
- package/src/utils/logRoutes.js +64 -0
- package/src/utils/lowerCaseKeys.js +6 -0
- package/src/utils/parseHeaders.js +14 -0
- package/src/utils/parseMultiValueHeaders.js +27 -0
- package/src/utils/parseMultiValueQueryStringParameters.js +31 -0
- package/src/utils/parseQueryStringParameters.js +15 -0
- package/src/utils/resolveJoins.js +29 -0
- package/src/utils/splitHandlerPathAndName.js +31 -0
- package/src/utils/unflatten.js +11 -0
- package/dist/ServerlessOffline.js +0 -507
- package/dist/checkEngine.js +0 -21
- package/dist/config/commandOptions.js +0 -149
- package/dist/config/constants.js +0 -30
- package/dist/config/index.js +0 -55
- package/dist/config/supportedRuntimes.js +0 -40
- package/dist/debugLog.js +0 -10
- package/dist/events/authCanExecuteResource.js +0 -35
- package/dist/events/authFunctionNameExtractor.js +0 -87
- package/dist/events/authMatchPolicyResource.js +0 -62
- package/dist/events/http/Endpoint.js +0 -171
- package/dist/events/http/Http.js +0 -77
- package/dist/events/http/HttpEventDefinition.js +0 -36
- package/dist/events/http/HttpServer.js +0 -1363
- package/dist/events/http/OfflineEndpoint.js +0 -40
- package/dist/events/http/authJWTSettingsExtractor.js +0 -76
- package/dist/events/http/authValidateContext.js +0 -48
- package/dist/events/http/createAuthScheme.js +0 -184
- package/dist/events/http/createJWTAuthScheme.js +0 -155
- package/dist/events/http/index.js +0 -15
- package/dist/events/http/javaHelpers.js +0 -99
- package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +0 -85
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +0 -244
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +0 -221
- package/dist/events/http/lambda-events/VelocityContext.js +0 -168
- package/dist/events/http/lambda-events/index.js +0 -39
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +0 -108
- package/dist/events/http/payloadSchemaValidator.js +0 -13
- package/dist/events/schedule/Schedule.js +0 -182
- package/dist/events/schedule/ScheduleEvent.js +0 -27
- package/dist/events/schedule/ScheduleEventDefinition.js +0 -36
- package/dist/events/schedule/index.js +0 -15
- package/dist/events/websocket/HttpServer.js +0 -112
- package/dist/events/websocket/WebSocket.js +0 -78
- package/dist/events/websocket/WebSocketClients.js +0 -550
- package/dist/events/websocket/WebSocketEventDefinition.js +0 -32
- package/dist/events/websocket/WebSocketServer.js +0 -140
- package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +0 -33
- package/dist/events/websocket/http-routes/_catchAll/index.js +0 -15
- package/dist/events/websocket/http-routes/connections/ConnectionsController.js +0 -45
- package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +0 -95
- package/dist/events/websocket/http-routes/connections/index.js +0 -15
- package/dist/events/websocket/http-routes/index.js +0 -23
- package/dist/events/websocket/index.js +0 -15
- package/dist/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +0 -99
- package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +0 -101
- package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +0 -47
- package/dist/events/websocket/lambda-events/WebSocketEvent.js +0 -54
- package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +0 -98
- package/dist/events/websocket/lambda-events/index.js +0 -39
- package/dist/index.js +0 -19
- package/dist/lambda/HttpServer.js +0 -122
- package/dist/lambda/Lambda.js +0 -113
- package/dist/lambda/LambdaContext.js +0 -53
- package/dist/lambda/LambdaFunction.js +0 -391
- package/dist/lambda/LambdaFunctionPool.js +0 -127
- package/dist/lambda/handler-runner/HandlerRunner.js +0 -223
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +0 -132
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +0 -40
- package/dist/lambda/handler-runner/child-process-runner/index.js +0 -15
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +0 -517
- package/dist/lambda/handler-runner/docker-runner/DockerImage.js +0 -67
- package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +0 -74
- package/dist/lambda/handler-runner/docker-runner/index.js +0 -15
- package/dist/lambda/handler-runner/go-runner/GoRunner.js +0 -211
- package/dist/lambda/handler-runner/go-runner/index.js +0 -15
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +0 -234
- package/dist/lambda/handler-runner/in-process-runner/index.js +0 -15
- package/dist/lambda/handler-runner/index.js +0 -15
- package/dist/lambda/handler-runner/java-runner/JavaRunner.js +0 -151
- package/dist/lambda/handler-runner/java-runner/index.js +0 -15
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +0 -180
- package/dist/lambda/handler-runner/python-runner/index.js +0 -15
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +0 -148
- package/dist/lambda/handler-runner/ruby-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +0 -94
- package/dist/lambda/handler-runner/worker-thread-runner/index.js +0 -15
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +0 -30
- package/dist/lambda/index.js +0 -15
- package/dist/lambda/routes/index.js +0 -23
- package/dist/lambda/routes/invocations/InvocationsController.js +0 -142
- package/dist/lambda/routes/invocations/index.js +0 -15
- package/dist/lambda/routes/invocations/invocationsRoute.js +0 -90
- package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +0 -38
- package/dist/lambda/routes/invoke-async/index.js +0 -15
- package/dist/lambda/routes/invoke-async/invokeAsyncRoute.js +0 -43
- package/dist/main.js +0 -11
- package/dist/serverlessLog.js +0 -91
- package/dist/utils/checkDockerDaemon.js +0 -27
- package/dist/utils/checkGoVersion.js +0 -27
- package/dist/utils/createApiKey.js +0 -12
- package/dist/utils/createUniqueId.js +0 -14
- package/dist/utils/detectExecutable.js +0 -21
- package/dist/utils/generateHapiPath.js +0 -28
- package/dist/utils/getHttpApiCorsConfig.js +0 -44
- package/dist/utils/index.js +0 -158
- package/dist/utils/jsonPath.js +0 -21
- package/dist/utils/parseHeaders.js +0 -23
- package/dist/utils/parseMultiValueHeaders.js +0 -36
- package/dist/utils/parseMultiValueQueryStringParameters.js +0 -40
- package/dist/utils/parseQueryStringParameters.js +0 -26
- package/dist/utils/resolveJoins.js +0 -34
- package/dist/utils/satisfiesVersionRange.js +0 -20
- package/dist/utils/splitHandlerPathAndName.js +0 -41
- package/dist/utils/unflatten.js +0 -18
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
class OfflineEndpoint {
|
|
9
|
-
constructor() {
|
|
10
|
-
return {
|
|
11
|
-
apiKeyRequired: false,
|
|
12
|
-
authorizationType: 'none',
|
|
13
|
-
authorizerFunction: false,
|
|
14
|
-
path: '',
|
|
15
|
-
requestParameters: {},
|
|
16
|
-
requestTemplates: {
|
|
17
|
-
'application/json': ''
|
|
18
|
-
},
|
|
19
|
-
responses: {
|
|
20
|
-
default: {
|
|
21
|
-
400: {
|
|
22
|
-
statusCode: '400'
|
|
23
|
-
},
|
|
24
|
-
responseModels: {
|
|
25
|
-
'application/json;charset=UTF-8': 'Empty'
|
|
26
|
-
},
|
|
27
|
-
responseParameters: {},
|
|
28
|
-
responseTemplates: {
|
|
29
|
-
'application/json;charset=UTF-8': ''
|
|
30
|
-
},
|
|
31
|
-
statusCode: 200
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
type: 'AWS'
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
exports.default = OfflineEndpoint;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = authJWTSettingsExtractor;
|
|
7
|
-
|
|
8
|
-
var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
|
-
function authJWTSettingsExtractor(endpoint, provider, ignoreJWTSignature, {
|
|
13
|
-
log
|
|
14
|
-
}) {
|
|
15
|
-
const buildFailureResult = warningMessage => {
|
|
16
|
-
if (log) {
|
|
17
|
-
log.warning(warningMessage);
|
|
18
|
-
} else {
|
|
19
|
-
(0, _serverlessLog.default)(`WARNING: ${warningMessage}`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
unsupportedAuth: true
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const buildSuccessResult = authorizerName => ({
|
|
28
|
-
authorizerName
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const {
|
|
32
|
-
authorizer
|
|
33
|
-
} = endpoint;
|
|
34
|
-
|
|
35
|
-
if (!authorizer) {
|
|
36
|
-
return buildSuccessResult(null);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!provider.httpApi || !provider.httpApi.authorizers) {
|
|
40
|
-
return buildSuccessResult(null);
|
|
41
|
-
} // TODO: add code that will actually validate a JWT.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!ignoreJWTSignature) {
|
|
45
|
-
return buildSuccessResult(null);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!authorizer.name) {
|
|
49
|
-
return buildFailureResult('Serverless Offline supports only JWT authorizers referenced by name');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const httpApiAuthorizer = provider.httpApi.authorizers[authorizer.name];
|
|
53
|
-
|
|
54
|
-
if (!httpApiAuthorizer) {
|
|
55
|
-
return buildFailureResult(`JWT authorizer ${authorizer.name} not found`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!httpApiAuthorizer.identitySource) {
|
|
59
|
-
return buildFailureResult(`JWT authorizer ${authorizer.name} missing identity source`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!httpApiAuthorizer.issuerUrl) {
|
|
63
|
-
return buildFailureResult(`JWT authorizer ${authorizer.name} missing issuer url`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!httpApiAuthorizer.audience || httpApiAuthorizer.audience.length === 0) {
|
|
67
|
-
return buildFailureResult(`JWT authorizer ${authorizer.name} missing audience`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const result = {
|
|
71
|
-
authorizerName: authorizer.name,
|
|
72
|
-
...authorizer,
|
|
73
|
-
...httpApiAuthorizer
|
|
74
|
-
};
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = createAuthScheme;
|
|
7
|
-
|
|
8
|
-
var _boom = _interopRequireDefault(require("@hapi/boom"));
|
|
9
|
-
|
|
10
|
-
var _authCanExecuteResource = _interopRequireDefault(require("../authCanExecuteResource.js"));
|
|
11
|
-
|
|
12
|
-
var _authValidateContext = _interopRequireDefault(require("./authValidateContext.js"));
|
|
13
|
-
|
|
14
|
-
var _debugLog = _interopRequireDefault(require("../../debugLog.js"));
|
|
15
|
-
|
|
16
|
-
var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
|
|
17
|
-
|
|
18
|
-
var _index = require("../../utils/index.js");
|
|
19
|
-
|
|
20
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
22
|
-
function createAuthScheme(authorizerOptions, provider, lambda, {
|
|
23
|
-
log
|
|
24
|
-
}) {
|
|
25
|
-
const authFunName = authorizerOptions.name;
|
|
26
|
-
let identityHeader = 'authorization';
|
|
27
|
-
|
|
28
|
-
if (authorizerOptions.type !== 'request') {
|
|
29
|
-
const identitySourceMatch = /^method.request.header.((?:\w+-?)+\w+)$/.exec(authorizerOptions.identitySource);
|
|
30
|
-
|
|
31
|
-
if (!identitySourceMatch || identitySourceMatch.length !== 2) {
|
|
32
|
-
throw new Error(`Serverless Offline only supports retrieving tokens from the headers (λ: ${authFunName})`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
identityHeader = identitySourceMatch[1].toLowerCase();
|
|
36
|
-
} // Create Auth Scheme
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return () => ({
|
|
40
|
-
async authenticate(request, h) {
|
|
41
|
-
if (log) {
|
|
42
|
-
log.notice();
|
|
43
|
-
log.notice(`Running Authorization function for ${request.method} ${request.path} (λ: ${authFunName})`);
|
|
44
|
-
} else {
|
|
45
|
-
console.log(''); // Just to make things a little pretty
|
|
46
|
-
|
|
47
|
-
(0, _serverlessLog.default)(`Running Authorization function for ${request.method} ${request.path} (λ: ${authFunName})`);
|
|
48
|
-
} // Get Authorization header
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const {
|
|
52
|
-
req
|
|
53
|
-
} = request.raw; // Get path params
|
|
54
|
-
// aws doesn't auto decode path params - hapi does
|
|
55
|
-
|
|
56
|
-
const pathParams = { ...request.params
|
|
57
|
-
};
|
|
58
|
-
const accountId = 'random-account-id';
|
|
59
|
-
const apiId = 'random-api-id';
|
|
60
|
-
const httpMethod = request.method.toUpperCase();
|
|
61
|
-
const resourcePath = request.route.path.replace(new RegExp(`^/${provider.stage}`), '');
|
|
62
|
-
let event = {
|
|
63
|
-
enhancedAuthContext: {},
|
|
64
|
-
methodArn: `arn:aws:execute-api:${provider.region}:${accountId}:${apiId}/${provider.stage}/${httpMethod}${resourcePath}`,
|
|
65
|
-
requestContext: {
|
|
66
|
-
accountId,
|
|
67
|
-
apiId,
|
|
68
|
-
httpMethod,
|
|
69
|
-
requestId: 'random-request-id',
|
|
70
|
-
resourceId: 'random-resource-id',
|
|
71
|
-
resourcePath,
|
|
72
|
-
path: request.path,
|
|
73
|
-
stage: provider.stage
|
|
74
|
-
},
|
|
75
|
-
resource: resourcePath
|
|
76
|
-
}; // Create event Object for authFunction
|
|
77
|
-
// methodArn is the ARN of the function we are running we are authorizing access to (or not)
|
|
78
|
-
// Account ID and API ID are not simulated
|
|
79
|
-
|
|
80
|
-
if (authorizerOptions.type === 'request') {
|
|
81
|
-
const {
|
|
82
|
-
rawHeaders,
|
|
83
|
-
url
|
|
84
|
-
} = req;
|
|
85
|
-
event = { ...event,
|
|
86
|
-
headers: (0, _index.parseHeaders)(rawHeaders),
|
|
87
|
-
httpMethod: request.method.toUpperCase(),
|
|
88
|
-
multiValueHeaders: (0, _index.parseMultiValueHeaders)(rawHeaders),
|
|
89
|
-
multiValueQueryStringParameters: (0, _index.parseMultiValueQueryStringParameters)(url),
|
|
90
|
-
path: request.path,
|
|
91
|
-
pathParameters: (0, _index.nullIfEmpty)(pathParams),
|
|
92
|
-
queryStringParameters: (0, _index.parseQueryStringParameters)(url),
|
|
93
|
-
type: 'REQUEST'
|
|
94
|
-
};
|
|
95
|
-
} else {
|
|
96
|
-
const authorization = req.headers[identityHeader];
|
|
97
|
-
const identityValidationExpression = new RegExp(authorizerOptions.identityValidationExpression);
|
|
98
|
-
const matchedAuthorization = identityValidationExpression.test(authorization);
|
|
99
|
-
const finalAuthorization = matchedAuthorization ? authorization : '';
|
|
100
|
-
|
|
101
|
-
if (log) {
|
|
102
|
-
log.debug(`Retrieved ${identityHeader} header "${finalAuthorization}"`);
|
|
103
|
-
} else {
|
|
104
|
-
(0, _debugLog.default)(`Retrieved ${identityHeader} header "${finalAuthorization}"`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
event = { ...event,
|
|
108
|
-
authorizationToken: finalAuthorization,
|
|
109
|
-
type: 'TOKEN'
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const lambdaFunction = lambda.get(authFunName);
|
|
114
|
-
lambdaFunction.setEvent(event);
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
const result = await lambdaFunction.runHandler();
|
|
118
|
-
if (result === 'Unauthorized') return _boom.default.unauthorized('Unauthorized'); // Validate that the policy document has the principalId set
|
|
119
|
-
|
|
120
|
-
if (!result.principalId) {
|
|
121
|
-
if (log) {
|
|
122
|
-
log.notice(`Authorization response did not include a principalId: (λ: ${authFunName})`);
|
|
123
|
-
} else {
|
|
124
|
-
(0, _serverlessLog.default)(`Authorization response did not include a principalId: (λ: ${authFunName})`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return _boom.default.forbidden('No principalId set on the Response');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!(0, _authCanExecuteResource.default)(result.policyDocument, event.methodArn)) {
|
|
131
|
-
if (log) {
|
|
132
|
-
log.notice(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`);
|
|
133
|
-
} else {
|
|
134
|
-
(0, _serverlessLog.default)(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`);
|
|
135
|
-
}
|
|
136
|
-
|
|
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;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (log) {
|
|
153
|
-
log.notice(`Authorization function returned a successful response: (λ: ${authFunName})`);
|
|
154
|
-
} else {
|
|
155
|
-
(0, _serverlessLog.default)(`Authorization function returned a successful response: (λ: ${authFunName})`);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const authorizer = {
|
|
159
|
-
integrationLatency: '42',
|
|
160
|
-
principalId: result.principalId,
|
|
161
|
-
...result.context
|
|
162
|
-
}; // Set the credentials for the rest of the pipeline
|
|
163
|
-
|
|
164
|
-
return h.authenticated({
|
|
165
|
-
credentials: {
|
|
166
|
-
authorizer,
|
|
167
|
-
context: result.context,
|
|
168
|
-
principalId: result.principalId,
|
|
169
|
-
usageIdentifierKey: result.usageIdentifierKey
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
} catch (err) {
|
|
173
|
-
if (log) {
|
|
174
|
-
log.notice(`Authorization function returned an error response: (λ: ${authFunName})`);
|
|
175
|
-
} else {
|
|
176
|
-
(0, _serverlessLog.default)(`Authorization function returned an error response: (λ: ${authFunName})`);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return _boom.default.unauthorized('Unauthorized');
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = createAuthScheme;
|
|
7
|
-
|
|
8
|
-
var _boom = _interopRequireDefault(require("@hapi/boom"));
|
|
9
|
-
|
|
10
|
-
var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
|
|
11
|
-
|
|
12
|
-
var _serverlessLog = _interopRequireDefault(require("../../serverlessLog.js"));
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
|
-
function createAuthScheme(jwtOptions, {
|
|
17
|
-
log
|
|
18
|
-
}) {
|
|
19
|
-
const authorizerName = jwtOptions.name;
|
|
20
|
-
const identitySourceMatch = /^\$request.header.((?:\w+-?)+\w+)$/.exec(jwtOptions.identitySource);
|
|
21
|
-
|
|
22
|
-
if (!identitySourceMatch || identitySourceMatch.length !== 2) {
|
|
23
|
-
throw new Error(`Serverless Offline only supports retrieving JWT from the headers (${authorizerName})`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const identityHeader = identitySourceMatch[1].toLowerCase(); // Create Auth Scheme
|
|
27
|
-
|
|
28
|
-
return () => ({
|
|
29
|
-
async authenticate(request, h) {
|
|
30
|
-
if (log) {
|
|
31
|
-
log.notice();
|
|
32
|
-
log.notice(`Running JWT Authorization function for ${request.method} ${request.path} (${authorizerName})`);
|
|
33
|
-
} else {
|
|
34
|
-
console.log(''); // Just to make things a little pretty
|
|
35
|
-
// TODO: this only validates specific properties of the JWT
|
|
36
|
-
// it does not verify the JWT is correctly signed. That would
|
|
37
|
-
// be a great feature to add under an optional flag :)
|
|
38
|
-
|
|
39
|
-
(0, _serverlessLog.default)(`Running JWT Authorization function for ${request.method} ${request.path} (${authorizerName})`);
|
|
40
|
-
} // Get Authorization header
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const {
|
|
44
|
-
req
|
|
45
|
-
} = request.raw;
|
|
46
|
-
let jwtToken = req.headers[identityHeader];
|
|
47
|
-
|
|
48
|
-
if (jwtToken && jwtToken.split(' ')[0] === 'Bearer') {
|
|
49
|
-
;
|
|
50
|
-
[, jwtToken] = jwtToken.split(' ');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
const decoded = _jsonwebtoken.default.decode(jwtToken, {
|
|
55
|
-
complete: true
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (!decoded) {
|
|
59
|
-
return _boom.default.unauthorized('JWT not decoded');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const expirationDate = new Date(decoded.payload.exp * 1000);
|
|
63
|
-
|
|
64
|
-
if (expirationDate.valueOf() < Date.now()) {
|
|
65
|
-
return _boom.default.unauthorized('JWT Token expired');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const {
|
|
69
|
-
iss,
|
|
70
|
-
aud,
|
|
71
|
-
scope
|
|
72
|
-
} = decoded.payload;
|
|
73
|
-
const clientId = decoded.payload.client_id;
|
|
74
|
-
|
|
75
|
-
if (iss !== jwtOptions.issuerUrl) {
|
|
76
|
-
if (log) {
|
|
77
|
-
log.notice(`JWT Token not from correct issuer url`);
|
|
78
|
-
} else {
|
|
79
|
-
(0, _serverlessLog.default)(`JWT Token not from correct issuer url`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return _boom.default.unauthorized('JWT Token not from correct issuer url');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const validAudiences = Array.isArray(jwtOptions.audience) ? jwtOptions.audience : [jwtOptions.audience];
|
|
86
|
-
const providedAudiences = Array.isArray(aud) ? aud : [aud];
|
|
87
|
-
const validAudienceProvided = providedAudiences.some(a => validAudiences.includes(a));
|
|
88
|
-
|
|
89
|
-
if (!validAudienceProvided && !validAudiences.includes(clientId)) {
|
|
90
|
-
if (log) {
|
|
91
|
-
log.notice(`JWT Token does not contain correct audience`);
|
|
92
|
-
} else {
|
|
93
|
-
(0, _serverlessLog.default)(`JWT Token does not contain correct audience`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return _boom.default.unauthorized('JWT Token does not contain correct audience');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let scopes = null;
|
|
100
|
-
|
|
101
|
-
if (jwtOptions.scopes && jwtOptions.scopes.length) {
|
|
102
|
-
if (!scope) {
|
|
103
|
-
if (log) {
|
|
104
|
-
log.notice(`JWT Token missing valid scope`);
|
|
105
|
-
} else {
|
|
106
|
-
(0, _serverlessLog.default)(`JWT Token missing valid scope`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return _boom.default.forbidden('JWT Token missing valid scope');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
scopes = scope.split(' ');
|
|
113
|
-
|
|
114
|
-
if (scopes.every(s => {
|
|
115
|
-
return !jwtOptions.scopes.includes(s);
|
|
116
|
-
})) {
|
|
117
|
-
if (log) {
|
|
118
|
-
log.notice(`JWT Token missing valid scope`);
|
|
119
|
-
} else {
|
|
120
|
-
(0, _serverlessLog.default)(`JWT Token missing valid scope`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return _boom.default.forbidden('JWT Token missing valid scope');
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (log) {
|
|
128
|
-
log.notice(`JWT Token validated`);
|
|
129
|
-
} else {
|
|
130
|
-
(0, _serverlessLog.default)(`JWT Token validated`);
|
|
131
|
-
} // Set the credentials for the rest of the pipeline
|
|
132
|
-
// return resolve(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return h.authenticated({
|
|
136
|
-
credentials: {
|
|
137
|
-
claims: decoded.payload,
|
|
138
|
-
scopes
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
} catch (err) {
|
|
142
|
-
if (log) {
|
|
143
|
-
log.notice(`JWT could not be decoded`);
|
|
144
|
-
log.error(err);
|
|
145
|
-
} else {
|
|
146
|
-
(0, _serverlessLog.default)(`JWT could not be decoded`);
|
|
147
|
-
(0, _serverlessLog.default)(err);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return _boom.default.unauthorized('Unauthorized');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
});
|
|
155
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "default", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _Http.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
var _Http = _interopRequireDefault(require("./Http.js"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = runInPollutedScope;
|
|
7
|
-
|
|
8
|
-
// String functions
|
|
9
|
-
// For velocity templates to access java functions, to mimick AWS
|
|
10
|
-
function javaContains(value) {
|
|
11
|
-
return this.includes(value);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function javaEquals(anObject) {
|
|
15
|
-
return this.toString() === anObject.toString();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function javaEqualsIgnoreCase(anotherString) {
|
|
19
|
-
return anotherString === null ? false : this === anotherString || this.toLowerCase() === anotherString.toLowerCase();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function javaMatches(value) {
|
|
23
|
-
return this.match(new RegExp(value, 'm'));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function javaReplaceAll(oldValue, newValue) {
|
|
27
|
-
return this.replace(new RegExp(oldValue, 'gm'), newValue);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function javaReplaceFirst(oldValue, newValue) {
|
|
31
|
-
return this.replace(new RegExp(oldValue, 'm'), newValue);
|
|
32
|
-
} // method has 2 function signatures:
|
|
33
|
-
// regionMatches(toffset: number, other: string, ooffset: number, len: number): boolean
|
|
34
|
-
// regionMatches(ignoreCase: boolean, toffset: number, other: string, ooffset: number, len: number): boolean
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
function javaRegionMatches(...args) {
|
|
38
|
-
let ignoreCase;
|
|
39
|
-
let toffset;
|
|
40
|
-
let other;
|
|
41
|
-
let ooffset;
|
|
42
|
-
let len;
|
|
43
|
-
|
|
44
|
-
if (args.length === 4) {
|
|
45
|
-
;
|
|
46
|
-
[toffset, other, ooffset, len] = args;
|
|
47
|
-
ignoreCase = false;
|
|
48
|
-
} else {
|
|
49
|
-
;
|
|
50
|
-
[ignoreCase, toffset, other, ooffset, len] = args;
|
|
51
|
-
} // Note: toffset, ooffset, or len might be near -1>>>1.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (ooffset < 0 || toffset < 0 || toffset > this.length - len || ooffset > other.length - len) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
let s1 = this.substring(toffset, toffset + len);
|
|
59
|
-
let s2 = other.substring(ooffset, ooffset + len);
|
|
60
|
-
|
|
61
|
-
if (ignoreCase) {
|
|
62
|
-
s1 = s1.toLowerCase();
|
|
63
|
-
s2 = s2.toLowerCase();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return s1 === s2;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const {
|
|
70
|
-
prototype,
|
|
71
|
-
prototype: {
|
|
72
|
-
contains,
|
|
73
|
-
equals,
|
|
74
|
-
equalsIgnoreCase,
|
|
75
|
-
matches,
|
|
76
|
-
regionMatches,
|
|
77
|
-
replaceAll,
|
|
78
|
-
replaceFirst
|
|
79
|
-
}
|
|
80
|
-
} = String;
|
|
81
|
-
|
|
82
|
-
function runInPollutedScope(runScope) {
|
|
83
|
-
prototype.contains = javaContains;
|
|
84
|
-
prototype.equals = javaEquals;
|
|
85
|
-
prototype.equalsIgnoreCase = javaEqualsIgnoreCase;
|
|
86
|
-
prototype.matches = javaMatches;
|
|
87
|
-
prototype.regionMatches = javaRegionMatches;
|
|
88
|
-
prototype.replaceAll = javaReplaceAll;
|
|
89
|
-
prototype.replaceFirst = javaReplaceFirst;
|
|
90
|
-
const result = runScope();
|
|
91
|
-
prototype.contains = contains;
|
|
92
|
-
prototype.equals = equals;
|
|
93
|
-
prototype.equalsIgnoreCase = equalsIgnoreCase;
|
|
94
|
-
prototype.matches = matches;
|
|
95
|
-
prototype.regionMatches = regionMatches;
|
|
96
|
-
prototype.replaceAll = replaceAll;
|
|
97
|
-
prototype.replaceFirst = replaceFirst;
|
|
98
|
-
return result;
|
|
99
|
-
}
|