diff --git a/README.md b/README.md index 9c0da88..ac3294b 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,31 @@ # [acme-dns-01-gandi.js](https://git.rootprojects.org/root/acme-dns-01-gandi.js) | a [Root](https://rootprojects.org/) project ###### Gandi LiveDNS + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js + ###### This handles ACME dns-01 challenges, compatible with ACME.js and Greenlock.js. Passes acme-dns-01-test. # Features -* Compatible - * Let’s Encrypt v2.1 / ACME draft 18 (2019) - * Gandi.net LiveDNS API - * ACME.js, Greenlock.js, and others -* Quality - * node v6 compatible VanillaJS - * < 150 lines of code - * Zero Dependencies - + +- Compatible + - Let’s Encrypt v2.1 / ACME draft 18 (2019) + - Gandi.net LiveDNS API + - ACME.js, Greenlock.js, and others +- Quality + - node v6 compatible VanillaJS + - < 150 lines of code + - Zero Dependencies + # Install + `npm install --save acme-dns-01-gandi` Generate Gandi LiveDNS API Token: -* Login to your account at: https://account.gandi.net/ -* Under the Security section, click the link next to 'Production API key' to generate a token. +- Login to your account at: https://account.gandi.net/ +- Under the Security section, click the link next to 'Production API key' to generate a token. # Usage + First you create an instance with your credentials: ``` @@ -30,9 +34,11 @@ var dns01 = require('acme-dns-01-gandi').create({ token: 'xxxx' }); ``` + Then you can use it with any compatible ACME library, such as Greenlock.js or ACME.js. ## Greenlock.js + ``` var Greenlock = require('greenlock-express'); var greenlock = Greenlock.create({ @@ -42,6 +48,7 @@ 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. ## ACME.js @@ -55,13 +62,14 @@ See [Greenlock Express](https://git.rootprojects.org/root/greenlock-express.js) 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)``` +- `init(config)` +- `zones(opts)` +- `set(opts)` +- `get(opts)` +- `remove(opts)` ``` dns01 @@ -79,19 +87,24 @@ dns01 console.log('Failed to set TXT record'); }); ``` + See acme-dns-01-test for more implementation details. # Tests + ``` # node ./test.js domain-zone api-token node ./test.js example.com xxxxxx ``` + # Authors -* Jarom Bridges -* AJ ONeal -See AUTHORS for contact info. + +- Jarom Bridges +- AJ ONeal + See AUTHORS for contact info. # Legal + [acme-dns-01-gandi.js](https://git.coolaj86.com/coolaj86/acme-dns-01-gandi.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 \ No newline at end of file +Copyright 2019 The Root Group LLC diff --git a/lib/index.js b/lib/index.js index 4e61b42..a0d57ec 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,18 +4,18 @@ var defaults = { baseUrl: 'https://dns.api.gandi.net/api/v5/' }; -module.exports.create = function (config) { +module.exports.create = function(config) { var baseUrl = (config.baseUrl || defaults.baseUrl).replace(/\/$/, ''); var authtoken = config.token; var request; return { - init: function (opts) { + init: function(opts) { request = opts.request; return null; }, - zones: function (opts) { + zones: function(opts) { console.log(opts); return request({ @@ -25,97 +25,130 @@ module.exports.create = function (config) { 'X-Api-Key': authtoken }, json: true - }).then(function (resp) { - return resp.body.map(function (zone) { + }).then(function(resp) { + return resp.body.map(function(zone) { return zone.name; - });; - });; + }); + }); }, - set: function (opts) { + set: function(opts) { console.log(opts); return request({ method: 'GET', - url: baseUrl + '/domains/' + opts.challenge.dnsZone + '/records/' + opts.challenge.dnsPrefix + '/TXT', + url: + baseUrl + + '/domains/' + + opts.challenge.dnsZone + + '/records/' + + opts.challenge.dnsPrefix + + '/TXT', headers: { 'X-Api-Key': authtoken }, json: true - }).then(function (resp) { + }).then(function(resp) { if (resp.body.cause === 'Not Found') { return request({ method: 'POST', - url: baseUrl + '/domains/' + opts.challenge.dnsZone + '/records', + url: + baseUrl + + '/domains/' + + opts.challenge.dnsZone + + '/records', headers: { 'X-Api-Key': authtoken }, json: { - 'rrset_name': opts.challenge.dnsPrefix, - 'rrset_type': 'TXT', - 'rrset_ttl': 300, - 'rrset_values': [opts.challenge.dnsAuthorization] + rrset_name: opts.challenge.dnsPrefix, + rrset_type: 'TXT', + rrset_ttl: 300, + rrset_values: [opts.challenge.dnsAuthorization] } - }) + }); } else { - const body = resp.body - let value = body.rrset_values.map(x => JSON.parse(x)) + const body = resp.body; + let value = body.rrset_values.map(x => JSON.parse(x)); if (body.rrset_values) { return request({ method: 'PUT', - url: baseUrl + '/domains/' + opts.challenge.dnsZone + '/records/' + opts.challenge.dnsPrefix + '/TXT', + url: + baseUrl + + '/domains/' + + opts.challenge.dnsZone + + '/records/' + + opts.challenge.dnsPrefix + + '/TXT', headers: { 'X-Api-Key': authtoken }, json: { - 'rrset_ttl': 300, - 'rrset_values': value.concat([opts.challenge.dnsAuthorization]) + rrset_ttl: 300, + rrset_values: value.concat([ + opts.challenge.dnsAuthorization + ]) } - }) + }); } } - });; + }); }, - remove: function (opts) { + remove: function(opts) { console.log(opts); return request({ method: 'DELETE', - url: baseUrl + '/domains/' + opts.challenge.dnsZone + '/records/' + opts.challenge.dnsPrefix + '/TXT', + url: + baseUrl + + '/domains/' + + opts.challenge.dnsZone + + '/records/' + + opts.challenge.dnsPrefix + + '/TXT', headers: { 'X-Api-Key': authtoken }, json: true - }) + }); }, - get: function (opts) { + get: function(opts) { console.log(opts); return request({ method: 'GET', - url: baseUrl + '/domains/' + opts.challenge.dnsZone + '/records/' + opts.challenge.dnsPrefix, + url: + baseUrl + + '/domains/' + + opts.challenge.dnsZone + + '/records/' + + opts.challenge.dnsPrefix, headers: { 'X-Api-Key': authtoken }, json: true - }).then(function (resp) { - const body = resp.body + }).then(function(resp) { + const body = resp.body; if (body.length > 0) { - let value = body[0].rrset_values.map(x => JSON.parse(x)).filter(field => field === opts.challenge.dnsAuthorization) + let value = body[0].rrset_values + .map(x => JSON.parse(x)) + .filter( + field => field === opts.challenge.dnsAuthorization + ); if (value !== []) { return { dnsAuthorization: value[0] - } + }; } else { - return null + return null; } } else { - return null + return null; } - }) + }); } - } -}; \ No newline at end of file + }; +}; diff --git a/package.json b/package.json index 25d746e..1542047 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,27 @@ { - "name": "acme-dns-01-gandi", - "version": "0.0.1", - "description": "Gandi + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js", - "main": "index.js", - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "https://git.coolaj86.com/coolaj86/acme-dns-01-gandi.js.git" - }, - "keywords": [ - "digitalocean", - "digital-ocean", - "dns", - "dns-01", - "letsencrypt", - "acme", - "greenlock" - ], - "author": "AJ ONeal (https://coolaj86.com/)", - "license": "MPL-2.0", - "devDependencies": { - "dotenv": "^8.0.0" - } + "name": "acme-dns-01-gandi", + "version": "0.0.1", + "description": "Gandi + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js", + "main": "index.js", + "scripts": { + "test": "node test.js" + }, + "repository": { + "type": "git", + "url": "https://git.coolaj86.com/coolaj86/acme-dns-01-gandi.js.git" + }, + "keywords": [ + "digitalocean", + "digital-ocean", + "dns", + "dns-01", + "letsencrypt", + "acme", + "greenlock" + ], + "author": "AJ ONeal (https://coolaj86.com/)", + "license": "MPL-2.0", + "devDependencies": { + "dotenv": "^8.0.0" + } }