serverless-openapi-documenter 0.0.108 → 0.0.110
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 +8 -7
- package/json/owasp.json +52 -56
- package/package.json +7 -8
- package/src/definitionGenerator.js +7 -1
- package/src/owasp.js +37 -11
- package/test/json/newOWASP.json +52 -56
- package/test/unit/definitionGenerator.spec.js +199 -83
- package/test/unit/openAPIGenerator.spec.js +4 -2
- package/test/unit/owasp.spec.js +106 -99
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
</a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
This will generate an OpenAPI V3 (up to v3.0.
|
|
15
|
+
This will generate an OpenAPI V3 (up to v3.0.4) file for you from your serverless file. It can optionally generate a [Postman Collection V2](https://github.com/postmanlabs/openapi-to-postman) from the OpenAPI file for you too. This currently works for `http` and `httpApi` configurations.
|
|
16
16
|
|
|
17
17
|
Originally based off of: https://github.com/temando/serverless-openapi-documentation
|
|
18
18
|
|
|
19
19
|
## Install
|
|
20
20
|
|
|
21
|
-
This plugin works for Serverless (2.x, 3.x and 4.x) and only supports node.js
|
|
21
|
+
This plugin works for Serverless (2.x, 3.x and 4.x) and only supports node.js 20 and up.
|
|
22
22
|
|
|
23
23
|
To add this plugin to your package.json:
|
|
24
24
|
|
|
@@ -39,7 +39,7 @@ plugins:
|
|
|
39
39
|
|
|
40
40
|
## Adding documentation to serverless
|
|
41
41
|
|
|
42
|
-
To Run: `serverless openapi generate -o openapi.json -f json -a 3.0.
|
|
42
|
+
To Run: `serverless openapi generate -o openapi.json -f json -a 3.0.4 -p postman.json`
|
|
43
43
|
|
|
44
44
|
Options:
|
|
45
45
|
|
|
@@ -316,7 +316,7 @@ custom:
|
|
|
316
316
|
in: header
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
It accepts all available Security Schemes and follows the specification: https://spec.openapis.org/oas/v3.0.
|
|
319
|
+
It accepts all available Security Schemes and follows the specification: https://spec.openapis.org/oas/v3.0.4#security-scheme-object
|
|
320
320
|
|
|
321
321
|
#### Security on each operation
|
|
322
322
|
|
|
@@ -904,7 +904,7 @@ getContent:
|
|
|
904
904
|
|
|
905
905
|
You can refer to the `operationId` that you created.
|
|
906
906
|
|
|
907
|
-
You can read more about [links](https://swagger.io/docs/specification/links/) on the swagger.io site and in the [OpenAPI](https://spec.openapis.org/oas/v3.0.
|
|
907
|
+
You can read more about [links](https://swagger.io/docs/specification/links/) on the swagger.io site and in the [OpenAPI](https://spec.openapis.org/oas/v3.0.4#link-object) specification. They don't seem widely supported just yet, but perhaps they'll improve your documentation.
|
|
908
908
|
|
|
909
909
|
##### `responseHeaders`
|
|
910
910
|
|
|
@@ -928,7 +928,7 @@ The generator will interpret your settings for CORS and automatically add the re
|
|
|
928
928
|
|
|
929
929
|
You can make use of the [OWASP Secure Headers](https://owasp.org/www-project-secure-headers/#x-permitted-cross-domain-policies) to generate response headers. These are a selection of response headers with default values that OWASP recommends returning with your response to help secure your application.
|
|
930
930
|
|
|
931
|
-
The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations. If you do not allow outside connections, it will default to a version of recommendations from **
|
|
931
|
+
The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations. If you do not allow outside connections, it will default to a version of recommendations from **2024-09-19 21:29:28 UTC**.
|
|
932
932
|
|
|
933
933
|
Like CORS, if you have already set any of the OWASP Secure headers via `responseHeaders`, it will not overwrite them.
|
|
934
934
|
|
|
@@ -973,13 +973,14 @@ The full list of OWASP Secure Headers you can set are:
|
|
|
973
973
|
- crossOriginOpenerPolicy - Cross-Origin-Opener-Policy,
|
|
974
974
|
- crossOriginResourcePolicy - Cross-Origin-Resource-Policy,
|
|
975
975
|
- permissionsPolicy - Permissions-Policy,
|
|
976
|
-
- pragma - Pragma,
|
|
977
976
|
- referrerPolicy - Referrer-Policy,
|
|
978
977
|
- strictTransportSecurity - Strict-Transport-Security,
|
|
979
978
|
- xContentTypeOptions - X-Content-Type-Options,
|
|
980
979
|
- xFrameOptions - X-Frame-Options,
|
|
981
980
|
- xPermittedCrossDomainPolicies - X-Permitted-Cross-Domain-Policies
|
|
982
981
|
|
|
982
|
+
You should note that `Pragma` has been [deprecated by owasp](https://owasp.org/www-project-secure-headers/#pragma), this plugin will issue a warning when you are still using Pragma and might drop support.
|
|
983
|
+
|
|
983
984
|
###### Subset of OWASP Secure Headers with user defined values
|
|
984
985
|
|
|
985
986
|
If you wish to override the OWASP Secure Headers, you can write your `methodResponse` like:
|
package/json/owasp.json
CHANGED
|
@@ -1,57 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"value": "none"
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
2
|
+
"last_update_utc": "2024-09-19 21:29:28",
|
|
3
|
+
"headers": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Cache-Control",
|
|
6
|
+
"value": "no-store, max-age=0"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "Clear-Site-Data",
|
|
10
|
+
"value": "\"cache\",\"cookies\",\"storage\""
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "Content-Security-Policy",
|
|
14
|
+
"value": "default-src 'self'; form-action 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "Cross-Origin-Embedder-Policy",
|
|
18
|
+
"value": "require-corp"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "Cross-Origin-Opener-Policy",
|
|
22
|
+
"value": "same-origin"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "Cross-Origin-Resource-Policy",
|
|
26
|
+
"value": "same-origin"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "Permissions-Policy",
|
|
30
|
+
"value": "accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), unload=()"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "Referrer-Policy",
|
|
34
|
+
"value": "no-referrer"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Strict-Transport-Security",
|
|
38
|
+
"value": "max-age=31536000; includeSubDomains"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "X-Content-Type-Options",
|
|
42
|
+
"value": "nosniff"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "X-Frame-Options",
|
|
46
|
+
"value": "deny"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "X-Permitted-Cross-Domain-Policies",
|
|
50
|
+
"value": "none"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serverless-openapi-documenter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.110",
|
|
4
4
|
"description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -51,17 +51,16 @@
|
|
|
51
51
|
"js-yaml": "^4.1.0",
|
|
52
52
|
"json-schema-for-openapi": "^0.5.0",
|
|
53
53
|
"lodash.isequal": "^4.5.0",
|
|
54
|
-
"openapi-to-postmanv2": "^
|
|
55
|
-
"
|
|
56
|
-
"uuid": "^10.0.0"
|
|
54
|
+
"openapi-to-postmanv2": "^5.0.0",
|
|
55
|
+
"uuid": "^11.1.0"
|
|
57
56
|
},
|
|
58
57
|
"engines": {
|
|
59
|
-
"node": ">=
|
|
58
|
+
"node": ">=20"
|
|
60
59
|
},
|
|
61
60
|
"devDependencies": {
|
|
62
61
|
"chai": "^4.5.0",
|
|
63
|
-
"mocha": "^
|
|
64
|
-
"nock": "^
|
|
65
|
-
"sinon": "^
|
|
62
|
+
"mocha": "^11.1.0",
|
|
63
|
+
"nock": "^14.0.2",
|
|
64
|
+
"sinon": "^20.0.0"
|
|
66
65
|
}
|
|
67
66
|
}
|
|
@@ -553,6 +553,12 @@ class DefinitionGenerator {
|
|
|
553
553
|
throw err;
|
|
554
554
|
});
|
|
555
555
|
} else {
|
|
556
|
+
if (Object.keys(response.owasp).includes("pragma")) {
|
|
557
|
+
this.logger.warn(
|
|
558
|
+
"Pragma has been deprecated by owasp (https://owasp.org/www-project-secure-headers/#pragma) and support for defaults will be dropped by this plugin."
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
|
|
556
562
|
owaspHeaders = await this.createResponseHeaders(
|
|
557
563
|
oWASP.getHeaders(response.owasp)
|
|
558
564
|
).catch((err) => {
|
|
@@ -603,7 +609,7 @@ class DefinitionGenerator {
|
|
|
603
609
|
).catch((err) => {
|
|
604
610
|
throw err;
|
|
605
611
|
});
|
|
606
|
-
} else if (this.currentEvent
|
|
612
|
+
} else if (this.currentEvent?.cors) {
|
|
607
613
|
const newHeaders = {};
|
|
608
614
|
for (const key of Object.keys(this.DEFAULT_CORS_HEADERS)) {
|
|
609
615
|
if (
|
package/src/owasp.js
CHANGED
|
@@ -47,11 +47,6 @@ class OWASP {
|
|
|
47
47
|
description:
|
|
48
48
|
"The HTTP Permissions-Policy header provides a mechanism to allow and deny the use of browser features in a document or within any [<iframe>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) elements in the document. - [MDN Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy)",
|
|
49
49
|
},
|
|
50
|
-
Pragma: {
|
|
51
|
-
description:
|
|
52
|
-
"The Pragma HTTP/1.0 general header is an implementation-specific header that may have various effects along the request-response chain. This header serves for backwards compatibility with the HTTP/1.0 caches that do not have a [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) HTTP/1.1 header. - [MDN Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma)",
|
|
53
|
-
deprecated: true,
|
|
54
|
-
},
|
|
55
50
|
"Referrer-Policy": {
|
|
56
51
|
description:
|
|
57
52
|
"The Referrer-Policy [HTTP header](https://developer.mozilla.org/en-US/docs/Glossary/HTTP_header) controls how much [referrer information](https://developer.mozilla.org/en-US/docs/Web/Security/Referer_header:_privacy_and_security_concerns) (sent with the [Referer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) header) should be included with requests. Aside from the HTTP header, you can [set this policy in HTML](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#integration_with_html). - [MDN Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy)",
|
|
@@ -153,13 +148,44 @@ class OWASP {
|
|
|
153
148
|
getHeaders(headerList) {
|
|
154
149
|
const obj = {};
|
|
155
150
|
for (const headerName of Object.keys(headerList)) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
if (headerName === "pragma") {
|
|
152
|
+
const pragma = {
|
|
153
|
+
Pragma: {
|
|
154
|
+
description:
|
|
155
|
+
"The Pragma HTTP/1.0 general header is an implementation-specific header that may have various effects along the request-response chain. This header serves for backwards compatibility with the HTTP/1.0 caches that do not have a [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) HTTP/1.1 header. - [MDN Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma)",
|
|
156
|
+
deprecated: true,
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (typeof headerList["pragma"] !== "boolean") {
|
|
161
|
+
Object.assign(pragma["Pragma"], {
|
|
162
|
+
schema: {
|
|
163
|
+
type: "string",
|
|
164
|
+
default: headerList["pragma"].value,
|
|
165
|
+
example: headerList["pragma"].value,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
Object.assign(pragma["Pragma"], {
|
|
170
|
+
schema: {
|
|
171
|
+
default: "no-cache",
|
|
172
|
+
type: "string",
|
|
173
|
+
example: "no-cache",
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Object.assign(obj, pragma);
|
|
179
|
+
} else {
|
|
180
|
+
const defaultHeader =
|
|
181
|
+
this.DEFAULT_OWASP_HEADERS[this.headerMap[headerName]];
|
|
182
|
+
|
|
183
|
+
Object.assign(obj, { [this.headerMap[headerName]]: defaultHeader });
|
|
159
184
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
185
|
+
if (typeof headerList[headerName] !== "boolean") {
|
|
186
|
+
obj[this.headerMap[headerName]].schema.default =
|
|
187
|
+
headerList[headerName].value;
|
|
188
|
+
}
|
|
163
189
|
}
|
|
164
190
|
}
|
|
165
191
|
|
package/test/json/newOWASP.json
CHANGED
|
@@ -1,57 +1,53 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"value": "none"
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
2
|
+
"last_update_utc": "2024-09-19 21:29:28",
|
|
3
|
+
"headers": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Cache-Control",
|
|
6
|
+
"value": "no-store, max-age=0"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "Clear-Site-Data",
|
|
10
|
+
"value": "\"cache\",\"cookies\",\"storage\""
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "Content-Security-Policy",
|
|
14
|
+
"value": "default-src 'self'; form-action 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "Cross-Origin-Embedder-Policy",
|
|
18
|
+
"value": "require-corp"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "Cross-Origin-Opener-Policy",
|
|
22
|
+
"value": "same-origin"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "Cross-Origin-Resource-Policy",
|
|
26
|
+
"value": "same-origin"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "Permissions-Policy",
|
|
30
|
+
"value": "accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), unload=()"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "Referrer-Policy",
|
|
34
|
+
"value": "no-referrer"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "Strict-Transport-Security",
|
|
38
|
+
"value": "max-age=31536000; includeSubDomains"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "X-Content-Type-Options",
|
|
42
|
+
"value": "nosniff"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "X-Frame-Options",
|
|
46
|
+
"value": "deny"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "X-Permitted-Cross-Domain-Policies",
|
|
50
|
+
"value": "none"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -10,6 +10,14 @@ const DefinitionGenerator = require("../../src/definitionGenerator");
|
|
|
10
10
|
|
|
11
11
|
describe("DefinitionGenerator", () => {
|
|
12
12
|
let mockServerless;
|
|
13
|
+
const logger = {
|
|
14
|
+
verbose: (str) => {
|
|
15
|
+
console.log(str);
|
|
16
|
+
},
|
|
17
|
+
warn: (str) => {
|
|
18
|
+
console.log(str);
|
|
19
|
+
},
|
|
20
|
+
};
|
|
13
21
|
const v4 = new RegExp(
|
|
14
22
|
/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
|
|
15
23
|
);
|
|
@@ -26,11 +34,7 @@ describe("DefinitionGenerator", () => {
|
|
|
26
34
|
|
|
27
35
|
describe("constructor", () => {
|
|
28
36
|
it("should return a definitionGenerator", function () {
|
|
29
|
-
const expected = new DefinitionGenerator(mockServerless,
|
|
30
|
-
verbose: (str) => {
|
|
31
|
-
console.log(str);
|
|
32
|
-
},
|
|
33
|
-
});
|
|
37
|
+
const expected = new DefinitionGenerator(mockServerless, logger);
|
|
34
38
|
expect(expected).to.be.an.instanceOf(DefinitionGenerator);
|
|
35
39
|
});
|
|
36
40
|
|
|
@@ -39,11 +43,10 @@ describe("DefinitionGenerator", () => {
|
|
|
39
43
|
JSON.stringify(mockServerless)
|
|
40
44
|
);
|
|
41
45
|
delete serverlessWithoutOpenAPIVersion.processedInput;
|
|
42
|
-
let expected = new DefinitionGenerator(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
46
|
+
let expected = new DefinitionGenerator(
|
|
47
|
+
serverlessWithoutOpenAPIVersion,
|
|
48
|
+
logger
|
|
49
|
+
);
|
|
47
50
|
expect(expected.version).to.be.equal("3.0.0");
|
|
48
51
|
|
|
49
52
|
Object.assign(serverlessWithoutOpenAPIVersion, { processedInput: {} });
|
|
@@ -57,55 +60,50 @@ describe("DefinitionGenerator", () => {
|
|
|
57
60
|
serverlessWithoutOpenAPIVersion.processedInput = {
|
|
58
61
|
options: {},
|
|
59
62
|
};
|
|
60
|
-
expected = new DefinitionGenerator(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
63
|
+
expected = new DefinitionGenerator(
|
|
64
|
+
serverlessWithoutOpenAPIVersion,
|
|
65
|
+
logger
|
|
66
|
+
);
|
|
65
67
|
expect(expected.version).to.be.equal("3.0.0");
|
|
66
68
|
|
|
67
69
|
serverlessWithoutOpenAPIVersion.processedInput.options = {
|
|
68
70
|
test: "abc",
|
|
69
71
|
};
|
|
70
72
|
|
|
71
|
-
expected = new DefinitionGenerator(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
73
|
+
expected = new DefinitionGenerator(
|
|
74
|
+
serverlessWithoutOpenAPIVersion,
|
|
75
|
+
logger
|
|
76
|
+
);
|
|
76
77
|
expect(expected.version).to.be.equal("3.0.0");
|
|
77
78
|
|
|
78
79
|
serverlessWithoutOpenAPIVersion.processedInput.options = {
|
|
79
80
|
openApiVersion: null,
|
|
80
81
|
};
|
|
81
82
|
|
|
82
|
-
expected = new DefinitionGenerator(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
});
|
|
83
|
+
expected = new DefinitionGenerator(
|
|
84
|
+
serverlessWithoutOpenAPIVersion,
|
|
85
|
+
logger
|
|
86
|
+
);
|
|
87
87
|
expect(expected.version).to.be.equal("3.0.0");
|
|
88
88
|
|
|
89
89
|
serverlessWithoutOpenAPIVersion.processedInput.options = {
|
|
90
90
|
openApiVersion: undefined,
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
expected = new DefinitionGenerator(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
93
|
+
expected = new DefinitionGenerator(
|
|
94
|
+
serverlessWithoutOpenAPIVersion,
|
|
95
|
+
logger
|
|
96
|
+
);
|
|
98
97
|
expect(expected.version).to.be.equal("3.0.0");
|
|
99
98
|
|
|
100
99
|
serverlessWithoutOpenAPIVersion.processedInput.options = {
|
|
101
100
|
openapiVersion: undefined,
|
|
102
101
|
};
|
|
103
102
|
|
|
104
|
-
expected = new DefinitionGenerator(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
103
|
+
expected = new DefinitionGenerator(
|
|
104
|
+
serverlessWithoutOpenAPIVersion,
|
|
105
|
+
logger
|
|
106
|
+
);
|
|
109
107
|
expect(expected.version).to.be.equal("3.0.0");
|
|
110
108
|
});
|
|
111
109
|
|
|
@@ -115,20 +113,15 @@ describe("DefinitionGenerator", () => {
|
|
|
115
113
|
);
|
|
116
114
|
serverlessWithOpenAPIVersion.processedInput.options.openApiVersion =
|
|
117
115
|
"3.0.2";
|
|
118
|
-
let expected = new DefinitionGenerator(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
});
|
|
116
|
+
let expected = new DefinitionGenerator(
|
|
117
|
+
serverlessWithOpenAPIVersion,
|
|
118
|
+
logger
|
|
119
|
+
);
|
|
123
120
|
expect(expected.version).to.be.equal("3.0.2");
|
|
124
121
|
|
|
125
122
|
serverlessWithOpenAPIVersion.processedInput.options.openApiVersion =
|
|
126
123
|
"3.0.1";
|
|
127
|
-
expected = new DefinitionGenerator(serverlessWithOpenAPIVersion,
|
|
128
|
-
verbose: (str) => {
|
|
129
|
-
console.log(str);
|
|
130
|
-
},
|
|
131
|
-
});
|
|
124
|
+
expected = new DefinitionGenerator(serverlessWithOpenAPIVersion, logger);
|
|
132
125
|
expect(expected.version).to.be.equal("3.0.1");
|
|
133
126
|
});
|
|
134
127
|
|
|
@@ -148,11 +141,7 @@ describe("DefinitionGenerator", () => {
|
|
|
148
141
|
throw err;
|
|
149
142
|
});
|
|
150
143
|
|
|
151
|
-
const expected = new DefinitionGenerator(mockServerless,
|
|
152
|
-
verbose: (str) => {
|
|
153
|
-
console.log(str);
|
|
154
|
-
},
|
|
155
|
-
});
|
|
144
|
+
const expected = new DefinitionGenerator(mockServerless, logger);
|
|
156
145
|
|
|
157
146
|
expect(expected.REDOCLY_RULES).to.have.property(
|
|
158
147
|
"operation-2xx-response",
|
|
@@ -173,7 +162,10 @@ describe("DefinitionGenerator", () => {
|
|
|
173
162
|
|
|
174
163
|
describe("createInfo", () => {
|
|
175
164
|
it("should create openAPI info object correctly", function () {
|
|
176
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
165
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
166
|
+
mockServerless,
|
|
167
|
+
logger
|
|
168
|
+
);
|
|
177
169
|
definitionGenerator.createInfo();
|
|
178
170
|
|
|
179
171
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -183,7 +175,10 @@ describe("DefinitionGenerator", () => {
|
|
|
183
175
|
|
|
184
176
|
it("should use the service name when documentation title has not been supplied", function () {
|
|
185
177
|
delete mockServerless.service.custom.documentation.title;
|
|
186
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
178
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
179
|
+
mockServerless,
|
|
180
|
+
logger
|
|
181
|
+
);
|
|
187
182
|
definitionGenerator.createInfo();
|
|
188
183
|
|
|
189
184
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -195,7 +190,10 @@ describe("DefinitionGenerator", () => {
|
|
|
195
190
|
|
|
196
191
|
it("should use the service name when documentation description has not been supplied", function () {
|
|
197
192
|
delete mockServerless.service.custom.documentation.description;
|
|
198
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
193
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
194
|
+
mockServerless,
|
|
195
|
+
logger
|
|
196
|
+
);
|
|
199
197
|
definitionGenerator.createInfo();
|
|
200
198
|
|
|
201
199
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -205,7 +203,10 @@ describe("DefinitionGenerator", () => {
|
|
|
205
203
|
|
|
206
204
|
it("should use an empty string when documentation description has not been supplied", function () {
|
|
207
205
|
delete mockServerless.service.custom.documentation.description;
|
|
208
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
206
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
207
|
+
mockServerless,
|
|
208
|
+
logger
|
|
209
|
+
);
|
|
209
210
|
definitionGenerator.createInfo();
|
|
210
211
|
|
|
211
212
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -216,7 +217,10 @@ describe("DefinitionGenerator", () => {
|
|
|
216
217
|
it("should generate a uuid for version when documentation version has not been supplied", function () {
|
|
217
218
|
delete mockServerless.service.custom.documentation.version;
|
|
218
219
|
|
|
219
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
220
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
221
|
+
mockServerless,
|
|
222
|
+
logger
|
|
223
|
+
);
|
|
220
224
|
definitionGenerator.createInfo();
|
|
221
225
|
|
|
222
226
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -230,7 +234,10 @@ describe("DefinitionGenerator", () => {
|
|
|
230
234
|
url: "http://example.com",
|
|
231
235
|
email: "john@example.com",
|
|
232
236
|
};
|
|
233
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
237
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
238
|
+
mockServerless,
|
|
239
|
+
logger
|
|
240
|
+
);
|
|
234
241
|
definitionGenerator.createInfo();
|
|
235
242
|
|
|
236
243
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -245,7 +252,10 @@ describe("DefinitionGenerator", () => {
|
|
|
245
252
|
name: "John",
|
|
246
253
|
email: "john@example.com",
|
|
247
254
|
};
|
|
248
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
255
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
256
|
+
mockServerless,
|
|
257
|
+
logger
|
|
258
|
+
);
|
|
249
259
|
definitionGenerator.createInfo();
|
|
250
260
|
|
|
251
261
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -263,7 +273,10 @@ describe("DefinitionGenerator", () => {
|
|
|
263
273
|
name: "Apache 2.0",
|
|
264
274
|
url: "https://www.apache.org/licenses/LICENSE-2.0.html",
|
|
265
275
|
};
|
|
266
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
276
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
277
|
+
mockServerless,
|
|
278
|
+
logger
|
|
279
|
+
);
|
|
267
280
|
definitionGenerator.createInfo();
|
|
268
281
|
|
|
269
282
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -277,7 +290,10 @@ describe("DefinitionGenerator", () => {
|
|
|
277
290
|
mockServerless.service.custom.documentation.license = {
|
|
278
291
|
url: "https://www.apache.org/licenses/LICENSE-2.0.html",
|
|
279
292
|
};
|
|
280
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
293
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
294
|
+
mockServerless,
|
|
295
|
+
logger
|
|
296
|
+
);
|
|
281
297
|
definitionGenerator.createInfo();
|
|
282
298
|
|
|
283
299
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -289,7 +305,10 @@ describe("DefinitionGenerator", () => {
|
|
|
289
305
|
mockServerless.service.custom.documentation.license = {
|
|
290
306
|
name: "John",
|
|
291
307
|
};
|
|
292
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
308
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
309
|
+
mockServerless,
|
|
310
|
+
logger
|
|
311
|
+
);
|
|
293
312
|
definitionGenerator.createInfo();
|
|
294
313
|
|
|
295
314
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -304,7 +323,10 @@ describe("DefinitionGenerator", () => {
|
|
|
304
323
|
|
|
305
324
|
it("should assign specification extension fields when included", function () {
|
|
306
325
|
mockServerless.service.custom.documentation["x-field"] = "john";
|
|
307
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
326
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
327
|
+
mockServerless,
|
|
328
|
+
logger
|
|
329
|
+
);
|
|
308
330
|
definitionGenerator.createInfo();
|
|
309
331
|
|
|
310
332
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -315,7 +337,10 @@ describe("DefinitionGenerator", () => {
|
|
|
315
337
|
|
|
316
338
|
it("should ignore fields that do not conform to specifiction extension", function () {
|
|
317
339
|
mockServerless.service.custom.documentation.otherField = "john";
|
|
318
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
340
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
341
|
+
mockServerless,
|
|
342
|
+
logger
|
|
343
|
+
);
|
|
319
344
|
definitionGenerator.createInfo();
|
|
320
345
|
|
|
321
346
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -337,7 +362,10 @@ describe("DefinitionGenerator", () => {
|
|
|
337
362
|
},
|
|
338
363
|
};
|
|
339
364
|
|
|
340
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
365
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
366
|
+
mockServerless,
|
|
367
|
+
logger
|
|
368
|
+
);
|
|
341
369
|
definitionGenerator.createSecuritySchemes(
|
|
342
370
|
mockServerless.service.custom.documentation.securitySchemes
|
|
343
371
|
);
|
|
@@ -369,7 +397,10 @@ describe("DefinitionGenerator", () => {
|
|
|
369
397
|
},
|
|
370
398
|
};
|
|
371
399
|
|
|
372
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
400
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
401
|
+
mockServerless,
|
|
402
|
+
logger
|
|
403
|
+
);
|
|
373
404
|
expect(() => {
|
|
374
405
|
definitionGenerator.createSecuritySchemes(
|
|
375
406
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -387,7 +418,10 @@ describe("DefinitionGenerator", () => {
|
|
|
387
418
|
},
|
|
388
419
|
};
|
|
389
420
|
|
|
390
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
421
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
422
|
+
mockServerless,
|
|
423
|
+
logger
|
|
424
|
+
);
|
|
391
425
|
expect(() => {
|
|
392
426
|
definitionGenerator.createSecuritySchemes(
|
|
393
427
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -407,7 +441,10 @@ describe("DefinitionGenerator", () => {
|
|
|
407
441
|
},
|
|
408
442
|
};
|
|
409
443
|
|
|
410
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
444
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
445
|
+
mockServerless,
|
|
446
|
+
logger
|
|
447
|
+
);
|
|
411
448
|
definitionGenerator.createSecuritySchemes(
|
|
412
449
|
mockServerless.service.custom.documentation.securitySchemes
|
|
413
450
|
);
|
|
@@ -432,7 +469,10 @@ describe("DefinitionGenerator", () => {
|
|
|
432
469
|
},
|
|
433
470
|
};
|
|
434
471
|
|
|
435
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
472
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
473
|
+
mockServerless,
|
|
474
|
+
logger
|
|
475
|
+
);
|
|
436
476
|
expect(() => {
|
|
437
477
|
definitionGenerator.createSecuritySchemes(
|
|
438
478
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -450,7 +490,10 @@ describe("DefinitionGenerator", () => {
|
|
|
450
490
|
},
|
|
451
491
|
};
|
|
452
492
|
|
|
453
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
493
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
494
|
+
mockServerless,
|
|
495
|
+
logger
|
|
496
|
+
);
|
|
454
497
|
definitionGenerator.createSecuritySchemes(
|
|
455
498
|
mockServerless.service.custom.documentation.securitySchemes
|
|
456
499
|
);
|
|
@@ -475,7 +518,10 @@ describe("DefinitionGenerator", () => {
|
|
|
475
518
|
},
|
|
476
519
|
};
|
|
477
520
|
|
|
478
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
521
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
522
|
+
mockServerless,
|
|
523
|
+
logger
|
|
524
|
+
);
|
|
479
525
|
expect(() => {
|
|
480
526
|
definitionGenerator.createSecuritySchemes(
|
|
481
527
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -503,7 +549,10 @@ describe("DefinitionGenerator", () => {
|
|
|
503
549
|
},
|
|
504
550
|
};
|
|
505
551
|
|
|
506
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
552
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
553
|
+
mockServerless,
|
|
554
|
+
logger
|
|
555
|
+
);
|
|
507
556
|
definitionGenerator.createSecuritySchemes(
|
|
508
557
|
mockServerless.service.custom.documentation.securitySchemes
|
|
509
558
|
);
|
|
@@ -557,7 +606,10 @@ describe("DefinitionGenerator", () => {
|
|
|
557
606
|
},
|
|
558
607
|
};
|
|
559
608
|
|
|
560
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
609
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
610
|
+
mockServerless,
|
|
611
|
+
logger
|
|
612
|
+
);
|
|
561
613
|
expect(() => {
|
|
562
614
|
definitionGenerator.createSecuritySchemes(
|
|
563
615
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -580,7 +632,10 @@ describe("DefinitionGenerator", () => {
|
|
|
580
632
|
},
|
|
581
633
|
};
|
|
582
634
|
|
|
583
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
635
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
636
|
+
mockServerless,
|
|
637
|
+
logger
|
|
638
|
+
);
|
|
584
639
|
expect(() => {
|
|
585
640
|
definitionGenerator.createSecuritySchemes(
|
|
586
641
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -604,7 +659,10 @@ describe("DefinitionGenerator", () => {
|
|
|
604
659
|
},
|
|
605
660
|
};
|
|
606
661
|
|
|
607
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
662
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
663
|
+
mockServerless,
|
|
664
|
+
logger
|
|
665
|
+
);
|
|
608
666
|
expect(() => {
|
|
609
667
|
definitionGenerator.createSecuritySchemes(
|
|
610
668
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -630,7 +688,10 @@ describe("DefinitionGenerator", () => {
|
|
|
630
688
|
},
|
|
631
689
|
};
|
|
632
690
|
|
|
633
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
691
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
692
|
+
mockServerless,
|
|
693
|
+
logger
|
|
694
|
+
);
|
|
634
695
|
expect(() => {
|
|
635
696
|
definitionGenerator.createSecuritySchemes(
|
|
636
697
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -653,7 +714,10 @@ describe("DefinitionGenerator", () => {
|
|
|
653
714
|
},
|
|
654
715
|
};
|
|
655
716
|
|
|
656
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
717
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
718
|
+
mockServerless,
|
|
719
|
+
logger
|
|
720
|
+
);
|
|
657
721
|
expect(() => {
|
|
658
722
|
definitionGenerator.createSecuritySchemes(
|
|
659
723
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -676,7 +740,10 @@ describe("DefinitionGenerator", () => {
|
|
|
676
740
|
},
|
|
677
741
|
};
|
|
678
742
|
|
|
679
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
743
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
744
|
+
mockServerless,
|
|
745
|
+
logger
|
|
746
|
+
);
|
|
680
747
|
expect(() => {
|
|
681
748
|
definitionGenerator.createSecuritySchemes(
|
|
682
749
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -696,7 +763,10 @@ describe("DefinitionGenerator", () => {
|
|
|
696
763
|
},
|
|
697
764
|
};
|
|
698
765
|
|
|
699
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
766
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
767
|
+
mockServerless,
|
|
768
|
+
logger
|
|
769
|
+
);
|
|
700
770
|
expect(() => {
|
|
701
771
|
definitionGenerator.createSecuritySchemes(
|
|
702
772
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -717,7 +787,10 @@ describe("DefinitionGenerator", () => {
|
|
|
717
787
|
},
|
|
718
788
|
};
|
|
719
789
|
|
|
720
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
790
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
791
|
+
mockServerless,
|
|
792
|
+
logger
|
|
793
|
+
);
|
|
721
794
|
expect(() => {
|
|
722
795
|
definitionGenerator.createSecuritySchemes(
|
|
723
796
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -737,7 +810,10 @@ describe("DefinitionGenerator", () => {
|
|
|
737
810
|
},
|
|
738
811
|
};
|
|
739
812
|
|
|
740
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
813
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
814
|
+
mockServerless,
|
|
815
|
+
logger
|
|
816
|
+
);
|
|
741
817
|
expect(() => {
|
|
742
818
|
definitionGenerator.createSecuritySchemes(
|
|
743
819
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -757,7 +833,10 @@ describe("DefinitionGenerator", () => {
|
|
|
757
833
|
},
|
|
758
834
|
};
|
|
759
835
|
|
|
760
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
836
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
837
|
+
mockServerless,
|
|
838
|
+
logger
|
|
839
|
+
);
|
|
761
840
|
expect(() => {
|
|
762
841
|
definitionGenerator.createSecuritySchemes(
|
|
763
842
|
mockServerless.service.custom.documentation.securitySchemes
|
|
@@ -788,7 +867,10 @@ describe("DefinitionGenerator", () => {
|
|
|
788
867
|
},
|
|
789
868
|
};
|
|
790
869
|
|
|
791
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
870
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
871
|
+
mockServerless,
|
|
872
|
+
logger
|
|
873
|
+
);
|
|
792
874
|
definitionGenerator.createSecuritySchemes(
|
|
793
875
|
mockServerless.service.custom.documentation.securitySchemes
|
|
794
876
|
);
|
|
@@ -814,7 +896,10 @@ describe("DefinitionGenerator", () => {
|
|
|
814
896
|
it("should add tags to the openAPI object correctly", function () {
|
|
815
897
|
mockServerless.service.custom.documentation.tags = [{ name: "tag1" }];
|
|
816
898
|
|
|
817
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
899
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
900
|
+
mockServerless,
|
|
901
|
+
logger
|
|
902
|
+
);
|
|
818
903
|
definitionGenerator.createTags();
|
|
819
904
|
|
|
820
905
|
expect(definitionGenerator.openAPI).to.be.an("object");
|
|
@@ -823,10 +908,41 @@ describe("DefinitionGenerator", () => {
|
|
|
823
908
|
});
|
|
824
909
|
|
|
825
910
|
it("should not add tags when they are not defined", function () {
|
|
826
|
-
const definitionGenerator = new DefinitionGenerator(
|
|
911
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
912
|
+
mockServerless,
|
|
913
|
+
logger
|
|
914
|
+
);
|
|
827
915
|
expect(() => {
|
|
828
916
|
definitionGenerator.createTags();
|
|
829
917
|
}).to.throw();
|
|
830
918
|
});
|
|
831
919
|
});
|
|
920
|
+
|
|
921
|
+
describe(`createResponses`, async function () {
|
|
922
|
+
it(`handles creating headers with pragma as a default`, async function () {
|
|
923
|
+
const description = "this is a description";
|
|
924
|
+
const responseMock = {
|
|
925
|
+
methodResponses: [
|
|
926
|
+
{
|
|
927
|
+
responseBody: { description: description },
|
|
928
|
+
statusCode: 200,
|
|
929
|
+
owasp: { pragma: true },
|
|
930
|
+
},
|
|
931
|
+
],
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
const definitionGenerator = new DefinitionGenerator(
|
|
935
|
+
mockServerless,
|
|
936
|
+
logger
|
|
937
|
+
);
|
|
938
|
+
|
|
939
|
+
const response = await definitionGenerator.createResponses(responseMock);
|
|
940
|
+
|
|
941
|
+
expect(response).to.be.an("object");
|
|
942
|
+
expect(response).to.have.property("200");
|
|
943
|
+
expect(response["200"]).to.have.property("description", description);
|
|
944
|
+
expect(response["200"].headers).to.be.an("object");
|
|
945
|
+
expect(response["200"].headers).to.have.property("Pragma");
|
|
946
|
+
});
|
|
947
|
+
});
|
|
832
948
|
});
|
|
@@ -237,7 +237,9 @@ describe("OpenAPIGenerator", () => {
|
|
|
237
237
|
it("should throw an error when writing a file fails", function () {
|
|
238
238
|
const errStub = sinon.stub(logOutput.log, "error").returns("");
|
|
239
239
|
const succSpy = sinon.spy(logOutput.log, "success");
|
|
240
|
-
const fsStub = sinon
|
|
240
|
+
const fsStub = sinon
|
|
241
|
+
.stub(fs, "writeFileSync")
|
|
242
|
+
.throws(new Error("throwing an error from writeFileSync"));
|
|
241
243
|
const openAPIGenerator = new OpenAPIGenerator(sls, {}, logOutput);
|
|
242
244
|
openAPIGenerator.processCliInput();
|
|
243
245
|
|
|
@@ -258,7 +260,7 @@ describe("OpenAPIGenerator", () => {
|
|
|
258
260
|
const errStub = sinon.spy(logOutput.log, "error");
|
|
259
261
|
const succSpy = sinon.spy(logOutput.log, "success");
|
|
260
262
|
const pgStub = sinon.stub(PostmanGenerator, "convert");
|
|
261
|
-
pgStub.yields(new Error());
|
|
263
|
+
pgStub.yields(new Error("throwing an error from PostmanGenerator"));
|
|
262
264
|
|
|
263
265
|
const openAPIGenerator = new OpenAPIGenerator(sls, {}, logOutput);
|
|
264
266
|
openAPIGenerator.processCliInput();
|
package/test/unit/owasp.spec.js
CHANGED
|
@@ -1,113 +1,120 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
const expect = require(
|
|
4
|
-
const nock = require(
|
|
3
|
+
const expect = require("chai").expect;
|
|
4
|
+
const nock = require("nock");
|
|
5
5
|
|
|
6
|
-
const owasp = require(
|
|
6
|
+
const owasp = require("../../src/owasp");
|
|
7
7
|
|
|
8
|
-
const owaspJSON = require(
|
|
9
|
-
const newOWASPJSON = require(
|
|
8
|
+
const owaspJSON = require("../../json/owasp.json");
|
|
9
|
+
const newOWASPJSON = require("../json/newOWASP.json");
|
|
10
10
|
|
|
11
11
|
describe(`owasp`, function () {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.reply(200, newOWASPJSON)
|
|
34
|
-
|
|
35
|
-
await owasp.getLatest()
|
|
36
|
-
.catch(err => {
|
|
37
|
-
console.error(err)
|
|
38
|
-
expect(err).to.be.undefined
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
expect(owasp.DEFAULT_OWASP_HEADERS['Cross-Origin-Embedder-Policy']).to.have.property('schema')
|
|
42
|
-
const newCrossOriginEmbedderPolicy = newOWASPJSON.headers.filter(obj => obj.name === 'Cross-Origin-Embedder-Policy')
|
|
43
|
-
expect(owasp.DEFAULT_OWASP_HEADERS['Cross-Origin-Embedder-Policy'].schema.default).to.be.equal(newCrossOriginEmbedderPolicy[0].value)
|
|
44
|
-
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(13)
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it(`does not remove any defaults not contained in a new release`, async function() {
|
|
48
|
-
const newOWASPJSONMissing = JSON.parse(JSON.stringify(newOWASPJSON))
|
|
49
|
-
|
|
50
|
-
const headers = newOWASPJSONMissing.headers.filter(obj => obj.name !== 'Pragma')
|
|
51
|
-
newOWASPJSONMissing.headers = headers
|
|
52
|
-
|
|
53
|
-
nock('https://owasp.org')
|
|
54
|
-
.get('/www-project-secure-headers/ci/headers_add.json')
|
|
55
|
-
.reply(200, newOWASPJSONMissing)
|
|
56
|
-
|
|
57
|
-
await owasp.getLatest()
|
|
58
|
-
.catch(err => {
|
|
59
|
-
console.error(err)
|
|
60
|
-
expect(err).to.be.undefined
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
expect(owasp.DEFAULT_OWASP_HEADERS).to.have.property('Pragma')
|
|
64
|
-
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(13)
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it(`adds any properties contained in a new release`, async function() {
|
|
68
|
-
const newOWASPJSONAdded = JSON.parse(JSON.stringify(newOWASPJSON))
|
|
69
|
-
newOWASPJSONAdded.headers.push({name: 'x-added', value: 'true'})
|
|
70
|
-
|
|
71
|
-
nock('https://owasp.org')
|
|
72
|
-
.get('/www-project-secure-headers/ci/headers_add.json')
|
|
73
|
-
.reply(200, newOWASPJSONAdded)
|
|
74
|
-
|
|
75
|
-
await owasp.getLatest()
|
|
76
|
-
.catch(err => {
|
|
77
|
-
console.error(err)
|
|
78
|
-
expect(err).to.be.undefined
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
expect(owasp.DEFAULT_OWASP_HEADERS).to.have.property('x-added')
|
|
82
|
-
expect(owasp.DEFAULT_OWASP_HEADERS['x-added']).to.have.property('schema')
|
|
83
|
-
expect(owasp.DEFAULT_OWASP_HEADERS['x-added'].schema.default).to.be.equal('true')
|
|
84
|
-
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(14)
|
|
85
|
-
});
|
|
12
|
+
describe(`getLatest`, function () {
|
|
13
|
+
it(`populates the defaults from the included OWASP release when the online version can not be reached`, async function () {
|
|
14
|
+
nock("https://owasp.org")
|
|
15
|
+
.get("/www-project-secure-headers/ci/headers_add.json")
|
|
16
|
+
.reply(404, {});
|
|
17
|
+
|
|
18
|
+
await owasp.getLatest().catch((err) => {
|
|
19
|
+
console.error(err);
|
|
20
|
+
expect(err).to.be.undefined;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(
|
|
24
|
+
owasp.DEFAULT_OWASP_HEADERS["Permissions-Policy"]
|
|
25
|
+
).to.have.property("schema");
|
|
26
|
+
const permissionsPolicyDefault = owaspJSON.headers.filter(
|
|
27
|
+
(obj) => obj.name === "Permissions-Policy"
|
|
28
|
+
);
|
|
29
|
+
expect(
|
|
30
|
+
owasp.DEFAULT_OWASP_HEADERS["Permissions-Policy"].schema.default
|
|
31
|
+
).to.be.equal(permissionsPolicyDefault[0].value);
|
|
32
|
+
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(12);
|
|
86
33
|
});
|
|
87
34
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
35
|
+
it(`populates the defaults with information from a new OWASP release`, async function () {
|
|
36
|
+
nock("https://owasp.org")
|
|
37
|
+
.get("/www-project-secure-headers/ci/headers_add.json")
|
|
38
|
+
.reply(200, newOWASPJSON);
|
|
39
|
+
|
|
40
|
+
await owasp.getLatest().catch((err) => {
|
|
41
|
+
console.error(err);
|
|
42
|
+
expect(err).to.be.undefined;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(
|
|
46
|
+
owasp.DEFAULT_OWASP_HEADERS["Cross-Origin-Embedder-Policy"]
|
|
47
|
+
).to.have.property("schema");
|
|
48
|
+
const newCrossOriginEmbedderPolicy = newOWASPJSON.headers.filter(
|
|
49
|
+
(obj) => obj.name === "Cross-Origin-Embedder-Policy"
|
|
50
|
+
);
|
|
51
|
+
expect(
|
|
52
|
+
owasp.DEFAULT_OWASP_HEADERS["Cross-Origin-Embedder-Policy"].schema
|
|
53
|
+
.default
|
|
54
|
+
).to.be.equal(newCrossOriginEmbedderPolicy[0].value);
|
|
55
|
+
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(12);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it(`adds any properties contained in a new release`, async function () {
|
|
59
|
+
const newOWASPJSONAdded = JSON.parse(JSON.stringify(newOWASPJSON));
|
|
60
|
+
newOWASPJSONAdded.headers.push({ name: "x-added", value: "true" });
|
|
61
|
+
|
|
62
|
+
nock("https://owasp.org")
|
|
63
|
+
.get("/www-project-secure-headers/ci/headers_add.json")
|
|
64
|
+
.reply(200, newOWASPJSONAdded);
|
|
65
|
+
|
|
66
|
+
await owasp.getLatest().catch((err) => {
|
|
67
|
+
console.error(err);
|
|
68
|
+
expect(err).to.be.undefined;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(owasp.DEFAULT_OWASP_HEADERS).to.have.property("x-added");
|
|
72
|
+
expect(owasp.DEFAULT_OWASP_HEADERS["x-added"]).to.have.property("schema");
|
|
73
|
+
expect(owasp.DEFAULT_OWASP_HEADERS["x-added"].schema.default).to.be.equal(
|
|
74
|
+
"true"
|
|
75
|
+
);
|
|
76
|
+
expect(Object.keys(owasp.DEFAULT_OWASP_HEADERS).length).to.be.equal(13);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe(`getHeaders`, function () {
|
|
81
|
+
it(`brings back default headers from a list`, function () {
|
|
82
|
+
const headerOptions = { cacheControl: true, xFrameOptions: true };
|
|
83
|
+
const headers = owasp.getHeaders(headerOptions);
|
|
84
|
+
|
|
85
|
+
expect(Object.keys(headers).length).to.be.equal(2);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it(`brings back default headers from a list with new schema defaults when values are provided`, function () {
|
|
89
|
+
const headerOptions = {
|
|
90
|
+
referrerPolicy: {
|
|
91
|
+
value: "true",
|
|
92
|
+
},
|
|
93
|
+
crossOriginOpenerPolicy: {
|
|
94
|
+
value: "strict",
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const headers = owasp.getHeaders(headerOptions);
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
expect(Object.keys(headers).length).to.be.equal(2);
|
|
101
|
+
|
|
102
|
+
expect(headers["Cross-Origin-Opener-Policy"].schema.default === "strict");
|
|
103
|
+
});
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
value: 'strict'
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
+
it(`handles pragma being deprecated`, function () {
|
|
106
|
+
const headerOptions = {
|
|
107
|
+
pragma: {
|
|
108
|
+
value: "true",
|
|
109
|
+
},
|
|
110
|
+
};
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
const headers = owasp.getHeaders(headerOptions);
|
|
107
113
|
|
|
108
|
-
|
|
114
|
+
expect(Object.keys(headers).length).to.be.equal(1);
|
|
109
115
|
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
expect(headers["Pragma"]).to.have.property("schema");
|
|
117
|
+
expect(headers["Pragma"].schema).to.have.property("default", "true");
|
|
112
118
|
});
|
|
119
|
+
});
|
|
113
120
|
});
|