serverless-offline 13.3.2 → 13.3.4
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 +19 -17
- 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 +157 -158
- 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 +2 -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,16 +1,16 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
albPort: 3003,
|
|
3
|
-
corsAllowHeaders:
|
|
4
|
-
corsAllowOrigin:
|
|
3
|
+
corsAllowHeaders: "accept,content-type,x-api-key,authorization",
|
|
4
|
+
corsAllowOrigin: "*",
|
|
5
5
|
corsDisallowCredentials: true,
|
|
6
|
-
corsExposedHeaders:
|
|
6
|
+
corsExposedHeaders: "WWW-Authenticate,Server-Authorization",
|
|
7
7
|
disableCookieValidation: false,
|
|
8
|
-
dockerHost:
|
|
8
|
+
dockerHost: "localhost",
|
|
9
9
|
dockerHostServicePath: null,
|
|
10
10
|
dockerNetwork: null,
|
|
11
11
|
dockerReadOnly: true,
|
|
12
12
|
enforceSecureCookies: false,
|
|
13
|
-
host:
|
|
13
|
+
host: "localhost",
|
|
14
14
|
httpPort: 3000,
|
|
15
15
|
httpsProtocol: null,
|
|
16
16
|
lambdaPort: 3002,
|
|
@@ -19,7 +19,7 @@ export default {
|
|
|
19
19
|
noAuth: false,
|
|
20
20
|
noPrependStageInUrl: false,
|
|
21
21
|
noTimeout: false,
|
|
22
|
-
prefix:
|
|
22
|
+
prefix: "",
|
|
23
23
|
reloadHandler: false,
|
|
24
24
|
resourceRoutes: false,
|
|
25
25
|
terminateIdleLambdaTime: 60,
|
package/src/config/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as commandOptions } from
|
|
2
|
-
export * from
|
|
3
|
-
export { default as defaultOptions } from
|
|
4
|
-
export * from
|
|
1
|
+
export { default as commandOptions } from "./commandOptions.js"
|
|
2
|
+
export * from "./constants.js"
|
|
3
|
+
export { default as defaultOptions } from "./defaultOptions.js"
|
|
4
|
+
export * from "./supportedRuntimes.js"
|
|
@@ -7,33 +7,33 @@
|
|
|
7
7
|
// ])
|
|
8
8
|
|
|
9
9
|
// GO
|
|
10
|
-
export const supportedGo = new Set([
|
|
10
|
+
export const supportedGo = new Set(["go1.x"])
|
|
11
11
|
|
|
12
12
|
// JAVA
|
|
13
|
-
export const supportedJava = new Set([
|
|
13
|
+
export const supportedJava = new Set(["java8", "java8.al2", "java11", "java17"])
|
|
14
14
|
|
|
15
15
|
// NODE.JS
|
|
16
16
|
export const supportedNodejs = new Set([
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
"nodejs14.x",
|
|
18
|
+
"nodejs16.x",
|
|
19
|
+
"nodejs18.x",
|
|
20
|
+
"nodejs20.x",
|
|
21
21
|
])
|
|
22
22
|
|
|
23
23
|
// PROVIDED
|
|
24
|
-
export const supportedProvided = new Set([
|
|
24
|
+
export const supportedProvided = new Set(["provided", "provided.al2"])
|
|
25
25
|
|
|
26
26
|
// PYTHON
|
|
27
27
|
export const supportedPython = new Set([
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
"python3.7",
|
|
29
|
+
"python3.8",
|
|
30
|
+
"python3.9",
|
|
31
|
+
"python3.10",
|
|
32
|
+
"python3.11",
|
|
33
33
|
])
|
|
34
34
|
|
|
35
35
|
// RUBY
|
|
36
|
-
export const supportedRuby = new Set([
|
|
36
|
+
export const supportedRuby = new Set(["ruby2.7", "ruby3.2"])
|
|
37
37
|
|
|
38
38
|
// deprecated runtimes
|
|
39
39
|
// https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html
|
|
@@ -48,9 +48,9 @@ export const supportedRuntimes = new Set([
|
|
|
48
48
|
])
|
|
49
49
|
|
|
50
50
|
export const unsupportedDockerRuntimes = new Set([
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
"nodejs14.x",
|
|
52
|
+
"nodejs16.x",
|
|
53
|
+
"nodejs18.x",
|
|
54
|
+
"nodejs20.x",
|
|
55
|
+
"python3.9",
|
|
56
56
|
])
|
package/src/errors/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// eslint-disable-next-line import/prefer-default-export
|
|
2
|
-
export { default as LambdaTimeoutError } from
|
|
2
|
+
export { default as LambdaTimeoutError } from "./LambdaTimeoutError.js"
|
package/src/events/alb/Alb.js
CHANGED
|
@@ -7,8 +7,8 @@ export default class AlbEventDefinition {
|
|
|
7
7
|
let conditions
|
|
8
8
|
let rest
|
|
9
9
|
|
|
10
|
-
if (typeof rawAlbEventDefinition ===
|
|
11
|
-
;[listenerArn, priority, conditions] = rawAlbEventDefinition.split(
|
|
10
|
+
if (typeof rawAlbEventDefinition === "string") {
|
|
11
|
+
;[listenerArn, priority, conditions] = rawAlbEventDefinition.split(" ")
|
|
12
12
|
} else {
|
|
13
13
|
;({ listenerArn, priority, conditions, ...rest } = rawAlbEventDefinition)
|
|
14
14
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Buffer } from
|
|
2
|
-
import { exit } from
|
|
3
|
-
import { Server } from
|
|
4
|
-
import { log } from
|
|
1
|
+
import { Buffer } from "node:buffer"
|
|
2
|
+
import { exit } from "node:process"
|
|
3
|
+
import { Server } from "@hapi/hapi"
|
|
4
|
+
import { log } from "@serverless/utils/log.js"
|
|
5
5
|
import {
|
|
6
6
|
detectEncoding,
|
|
7
7
|
generateAlbHapiPath,
|
|
8
8
|
getHttpApiCorsConfig,
|
|
9
|
-
} from
|
|
10
|
-
import LambdaAlbRequestEvent from
|
|
11
|
-
import logRoutes from
|
|
9
|
+
} from "../../utils/index.js"
|
|
10
|
+
import LambdaAlbRequestEvent from "./lambda-events/LambdaAlbRequestEvent.js"
|
|
11
|
+
import logRoutes from "../../utils/logRoutes.js"
|
|
12
12
|
|
|
13
13
|
const { stringify } = JSON
|
|
14
14
|
const { entries } = Object
|
|
@@ -45,7 +45,7 @@ export default class HttpServer {
|
|
|
45
45
|
|
|
46
46
|
this.#server = new Server(serverOptions)
|
|
47
47
|
|
|
48
|
-
this.#server.ext(
|
|
48
|
+
this.#server.ext("onPreResponse", (request, h) => {
|
|
49
49
|
if (request.headers.origin) {
|
|
50
50
|
const response = request.response.isBoom
|
|
51
51
|
? request.response.output
|
|
@@ -64,11 +64,11 @@ export default class HttpServer {
|
|
|
64
64
|
this,
|
|
65
65
|
)
|
|
66
66
|
|
|
67
|
-
if (request.method ===
|
|
67
|
+
if (request.method === "options") {
|
|
68
68
|
response.statusCode = 204
|
|
69
69
|
const allowAllOrigins =
|
|
70
70
|
httpApiCors.allowedOrigins.length === 1 &&
|
|
71
|
-
httpApiCors.allowedOrigins[0] ===
|
|
71
|
+
httpApiCors.allowedOrigins[0] === "*"
|
|
72
72
|
if (
|
|
73
73
|
!allowAllOrigins &&
|
|
74
74
|
!httpApiCors.allowedOrigins.includes(request.headers.origin)
|
|
@@ -77,47 +77,47 @@ export default class HttpServer {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
response.headers[
|
|
80
|
+
response.headers["access-control-allow-origin"] =
|
|
81
81
|
request.headers.origin
|
|
82
82
|
if (httpApiCors.allowCredentials) {
|
|
83
|
-
response.headers[
|
|
83
|
+
response.headers["access-control-allow-credentials"] = "true"
|
|
84
84
|
}
|
|
85
85
|
if (httpApiCors.maxAge) {
|
|
86
|
-
response.headers[
|
|
86
|
+
response.headers["access-control-max-age"] = httpApiCors.maxAge
|
|
87
87
|
}
|
|
88
88
|
if (httpApiCors.exposedResponseHeaders) {
|
|
89
|
-
response.headers[
|
|
90
|
-
httpApiCors.exposedResponseHeaders.join(
|
|
89
|
+
response.headers["access-control-expose-headers"] =
|
|
90
|
+
httpApiCors.exposedResponseHeaders.join(",")
|
|
91
91
|
}
|
|
92
92
|
if (httpApiCors.allowedMethods) {
|
|
93
|
-
response.headers[
|
|
94
|
-
httpApiCors.allowedMethods.join(
|
|
93
|
+
response.headers["access-control-allow-methods"] =
|
|
94
|
+
httpApiCors.allowedMethods.join(",")
|
|
95
95
|
}
|
|
96
96
|
if (httpApiCors.allowedHeaders) {
|
|
97
|
-
response.headers[
|
|
98
|
-
httpApiCors.allowedHeaders.join(
|
|
97
|
+
response.headers["access-control-allow-headers"] =
|
|
98
|
+
httpApiCors.allowedHeaders.join(",")
|
|
99
99
|
}
|
|
100
100
|
} else {
|
|
101
|
-
response.headers[
|
|
101
|
+
response.headers["access-control-allow-origin"] =
|
|
102
102
|
request.headers.origin
|
|
103
|
-
response.headers[
|
|
103
|
+
response.headers["access-control-allow-credentials"] = "true"
|
|
104
104
|
|
|
105
|
-
if (request.method ===
|
|
105
|
+
if (request.method === "options") {
|
|
106
106
|
response.statusCode = 200
|
|
107
107
|
|
|
108
|
-
response.headers[
|
|
109
|
-
request.headers[
|
|
110
|
-
|
|
111
|
-
response.headers[
|
|
108
|
+
response.headers["access-control-expose-headers"] =
|
|
109
|
+
request.headers["access-control-expose-headers"] ||
|
|
110
|
+
"content-type, content-length, etag"
|
|
111
|
+
response.headers["access-control-max-age"] = 60 * 10
|
|
112
112
|
|
|
113
|
-
if (request.headers[
|
|
114
|
-
response.headers[
|
|
115
|
-
request.headers[
|
|
113
|
+
if (request.headers["access-control-request-headers"]) {
|
|
114
|
+
response.headers["access-control-allow-headers"] =
|
|
115
|
+
request.headers["access-control-request-headers"]
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
if (request.headers[
|
|
119
|
-
response.headers[
|
|
120
|
-
request.headers[
|
|
118
|
+
if (request.headers["access-control-request-method"]) {
|
|
119
|
+
response.headers["access-control-allow-methods"] =
|
|
120
|
+
request.headers["access-control-request-method"]
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -147,7 +147,7 @@ export default class HttpServer {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// TODO move the following block
|
|
150
|
-
const server = `${httpsProtocol ?
|
|
150
|
+
const server = `${httpsProtocol ? "https" : "http"}://${host}:${albPort}`
|
|
151
151
|
|
|
152
152
|
log.notice(`ALB Server ready: ${server} 🚀`)
|
|
153
153
|
}
|
|
@@ -191,7 +191,7 @@ export default class HttpServer {
|
|
|
191
191
|
return this.#reply502(response, ``, err)
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
log.debug(
|
|
194
|
+
log.debug("event:", event)
|
|
195
195
|
|
|
196
196
|
const lambdaFunction = this.#lambda.get(functionKey)
|
|
197
197
|
|
|
@@ -206,10 +206,10 @@ export default class HttpServer {
|
|
|
206
206
|
err = _err
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
log.debug(
|
|
209
|
+
log.debug("_____ HANDLER RESOLVED _____")
|
|
210
210
|
|
|
211
211
|
// Failure handling
|
|
212
|
-
let errorStatusCode =
|
|
212
|
+
let errorStatusCode = "502"
|
|
213
213
|
|
|
214
214
|
if (err) {
|
|
215
215
|
const errorMessage = (err.message || err).toString()
|
|
@@ -219,7 +219,7 @@ export default class HttpServer {
|
|
|
219
219
|
if (found && found.length > 1) {
|
|
220
220
|
;[, errorStatusCode] = found
|
|
221
221
|
} else {
|
|
222
|
-
errorStatusCode =
|
|
222
|
+
errorStatusCode = "502"
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
// Mocks Lambda errors
|
|
@@ -260,26 +260,26 @@ export default class HttpServer {
|
|
|
260
260
|
)
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
log.debug(
|
|
263
|
+
log.debug("headers:", headers)
|
|
264
264
|
|
|
265
|
-
response.header(
|
|
265
|
+
response.header("Content-Type", "application/json", {
|
|
266
266
|
duplicate: false,
|
|
267
267
|
override: false,
|
|
268
268
|
})
|
|
269
269
|
|
|
270
|
-
if (typeof result ===
|
|
270
|
+
if (typeof result === "string") {
|
|
271
271
|
response.source = stringify(result)
|
|
272
272
|
} else if (result && result.body !== undefined) {
|
|
273
273
|
if (result.isBase64Encoded) {
|
|
274
|
-
response.encoding =
|
|
275
|
-
response.source = Buffer.from(result.body,
|
|
276
|
-
response.variety =
|
|
274
|
+
response.encoding = "binary"
|
|
275
|
+
response.source = Buffer.from(result.body, "base64")
|
|
276
|
+
response.variety = "buffer"
|
|
277
277
|
} else {
|
|
278
|
-
if (result && result.body && typeof result.body !==
|
|
278
|
+
if (result && result.body && typeof result.body !== "string") {
|
|
279
279
|
// FIXME TODO we should probably just write to console instead of returning a payload
|
|
280
280
|
return this.#reply502(
|
|
281
281
|
response,
|
|
282
|
-
|
|
282
|
+
"According to the API Gateway specs, the body content must be stringified. Check your Lambda response and make sure you are invoking JSON.stringify(YOUR_CONTENT) on your body object",
|
|
283
283
|
{},
|
|
284
284
|
)
|
|
285
285
|
}
|
|
@@ -292,7 +292,7 @@ export default class HttpServer {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
createRoutes(functionKey, albEvent) {
|
|
295
|
-
let method =
|
|
295
|
+
let method = "ANY"
|
|
296
296
|
if ((albEvent.conditions.method || []).length > 0) {
|
|
297
297
|
method = albEvent.conditions.method[0].toUpperCase()
|
|
298
298
|
}
|
|
@@ -302,7 +302,7 @@ export default class HttpServer {
|
|
|
302
302
|
|
|
303
303
|
const stage = this.#options.stage || this.#serverless.service.provider.stage
|
|
304
304
|
const { host, albPort, httpsProtocol } = this.#options
|
|
305
|
-
const server = `${httpsProtocol ?
|
|
305
|
+
const server = `${httpsProtocol ? "https" : "http"}://${host}:${albPort}`
|
|
306
306
|
|
|
307
307
|
this.#terminalInfo.push({
|
|
308
308
|
invokePath: `/2015-03-31/functions/${functionKey}/invocations`,
|
|
@@ -312,7 +312,7 @@ export default class HttpServer {
|
|
|
312
312
|
stage: this.#options.noPrependStageInUrl ? null : stage,
|
|
313
313
|
})
|
|
314
314
|
|
|
315
|
-
const hapiMethod = method ===
|
|
315
|
+
const hapiMethod = method === "ANY" ? "*" : method
|
|
316
316
|
const hapiOptions = {
|
|
317
317
|
response: {
|
|
318
318
|
emptyStatusCode: 200,
|
|
@@ -321,15 +321,15 @@ export default class HttpServer {
|
|
|
321
321
|
|
|
322
322
|
// skip HEAD routes as hapi will fail with 'Method name not allowed: HEAD ...'
|
|
323
323
|
// for more details, check https://github.com/dherault/serverless-offline/issues/204
|
|
324
|
-
if (hapiMethod ===
|
|
324
|
+
if (hapiMethod === "HEAD") {
|
|
325
325
|
log.notice(
|
|
326
|
-
|
|
326
|
+
"HEAD method event detected. Skipping HAPI server route mapping",
|
|
327
327
|
)
|
|
328
328
|
|
|
329
329
|
return
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
if (hapiMethod !==
|
|
332
|
+
if (hapiMethod !== "HEAD" && hapiMethod !== "GET") {
|
|
333
333
|
// maxBytes: Increase request size from 1MB default limit to 10MB.
|
|
334
334
|
// Cf AWS API GW payload limits.
|
|
335
335
|
hapiOptions.payload = {
|
|
@@ -357,14 +357,14 @@ export default class HttpServer {
|
|
|
357
357
|
|
|
358
358
|
log.error(error)
|
|
359
359
|
|
|
360
|
-
response.header(
|
|
360
|
+
response.header("Content-Type", "application/json")
|
|
361
361
|
|
|
362
362
|
response.statusCode = statusCode
|
|
363
363
|
response.source = {
|
|
364
364
|
errorMessage: message,
|
|
365
365
|
errorType: error.constructor.name,
|
|
366
366
|
offlineInfo:
|
|
367
|
-
|
|
367
|
+
"If you believe this is an issue with serverless-offline please submit it, thanks. https://github.com/dherault/serverless-offline/issues",
|
|
368
368
|
stackTrace: this.#getArrayStackTrace(error.stack),
|
|
369
369
|
}
|
|
370
370
|
|
|
@@ -379,7 +379,7 @@ export default class HttpServer {
|
|
|
379
379
|
#getArrayStackTrace(stack) {
|
|
380
380
|
if (!stack) return null
|
|
381
381
|
|
|
382
|
-
const splittedStack = stack.split(
|
|
382
|
+
const splittedStack = stack.split("\n")
|
|
383
383
|
|
|
384
384
|
return splittedStack
|
|
385
385
|
.slice(
|
package/src/events/alb/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from
|
|
1
|
+
export { default } from "./Alb.js"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseMultiValueHeaders,
|
|
3
3
|
parseMultiValueQueryStringParameters,
|
|
4
|
-
} from
|
|
4
|
+
} from "../../../utils/index.js"
|
|
5
5
|
|
|
6
6
|
const { fromEntries } = Object
|
|
7
7
|
|
|
@@ -44,7 +44,7 @@ export default class LambdaAlbRequestEvent {
|
|
|
44
44
|
elb: {
|
|
45
45
|
targetGroupArn:
|
|
46
46
|
// TODO: probably replace this
|
|
47
|
-
|
|
47
|
+
"arn:aws:elasticloadbalancing:us-east-1:550213415212:targetgroup/5811b5d6aff964cd50efa8596604c4e0/b49d49c443aa999f",
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default } from
|
|
1
|
+
export { default } from "./LambdaAlbRequestEvent.js"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import authMatchPolicyResource from
|
|
1
|
+
import authMatchPolicyResource from "./authMatchPolicyResource.js"
|
|
2
2
|
|
|
3
3
|
const { isArray } = Array
|
|
4
4
|
|
|
@@ -24,12 +24,12 @@ export default function authCanExecuteResource(policy, resource) {
|
|
|
24
24
|
const denyStatementFound = checkStatementsAgainstResource(
|
|
25
25
|
Statement,
|
|
26
26
|
resource,
|
|
27
|
-
|
|
27
|
+
"Deny",
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
if (denyStatementFound) {
|
|
31
31
|
return false
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
return checkStatementsAgainstResource(Statement, resource,
|
|
34
|
+
return checkStatementsAgainstResource(Statement, resource, "Allow")
|
|
35
35
|
}
|
|
@@ -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)
|
|
@@ -15,9 +15,9 @@ function buildSuccessResult(authorizerName) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function handleStringAuthorizer(authorizerString) {
|
|
18
|
-
if (authorizerString.toUpperCase() ===
|
|
18
|
+
if (authorizerString.toUpperCase() === "AWS_IAM") {
|
|
19
19
|
return buildFailureResult(
|
|
20
|
-
|
|
20
|
+
"Serverless Offline does not support the AWS_IAM authorization type",
|
|
21
21
|
)
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -27,9 +27,9 @@ function handleStringAuthorizer(authorizerString) {
|
|
|
27
27
|
function handleObjectAuthorizer(authorizerObject) {
|
|
28
28
|
const { arn, authorizerId, name, type } = authorizerObject
|
|
29
29
|
|
|
30
|
-
if (type && type.toUpperCase() ===
|
|
30
|
+
if (type && type.toUpperCase() === "AWS_IAM") {
|
|
31
31
|
return buildFailureResult(
|
|
32
|
-
|
|
32
|
+
"Serverless Offline does not support the AWS_IAM authorization type",
|
|
33
33
|
)
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -47,7 +47,7 @@ function handleObjectAuthorizer(authorizerObject) {
|
|
|
47
47
|
|
|
48
48
|
if (!name) {
|
|
49
49
|
return buildFailureResult(
|
|
50
|
-
|
|
50
|
+
"Serverless Offline supports local authorizers but authorizer name is missing",
|
|
51
51
|
)
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -61,15 +61,15 @@ export default function authFunctionNameExtractor(endpoint) {
|
|
|
61
61
|
return buildSuccessResult(null)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
if (typeof authorizer ===
|
|
64
|
+
if (typeof authorizer === "string") {
|
|
65
65
|
return handleStringAuthorizer(authorizer)
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (typeof authorizer ===
|
|
68
|
+
if (typeof authorizer === "object") {
|
|
69
69
|
return handleObjectAuthorizer(authorizer)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
return buildFailureResult(
|
|
73
|
-
|
|
73
|
+
"Serverless Offline supports only local authorizers defined as string or object",
|
|
74
74
|
)
|
|
75
75
|
}
|
|
@@ -17,41 +17,41 @@ export default function authMatchPolicyResource(policyResource, resource) {
|
|
|
17
17
|
return true
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
if (policyResource ===
|
|
20
|
+
if (policyResource === "*") {
|
|
21
21
|
return true
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
if (policyResource ===
|
|
24
|
+
if (policyResource === "arn:aws:execute-api:**") {
|
|
25
25
|
// better fix for #523
|
|
26
26
|
return true
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
if (policyResource ===
|
|
29
|
+
if (policyResource === "arn:aws:execute-api:*:*:*") {
|
|
30
30
|
return true
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if (policyResource.includes(
|
|
33
|
+
if (policyResource.includes("*") || policyResource.includes("?")) {
|
|
34
34
|
// Policy contains a wildcard resource
|
|
35
35
|
|
|
36
36
|
const parsedPolicyResource = parseResource(policyResource)
|
|
37
37
|
const parsedResource = parseResource(resource)
|
|
38
38
|
|
|
39
39
|
if (
|
|
40
|
-
parsedPolicyResource.region !==
|
|
40
|
+
parsedPolicyResource.region !== "*" &&
|
|
41
41
|
parsedPolicyResource.region !== parsedResource.region
|
|
42
42
|
) {
|
|
43
43
|
return false
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (
|
|
47
|
-
parsedPolicyResource.accountId !==
|
|
47
|
+
parsedPolicyResource.accountId !== "*" &&
|
|
48
48
|
parsedPolicyResource.accountId !== parsedResource.accountId
|
|
49
49
|
) {
|
|
50
50
|
return false
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if (
|
|
54
|
-
parsedPolicyResource.restApiId !==
|
|
54
|
+
parsedPolicyResource.restApiId !== "*" &&
|
|
55
55
|
parsedPolicyResource.restApiId !== parsedResource.restApiId
|
|
56
56
|
) {
|
|
57
57
|
return false
|
|
@@ -61,7 +61,7 @@ export default function authMatchPolicyResource(policyResource, resource) {
|
|
|
61
61
|
// for the requested resource and the resource defined in the policy
|
|
62
62
|
// Need to create a regex replacing ? with one character and * with any number of characters
|
|
63
63
|
const regExp = new RegExp(
|
|
64
|
-
parsedPolicyResource.path.replaceAll(
|
|
64
|
+
parsedPolicyResource.path.replaceAll("*", ".*").replaceAll("?", "."),
|
|
65
65
|
)
|
|
66
66
|
|
|
67
67
|
return regExp.test(parsedResource.path)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import Boom from
|
|
2
|
-
import { log } from
|
|
1
|
+
import Boom from "@hapi/boom"
|
|
2
|
+
import { log } from "@serverless/utils/log.js"
|
|
3
3
|
|
|
4
4
|
const { entries, fromEntries, values } = Object
|
|
5
5
|
|
|
6
6
|
function internalServerError(message) {
|
|
7
|
-
const errorType =
|
|
7
|
+
const errorType = "AuthorizerConfigurationException"
|
|
8
8
|
|
|
9
9
|
const error = Boom.internal()
|
|
10
10
|
|
|
11
|
-
error.output.headers[
|
|
11
|
+
error.output.headers["x-amzn-ErrorType"] = errorType
|
|
12
12
|
error.output.payload.error = errorType
|
|
13
13
|
error.output.payload.message = message
|
|
14
14
|
|
|
@@ -18,9 +18,9 @@ function internalServerError(message) {
|
|
|
18
18
|
function isValidContext(context) {
|
|
19
19
|
return values(context).every(
|
|
20
20
|
(value) =>
|
|
21
|
-
typeof value ===
|
|
22
|
-
typeof value ===
|
|
23
|
-
typeof value ===
|
|
21
|
+
typeof value === "boolean" ||
|
|
22
|
+
typeof value === "number" ||
|
|
23
|
+
typeof value === "string",
|
|
24
24
|
)
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -31,17 +31,17 @@ function transform(context) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export default function authValidateContext(context, authFunName) {
|
|
34
|
-
if (typeof context !==
|
|
35
|
-
return internalServerError(
|
|
34
|
+
if (typeof context !== "object") {
|
|
35
|
+
return internalServerError("Authorizer response context must be an object")
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
if (!isValidContext(context)) {
|
|
39
39
|
const error =
|
|
40
|
-
|
|
40
|
+
"Authorizer response context values must be of type string, number, or boolean"
|
|
41
41
|
|
|
42
42
|
log.notice(
|
|
43
43
|
`Detected invalid value types returned in authorizer context: (λ: ${authFunName}). ${error}. ` +
|
|
44
|
-
|
|
44
|
+
"More info: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html",
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
return internalServerError(error)
|