serverless-offline 13.3.1 → 13.3.3
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 +17 -17
- package/package.json +14 -13
- package/src/ServerlessOffline.js +42 -42
- package/src/config/colors.js +9 -9
- package/src/config/commandOptions.js +61 -61
- package/src/config/constants.js +5 -5
- package/src/config/defaultOptions.js +6 -6
- package/src/config/index.js +4 -4
- package/src/config/supportedRuntimes.js +18 -18
- package/src/errors/index.js +1 -1
- package/src/events/alb/Alb.js +2 -2
- package/src/events/alb/AlbEventDefinition.js +2 -2
- package/src/events/alb/HttpServer.js +54 -54
- package/src/events/alb/index.js +1 -1
- package/src/events/alb/lambda-events/LambdaAlbRequestEvent.js +2 -2
- package/src/events/alb/lambda-events/index.js +1 -1
- package/src/events/authCanExecuteResource.js +3 -3
- package/src/events/authFunctionNameExtractor.js +9 -9
- package/src/events/authMatchPolicyResource.js +8 -8
- package/src/events/authValidateContext.js +11 -11
- package/src/events/http/Endpoint.js +26 -26
- package/src/events/http/Http.js +2 -2
- package/src/events/http/HttpEventDefinition.js +2 -2
- package/src/events/http/HttpServer.js +156 -156
- package/src/events/http/OfflineEndpoint.js +7 -7
- package/src/events/http/authJWTSettingsExtractor.js +2 -2
- package/src/events/http/createAuthScheme.js +29 -27
- package/src/events/http/createJWTAuthScheme.js +12 -12
- package/src/events/http/index.js +1 -1
- package/src/events/http/javaHelpers.js +2 -2
- package/src/events/http/lambda-events/LambdaIntegrationEvent.js +5 -5
- package/src/events/http/lambda-events/LambdaProxyIntegrationEvent.js +47 -47
- package/src/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +27 -27
- package/src/events/http/lambda-events/VelocityContext.js +28 -32
- package/src/events/http/lambda-events/index.js +4 -4
- package/src/events/http/lambda-events/renderVelocityTemplateObject.js +13 -13
- package/src/events/http/parseResources.js +6 -6
- package/src/events/http/payloadSchemaValidator.js +2 -2
- package/src/events/schedule/Schedule.js +21 -21
- package/src/events/schedule/ScheduleEvent.js +7 -7
- package/src/events/schedule/ScheduleEventDefinition.js +1 -1
- package/src/events/schedule/index.js +1 -1
- package/src/events/websocket/HttpServer.js +9 -9
- package/src/events/websocket/WebSocket.js +4 -4
- package/src/events/websocket/WebSocketClients.js +29 -29
- package/src/events/websocket/WebSocketEventDefinition.js +1 -1
- package/src/events/websocket/WebSocketServer.js +9 -9
- package/src/events/websocket/http-routes/_catchAll/catchAllRoute.js +3 -3
- package/src/events/websocket/http-routes/_catchAll/index.js +1 -1
- package/src/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/src/events/websocket/http-routes/connections/connectionsRoutes.js +6 -6
- package/src/events/websocket/http-routes/connections/index.js +1 -1
- package/src/events/websocket/http-routes/index.js +2 -2
- package/src/events/websocket/index.js +1 -1
- package/src/events/websocket/lambda-events/WebSocketAuthorizerEvent.js +5 -5
- package/src/events/websocket/lambda-events/WebSocketConnectEvent.js +7 -6
- package/src/events/websocket/lambda-events/WebSocketDisconnectEvent.js +5 -5
- package/src/events/websocket/lambda-events/WebSocketEvent.js +2 -2
- package/src/events/websocket/lambda-events/WebSocketRequestContext.js +12 -11
- package/src/events/websocket/lambda-events/index.js +4 -4
- package/src/index.js +1 -1
- package/src/lambda/HttpServer.js +11 -11
- package/src/lambda/Lambda.js +2 -2
- package/src/lambda/LambdaContext.js +1 -1
- package/src/lambda/LambdaFunction.js +34 -34
- package/src/lambda/LambdaFunctionPool.js +3 -3
- package/src/lambda/handler-runner/HandlerRunner.js +12 -12
- package/src/lambda/handler-runner/docker-runner/DockerContainer.js +59 -59
- package/src/lambda/handler-runner/docker-runner/DockerImage.js +6 -6
- package/src/lambda/handler-runner/docker-runner/DockerRunner.js +2 -2
- package/src/lambda/handler-runner/docker-runner/index.js +1 -1
- package/src/lambda/handler-runner/go-runner/GoRunner.js +34 -34
- package/src/lambda/handler-runner/go-runner/index.js +1 -1
- package/src/lambda/handler-runner/in-process-runner/InProcessRunner.js +7 -7
- package/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js +52 -52
- package/src/lambda/handler-runner/in-process-runner/index.js +1 -1
- package/src/lambda/handler-runner/index.js +1 -1
- package/src/lambda/handler-runner/java-runner/JavaRunner.js +13 -13
- package/src/lambda/handler-runner/java-runner/index.js +1 -1
- package/src/lambda/handler-runner/python-runner/PythonRunner.js +21 -21
- package/src/lambda/handler-runner/python-runner/index.js +1 -1
- package/src/lambda/handler-runner/ruby-runner/RubyRunner.js +11 -11
- package/src/lambda/handler-runner/ruby-runner/index.js +1 -1
- package/src/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +6 -6
- package/src/lambda/handler-runner/worker-thread-runner/index.js +1 -1
- package/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +4 -4
- package/src/lambda/index.js +1 -1
- package/src/lambda/routes/index.js +2 -2
- package/src/lambda/routes/invocations/InvocationsController.js +11 -11
- package/src/lambda/routes/invocations/index.js +1 -1
- package/src/lambda/routes/invocations/invocationsRoute.js +15 -15
- package/src/lambda/routes/invoke-async/index.js +1 -1
- package/src/lambda/routes/invoke-async/invokeAsyncRoute.js +6 -6
- package/src/utils/checkDockerDaemon.js +8 -8
- package/src/utils/checkGoVersion.js +3 -3
- package/src/utils/createApiKey.js +2 -2
- package/src/utils/detectExecutable.js +2 -2
- package/src/utils/formatToClfTime.js +2 -2
- package/src/utils/generateHapiPath.js +8 -8
- package/src/utils/getApiKeysValues.js +10 -2
- package/src/utils/getHttpApiCorsConfig.js +11 -11
- package/src/utils/getRawQueryParams.js +2 -2
- package/src/utils/index.js +25 -26
- package/src/utils/jsonPath.js +1 -1
- package/src/utils/logRoutes.js +13 -13
- package/src/utils/parseHeaders.js +1 -1
- package/src/utils/parseMultiValueHeaders.js +1 -1
- package/src/utils/parseMultiValueQueryStringParameters.js +1 -1
- package/src/utils/parseQueryStringParameters.js +1 -1
- package/src/utils/parseQueryStringParametersForPayloadV2.js +1 -1
- package/src/utils/splitHandlerPathAndName.js +3 -3
- package/src/utils/createUniqueId.js +0 -5
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
export default class OfflineEndpoint {
|
|
2
2
|
apiKeyRequired = false
|
|
3
3
|
|
|
4
|
-
authorizationType =
|
|
4
|
+
authorizationType = "none"
|
|
5
5
|
|
|
6
6
|
authorizerFunction = false
|
|
7
7
|
|
|
8
|
-
path =
|
|
8
|
+
path = ""
|
|
9
9
|
|
|
10
10
|
requestParameters = {}
|
|
11
11
|
|
|
12
12
|
requestTemplates = {
|
|
13
|
-
|
|
13
|
+
"application/json": "",
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
responses = {
|
|
17
17
|
default: {
|
|
18
18
|
400: {
|
|
19
|
-
statusCode:
|
|
19
|
+
statusCode: "400",
|
|
20
20
|
},
|
|
21
21
|
responseModels: {
|
|
22
|
-
|
|
22
|
+
"application/json;charset=UTF-8": "Empty",
|
|
23
23
|
},
|
|
24
24
|
responseParameters: {},
|
|
25
25
|
responseTemplates: {
|
|
26
|
-
|
|
26
|
+
"application/json;charset=UTF-8": "",
|
|
27
27
|
},
|
|
28
28
|
statusCode: 200,
|
|
29
29
|
},
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
type =
|
|
32
|
+
type = "AWS"
|
|
33
33
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { log } from
|
|
1
|
+
import { log } from "@serverless/utils/log.js"
|
|
2
2
|
|
|
3
3
|
function buildFailureResult(warningMessage) {
|
|
4
4
|
log.warning(warningMessage)
|
|
@@ -36,7 +36,7 @@ export default function authJWTSettingsExtractor(
|
|
|
36
36
|
|
|
37
37
|
if (!authorizer.name) {
|
|
38
38
|
return buildFailureResult(
|
|
39
|
-
|
|
39
|
+
"Serverless Offline supports only JWT authorizers referenced by name",
|
|
40
40
|
)
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import Boom from
|
|
2
|
-
import { log } from
|
|
3
|
-
import authCanExecuteResource from
|
|
4
|
-
import authValidateContext from
|
|
1
|
+
import Boom from "@hapi/boom"
|
|
2
|
+
import { log } from "@serverless/utils/log.js"
|
|
3
|
+
import authCanExecuteResource from "../authCanExecuteResource.js"
|
|
4
|
+
import authValidateContext from "../authValidateContext.js"
|
|
5
5
|
import {
|
|
6
6
|
getRawQueryParams,
|
|
7
7
|
nullIfEmpty,
|
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
parseMultiValueHeaders,
|
|
10
10
|
parseMultiValueQueryStringParameters,
|
|
11
11
|
parseQueryStringParameters,
|
|
12
|
-
} from
|
|
12
|
+
} from "../../utils/index.js"
|
|
13
13
|
|
|
14
|
-
const IDENTITY_SOURCE_TYPE_HEADER =
|
|
15
|
-
const IDENTITY_SOURCE_TYPE_QUERYSTRING =
|
|
16
|
-
const IDENTITY_SOURCE_TYPE_NONE =
|
|
14
|
+
const IDENTITY_SOURCE_TYPE_HEADER = "header"
|
|
15
|
+
const IDENTITY_SOURCE_TYPE_QUERYSTRING = "querystring"
|
|
16
|
+
const IDENTITY_SOURCE_TYPE_NONE = "none"
|
|
17
17
|
|
|
18
18
|
export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
19
19
|
const authFunName = authorizerOptions.name
|
|
20
|
-
let identitySourceField =
|
|
20
|
+
let identitySourceField = "authorization"
|
|
21
21
|
let identitySourceType = IDENTITY_SOURCE_TYPE_HEADER
|
|
22
22
|
|
|
23
23
|
const finalizeAuthScheme = () => {
|
|
@@ -34,14 +34,14 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
34
34
|
// aws doesn't auto decode path params - hapi does
|
|
35
35
|
const pathParams = { ...request.params }
|
|
36
36
|
|
|
37
|
-
const accountId =
|
|
38
|
-
const apiId =
|
|
39
|
-
const requestId =
|
|
37
|
+
const accountId = "random-account-id"
|
|
38
|
+
const apiId = "random-api-id"
|
|
39
|
+
const requestId = "random-request-id"
|
|
40
40
|
|
|
41
41
|
const httpMethod = request.method.toUpperCase()
|
|
42
42
|
const resourcePath = request.route.path.replace(
|
|
43
43
|
new RegExp(`^/${provider.stage}`),
|
|
44
|
-
|
|
44
|
+
"",
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
let event = {
|
|
@@ -94,7 +94,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
94
94
|
`Identity Source is null for ${identitySourceType} ${identitySourceField} (λ: ${authFunName})`,
|
|
95
95
|
)
|
|
96
96
|
return Boom.unauthorized(
|
|
97
|
-
|
|
97
|
+
"User is not authorized to access this resource",
|
|
98
98
|
)
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -103,14 +103,14 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
103
103
|
)
|
|
104
104
|
const matchedAuthorization =
|
|
105
105
|
identityValidationExpression.test(authorization)
|
|
106
|
-
finalAuthorization = matchedAuthorization ? authorization :
|
|
106
|
+
finalAuthorization = matchedAuthorization ? authorization : ""
|
|
107
107
|
|
|
108
108
|
log.debug(
|
|
109
109
|
`Retrieved ${identitySourceField} ${identitySourceType} "${finalAuthorization}"`,
|
|
110
110
|
)
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
if (authorizerOptions.payloadVersion ===
|
|
113
|
+
if (authorizerOptions.payloadVersion === "1.0") {
|
|
114
114
|
event = {
|
|
115
115
|
...event,
|
|
116
116
|
authorizationToken: finalAuthorization,
|
|
@@ -124,6 +124,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
124
124
|
pathParameters: nullIfEmpty(pathParams),
|
|
125
125
|
queryStringParameters: parseQueryStringParameters(url),
|
|
126
126
|
requestContext: {
|
|
127
|
+
...event.requestContext,
|
|
127
128
|
extendedRequestId: requestId,
|
|
128
129
|
httpMethod,
|
|
129
130
|
path: request.path,
|
|
@@ -138,13 +139,14 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
if (authorizerOptions.payloadVersion ===
|
|
142
|
+
if (authorizerOptions.payloadVersion === "2.0") {
|
|
142
143
|
event = {
|
|
143
144
|
...event,
|
|
144
145
|
identitySource: [finalAuthorization],
|
|
145
146
|
rawPath: request.path,
|
|
146
147
|
rawQueryString: getRawQueryParams(url),
|
|
147
148
|
requestContext: {
|
|
149
|
+
...event.requestContext,
|
|
148
150
|
http: {
|
|
149
151
|
method: httpMethod,
|
|
150
152
|
path: resourcePath,
|
|
@@ -164,7 +166,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
164
166
|
event = {
|
|
165
167
|
...event,
|
|
166
168
|
// This is safe since type: 'TOKEN' cannot have payload format 2.0
|
|
167
|
-
type: authorizerOptions.type ===
|
|
169
|
+
type: authorizerOptions.type === "request" ? "REQUEST" : "TOKEN",
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
const lambdaFunction = lambda.get(authFunName)
|
|
@@ -176,7 +178,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
176
178
|
if (authorizerOptions.enableSimpleResponses) {
|
|
177
179
|
if (result.isAuthorized) {
|
|
178
180
|
const authorizer = {
|
|
179
|
-
integrationLatency:
|
|
181
|
+
integrationLatency: "42",
|
|
180
182
|
...result.context,
|
|
181
183
|
}
|
|
182
184
|
return h.authenticated({
|
|
@@ -187,12 +189,12 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
187
189
|
})
|
|
188
190
|
}
|
|
189
191
|
return Boom.forbidden(
|
|
190
|
-
|
|
192
|
+
"User is not authorized to access this resource",
|
|
191
193
|
)
|
|
192
194
|
}
|
|
193
195
|
|
|
194
|
-
if (result ===
|
|
195
|
-
return Boom.unauthorized(
|
|
196
|
+
if (result === "Unauthorized")
|
|
197
|
+
return Boom.unauthorized("Unauthorized")
|
|
196
198
|
|
|
197
199
|
// Validate that the policy document has the principalId set
|
|
198
200
|
if (!result.principalId) {
|
|
@@ -200,7 +202,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
200
202
|
`Authorization response did not include a principalId: (λ: ${authFunName})`,
|
|
201
203
|
)
|
|
202
204
|
|
|
203
|
-
return Boom.forbidden(
|
|
205
|
+
return Boom.forbidden("No principalId set on the Response")
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
if (
|
|
@@ -214,7 +216,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
214
216
|
)
|
|
215
217
|
|
|
216
218
|
return Boom.forbidden(
|
|
217
|
-
|
|
219
|
+
"User is not authorized to access this resource",
|
|
218
220
|
)
|
|
219
221
|
}
|
|
220
222
|
|
|
@@ -238,7 +240,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
238
240
|
)
|
|
239
241
|
|
|
240
242
|
const authorizer = {
|
|
241
|
-
integrationLatency:
|
|
243
|
+
integrationLatency: "42",
|
|
242
244
|
principalId: result.principalId,
|
|
243
245
|
...result.context,
|
|
244
246
|
}
|
|
@@ -257,7 +259,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
257
259
|
`Authorization function returned an error response: (λ: ${authFunName})`,
|
|
258
260
|
)
|
|
259
261
|
|
|
260
|
-
return Boom.unauthorized(
|
|
262
|
+
return Boom.unauthorized("Unauthorized")
|
|
261
263
|
}
|
|
262
264
|
},
|
|
263
265
|
})
|
|
@@ -273,7 +275,7 @@ export default function createAuthScheme(authorizerOptions, provider, lambda) {
|
|
|
273
275
|
}
|
|
274
276
|
|
|
275
277
|
if (
|
|
276
|
-
authorizerOptions.type !==
|
|
278
|
+
authorizerOptions.type !== "request" ||
|
|
277
279
|
authorizerOptions.identitySource
|
|
278
280
|
) {
|
|
279
281
|
// Only validate the first of N possible headers.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import Boom from
|
|
2
|
-
import { log } from
|
|
3
|
-
import { decodeJwt } from
|
|
1
|
+
import Boom from "@hapi/boom"
|
|
2
|
+
import { log } from "@serverless/utils/log.js"
|
|
3
|
+
import { decodeJwt } from "jose"
|
|
4
4
|
|
|
5
5
|
const { isArray } = Array
|
|
6
6
|
const { now } = Date
|
|
@@ -31,8 +31,8 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
31
31
|
// Get Authorization header
|
|
32
32
|
const { req } = request.raw
|
|
33
33
|
let jwtToken = req.headers[identityHeader]
|
|
34
|
-
if (jwtToken && jwtToken.split(
|
|
35
|
-
;[, jwtToken] = jwtToken.split(
|
|
34
|
+
if (jwtToken && jwtToken.split(" ")[0] === "Bearer") {
|
|
35
|
+
;[, jwtToken] = jwtToken.split(" ")
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
try {
|
|
@@ -40,14 +40,14 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
40
40
|
|
|
41
41
|
const expirationDate = new Date(claims.exp * 1000)
|
|
42
42
|
if (expirationDate.getTime() < now()) {
|
|
43
|
-
return Boom.unauthorized(
|
|
43
|
+
return Boom.unauthorized("JWT Token expired")
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
const { aud, iss, scope, client_id: clientId } = claims
|
|
47
47
|
if (iss !== jwtOptions.issuerUrl) {
|
|
48
48
|
log.notice(`JWT Token not from correct issuer url`)
|
|
49
49
|
|
|
50
|
-
return Boom.unauthorized(
|
|
50
|
+
return Boom.unauthorized("JWT Token not from correct issuer url")
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const validAudiences = isArray(jwtOptions.audience)
|
|
@@ -62,7 +62,7 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
62
62
|
log.notice(`JWT Token does not contain correct audience`)
|
|
63
63
|
|
|
64
64
|
return Boom.unauthorized(
|
|
65
|
-
|
|
65
|
+
"JWT Token does not contain correct audience",
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -71,14 +71,14 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
71
71
|
if (!scope) {
|
|
72
72
|
log.notice(`JWT Token missing valid scope`)
|
|
73
73
|
|
|
74
|
-
return Boom.forbidden(
|
|
74
|
+
return Boom.forbidden("JWT Token missing valid scope")
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
scopes = scope.split(
|
|
77
|
+
scopes = scope.split(" ")
|
|
78
78
|
if (scopes.every((s) => !jwtOptions.scopes.includes(s))) {
|
|
79
79
|
log.notice(`JWT Token missing valid scope`)
|
|
80
80
|
|
|
81
|
-
return Boom.forbidden(
|
|
81
|
+
return Boom.forbidden("JWT Token missing valid scope")
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -96,7 +96,7 @@ export default function createAuthScheme(jwtOptions) {
|
|
|
96
96
|
log.notice(`JWT could not be decoded`)
|
|
97
97
|
log.error(err)
|
|
98
98
|
|
|
99
|
-
return Boom.unauthorized(
|
|
99
|
+
return Boom.unauthorized("Unauthorized")
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
102
|
})
|
package/src/events/http/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from
|
|
1
|
+
export { default } from "./Http.js"
|
|
@@ -17,11 +17,11 @@ function javaEqualsIgnoreCase(anotherString) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function javaMatches(value) {
|
|
20
|
-
return this.match(new RegExp(value,
|
|
20
|
+
return this.match(new RegExp(value, "m"))
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function javaReplaceFirst(oldValue, newValue) {
|
|
24
|
-
return this.replace(new RegExp(oldValue,
|
|
24
|
+
return this.replace(new RegExp(oldValue, "m"), newValue)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// method has 2 function signatures:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { env } from
|
|
2
|
-
import { log } from
|
|
3
|
-
import renderVelocityTemplateObject from
|
|
4
|
-
import VelocityContext from
|
|
1
|
+
import { env } from "node:process"
|
|
2
|
+
import { log } from "@serverless/utils/log.js"
|
|
3
|
+
import renderVelocityTemplateObject from "./renderVelocityTemplateObject.js"
|
|
4
|
+
import VelocityContext from "./VelocityContext.js"
|
|
5
5
|
|
|
6
6
|
const { parse } = JSON
|
|
7
7
|
|
|
@@ -35,7 +35,7 @@ export default class LambdaIntegrationEvent {
|
|
|
35
35
|
}
|
|
36
36
|
} catch {
|
|
37
37
|
log.error(
|
|
38
|
-
|
|
38
|
+
"Could not parse process.env.AUTHORIZER, make sure it is correct JSON",
|
|
39
39
|
)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { Buffer } from
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Buffer } from "node:buffer"
|
|
2
|
+
import crypto from "node:crypto"
|
|
3
|
+
import { env } from "node:process"
|
|
4
|
+
import { log } from "@serverless/utils/log.js"
|
|
5
|
+
import { decodeJwt } from "jose"
|
|
5
6
|
import {
|
|
6
|
-
createUniqueId,
|
|
7
7
|
formatToClfTime,
|
|
8
8
|
nullIfEmpty,
|
|
9
9
|
parseHeaders,
|
|
10
10
|
parseMultiValueHeaders,
|
|
11
11
|
parseMultiValueQueryStringParameters,
|
|
12
12
|
parseQueryStringParameters,
|
|
13
|
-
} from
|
|
13
|
+
} from "../../../utils/index.js"
|
|
14
14
|
|
|
15
15
|
const { byteLength } = Buffer
|
|
16
16
|
const { parse } = JSON
|
|
@@ -57,7 +57,7 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
57
57
|
authAuthorizer = parse(env.AUTHORIZER)
|
|
58
58
|
} catch {
|
|
59
59
|
log.error(
|
|
60
|
-
|
|
60
|
+
"Could not parse env.AUTHORIZER, make sure it is correct JSON",
|
|
61
61
|
)
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -69,42 +69,42 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
69
69
|
// NOTE FIXME request.raw.req.rawHeaders can only be null for testing (hapi shot inject())
|
|
70
70
|
const headers = parseHeaders(rawHeaders || []) || {}
|
|
71
71
|
|
|
72
|
-
if (headers[
|
|
72
|
+
if (headers["sls-offline-authorizer-override"]) {
|
|
73
73
|
try {
|
|
74
|
-
authAuthorizer = parse(headers[
|
|
74
|
+
authAuthorizer = parse(headers["sls-offline-authorizer-override"])
|
|
75
75
|
} catch {
|
|
76
76
|
log.error(
|
|
77
|
-
|
|
77
|
+
"Could not parse header sls-offline-authorizer-override, make sure it is correct JSON",
|
|
78
78
|
)
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
if (body) {
|
|
83
|
-
if (typeof body !==
|
|
83
|
+
if (typeof body !== "string") {
|
|
84
84
|
// this.#request.payload is NOT the same as the rawPayload
|
|
85
85
|
body = this.#request.rawPayload
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
if (
|
|
89
|
-
!headers[
|
|
90
|
-
!headers[
|
|
91
|
-
!headers[
|
|
92
|
-
(typeof body ===
|
|
89
|
+
!headers["Content-Length"] &&
|
|
90
|
+
!headers["content-length"] &&
|
|
91
|
+
!headers["Content-length"] &&
|
|
92
|
+
(typeof body === "string" ||
|
|
93
93
|
body instanceof Buffer ||
|
|
94
94
|
body instanceof ArrayBuffer)
|
|
95
95
|
) {
|
|
96
|
-
headers[
|
|
96
|
+
headers["Content-Length"] = String(byteLength(body))
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Set a default Content-Type if not provided.
|
|
100
100
|
if (
|
|
101
|
-
!headers[
|
|
102
|
-
!headers[
|
|
103
|
-
!headers[
|
|
101
|
+
!headers["Content-Type"] &&
|
|
102
|
+
!headers["content-type"] &&
|
|
103
|
+
!headers["Content-type"]
|
|
104
104
|
) {
|
|
105
|
-
headers[
|
|
105
|
+
headers["Content-Type"] = "application/json"
|
|
106
106
|
}
|
|
107
|
-
} else if (body === undefined || body ===
|
|
107
|
+
} else if (body === undefined || body === "") {
|
|
108
108
|
body = null
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -113,8 +113,8 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
113
113
|
|
|
114
114
|
let token = headers.Authorization || headers.authorization
|
|
115
115
|
|
|
116
|
-
if (token && token.split(
|
|
117
|
-
;[, token] = token.split(
|
|
116
|
+
if (token && token.split(" ")[0] === "Bearer") {
|
|
117
|
+
;[, token] = token.split(" ")
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
let claims
|
|
@@ -124,7 +124,7 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
124
124
|
try {
|
|
125
125
|
claims = decodeJwt(token)
|
|
126
126
|
if (claims.scope) {
|
|
127
|
-
scopes = claims.scope.split(
|
|
127
|
+
scopes = claims.scope.split(" ")
|
|
128
128
|
// In AWS HTTP Api the scope property is removed from the decoded JWT
|
|
129
129
|
// I'm leaving this property because I'm not sure how all of the authorizers
|
|
130
130
|
// for AWS REST Api handle JWT.
|
|
@@ -149,7 +149,7 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
149
149
|
// NOTE replace * added by generateHapiPath util so api gateway event is accurate
|
|
150
150
|
const resource =
|
|
151
151
|
this.#routeKey ||
|
|
152
|
-
route.path.replace(`/${this.#stage}`,
|
|
152
|
+
route.path.replace(`/${this.#stage}`, "").replace("*", "+")
|
|
153
153
|
|
|
154
154
|
return {
|
|
155
155
|
body,
|
|
@@ -166,8 +166,8 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
166
166
|
pathParameters: nullIfEmpty(pathParams),
|
|
167
167
|
queryStringParameters: parseQueryStringParameters(url),
|
|
168
168
|
requestContext: {
|
|
169
|
-
accountId:
|
|
170
|
-
apiId:
|
|
169
|
+
accountId: "offlineContext_accountId",
|
|
170
|
+
apiId: "offlineContext_apiId",
|
|
171
171
|
authorizer:
|
|
172
172
|
authAuthorizer ||
|
|
173
173
|
assign(authContext, {
|
|
@@ -176,46 +176,46 @@ export default class LambdaProxyIntegrationEvent {
|
|
|
176
176
|
principalId:
|
|
177
177
|
authPrincipalId ||
|
|
178
178
|
env.PRINCIPAL_ID ||
|
|
179
|
-
|
|
179
|
+
"offlineContext_authorizer_principalId", // See #24
|
|
180
180
|
scopes,
|
|
181
181
|
}),
|
|
182
|
-
domainName:
|
|
183
|
-
domainPrefix:
|
|
184
|
-
extendedRequestId:
|
|
182
|
+
domainName: "offlineContext_domainName",
|
|
183
|
+
domainPrefix: "offlineContext_domainPrefix",
|
|
184
|
+
extendedRequestId: crypto.randomUUID(),
|
|
185
185
|
httpMethod,
|
|
186
186
|
identity: {
|
|
187
187
|
accessKey: null,
|
|
188
|
-
accountId: env.SLS_ACCOUNT_ID ||
|
|
189
|
-
apiKey: env.SLS_API_KEY ||
|
|
190
|
-
apiKeyId: env.SLS_API_KEY_ID ||
|
|
191
|
-
caller: env.SLS_CALLER ||
|
|
188
|
+
accountId: env.SLS_ACCOUNT_ID || "offlineContext_accountId",
|
|
189
|
+
apiKey: env.SLS_API_KEY || "offlineContext_apiKey",
|
|
190
|
+
apiKeyId: env.SLS_API_KEY_ID || "offlineContext_apiKeyId",
|
|
191
|
+
caller: env.SLS_CALLER || "offlineContext_caller",
|
|
192
192
|
cognitoAuthenticationProvider:
|
|
193
|
-
_headers[
|
|
193
|
+
_headers["cognito-authentication-provider"] ||
|
|
194
194
|
env.SLS_COGNITO_AUTHENTICATION_PROVIDER ||
|
|
195
|
-
|
|
195
|
+
"offlineContext_cognitoAuthenticationProvider",
|
|
196
196
|
cognitoAuthenticationType:
|
|
197
197
|
env.SLS_COGNITO_AUTHENTICATION_TYPE ||
|
|
198
|
-
|
|
198
|
+
"offlineContext_cognitoAuthenticationType",
|
|
199
199
|
cognitoIdentityId:
|
|
200
|
-
_headers[
|
|
200
|
+
_headers["cognito-identity-id"] ||
|
|
201
201
|
env.SLS_COGNITO_IDENTITY_ID ||
|
|
202
|
-
|
|
202
|
+
"offlineContext_cognitoIdentityId",
|
|
203
203
|
cognitoIdentityPoolId:
|
|
204
204
|
env.SLS_COGNITO_IDENTITY_POOL_ID ||
|
|
205
|
-
|
|
205
|
+
"offlineContext_cognitoIdentityPoolId",
|
|
206
206
|
principalOrgId: null,
|
|
207
207
|
sourceIp: remoteAddress,
|
|
208
|
-
user:
|
|
209
|
-
userAgent: _headers[
|
|
210
|
-
userArn:
|
|
208
|
+
user: "offlineContext_user",
|
|
209
|
+
userAgent: _headers["user-agent"] || "",
|
|
210
|
+
userArn: "offlineContext_userArn",
|
|
211
211
|
},
|
|
212
212
|
operationName: this.#additionalRequestContext.operationName,
|
|
213
213
|
path: this.#path,
|
|
214
|
-
protocol:
|
|
215
|
-
requestId:
|
|
214
|
+
protocol: "HTTP/1.1",
|
|
215
|
+
requestId: crypto.randomUUID(),
|
|
216
216
|
requestTime,
|
|
217
217
|
requestTimeEpoch,
|
|
218
|
-
resourceId:
|
|
218
|
+
resourceId: "offlineContext_resourceId",
|
|
219
219
|
resourcePath: route.path,
|
|
220
220
|
stage: this.#stage,
|
|
221
221
|
},
|