v3.0.0: initial release
This commit is contained in:
		
							parent
							
								
									96a1f55a08
								
							
						
					
					
						commit
						79a8329179
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +1,2 @@
 | 
			
		||||
*secret*
 | 
			
		||||
node_modules/
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								README.md
									
									
									
									
									
								
							@ -5,24 +5,39 @@ Digital Ocean DNS + Let's Encrypt for Node.js
 | 
			
		||||
This handles ACME dns-01 challenges, compatible with ACME.js and Greenlock.js.
 | 
			
		||||
Passes [acme-dns-01-test](https://git.rootprojects.org/root/acme-dns-01-test.js).
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- Compatible
 | 
			
		||||
  - [x] Let's Encrypt v2.1 / ACME draft 18 (2019)
 | 
			
		||||
  - [x] Digital Ocean v2 API
 | 
			
		||||
  - [x] ACME.js, Greenlock.js, and others
 | 
			
		||||
- Quality
 | 
			
		||||
  - [x] node v6 compatible VanillaJS
 | 
			
		||||
  - [x] < 150 lines of code
 | 
			
		||||
  - [x] **Zero Dependencies**
 | 
			
		||||
 | 
			
		||||
# Install
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npm install --save acme-dns-01-digitalocean@3.x
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Generate Digital Ocean API Token:
 | 
			
		||||
 | 
			
		||||
- <https://cloud.digitalocean.com/account/api/tokens>
 | 
			
		||||
 | 
			
		||||
# Usage
 | 
			
		||||
 | 
			
		||||
First you create an instance with your credentials:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var dns01 = require('acme-dns-01-digitalocean').create({
 | 
			
		||||
	baseUrl: 'https://api.digitalocean.com', // default
 | 
			
		||||
	baseUrl: 'https://api.digitalocean.com/v2/domains', // default
 | 
			
		||||
	token: 'xxxx'
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then you can use it with any compatible ACME module,
 | 
			
		||||
Then you can use it with any compatible ACME library,
 | 
			
		||||
such as Greenlock.js or ACME.js.
 | 
			
		||||
 | 
			
		||||
### Greenlock.js
 | 
			
		||||
@ -37,8 +52,9 @@ var greenlock = Greenlock.create({
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
@ -50,20 +66,29 @@ 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.com' },
 | 
			
		||||
    wildcard: false,
 | 
			
		||||
    dnsHost: '_acme-challenge.foo.example.com'
 | 
			
		||||
    dnsAuthorization: 'xxx_secret_xxx'
 | 
			
		||||
  })
 | 
			
		||||
  .then(function () {
 | 
			
		||||
    console.log("TXT record set");
 | 
			
		||||
  })
 | 
			
		||||
  .catch(function () {
 | 
			
		||||
    console.log("Failed to set TXT record");
 | 
			
		||||
  });
 | 
			
		||||
	.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](https://git.rootprojects.org/root/acme-dns-01-test.js)
 | 
			
		||||
@ -75,3 +100,23 @@ for more implementation details.
 | 
			
		||||
# node ./test.js domain-zone api-token
 | 
			
		||||
node ./test.js example.com xxxxxx
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Authors
 | 
			
		||||
 | 
			
		||||
- Aneem Patrabansha
 | 
			
		||||
- AJ ONeal
 | 
			
		||||
 | 
			
		||||
See AUTHORS for contact info.
 | 
			
		||||
 | 
			
		||||
<!-- {{ if .Legal }} -->
 | 
			
		||||
 | 
			
		||||
# Legal
 | 
			
		||||
 | 
			
		||||
[acme-dns-01-digitalocean.js](https://git.coolaj86.com/coolaj86/acme-dns-01-digitalocean.js) |
 | 
			
		||||
MPL-2.0 |
 | 
			
		||||
[Terms of Use](https://therootcompany.com/legal/#terms) |
 | 
			
		||||
[Privacy Policy](https://therootcompany.com/legal/#privacy)
 | 
			
		||||
 | 
			
		||||
Copyright 2019 The Root Group LLC
 | 
			
		||||
 | 
			
		||||
<!-- {{ end }} -->
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										41
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								lib/index.js
									
									
									
									
									
								
							@ -1,19 +1,17 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
var request = require('@root/request');
 | 
			
		||||
request = require('util').promisify(request);
 | 
			
		||||
 | 
			
		||||
var defaults = {
 | 
			
		||||
	baseUrl: 'https://api.digitalocean.com'
 | 
			
		||||
	baseUrl: 'https://api.digitalocean.com/v2/domains'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
module.exports.create = function(config) {
 | 
			
		||||
	// config = { baseUrl, token }
 | 
			
		||||
	var baseUrl = config.baseUrl || defaults.baseUrl;
 | 
			
		||||
	var baseUrl = (config.baseUrl || defaults.baseUrl).replace(/\/$/, '');
 | 
			
		||||
	var authtoken = config.token;
 | 
			
		||||
	var request;
 | 
			
		||||
 | 
			
		||||
	function api(method, path, form) {
 | 
			
		||||
		return request({
 | 
			
		||||
		var req = {
 | 
			
		||||
			method: method,
 | 
			
		||||
			url: baseUrl + path,
 | 
			
		||||
			headers: {
 | 
			
		||||
@ -22,13 +20,27 @@ module.exports.create = function(config) {
 | 
			
		||||
			},
 | 
			
		||||
			json: true,
 | 
			
		||||
			form: form
 | 
			
		||||
		};
 | 
			
		||||
		return request(req).then(function(resp) {
 | 
			
		||||
			if (2 !== Math.floor(resp.statusCode / 100)) {
 | 
			
		||||
				console.error(resp.statusCode, req.url);
 | 
			
		||||
				console.error();
 | 
			
		||||
				console.error('Request:');
 | 
			
		||||
				console.error(req);
 | 
			
		||||
				console.error();
 | 
			
		||||
				console.error('Response:');
 | 
			
		||||
				console.error(resp.body);
 | 
			
		||||
				console.error();
 | 
			
		||||
				throw new Error('Error response. Check token, baseUrl, domains, etc.');
 | 
			
		||||
			}
 | 
			
		||||
			return resp;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var helpers = {
 | 
			
		||||
		getZonenames: function(/*opts*/) {
 | 
			
		||||
			// { dnsHosts: [ xxxx.foo.example.com ] }
 | 
			
		||||
			return api('GET', '/v2/domains/').then(function(resp) {
 | 
			
		||||
			return api('GET', '/').then(function(resp) {
 | 
			
		||||
				return resp.body.domains.map(function(x) {
 | 
			
		||||
					return x.name;
 | 
			
		||||
				});
 | 
			
		||||
@ -42,9 +54,7 @@ module.exports.create = function(config) {
 | 
			
		||||
			// Digital ocean provides the api to fetch records by ID. Since we do not have id, we fetch all the records,
 | 
			
		||||
			// filter the required TXT record
 | 
			
		||||
 | 
			
		||||
			return api('GET', '/v2/domains/' + data.zone + '/records').then(function(
 | 
			
		||||
				resp
 | 
			
		||||
			) {
 | 
			
		||||
			return api('GET', '/' + data.zone + '/records').then(function(resp) {
 | 
			
		||||
				resp = resp.body;
 | 
			
		||||
				var entries =
 | 
			
		||||
					resp &&
 | 
			
		||||
@ -58,6 +68,10 @@ module.exports.create = function(config) {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		init: function(opts) {
 | 
			
		||||
			request = opts.request;
 | 
			
		||||
			return null;
 | 
			
		||||
		},
 | 
			
		||||
		zones: function(data) {
 | 
			
		||||
			//console.info('Get zones');
 | 
			
		||||
			return helpers.getZonenames(data);
 | 
			
		||||
@ -67,7 +81,7 @@ module.exports.create = function(config) {
 | 
			
		||||
			var txt = ch.dnsAuthorization;
 | 
			
		||||
 | 
			
		||||
			// console.info('Adding TXT', data);
 | 
			
		||||
			return api('POST', '/v2/domains/' + ch.dnsZone + '/records', {
 | 
			
		||||
			return api('POST', '/' + ch.dnsZone + '/records', {
 | 
			
		||||
				type: 'TXT',
 | 
			
		||||
				name: ch.dnsPrefix,
 | 
			
		||||
				data: txt,
 | 
			
		||||
@ -93,12 +107,11 @@ module.exports.create = function(config) {
 | 
			
		||||
 | 
			
		||||
			return helpers.getTXTRecord(payload).then(function(txtRecord) {
 | 
			
		||||
				if (txtRecord) {
 | 
			
		||||
					var url =
 | 
			
		||||
						baseUrl + '/v2/domains/' + ch.dnsZone + '/records/' + txtRecord.id;
 | 
			
		||||
					var url = baseUrl + '/' + ch.dnsZone + '/records/' + txtRecord.id;
 | 
			
		||||
 | 
			
		||||
					return api(
 | 
			
		||||
						'DELETE',
 | 
			
		||||
						'/v2/domains/' + ch.dnsZone + '/records/' + txtRecord.id
 | 
			
		||||
						'/' + ch.dnsZone + '/records/' + txtRecord.id
 | 
			
		||||
					).then(function(resp) {
 | 
			
		||||
						resp = resp.body;
 | 
			
		||||
						return true;
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,6 @@
 | 
			
		||||
	"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
 | 
			
		||||
	"license": "MPL-2.0",
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
		"@root/request": "^1.3.11"
 | 
			
		||||
	},
 | 
			
		||||
	"devDependencies": {
 | 
			
		||||
		"acme-dns-01-test": "^3.2.0"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user