Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

serverless-appsync-cloudfront

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serverless-appsync-cloudfront - npm Package Compare versions

Comparing version 0.9.7 to 1.0.0

213

index.js

@@ -1,8 +0,8 @@

const path = require('path');
const _ = require('lodash');
const chalk = require('chalk');
const yaml = require('js-yaml');
const fs = require('fs');
const path = require("path");
const _ = require("lodash");
const chalk = require("chalk");
const yaml = require("js-yaml");
const fs = require("fs");
const certStatuses = ['PENDING_VALIDATION', 'ISSUED', 'INACTIVE'];
const certStatuses = ["PENDING_VALIDATION", "ISSUED", "INACTIVE"];

@@ -13,7 +13,9 @@ class ServerlessAppSyncCloudFrontPlugin {

this.options = options;
this.givenDomainName = this.serverless.service.custom.appSyncCloudFront.domainName;
this.givenDomainName = this.getConfig("domainName", null);
this.hooks = {
'package:createDeploymentArtifacts': this.createDeploymentArtifacts.bind(this),
'aws:info:displayStackOutputs': this.printSummary.bind(this),
"package:createDeploymentArtifacts": this.createDeploymentArtifacts.bind(
this
),
"aws:info:displayStackOutputs": this.printSummary.bind(this),
};

@@ -23,12 +25,14 @@ }

