aws-spa
Version:
A no-brainer script to deploy a single page app on AWS
166 lines (124 loc) • 5.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getCertificateARN = exports.domainNameMatch = exports.createCertificate = void 0;
var _awsHelper = require("./aws-helper");
var _awsServices = require("./aws-services");
var _logger = require("./logger");
var _route = require("./route53");
const getCertificateARN = async domainName => {
let pendingCertificateARN = null;
const certificates = await (0, _awsHelper.getAll)(async (nextMarker, page) => {
_logger.logger.info(`[ACM] 🔍 Looking for a certificate matching "${domainName}" in zone "us-east-1" (page ${page})...`);
const {
CertificateSummaryList,
NextToken
} = await _awsServices.acm.listCertificates({
NextToken: nextMarker
});
return {
items: CertificateSummaryList || [],
nextMarker: NextToken
};
});
for (const certificate of certificates) {
if (!certificate.CertificateArn) {
continue;
}
const {
Certificate
} = await _awsServices.acm.describeCertificate({
CertificateArn: certificate.CertificateArn
});
if (!Certificate) {
continue;
}
if (domainNameMatch(Certificate.DomainName, domainName)) {
if (Certificate.Status !== 'ISSUED') {
_logger.logger.info(`[ACM] 👍 Certificate with domain name "${Certificate.DomainName}" is matching but its status is "${Certificate.Status}"`);
if (Certificate.Status === 'PENDING_VALIDATION') {
pendingCertificateARN = Certificate.CertificateArn || null;
}
continue;
}
_logger.logger.info(`[ACM] 👍 Certificate with domain name "${Certificate.DomainName}" is matching`);
return certificate.CertificateArn;
}
if (!Certificate.SubjectAlternativeNames) {
continue;
}
for (const alternativeName of Certificate.SubjectAlternativeNames) {
if (domainNameMatch(alternativeName, domainName)) {
if (Certificate.Status !== 'ISSUED') {
_logger.logger.info(`[ACM] 👍 Certificate with alternative name "${alternativeName}" (domain name "${Certificate.DomainName}") is matching but its status is "${Certificate.Status}"`);
if (Certificate.Status === 'PENDING_VALIDATION') {
pendingCertificateARN = Certificate.CertificateArn || null;
}
continue;
}
_logger.logger.info(`[ACM] 👍 Alternative name "${alternativeName}" of certificate "${Certificate.DomainName}" is matching`);
return certificate.CertificateArn;
}
}
}
if (!pendingCertificateARN) {
return null;
}
_logger.logger.info(`[ACM] ⏱ Waiting for certificate validation: the domain owner of "${domainName}" should have received an email...`);
await _awsServices.waitUntil.certificateValidated({
client: _awsServices.acm,
maxWaitTime: 600
}, {
CertificateArn: pendingCertificateARN
});
_logger.logger.info(`[ACM] ✅ Certificate with domain name "${domainName}" is now validated`);
return pendingCertificateARN;
};
exports.getCertificateARN = getCertificateARN;
const createCertificate = async (domainName, hostedZoneId, delay) => {
_logger.logger.info(`[ACM] ✏️ Requesting a certificate for "${domainName}"...`);
const {
CertificateArn
} = await _awsServices.acm.requestCertificate({
DomainName: domainName,
ValidationMethod: 'DNS'
});
if (!CertificateArn) {
throw new Error('No CertificateArn returned');
}
await handleDNSValidation(CertificateArn, domainName, hostedZoneId, delay);
return CertificateArn;
};
exports.createCertificate = createCertificate;
const handleDNSValidation = async (certificateARN, domainName, hostedZoneId, delay = 5000) => {
// https://github.com/aws/aws-sdk-js/issues/2133
await new Promise(resolve => setTimeout(resolve, delay));
const {
Certificate
} = await _awsServices.acm.describeCertificate({
CertificateArn: certificateARN
});
if (!Certificate || !Certificate.DomainValidationOptions) {
throw new Error('Could not access domain validation options');
}
const domainValidationOption = Certificate.DomainValidationOptions.find(({
DomainName,
ResourceRecord
}) => DomainName === domainName && Boolean(ResourceRecord));
if (!domainValidationOption) {
throw new Error(`Could not find domain validation options for "${domainName}" with DNS validation`);
}
await (0, _route.createCertificateValidationDNSRecord)(domainValidationOption.ResourceRecord, hostedZoneId);
_logger.logger.info(`[ACM] ⏱ Request sent. Waiting for certificate validation by DNS`);
await _awsServices.waitUntil.certificateValidated({
client: _awsServices.acm,
maxWaitTime: 600,
minDelay: 10
}, {
CertificateArn: certificateARN
});
_logger.logger.info(`[ACM] ✅ Certificate with domain name "${domainName}" is now validated`);
};
const domainNameMatch = (certificateDomainName = '', domainName) => [`*.${domainName.split('.').slice(1).join('.')}`, domainName].includes(certificateDomainName);
exports.domainNameMatch = domainNameMatch;