refactor
This commit is contained in:
		
							parent
							
								
									9a54d2e3bc
								
							
						
					
					
						commit
						1ec51c635c
					
				
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							@ -1 +1,2 @@
 | 
			
		||||
AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)
 | 
			
		||||
Hitesh Walia <hiteshwar.walia@gmail.com>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										110
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								README.md
									
									
									
									
									
								
							@ -1,3 +1,111 @@
 | 
			
		||||
# acme-dns-01-route53
 | 
			
		||||
 | 
			
		||||
Amazon AWS Route53 DNS + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js
 | 
			
		||||
Amazon AWS Route53 DNS + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Features
 | 
			
		||||
 | 
			
		||||
-   Compatible
 | 
			
		||||
    -   Let’s Encrypt v2.1 / ACME draft 18 (2019)
 | 
			
		||||
    -   DNSimple v2 API
 | 
			
		||||
    -   ACME.js, Greenlock.js, and others
 | 
			
		||||
-   Quality
 | 
			
		||||
    -   node v6 compatible VanillaJS
 | 
			
		||||
 | 
			
		||||
# Install
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
npm install --save acme-dns-01-route53
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
AWS API keys:
 | 
			
		||||
 | 
			
		||||
-   Login to your account at: https://console.aws.amazon.com
 | 
			
		||||
-   Go to Services > IAM > Users, create a new user and assign AmazonRoute53FullAccess  policy.
 | 
			
		||||
-   Click *Securty credentials* tab and then click *Create access key*.
 | 
			
		||||
 | 
			
		||||
# Usage
 | 
			
		||||
 | 
			
		||||
