Skip to content

Commit

Permalink
Fix support for regional domains using TLS 1.0 (#348)
Browse files Browse the repository at this point in the history
* Fix support for regional domains using TLS 1.0

* fix lint

* add unit test

* update changelog

* check if existing domain is tls 1.0 instead of config

* fix lint errors

* update release date
:
  • Loading branch information
aoskotsky-amplify committed May 25, 2020
1 parent 36bd088 commit 88a558e
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 12 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [4.1.1] - 2020-05-25

### Changed
- Fix support for TLS 1.0 regional domains which were broken in the 4.0.0 release. Discovered by @jufemaiz ([#348](https://github.com/amplify-education/serverless-domain-manager/pull/348))

## [4.1.0] - 2020-05-18

### Changed
Expand All @@ -16,6 +21,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [4.0.0] - 2020-05-06

### Breaking Changes
- Regional domains with TLS 1.0 no longer work. Fixed in 4.1.1

### Added
- Add support for WebSocket and HTTP APIs. A domain name can be created for each API type (Rest, WebSocket, HTTP)
for up to 3 domain names in a single Serverless config. Thanks @TehNrd ([#319](https://github.com/amplify-education/serverless-domain-manager/pull/319))
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "serverless-domain-manager",
"version": "4.1.0",
"version": "4.1.1",
"engines": {
"node": ">=4.0"
},
Expand Down
28 changes: 19 additions & 9 deletions src/index.ts
Expand Up @@ -152,14 +152,14 @@ class ServerlessCustomDomain {

domain.apiMapping = await this.getBasePathMapping(domain);

await this.getDomainInfo();

if (!domain.apiMapping) {
await this.createBasePathMapping(domain);
} else {
await this.updateBasePathMapping(domain);
}

await this.getDomainInfo();

} catch (err) {
this.logIfDebug(err, domain.givenDomainName);
throw new Error(`Error: Unable to setup base domain mappings for ${domain.givenDomainName}`);
Expand Down Expand Up @@ -390,18 +390,25 @@ class ServerlessCustomDomain {

let createdDomain = {};

// For EDGE domain name, create with APIGateway (v1)
if (domain.endpointType === Globals.endpointTypes.edge) {
// For EDGE domain name or TLS 1.0, create with APIGateway (v1)
if (domain.endpointType === Globals.endpointTypes.edge || domain.securityPolicy === "TLS_1_0") {
// Set up parameters
const params = {
certificateArn: domain.certificateArn,
domainName: domain.givenDomainName,
endpointConfiguration: {
types: [domain.endpointType],
},
securityPolicy: domain.securityPolicy,
};

/* tslint:disable:no-string-literal */
if (domain.endpointType === Globals.endpointTypes.edge) {
params["certificateArn"] = domain.certificateArn;
} else {
params["regionalCertificateArn"] = domain.certificateArn;
}
/* tslint:enable:no-string-literal */

// Make API call to create domain
try {
// Creating EDGE domain so use APIGateway (v1) service
Expand Down Expand Up @@ -581,8 +588,8 @@ class ServerlessCustomDomain {
* Creates basepath mapping
*/
public async createBasePathMapping(domain: DomainConfig): Promise<void> {
// Use APIGateway (v1) for EDGE domains
if (domain.endpointType === Globals.endpointTypes.edge) {
// Use APIGateway (v1) for EDGE or TLS 1.0 domains
if (domain.endpointType === Globals.endpointTypes.edge || domain.securityPolicy === "TLS_1_0") {
const params = {
basePath: domain.basePath,
domainName: domain.givenDomainName,
Expand Down Expand Up @@ -620,8 +627,11 @@ class ServerlessCustomDomain {
* Updates basepath mapping
*/
public async updateBasePathMapping(domain: DomainConfig): Promise<void> {
// Use APIGateway (v1) for EDGE domains
if (domain.endpointType === Globals.endpointTypes.edge) {
// Use APIGateway (v1) for EDGE or TLS 1.0 domains
// check here if the EXISTING domain is using TLS 1.0 regardless of what is configured
// We don't support updating custom domains so switching from TLS 1.0 to 1.2 will require recreating
// the domain
if (domain.endpointType === Globals.endpointTypes.edge || domain.domainInfo.securityPolicy === "TLS_1_0") {
const params = {
basePath: domain.apiMapping.ApiMappingKey || "(none)",
domainName: domain.givenDomainName,
Expand Down
8 changes: 8 additions & 0 deletions test/integration-tests/integration.test.ts
Expand Up @@ -86,6 +86,14 @@ const testCases = [
testFolder: "http-api",
testStage: "$default",
},
{
testBasePath: "(none)",
testDescription: "Deploy regional domain with TLS 1.0",
testDomain: `regional-tls-1-0-${RANDOM_STRING}.${TEST_DOMAIN}`,
testEndpoint: "REGIONAL",
testFolder: "regional-tls-1-0",
testStage: "dev",
},
];

describe("Integration Tests", function() {
Expand Down
16 changes: 16 additions & 0 deletions test/integration-tests/regional-tls-1-0/handler.js
@@ -0,0 +1,16 @@
"use strict";

module.exports.helloWorld = (event, context, callback) => {
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
},
body: JSON.stringify({
message: "Go Serverless v1.0! Your function executed successfully!",
input: event,
}),
};

callback(null, response);
};
28 changes: 28 additions & 0 deletions test/integration-tests/regional-tls-1-0/serverless.yml
@@ -0,0 +1,28 @@
# Test regional domains with TLS 1.0
service: regional-tls-1-0-${opt:RANDOM_STRING}
provider:
name: aws
runtime: nodejs12.x
region: us-west-2
stage: dev
endpointType: regional

functions:
helloWorld:
handler: handler.helloWorld
events:
- http:
path: hello-world
method: get
cors: true
plugins:
- serverless-domain-manager
custom:
customDomain:
domainName: regional-tls-1-0-${opt:RANDOM_STRING}.${env:TEST_DOMAIN}
securityPolicy: tls_1_0
endpointType: regional

package:
exclude:
- node_modules/**
64 changes: 63 additions & 1 deletion test/unit-tests/index.test.ts
Expand Up @@ -189,6 +189,61 @@ describe("Custom Domain Plugin", () => {
});
});

it("Creates basepath mapping for regional tls 1.0 REST api", async () => {
AWS.mock("APIGateway", "createBasePathMapping", (params, callback) => {
callback(null, params);
});
const plugin = constructPlugin({
basePath: "test_basepath",
domainName: "test_domain",
endpointType: "regional",
securityPolicy: "tls_1_0",
});
plugin.initializeVariables();
plugin.apigateway = new aws.APIGateway();

const dc: DomainConfig = new DomainConfig(plugin.serverless.service.custom.customDomain);
dc.apiId = "test_rest_api_id";

const spy = chai.spy.on(plugin.apigateway, "createBasePathMapping");

await plugin.createBasePathMapping(dc);

expect(spy).to.have.been.called.with({
basePath: "test_basepath",
domainName: "test_domain",
restApiId: "test_rest_api_id",
stage: "test",
});
});

it("Creates basepath mapping for regional tls 1.2 REST api", async () => {
AWS.mock("ApiGatewayV2", "createApiMapping", (params, callback) => {
callback(null, params);
});
const plugin = constructPlugin({
basePath: "test_basepath",
domainName: "test_domain",
endpointType: "regional",
});
plugin.initializeVariables();
plugin.apigatewayV2 = new aws.ApiGatewayV2();

const dc: DomainConfig = new DomainConfig(plugin.serverless.service.custom.customDomain);
dc.apiId = "test_rest_api_id";

const spy = chai.spy.on(plugin.apigatewayV2, "createApiMapping");

await plugin.createBasePathMapping(dc);

expect(spy).to.have.been.called.with({
ApiId: "test_rest_api_id",
ApiMappingKey: "test_basepath",
DomainName: "test_domain",
Stage: "test",
});
});

it("Creates basepath mapping for regional HTTP/Websocket api", async () => {
AWS.mock("ApiGatewayV2", "createApiMapping", (params, callback) => {
callback(null, params);
Expand Down Expand Up @@ -264,8 +319,15 @@ describe("Custom Domain Plugin", () => {
plugin.apigatewayV2 = new aws.ApiGatewayV2();

const dc: DomainConfig = new DomainConfig(plugin.serverless.service.custom.customDomain);
dc.apiId = "test_api_id",
dc.apiId = "test_api_id";
dc.apiMapping = {ApiMappingId: "test_mapping_id"};
dc.domainInfo = new DomainInfo({
DomainNameConfigurations: [{
ApiGatewayDomainName: "fake_dist_name",
HostedZoneId: "fake_zone_id",
SecurityPolicy: "TLS_1_2",
}],
});

const spy = chai.spy.on(plugin.apigatewayV2, "updateApiMapping");

Expand Down

0 comments on commit 88a558e

Please sign in to comment.