From b104b1c27bb435af841c5d20c354d48433832f00 Mon Sep 17 00:00:00 2001 From: drexler Date: Mon, 29 Jul 2019 07:57:25 -0400 Subject: [PATCH 1/3] feat: add ability to choose TLS version --- DomainInfo.ts | 3 + README.md | 2 + index.ts | 15 ++++ package-lock.json | 179 ++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- types.ts | 1 + 6 files changed, 170 insertions(+), 32 deletions(-) diff --git a/DomainInfo.ts b/DomainInfo.ts index a200994f..113bb75d 100644 --- a/DomainInfo.ts +++ b/DomainInfo.ts @@ -5,6 +5,7 @@ class DomainInfo { public domainName: string; public hostedZoneId: string; + public securityPolicy: string; /** * Sometimes, the getDomainName call doesn't return either a distributionHostedZoneId or a regionalHostedZoneId. @@ -14,12 +15,14 @@ class DomainInfo { * PR: https://github.com/amplify-education/serverless-domain-manager/pull/171 */ private defaultHostedZoneId: string = "Z2FDTNDATAQYW2"; + private defaultSecurityPolicy: string = "TLS_1_2"; constructor(data: any) { this.domainName = data.distributionDomainName || data.regionalDomainName; this.hostedZoneId = data.distributionHostedZoneId || data.regionalHostedZoneId || this.defaultHostedZoneId; + this.securityPolicy = data.securityPolicy || this.defaultSecurityPolicy; } } diff --git a/README.md b/README.md index 7af9fda6..70333413 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ custom: certificateName: '*.foo.com' createRoute53Record: true endpointType: 'regional' + securityPolicy: tls_1_2 ``` | Parameter Name | Default Value | Description | @@ -83,6 +84,7 @@ custom: | hostedZoneId | | If hostedZoneId is set the route53 record set will be created in the matching zone, otherwise the hosted zone will be figured out from the domainName (hosted zone with matching domain). | | hostedZonePrivate | | If hostedZonePrivate is set to `true` then only private hosted zones will be used for route 53 records. If it is set to `false` then only public hosted zones will be used for route53 records. Setting this parameter is specially useful if you have multiple hosted zones with the same domain name (e.g. a public and a private one) | | enabled | true | Sometimes there are stages for which is not desired to have custom domain names. This flag allows the developer to disable the plugin for such cases. Accepts either `boolean` or `string` values and defaults to `true` for backwards compatibility. | +securityPolicy | tls_1_2 | The security policy to apply to the custom domain name. Accepts `tls_1_0` or `tls_1_2`| ## Running diff --git a/index.ts b/index.ts index 5ccd5d1e..0f29566d 100644 --- a/index.ts +++ b/index.ts @@ -9,6 +9,11 @@ const endpointTypes = { regional: "REGIONAL", }; +const tlsVersions = { + tls_1_0: "TLS_1_0", + tls_1_2: "TLS_1_2", +}; + const certStatuses = ["PENDING_VALIDATION", "ISSUED", "INACTIVE"]; class ServerlessCustomDomain { @@ -33,6 +38,7 @@ class ServerlessCustomDomain { public basePath: string; private endpointType: string; private stage: string; + private securityPolicy: string; constructor(serverless: ServerlessInstance, options: ServerlessOptions) { this.serverless = serverless; @@ -197,6 +203,14 @@ class ServerlessCustomDomain { } this.endpointType = endpointTypeToUse; + const securityPolicyDefault = this.serverless.service.custom.customDomain.securityPolicy || + tlsVersions.tls_1_2; + const tlsVersionToUse = tlsVersions[securityPolicyDefault.toLowerCase()]; + if (!tlsVersionToUse) { + throw new Error(`${securityPolicyDefault} is not a supported securityPolicy, use tls_1_0 or tls_1_2.`); + } + this.securityPolicy = tlsVersionToUse; + this.acmRegion = this.endpointType === endpointTypes.regional ? this.serverless.providers.aws.getRegion() : "us-east-1"; const acmCredentials = Object.assign({}, credentials, { region: this.acmRegion }); @@ -317,6 +331,7 @@ class ServerlessCustomDomain { types: [this.endpointType], }, regionalCertificateArn: certificateArn, + securityPolicy: this.securityPolicy, }; if (this.endpointType === endpointTypes.edge) { params.regionalCertificateArn = undefined; diff --git a/package-lock.json b/package-lock.json index c6cd66fc..61aa03a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -268,9 +268,9 @@ "dev": true }, "aws-sdk": { - "version": "2.302.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.302.0.tgz", - "integrity": "sha512-fXseIBVXxY9ApKs0RaSH+i+ppwcysIOfBpH73Lm/983Yt6sj4nbsll9WJKHQXg4FA3S+HiZW63x08+5SU/oC6Q==", + "version": "2.490.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.490.0.tgz", + "integrity": "sha512-8dCf+F360XEwOorTk0wVV/haaxYvUZnfZI6PVXfR8xbcVd7Ioh9KWRe+MqHNStEttE4UQzknEPrUj/mDW++NDw==", "requires": { "buffer": "4.9.1", "events": "1.1.1", @@ -279,7 +279,7 @@ "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", - "uuid": "3.1.0", + "uuid": "3.3.2", "xml2js": "0.4.19" } }, @@ -292,26 +292,6 @@ "aws-sdk": "^2.3.0", "sinon": "^1.17.3", "traverse": "^0.6.6" - }, - "dependencies": { - "lolex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", - "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", - "dev": true - }, - "sinon": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", - "dev": true, - "requires": { - "formatio": "1.1.1", - "lolex": "1.3.2", - "samsam": "1.1.2", - "util": ">=0.10.3 <1" - } - } } }, "aws-sign2": { @@ -635,6 +615,15 @@ "strip-bom": "^3.0.0" } }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -681,6 +670,31 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -882,6 +896,12 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -988,6 +1008,15 @@ } } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -1002,6 +1031,12 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", @@ -1073,24 +1108,66 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-generator-function": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", + "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1413,6 +1490,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lolex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", + "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", + "dev": true + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -1683,6 +1766,24 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2126,6 +2227,18 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "sinon": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", + "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", + "dev": true, + "requires": { + "formatio": "1.1.1", + "lolex": "1.3.2", + "samsam": "1.1.2", + "util": ">=0.10.3 <1" + } + }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -2487,18 +2600,22 @@ } }, "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.1.tgz", + "integrity": "sha512-MREAtYOp+GTt9/+kwf00IYoHZyjM8VU4aVrkzUlejyqaIjd2GztVl5V9hGXKlvBKE3gENn/FMfHE5v6hElXGcQ==", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "object.entries": "^1.1.0", + "safe-buffer": "^5.1.2" } }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/package.json b/package.json index 228440ab..d251c921 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "wrappy": "^1.0.2" }, "dependencies": { - "aws-sdk": "^2.177.0", + "aws-sdk": "^2.490.0", "chalk": "^2.4.1" } } diff --git a/types.ts b/types.ts index 5dd9ae2c..5d612493 100644 --- a/types.ts +++ b/types.ts @@ -23,6 +23,7 @@ export interface ServerlessInstance { // tslint:disable-line hostedZoneId: string | undefined, hostedZonePrivate: boolean | undefined, enabled: boolean | string | undefined, + securityPolicy: string | undefined, }, }, }; From fc4129a32d62a2e6c68186fc932caec31cffc3fd Mon Sep 17 00:00:00 2001 From: drexler Date: Mon, 29 Jul 2019 07:58:08 -0400 Subject: [PATCH 2/3] test: add coverage test for TLS version support --- test/unit-tests/index.test.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/unit-tests/index.test.ts b/test/unit-tests/index.test.ts index 448c5d52..27bb5c0c 100644 --- a/test/unit-tests/index.test.ts +++ b/test/unit-tests/index.test.ts @@ -69,6 +69,7 @@ const constructPlugin = (customDomainOptions) => { endpointType: customDomainOptions.endpointType, hostedZoneId: customDomainOptions.hostedZoneId, hostedZonePrivate: customDomainOptions.hostedZonePrivate, + securityPolicy: customDomainOptions.securityPolicy, stage: customDomainOptions.stage, }, }, @@ -308,7 +309,7 @@ describe("Custom Domain Plugin", () => { it("Create a domain name", async () => { AWS.mock("APIGateway", "createDomainName", (params, callback) => { - callback(null, { distributionDomainName: "foo" }); + callback(null, { distributionDomainName: "foo", securityPolicy: "TLS_1_2"}); }); const plugin = constructPlugin({ domainName: "test_domain"}); @@ -318,6 +319,22 @@ describe("Custom Domain Plugin", () => { const result = await plugin.createCustomDomain("fake_cert"); expect(result.domainName).to.equal("foo"); + expect(result.securityPolicy).to.equal("TLS_1_2"); + }); + + it("Create a domain name with specific TLS version", async () => { + AWS.mock("APIGateway", "createDomainName", (params, callback) => { + callback(null, { distributionDomainName: "foo", securityPolicy: "TLS_1_2"}); + }); + + const plugin = constructPlugin({ domainName: "test_domain", securityPolicy: "tls_1_2"}); + plugin.apigateway = new aws.APIGateway(); + plugin.givenDomainName = plugin.serverless.service.custom.customDomain.domainName; + + const result = await plugin.createCustomDomain("fake_cert"); + + expect(result.domainName).to.equal("foo"); + expect(result.securityPolicy).to.equal("TLS_1_2"); }); it("Create a new A Alias Record", async () => { From 4baf09559df312637a06e809e8ce06649ac10bd1 Mon Sep 17 00:00:00 2001 From: drexler Date: Mon, 29 Jul 2019 07:58:36 -0400 Subject: [PATCH 3/3] chore: bump version number --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61aa03a8..4aa7992f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "serverless-domain-manager", - "version": "3.2.7", + "version": "3.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d251c921..7b539e7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-domain-manager", - "version": "3.2.7", + "version": "3.3.0", "engines": { "node": ">=4.0" },