First you create an instance with your credentials:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var dns01 = require('acme-dns-01-route53').create({
 | 
			
		||||
	key: 'your_key',
 | 
			
		||||
	secret: 'your_secret'
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then you can use it with any compatible ACME library, such as Greenlock.js or ACME.js.
 | 
			
		||||
 | 
			
		||||
## Greenlock.js
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var Greenlock = require('greenlock-express');
 | 
			
		||||
var greenlock = Greenlock.create({
 | 
			
		||||
	challenges: {
 | 
			
		||||
		'dns-01': dns01
 | 
			
		||||
		// ...
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See [Greenlock Express](https://git.rootprojects.org/root/greenlock-express.js) and/or [Greenlock.js](https://git.rootprojects.org/root/greenlock.js) documentation for more details.
 | 
			
		||||
 | 
			
		||||
## ACME.js
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// TODO
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See the [ACME.js](https://git.rootprojects.org/root/acme-v2.js) for more details.
 | 
			
		||||
 | 
			
		||||
## Build your own
 | 
			
		||||
 | 
			
		||||
There are only 5 methods:
 | 
			
		||||
 | 
			
		||||
-   `init(config)`
 | 
			
		||||
-   `zones(opts)`
 | 
			
		||||
-   `set(opts)`
 | 
			
		||||
-   `get(opts)`
 | 
			
		||||
-   `remove(opts)`
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
dns01
 | 
			
		||||
	.set({
 | 
			
		||||
		identifier: { value: 'foo.example.co.uk' },
 | 
			
		||||
		wildcard: false,
 | 
			
		||||
		dnsZone: 'example.co.uk',
 | 
			
		||||
		dnsPrefix: '_acme-challenge.foo',
 | 
			
		||||
		dnsAuthorization: 'xxx_secret_xxx'
 | 
			
		||||
	})
 | 
			
		||||
	.then(function() {
 | 
			
		||||
		console.log('TXT record set');
 | 
			
		||||
	})
 | 
			
		||||
	.catch(function() {
 | 
			
		||||
		console.log('Failed to set TXT record');
 | 
			
		||||
	});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
See acme-dns-01-test for more implementation details.
 | 
			
		||||
 | 
			
		||||
# Tests
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# node ./test.js domain-zone key secret
 | 
			
		||||
node ./test.js example.com xxxxx yyyyy
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Authors
 | 
			
		||||
 | 
			
		||||
-   AJ ONeal
 | 
			
		||||
-   Hitesh Walia
 | 
			
		||||
 | 
			
		||||
See AUTHORS for contact info.
 | 
			
		||||
 | 
			
		||||
# Legal
 | 
			
		||||
 | 
			
		||||
[acme-dns-01-dnsimple.js](https://git.coolaj86.com/coolaj86/acme-dns-01-dnsimple.js) | MPL-2.0 | [Terms of Use](https://therootcompany.com/legal/#terms) | [Privacy Policy](https://therootcompany.com/legal/#privacy)
 | 
			
		||||
 | 
			
		||||
Copyright 2019 Hitesh Walia  
 | 
			
		||||
Copyright 2019 AJ ONeal  
 | 
			
		||||
Copyright 2019 The Root Group LLC
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										468
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										468
									
								
								lib/index.js
									
									
									
									
									
								
							@ -5,14 +5,66 @@ var xml2js = require('xml2js');
 | 
			
		||||
var parseString = xml2js.parseString;
 | 
			
		||||
parseString = require('util').promisify(parseString);
 | 
			
		||||
var builder = new xml2js.Builder();
 | 
			
		||||
 | 
			
		||||
var request = require('@root/request');
 | 
			
		||||
//request.debug = false;
 | 
			
		||||
var request;
 | 
			
		||||
 | 
			
		||||
var defaults = {
 | 
			
		||||
	baseUri: '/2013-04-01/'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function setWeightedPolicy(XmlObject, isWildcard) {
 | 
			
		||||
	if (isWildcard) {
 | 
			
		||||
		XmlObject.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
			'wildcard'
 | 
			
		||||
		];
 | 
			
		||||
	} else {
 | 
			
		||||
		XmlObject.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
			'subdomain'
 | 
			
		||||
		];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	XmlObject.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Weight = [
 | 
			
		||||
		1
 | 
			
		||||
	];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used to build XML payload
 | 
			
		||||
var XmlParameters = {
 | 
			
		||||
	ChangeResourceRecordSetsRequest: {
 | 
			
		||||
		$: {
 | 
			
		||||
			xmlns: ''
 | 
			
		||||
		},
 | 
			
		||||
		ChangeBatch: [
 | 
			
		||||
			{
 | 
			
		||||
				Changes: [
 | 
			
		||||
					{
 | 
			
		||||
						Change: [
 | 
			
		||||
							{
 | 
			
		||||
								Action: [''],
 | 
			
		||||
								ResourceRecordSet: [
 | 
			
		||||
									{
 | 
			
		||||
										Type: ['TXT'],
 | 
			
		||||
										Name: [''],
 | 
			
		||||
										ResourceRecords: [
 | 
			
		||||
											{
 | 
			
		||||
												ResourceRecord: [
 | 
			
		||||
													{
 | 
			
		||||
														Value: ['']
 | 
			
		||||
													}
 | 
			
		||||
												]
 | 
			
		||||
											}
 | 
			
		||||
										],
 | 
			
		||||
										TTL: [300]
 | 
			
		||||
									}
 | 
			
		||||
								]
 | 
			
		||||
							}
 | 
			
		||||
						]
 | 
			
		||||
					}
 | 
			
		||||
				]
 | 
			
		||||
			}
 | 
			
		||||
		]
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports.create = function(config) {
 | 
			
		||||
	var baseUri = defaults.baseUri.replace(/\/$/, '');
 | 
			
		||||
	var key = config.key;
 | 
			
		||||
@ -21,33 +73,34 @@ module.exports.create = function(config) {
 | 
			
		||||
	function api(method, path, body, query) {
 | 
			
		||||
		var body = body || '';
 | 
			
		||||
		var query = query || {};
 | 
			
		||||
		var options = { 
 | 
			
		||||
			key: key, 
 | 
			
		||||
			secret: secret, 
 | 
			
		||||
			query: query 
 | 
			
		||||
		var options = {
 | 
			
		||||
			key: key,
 | 
			
		||||
			secret: secret,
 | 
			
		||||
			query: query
 | 
			
		||||
		};
 | 
			
		||||
		
 | 
			
		||||
		if(method === 'POST') {
 | 
			
		||||
			options.headers = { 'Content-Type': 'application/xml' }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var url = v4.createPresignedURL(method, 'route53.amazonaws.com', path, 'route53', body, options);
 | 
			
		||||
		//console.log('url: ' + url + '\n');
 | 
			
		||||
 | 
			
		||||
		var parameters = {
 | 
			
		||||
			method: method,
 | 
			
		||||
			url: url
 | 
			
		||||
			method: method
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if(method === 'POST') {
 | 
			
		||||
			parameters.headers = { 'Content-Type': 'application/xml' }
 | 
			
		||||
		if (method === 'POST') {
 | 
			
		||||
			options.headers = { 'Content-Type': 'application/xml' };
 | 
			
		||||
			parameters.headers = { 'Content-Type': 'application/xml' };
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(body) {
 | 
			
		||||
		if (body) {
 | 
			
		||||
			parameters.body = body;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// console.log(method, path, query);
 | 
			
		||||
		var url = v4.createPresignedURL(
 | 
			
		||||
			method,
 | 
			
		||||
			'route53.amazonaws.com',
 | 
			
		||||
			path,
 | 
			
		||||
			'route53',
 | 
			
		||||
			body,
 | 
			
		||||
			options
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		parameters.url = url;
 | 
			
		||||
 | 
			
		||||
		return request(parameters).then(function(response) {
 | 
			
		||||
			if (response.statusCode < 200 || response.statusCode >= 300) {
 | 
			
		||||
@ -67,263 +120,174 @@ module.exports.create = function(config) {
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	api('GET', baseUri + '/' + 'hostedzone').then(function(response){
 | 
			
		||||
		console.log('######## RESPONSE #########');
 | 
			
		||||
 | 
			
		||||
	});
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		init: function(options) {
 | 
			
		||||
			request = options.request;
 | 
			
		||||
			return null;
 | 
			
		||||
		},
 | 
			
		||||
		zones: function(data) {		
 | 
			
		||||
			//console.info('List Zones', data);
 | 
			
		||||
			return api('GET', baseUri + '/' + 'hostedzone').then(function(response){
 | 
			
		||||
				return parseString(response.body).then(function(body){
 | 
			
		||||
					var zones = body.ListHostedZonesResponse.HostedZones[0].HostedZone.map(function(element) {
 | 
			
		||||
						return element.Name[0].replace(/\.$/, ''); // all route 53 domains terminate with a dot
 | 
			
		||||
					});
 | 
			
		||||
		zones: function(data) {
 | 
			
		||||
			return api('GET', baseUri + '/' + 'hostedzone').then(function(
 | 
			
		||||
				response
 | 
			
		||||
			) {
 | 
			
		||||
				return parseString(response.body).then(function(body) {
 | 
			
		||||
					var zones = body.ListHostedZonesResponse.HostedZones[0].HostedZone.map(
 | 
			
		||||
						function(element) {
 | 
			
		||||
							return element.Name[0].replace(/\.$/, ''); // all route 53 domains terminate with a dot
 | 
			
		||||
						}
 | 
			
		||||
					);
 | 
			
		||||
 | 
			
		||||
					return zones;
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
			
 | 
			
		||||
		},
 | 
			
		||||
		set: function(data) {
 | 
			
		||||
			// console.info('Add TXT', data);
 | 
			
		||||
			// console.log('data: ' + JSON.stringify(data, null, 2));
 | 
			
		||||
			var challenge = data.challenge;
 | 
			
		||||
 | 
			
		||||
			if (!challenge.dnsZone) {
 | 
			
		||||
				throw new Error('No matching zone for ' + challenge.dnsHost);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return api('GET', baseUri + '/' + 'hostedzonesbyname', null, 'dnsname=' + challenge.dnsZone + '&maxitems=1')
 | 
			
		||||
						.then(function(response){
 | 
			
		||||
							return parseString(response.body).then(function(body){
 | 
			
		||||
								return body;
 | 
			
		||||
								});		
 | 
			
		||||
						})
 | 
			
		||||
						.then(function(body){
 | 
			
		||||
							var zoneID =  body.ListHostedZonesByNameResponse.HostedZones[0].HostedZone[0].Id[0];
 | 
			
		||||
							var xmlns =  body.ListHostedZonesByNameResponse.$.xmlns;
 | 
			
		||||
							
 | 
			
		||||
							var parameters = {
 | 
			
		||||
								'ChangeResourceRecordSetsRequest': {
 | 
			
		||||
									'$': {
 | 
			
		||||
										'xmlns': xmlns
 | 
			
		||||
									},
 | 
			
		||||
									'ChangeBatch': [
 | 
			
		||||
										{
 | 
			
		||||
											'Changes': [
 | 
			
		||||
												{
 | 
			
		||||
													'Change': [
 | 
			
		||||
														{
 | 
			
		||||
															'Action': [
 | 
			
		||||
																'CREATE'
 | 
			
		||||
															],
 | 
			
		||||
															'ResourceRecordSet': [
 | 
			
		||||
																{
 | 
			
		||||
																	'Type': [
 | 
			
		||||
																		'TXT'
 | 
			
		||||
																	],
 | 
			
		||||
																	'Name': [
 | 
			
		||||
																		challenge.dnsHost // AWS requires FQDN
 | 
			
		||||
																	],
 | 
			
		||||
																	'ResourceRecords': [
 | 
			
		||||
																		{
 | 
			
		||||
																			'ResourceRecord': [
 | 
			
		||||
																				{
 | 
			
		||||
																					'Value': [
 | 
			
		||||
																						'"' + challenge.dnsAuthorization + '"' // value must be surrounded by double quotes
 | 
			
		||||
																					]
 | 
			
		||||
																				}
 | 
			
		||||
																			]
 | 
			
		||||
																		}
 | 
			
		||||
																	],
 | 
			
		||||
																	'TTL': [
 | 
			
		||||
																		300
 | 
			
		||||
																	]
 | 
			
		||||
																}
 | 
			
		||||
															]
 | 
			
		||||
															
 | 
			
		||||
														}
 | 
			
		||||
													]
 | 
			
		||||
												}
 | 
			
		||||
											]
 | 
			
		||||
										}
 | 
			
		||||
									]
 | 
			
		||||
								}
 | 
			
		||||
							}; 
 | 
			
		||||
			return api(
 | 
			
		||||
				'GET',
 | 
			
		||||
				baseUri + '/' + 'hostedzonesbyname',
 | 
			
		||||
				null,
 | 
			
		||||
				'dnsname=' + challenge.dnsZone + '&maxitems=1'
 | 
			
		||||
			)
 | 
			
		||||
				.then(function(response) {
 | 
			
		||||
					return parseString(response.body).then(function(body) {
 | 
			
		||||
						return body;
 | 
			
		||||
					});
 | 
			
		||||
				})
 | 
			
		||||
				.then(function(body) {
 | 
			
		||||
					var zoneID =
 | 
			
		||||
						body.ListHostedZonesByNameResponse.HostedZones[0]
 | 
			
		||||
							.HostedZone[0].Id[0];
 | 
			
		||||
					var xmlns = body.ListHostedZonesByNameResponse.$.xmlns;
 | 
			
		||||
 | 
			
		||||
							// By default AWS creates record sets with simple routing policy, so duplicates are not allowed.
 | 
			
		||||
							// A workaround is put the record sets in different weighted policies.   
 | 
			
		||||
							if(challenge.identifier.value.startsWith('foo')) {
 | 
			
		||||
								if(challenge.wildcard) {
 | 
			
		||||
									
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Weight = [
 | 
			
		||||
										1
 | 
			
		||||
									];
 | 
			
		||||
					var parameters = JSON.parse(JSON.stringify(XmlParameters));
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.$.xmlns = xmlns;
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].Action[0] =
 | 
			
		||||
						'CREATE';
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Name[0] =
 | 
			
		||||
						challenge.dnsHost; // AWS requires FQDN
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].ResourceRecords[0].ResourceRecord[0].Value[0] =
 | 
			
		||||
						'"' + challenge.dnsAuthorization + '"'; // value must be surrounded by double quotes
 | 
			
		||||
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
										'wildcard'
 | 
			
		||||
									];
 | 
			
		||||
								} else {
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Weight = [
 | 
			
		||||
										1
 | 
			
		||||
									];
 | 
			
		||||
					// By default AWS creates record sets with simple routing policy, so duplicates are not allowed.
 | 
			
		||||
					// A workaround is put the record sets in different weighted policies.
 | 
			
		||||
					if (challenge.identifier.value.startsWith('foo')) {
 | 
			
		||||
						setWeightedPolicy(parameters, challenge.wildcard);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
										'subdomain'
 | 
			
		||||
									];
 | 
			
		||||
								}				
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							var xml = builder.buildObject(parameters);
 | 
			
		||||
							//console.log('xml: ' + xml);
 | 
			
		||||
 | 
			
		||||
							return api('POST', baseUri + zoneID + '/rrset/', xml);
 | 
			
		||||
	
 | 
			
		||||
						});
 | 
			
		||||
 | 
			
		||||
			
 | 
			
		||||
					var xml = builder.buildObject(parameters);
 | 
			
		||||
					return api('POST', baseUri + zoneID + '/rrset/', xml);
 | 
			
		||||
				});
 | 
			
		||||
		},
 | 
			
		||||
		get: function(data) {
 | 
			
		||||
			// console.info('List TXT', data);
 | 
			
		||||
			var challenge = data.challenge;
 | 
			
		||||
 | 
			
		||||
			return api('GET', baseUri + '/' + 'hostedzonesbyname', null, 'dnsname=' + challenge.dnsZone + '&maxitems=1')
 | 
			
		||||
						.then(function(response){
 | 
			
		||||
							return parseString(response.body).then(function(body){
 | 
			
		||||
								return body;
 | 
			
		||||
								});		
 | 
			
		||||
						})
 | 
			
		||||
						.then(function(body){
 | 
			
		||||
							var zoneID =  body.ListHostedZonesByNameResponse.HostedZones[0].HostedZone[0].Id[0];
 | 
			
		||||
							// console.log('zoneID: ' + zoneID);
 | 
			
		||||
							return zoneID;
 | 
			
		||||
						})
 | 
			
		||||
						.then(function(zoneID){
 | 
			
		||||
							// GET /2013-04-01/hostedzone/Id/rrset?identifier=StartRecordIdentifier&maxitems=MaxItems&name=StartRecordName&type=StartRecordType HTTP/1.1
 | 
			
		||||
							
 | 
			
		||||
							return api('GET', baseUri + '/' + zoneID + '/rrset', null, 'name=' + challenge.dnsPrefix + '.' + challenge.dnsZone + '.' + '&type=TXT')
 | 
			
		||||
							.then(function(response){
 | 
			
		||||
								return parseString(response.body).then(function(body){
 | 
			
		||||
										if (body.ListResourceRecordSetsResponse.ResourceRecordSets[0] === '') return null;
 | 
			
		||||
										
 | 
			
		||||
										var record = body.ListResourceRecordSetsResponse.ResourceRecordSets[0].ResourceRecordSet.filter(function(element){
 | 
			
		||||
											return (
 | 
			
		||||
												element.ResourceRecords[0].ResourceRecord[0].Value[0].replace(/\"/g, '') === challenge.dnsAuthorization &&
 | 
			
		||||
												element.Name[0].includes(challenge.dnsPrefix)
 | 
			
		||||
											);
 | 
			
		||||
										})[0];
 | 
			
		||||
 | 
			
		||||
										if (record) {
 | 
			
		||||
											return { dnsAuthorization: record.ResourceRecords[0].ResourceRecord[0].Value[0].replace(/\"/g, '') };
 | 
			
		||||
										}
 | 
			
		||||
						
 | 
			
		||||
										return null;
 | 
			
		||||
									});		
 | 
			
		||||
							});
 | 
			
		||||
									
 | 
			
		||||
						});
 | 
			
		||||
		
 | 
			
		||||
		},
 | 
			
		||||
		remove: function(data) {
 | 
			
		||||
			// console.info('Remove TXT', data);
 | 
			
		||||
 | 
			
		||||
			var challenge = data.challenge;
 | 
			
		||||
 | 
			
		||||
			return api('GET', baseUri + '/' + 'hostedzonesbyname', null, 'dnsname=' + challenge.dnsZone + '&maxitems=1')
 | 
			
		||||
						.then(function(response){
 | 
			
		||||
							return parseString(response.body).then(function(body){
 | 
			
		||||
								return body;
 | 
			
		||||
								});		
 | 
			
		||||
						})
 | 
			
		||||
						.then(function(body){
 | 
			
		||||
							var zoneID =  body.ListHostedZonesByNameResponse.HostedZones[0].HostedZone[0].Id[0];
 | 
			
		||||
							var xmlns =  body.ListHostedZonesByNameResponse.$.xmlns;
 | 
			
		||||
							
 | 
			
		||||
							var parameters = {
 | 
			
		||||
								'ChangeResourceRecordSetsRequest': {
 | 
			
		||||
									'$': {
 | 
			
		||||
										'xmlns': xmlns
 | 
			
		||||
									},
 | 
			
		||||
									'ChangeBatch': [
 | 
			
		||||
										{
 | 
			
		||||
											'Changes': [
 | 
			
		||||
												{
 | 
			
		||||
													'Change': [
 | 
			
		||||
														{
 | 
			
		||||
															'Action': [
 | 
			
		||||
																'DELETE'
 | 
			
		||||
															],
 | 
			
		||||
															'ResourceRecordSet': [
 | 
			
		||||
																{
 | 
			
		||||
																	'Type': [
 | 
			
		||||
																		'TXT'
 | 
			
		||||
																	],
 | 
			
		||||
																	'Name': [
 | 
			
		||||
																		challenge.dnsHost // AWS requires FQDN
 | 
			
		||||
																	],
 | 
			
		||||
																	'ResourceRecords': [
 | 
			
		||||
																		{
 | 
			
		||||
																			'ResourceRecord': [
 | 
			
		||||
																				{
 | 
			
		||||
																					'Value': [
 | 
			
		||||
																						'"' + challenge.dnsAuthorization + '"' // value must be surrounded by double quotes
 | 
			
		||||
																					]
 | 
			
		||||
																				}
 | 
			
		||||
																			]
 | 
			
		||||
																		}
 | 
			
		||||
																	],
 | 
			
		||||
																	'TTL': [
 | 
			
		||||
																		300
 | 
			
		||||
																	]
 | 
			
		||||
																}
 | 
			
		||||
															]
 | 
			
		||||
															
 | 
			
		||||
														}
 | 
			
		||||
													]
 | 
			
		||||
												}
 | 
			
		||||
											]
 | 
			
		||||
										}
 | 
			
		||||
									]
 | 
			
		||||
								}
 | 
			
		||||
							}; 
 | 
			
		||||
 | 
			
		||||
							if(challenge.identifier.value.startsWith('foo')) {
 | 
			
		||||
								if(challenge.wildcard) {
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Weight = [
 | 
			
		||||
										1
 | 
			
		||||
									];
 | 
			
		||||
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
										'wildcard'
 | 
			
		||||
									];
 | 
			
		||||
								} else {
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Weight = [
 | 
			
		||||
										1
 | 
			
		||||
									];
 | 
			
		||||
 | 
			
		||||
									parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].SetIdentifier = [
 | 
			
		||||
										'subdomain'
 | 
			
		||||
									];
 | 
			
		||||
								}				
 | 
			
		||||
			return api(
 | 
			
		||||
				'GET',
 | 
			
		||||
				baseUri + '/' + 'hostedzonesbyname',
 | 
			
		||||
				null,
 | 
			
		||||
				'dnsname=' + challenge.dnsZone + '&maxitems=1'
 | 
			
		||||
			)
 | 
			
		||||
				.then(function(response) {
 | 
			
		||||
					return parseString(response.body).then(function(body) {
 | 
			
		||||
						return body;
 | 
			
		||||
					});
 | 
			
		||||
				})
 | 
			
		||||
				.then(function(body) {
 | 
			
		||||
					var zoneID =
 | 
			
		||||
						body.ListHostedZonesByNameResponse.HostedZones[0]
 | 
			
		||||
							.HostedZone[0].Id[0];
 | 
			
		||||
					return zoneID;
 | 
			
		||||
				})
 | 
			
		||||
				.then(function(zoneID) {
 | 
			
		||||
					return api(
 | 
			
		||||
						'GET',
 | 
			
		||||
						baseUri + '/' + zoneID + '/rrset',
 | 
			
		||||
						null,
 | 
			
		||||
						'name=' +
 | 
			
		||||
							challenge.dnsPrefix +
 | 
			
		||||
							'.' +
 | 
			
		||||
							challenge.dnsZone +
 | 
			
		||||
							'.' +
 | 
			
		||||
							'&type=TXT'
 | 
			
		||||
					).then(function(response) {
 | 
			
		||||
						return parseString(response.body).then(function(body) {
 | 
			
		||||
							if (
 | 
			
		||||
								body.ListResourceRecordSetsResponse
 | 
			
		||||
									.ResourceRecordSets[0] === ''
 | 
			
		||||
							) {
 | 
			
		||||
								return null;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							var xml = builder.buildObject(parameters);
 | 
			
		||||
							// console.log('\n', xml, '\n');
 | 
			
		||||
							
 | 
			
		||||
							return api('POST', baseUri + zoneID + '/rrset/', xml);
 | 
			
		||||
	
 | 
			
		||||
						});
 | 
			
		||||
							var record = body.ListResourceRecordSetsResponse.ResourceRecordSets[0].ResourceRecordSet.filter(
 | 
			
		||||
								function(element) {
 | 
			
		||||
									return (
 | 
			
		||||
										element.ResourceRecords[0].ResourceRecord[0].Value[0].replace(
 | 
			
		||||
											/\"/g,
 | 
			
		||||
											''
 | 
			
		||||
										) === challenge.dnsAuthorization &&
 | 
			
		||||
										element.Name[0].includes(
 | 
			
		||||
											challenge.dnsPrefix
 | 
			
		||||
										)
 | 
			
		||||
									);
 | 
			
		||||
								}
 | 
			
		||||
							)[0];
 | 
			
		||||
 | 
			
		||||
							if (record) {
 | 
			
		||||
								return {
 | 
			
		||||
									dnsAuthorization: record.ResourceRecords[0].ResourceRecord[0].Value[0].replace(
 | 
			
		||||
										/\"/g,
 | 
			
		||||
										''
 | 
			
		||||
									)
 | 
			
		||||
								};
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							return null;
 | 
			
		||||
						});
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
		},
 | 
			
		||||
		remove: function(data) {
 | 
			
		||||
			var challenge = data.challenge;
 | 
			
		||||
 | 
			
		||||
			return api(
 | 
			
		||||
				'GET',
 | 
			
		||||
				baseUri + '/' + 'hostedzonesbyname',
 | 
			
		||||
				null,
 | 
			
		||||
				'dnsname=' + challenge.dnsZone + '&maxitems=1'
 | 
			
		||||
			)
 | 
			
		||||
				.then(function(response) {
 | 
			
		||||
					return parseString(response.body).then(function(body) {
 | 
			
		||||
						return body;
 | 
			
		||||
					});
 | 
			
		||||
				})
 | 
			
		||||
				.then(function(body) {
 | 
			
		||||
					var zoneID =
 | 
			
		||||
						body.ListHostedZonesByNameResponse.HostedZones[0]
 | 
			
		||||
							.HostedZone[0].Id[0];
 | 
			
		||||
					var xmlns = body.ListHostedZonesByNameResponse.$.xmlns;
 | 
			
		||||
 | 
			
		||||
					var parameters = JSON.parse(JSON.stringify(XmlParameters));
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.$.xmlns = xmlns;
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].Action[0] =
 | 
			
		||||
						'DELETE';
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].Name[0] =
 | 
			
		||||
						challenge.dnsHost; // AWS requires FQDN
 | 
			
		||||
					parameters.ChangeResourceRecordSetsRequest.ChangeBatch[0].Changes[0].Change[0].ResourceRecordSet[0].ResourceRecords[0].ResourceRecord[0].Value[0] =
 | 
			
		||||
						'"' + challenge.dnsAuthorization + '"'; // value must be surrounded by double quotes
 | 
			
		||||
 | 
			
		||||
					// need to add weight and setidentifier to delete record set
 | 
			
		||||
					if (challenge.identifier.value.startsWith('foo')) {
 | 
			
		||||
						setWeightedPolicy(parameters, challenge.wildcard);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					var xml = builder.buildObject(parameters);
 | 
			
		||||
					return api('POST', baseUri + zoneID + '/rrset/', xml);
 | 
			
		||||
				});
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,10 @@
 | 
			
		||||
		"acme",
 | 
			
		||||
		"greenlock"
 | 
			
		||||
	],
 | 
			
		||||
	"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
 | 
			
		||||
	"author": "Hitesh Walia <hiteshwar.walia@gmail.com",
 | 
			
		||||
	"contributors": [
 | 
			
		||||
		"AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)"
 | 
			
		||||
	],
 | 
			
		||||
	"license": "MPL-2.0",
 | 
			
		||||
	"devDependencies": {
 | 
			
		||||
		"dotenv": "^8.1.0"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user