async createDeploymentArtifacts() {
if (this.serverless.service.custom.appSyncCloudFront.enabled !== false) {
this.givenDomainName = this.serverless.service.custom.appSyncCloudFront.domainName;
if (this.getConfig("enabled", true) !== false) {
const credentials = this.serverless.providers.aws.getCredentials();
const acmCredentials = Object.assign({}, credentials, { region: 'us-east-1' });
const acmCredentials = Object.assign({}, credentials, {
region: "us-east-1",
});
this.acm = new this.serverless.providers.aws.sdk.ACM(acmCredentials);
this.route53 = new this.serverless.providers.aws.sdk.Route53(credentials);
const baseResources = this.serverless.service.provider.compiledCloudFormationTemplate;
const baseResources = this.serverless.service.provider
.compiledCloudFormationTemplate;
const filename = path.resolve(__dirname, 'resources.yml');
const content = fs.readFileSync(filename, 'utf-8');
const filename = path.resolve(__dirname, "resources.yml");
const content = fs.readFileSync(filename, "utf-8");
const resources = yaml.safeLoad(content, { filename });

@@ -42,5 +46,6 @@

async printSummary() {
const awsInfo = _.find(this.serverless.pluginManager.getPlugins(), plugin => (
plugin.constructor.name === 'AwsInfo'
));
const awsInfo = _.find(
this.serverless.pluginManager.getPlugins(),
(plugin) => plugin.constructor.name === "AwsInfo"
);

@@ -52,5 +57,6 @@ if (!awsInfo || !awsInfo.gatheredData) {

const { outputs } = awsInfo.gatheredData;
const apiDistributionDomain = _.find(outputs, output => (
output.OutputKey === 'AppSyncApiDistribution'
));
const apiDistributionDomain = _.find(
outputs,
(output) => output.OutputKey === "AppSyncApiDistribution"
);

@@ -61,10 +67,16 @@ if (!apiDistributionDomain || !apiDistributionDomain.OutputValue) {

const cnameDomain = this.getConfig('domainName', null);
this.serverless.cli.consoleLog(chalk.yellow('CloudFront domain name'));
this.serverless.cli.consoleLog(` ${apiDistributionDomain.OutputValue} (CNAME: ${cnameDomain || '-'})`);
const cnameDomain = this.getConfig("domainName", null);
this.serverless.cli.consoleLog(chalk.yellow("CloudFront domain name"));
this.serverless.cli.consoleLog(
` ${apiDistributionDomain.OutputValue} (CNAME: ${cnameDomain || "-"})`
);
if (cnameDomain) {
this.serverless.cli.consoleLog(`AppSync: ${chalk.yellow(`Creating Route53 records for ${cnameDomain}...`)}`);
this.serverless.cli.consoleLog(
`AppSync: ${chalk.yellow(
`Creating Route53 records for ${cnameDomain}...`
)}`
);
this.changeResourceRecordSet('UPSERT', apiDistributionDomain.OutputValue);
this.changeResourceRecordSet("UPSERT", apiDistributionDomain.OutputValue);
}

@@ -78,8 +90,8 @@ }

let certificateArn; // The arn of the choosen certificate
let { certificateName } = this.serverless.service.custom.appSyncCloudFront; // The certificate name
const { domainName } = this.serverless.service.custom.appSyncCloudFront; // Domain name
let certificateName = this.getConfig("certificateName", null);
if (!certificateName && !this.givenDomainName) return;
try {
const certData = await this.acm.listCertificates(
{ CertificateStatuses: certStatuses },
).promise();
const certData = await this.acm
.listCertificates({ CertificateStatuses: certStatuses })
.promise();

@@ -92,4 +104,5 @@ // The more specific name will be the longest

if (certificateName != null) {
const foundCertificate = certificates
.find(certificate => (certificate.DomainName === certificateName));
const foundCertificate = certificates.find(
(certificate) => certificate.DomainName === certificateName
);
if (foundCertificate != null) {

@@ -99,7 +112,7 @@ certificateArn = foundCertificate.CertificateArn;

} else {
certificateName = domainName;
certificateName = this.givenDomainName;
certificates.forEach((certificate) => {
let certificateListName = certificate.DomainName;
// Looks for wild card and takes it out when checking
if (certificateListName[0] === '*') {
if (certificateListName[0] === "*") {
certificateListName = certificateListName.substr(1);

@@ -109,4 +122,6 @@ }

// Also checks if the name is more specific than previous ones
if (certificateName.includes(certificateListName)
&& certificateListName.length > nameLength) {
if (
certificateName.includes(certificateListName) &&
certificateListName.length > nameLength
) {
nameLength = certificateListName.length;

@@ -118,3 +133,5 @@ certificateArn = certificate.CertificateArn;

} catch (err) {
throw Error(`Error: Could not list certificates in Certificate Manager.\n${err}`);
throw Error(
`Error: Could not list certificates in Certificate Manager.\n${err}`
);
}

@@ -128,8 +145,8 @@ if (certificateArn == null) {

/**
* Change A Alias record through Route53 based on given action
* @param action: String descriptor of change to be made. Valid actions are ['UPSERT', 'DELETE']
* @param domain: DomainInfo object containing info about custom domain
*/
* Change A Alias record through Route53 based on given action
* @param action: String descriptor of change to be made. Valid actions are ['UPSERT', 'DELETE']
* @param domain: DomainInfo object containing info about custom domain
*/
async changeResourceRecordSet(action, domain) {
if (action !== 'UPSERT' && action !== 'DELETE') {
if (action !== "UPSERT" && action !== "DELETE") {
throw new Error(`Error: Invalid action "${action}" when changing Route53 Record.

@@ -139,5 +156,5 @@ Action must be either UPSERT or DELETE.\n`);

const createRoute53Record = this.getConfig('createRoute53Record', null);
const createRoute53Record = this.getConfig("createRoute53Record", null);
if (createRoute53Record !== undefined && createRoute53Record === false) {
this.serverless.cli.log('Skipping creation of Route53 record.');
this.serverless.cli.log("Skipping creation of Route53 record.");
return;

@@ -147,3 +164,3 @@ }

const route53HostedZoneId = await this.getRoute53HostedZoneId();
const Changes = ['A', 'AAAA'].map(Type => ({
const Changes = ["A", "AAAA"].map((Type) => ({
Action: action,

@@ -154,3 +171,3 @@ ResourceRecordSet: {

EvaluateTargetHealth: false,
HostedZoneId: 'Z2FDTNDATAQYW2', // CloudFront HZID is always Z2FDTNDATAQYW2
HostedZoneId: "Z2FDTNDATAQYW2", // CloudFront HZID is always Z2FDTNDATAQYW2
},

@@ -164,3 +181,3 @@ Name: this.givenDomainName,

Changes,
Comment: 'Record created by serverless-appsync-cloudfront',
Comment: "Record created by serverless-appsync-cloudfront",
},

@@ -173,3 +190,5 @@ HostedZoneId: route53HostedZoneId,

} catch (err) {
throw new Error(`Error: Failed to ${action} A Alias for ${this.givenDomainName}\n`);
throw new Error(
`Error: Failed to ${action} A Alias for ${this.givenDomainName}\n`
);
}

@@ -184,3 +203,4 @@ }

this.serverless.cli.log(
`Selected specific hostedZoneId ${this.serverless.service.custom.appSyncCloudFront.hostedZoneId}`);
`Selected specific hostedZoneId ${this.serverless.service.custom.appSyncCloudFront.hostedZoneId}`
);
return this.serverless.service.custom.appSyncCloudFront.hostedZoneId;

@@ -191,16 +211,16 @@ }

if (filterZone && this.hostedZonePrivate) {
this.serverless.cli.log('Filtering to only private zones.');
this.serverless.cli.log("Filtering to only private zones.");
} else if (filterZone && !this.hostedZonePrivate) {
this.serverless.cli.log('Filtering to only public zones.');
this.serverless.cli.log("Filtering to only public zones.");
}
let hostedZoneData;
const givenDomainNameReverse = this.givenDomainName.split('.').reverse();
const givenDomainNameReverse = this.givenDomainName.split(".").reverse();
try {
hostedZoneData = await this.route53.listHostedZones({}).promise();
const targetHostedZone = hostedZoneData.HostedZones
.filter((hostedZone) => {
const targetHostedZone = hostedZoneData.HostedZones.filter(
(hostedZone) => {
let hostedZoneName;
if (hostedZone.Name.endsWith('.')) {
if (hostedZone.Name.endsWith(".")) {
hostedZoneName = hostedZone.Name.slice(0, -1);

@@ -210,7 +230,12 @@ } else {

}
if (!filterZone || this.hostedZonePrivate === hostedZone.Config.PrivateZone) {
const hostedZoneNameReverse = hostedZoneName.split('.').reverse();
if (
!filterZone ||
this.hostedZonePrivate === hostedZone.Config.PrivateZone
) {
const hostedZoneNameReverse = hostedZoneName.split(".").reverse();
if (givenDomainNameReverse.length === 1
|| (givenDomainNameReverse.length >= hostedZoneNameReverse.length)) {
if (
givenDomainNameReverse.length === 1 ||
givenDomainNameReverse.length >= hostedZoneNameReverse.length
) {
for (let i = 0; i < hostedZoneNameReverse.length; i += 1) {

@@ -225,3 +250,4 @@ if (givenDomainNameReverse[i] !== hostedZoneNameReverse[i]) {

return false;
})
}
)
.sort((zone1, zone2) => zone2.Name.length - zone1.Name.length)

@@ -233,3 +259,3 @@ .shift();

// Extracts the hostzone Id
const startPos = hostedZoneId.indexOf('e/') + 2;
const startPos = hostedZoneId.indexOf("e/") + 2;
const endPos = hostedZoneId.length;

@@ -242,8 +268,10 @@ return hostedZoneId.substring(startPos, endPos);

}
throw new Error(`Error: Could not find hosted zone "${this.givenDomainName}"`);
throw new Error(
`Error: Could not find hosted zone "${this.givenDomainName}"`
);
}
async prepareResources(resources) {
const distributionConfig = resources.Resources.AppSyncApiDistribution.Properties.DistributionConfig;
const distributionConfig =
resources.Resources.AppSyncApiDistribution.Properties.DistributionConfig;

@@ -253,3 +281,2 @@ this.prepareLogging(distributionConfig);

this.preparePriceClass(distributionConfig);
// this.prepareOrigins(distributionConfig);
this.prepareCookies(distributionConfig);

@@ -266,7 +293,7 @@ this.prepareHeaders(distributionConfig);

prepareLogging(distributionConfig) {
const loggingBucket = this.getConfig('logging.bucket', null);
const loggingBucket = this.getConfig("logging.bucket", null);
if (loggingBucket !== null) {
distributionConfig.Logging.Bucket = loggingBucket;
distributionConfig.Logging.Prefix = this.getConfig('logging.prefix', '');
distributionConfig.Logging.Prefix = this.getConfig("logging.prefix", "");
} else {

@@ -278,3 +305,3 @@ delete distributionConfig.Logging;

prepareDomain(distributionConfig) {
const domain = this.getConfig('domainName', null);
const domain = this.getConfig("domainName", null);
if (domain !== null) {

@@ -288,3 +315,3 @@ distributionConfig.Aliases = Array.isArray(domain) ? domain : [domain];

preparePriceClass(distributionConfig) {
const priceClass = this.getConfig('priceClass', 'PriceClass_All');
const priceClass = this.getConfig("priceClass", "PriceClass_All");
distributionConfig.PriceClass = priceClass;

@@ -298,4 +325,8 @@ }

prepareCookies(distributionConfig) {
const forwardCookies = this.getConfig('cookies', 'all');
distributionConfig.DefaultCacheBehavior.ForwardedValues.Cookies.Forward = Array.isArray(forwardCookies) ? 'whitelist' : forwardCookies;
const forwardCookies = this.getConfig("cookies", "all");
distributionConfig.DefaultCacheBehavior.ForwardedValues.Cookies.Forward = Array.isArray(
forwardCookies
)
? "whitelist"
: forwardCookies;
if (Array.isArray(forwardCookies)) {

@@ -307,3 +338,3 @@ distributionConfig.DefaultCacheBehavior.ForwardedValues.Cookies.WhitelistedNames = forwardCookies;

prepareHeaders(distributionConfig) {
const forwardHeaders = this.getConfig('headers', 'none');
const forwardHeaders = this.getConfig("headers", "none");

@@ -313,3 +344,4 @@ if (Array.isArray(forwardHeaders)) {

} else {
distributionConfig.DefaultCacheBehavior.ForwardedValues.Headers = forwardHeaders === 'none' ? [] : ['*'];
distributionConfig.DefaultCacheBehavior.ForwardedValues.Headers =
forwardHeaders === "none" ? [] : ["*"];
}

@@ -319,3 +351,3 @@ }

prepareQueryString(distributionConfig) {
const forwardQueryString = this.getConfig('querystring', 'all');
const forwardQueryString = this.getConfig("querystring", "all");

@@ -326,3 +358,4 @@ if (Array.isArray(forwardQueryString)) {

} else {
distributionConfig.DefaultCacheBehavior.ForwardedValues.QueryString = forwardQueryString === 'all';
distributionConfig.DefaultCacheBehavior.ForwardedValues.QueryString =
forwardQueryString === "all";
}

@@ -332,3 +365,3 @@ }

prepareComment(distributionConfig) {
const name = this.serverless.getProvider('aws').naming.getApiGatewayName();
const name = this.serverless.getProvider("aws").naming.getApiGatewayName();
distributionConfig.Comment = `Serverless Managed ${name}`;

@@ -338,8 +371,10 @@ }

async prepareCertificate(distributionConfig) {
const certificate = this.getConfig('certificate', null) || await this.getCertArn();
if (certificate !== null) {
const certificate =
this.getConfig("certificate", null) || (await this.getCertArn());
if (certificate) {
distributionConfig.ViewerCertificate.AcmCertificateArn = certificate;
} else {
delete distributionConfig.ViewerCertificate;
delete distributionConfig.ViewerCertificate.AcmCertificateArn;
delete distributionConfig.ViewerCertificate.SslSupportMethod;
distributionConfig.ViewerCertificate.CloudFrontDefaultCertificate = true;
}

@@ -349,3 +384,3 @@ }

prepareWaf(distributionConfig) {
const waf = this.getConfig('waf', null);
const waf = this.getConfig("waf", null);

@@ -360,7 +395,11 @@ if (waf !== null) {

prepareCompress(distributionConfig) {
distributionConfig.DefaultCacheBehavior.Compress = (this.getConfig('compress', false) === true);
distributionConfig.DefaultCacheBehavior.Compress =
this.getConfig("compress", false) === true;
}
prepareMinimumProtocolVersion(distributionConfig) {
const minimumProtocolVersion = this.getConfig('minimumProtocolVersion', undefined);
const minimumProtocolVersion = this.getConfig(
"minimumProtocolVersion",
undefined
);

@@ -373,3 +412,7 @@ if (minimumProtocolVersion) {

getConfig(field, defaultValue) {
return _.get(this.serverless, `service.custom.appSyncCloudFront.${field}`, defaultValue);
return _.get(
this.serverless,
`service.custom.appSyncCloudFront.${field}`,
defaultValue
);
}

@@ -376,0 +419,0 @@ }

{
"name": "serverless-appsync-cloudfront",
"version": "0.9.7",
"version": "1.0.0",
"engines": {

@@ -5,0 +5,0 @@ "node": ">=8.10"

@@ -18,10 +18,12 @@ # serverless-appsync-cloudfront

Either point to this repository from your package.json or clone this repo to `.serverless_plugins` folder in your project.
`npm i --save-dev serverless-appsync-cloudfront`
TODO: pending NPM release
or
`yarn add -D serverless-appsync-cloudfront`
## Configuration
* All appSyncCloudFront configuration parameters are optional - e.g. don't provide ACM Certificate ARN to use default CloudFront certificate (which works only for default cloudfront.net domain).
* First deployment may be quite long (e.g. 10 min) as Serverless is waiting for CloudFormation to deploy CloudFront distribution.
- All appSyncCloudFront configuration parameters are optional - e.g. don't provide ACM Certificate ARN to use default CloudFront certificate (which works only for default cloudfront.net domain).
- First deployment may be quite long (e.g. 10 min) as Serverless is waiting for CloudFormation to deploy CloudFront distribution.

@@ -34,2 +36,3 @@ ```

# All of these custom parameters are optional
custom:

@@ -57,3 +60,3 @@ appSyncCloudFront:

* `domain` can be list, so if you want to add more domains, instead string you list multiple ones:
- `domain` can be list, so if you want to add more domains, instead string you list multiple ones:

@@ -66,3 +69,4 @@ ```

* `cookies` can be *all* (default), *none* or a list that lists the cookies to whitelist
- `cookies` can be _all_ (default), _none_ or a list that lists the cookies to whitelist
```

@@ -74,3 +78,3 @@ cookies:

* [`headers`][headers-default-cache] can be *all*, *none* (default) or a list of headers ([see CloudFront custom behaviour][headers-list]):
- [`headers`][headers-default-cache] can be _all_, _none_ (default) or a list of headers ([see CloudFront custom behaviour][headers-list]):

@@ -84,3 +88,3 @@ ```

* `querystring` can be *all* (default), *none* or a list, in which case all querystring parameters are forwarded, but cache is based on the list:
- `querystring` can be _all_ (default), _none_ or a list, in which case all querystring parameters are forwarded, but cache is based on the list:

@@ -91,5 +95,4 @@ ```

* [`priceClass`][price-class] can be `PriceClass_All` (default), `PriceClass_100` or `PriceClass_200`:
- [`priceClass`][price-class] can be `PriceClass_All` (default), `PriceClass_100` or `PriceClass_200`:
```

@@ -101,5 +104,4 @@ priceClass: PriceClass_All

* [`minimumProtocolVersion`][minimum-protocol-version] can be `TLSv1` (default), `TLSv1_2016`, `TLSv1.1_2016`, `TLSv1.2_2018` or `SSLv3`:
- [`minimumProtocolVersion`][minimum-protocol-version] can be `TLSv1` (default), `TLSv1_2016`, `TLSv1.1_2016`, `TLSv1.2_2018` or `SSLv3`:
```

@@ -111,3 +113,3 @@ minimumProtocolVersion: TLSv1

* `enabled` can be `true` (default) or `false`. Can be used to disable cloudfront distribution deployment.
- `enabled` can be `true` (default) or `false`. Can be used to disable cloudfront distribution deployment.

@@ -124,8 +126,8 @@ ```

* `cloudfront:CreateDistribution`
* `cloudfront:GetDistribution`
* `cloudfront:UpdateDistribution`
* `cloudfront:DeleteDistribution`
* `cloudfront:TagResource`
- `cloudfront:CreateDistribution`
- `cloudfront:GetDistribution`
- `cloudfront:UpdateDistribution`
- `cloudfront:DeleteDistribution`
- `cloudfront:TagResource`
You can read more about IAM profiles and policies in the [Serverless documentation](https://serverless.com/framework/docs/providers/aws/guide/credentials#creating-aws-access-keys).

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc