UNPKG

aws-spa

Version:

A no-brainer script to deploy a single page app on AWS

166 lines (124 loc) 5.12 kB
"use strict"; 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;