diff --git a/AUTHORS b/AUTHORS index f2496e6..6966d87 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ AJ ONeal (https://coolaj86.com/) +Hitesh Walia \ No newline at end of file diff --git a/example.env b/example.env deleted file mode 100644 index e053b84..0000000 --- a/example.env +++ /dev/null @@ -1,3 +0,0 @@ -ZONE=example.co.uk -USERNAME=johndoe -PASSWORD=xxxxxxxx diff --git a/lib/index.js b/lib/index.js index e25856a..4e62c9b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,29 +1,120 @@ 'use strict'; var request; -var defaults = {}; +var defaults = { + baseUrl: 'https://api.dnsimple.com/v2/' +}; + module.exports.create = function(config) { + var baseUrl = (config.baseUrl || defaults.baseUrl).replace(/\/$/, ''); + var token = config.token; + var account = config.account; + return { init: function(opts) { request = opts.request; return null; }, zones: function(data) { - //console.info('List Zones', data); - throw Error('listing zones not implemented'); + // console.info('List Zones', data); + return api('GET', '/' + account + '/zones') + .then(function(resp) { + return resp['body']['data'].map(function(elem) { + // console.log('DEBUG >>> elem.name: ' + elem.name); + return elem.name; + }); + }); + + }, set: function(data) { // console.info('Add TXT', data); - throw Error('setting TXT not implemented'); - }, - remove: function(data) { - // console.info('Remove TXT', data); - throw Error('removing TXT not implemented'); + var ch = data.challenge; + //console.log('DEBUG >>> ch: ' + JSON.stringify(ch, null, 2)); + var txt = ch.dnsAuthorization; + //console.log('DEBUG >>> txt: ' + txt); + + return api('POST', '/' + account + '/zones/' + ch.dnsZone + '/records', { + name: '', + type: 'TXT', + content: txt + }).then(function(resp) { + //console.log('DEBUG >>> resp: ' + JSON.stringify(resp, null, 2)); + + if (resp.statusCode === 201) { + return true; + } + throw new Error('record did not set. check subdomain, api key, etc'); + + }); }, get: function(data) { // console.info('List TXT', data); - throw Error('listing TXTs not implemented'); + + return api('GET', '/' + account + '/zones/' + data.challenge.dnsZone + '/records') + .then(function(resp) { + + var txtRecord = resp.body.data.filter(function (record) { + return data.challenge.dnsAuthorization === record.content; + })[0]; + + //console.log('DEBUG >>> txtRecord: ' + JSON.stringify(txtRecord,null,2)); + if(txtRecord) return { dnsAuthorization: txtRecord.content }; + else return null; + + }); + + }, + remove: function(data) { + + return api('GET', '/' + account + '/zones/' + data.challenge.dnsZone + '/records') + .then(function(resp) { + + var record = resp.body.data.filter(function (record) { + return data.challenge.dnsAuthorization === record.content; + })[0]; + + if(record) { + return api('DELETE', '/' + account + '/zones/' + data.challenge.dnsZone + '/records/' + record.id) + .then(function(resp) { + // console.info('DEBUG >>> resp: ', JSON.stringify(resp, null, 2)); + return true; + }); + } + else { + throw new Error('Txt Record not found for removal'); + } + }); } - }; + } + + // Authentication and Error handling here + function api(method, path, form) { + var req = { + method: method, + url: baseUrl + path, + headers: { + Authorization: 'Bearer ' + token, + 'Content-Type': 'application/json' + }, + 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; + }); + } + }; diff --git a/test.js b/test.js index a459da9..ca647ba 100755 --- a/test.js +++ b/test.js @@ -5,11 +5,12 @@ var tester = require('acme-challenge-test'); require('dotenv').config(); -// Usage: node ./test.js example.com username xxxxxxxxx +// Usage: node ./test.js example.com token account var zone = process.argv[2] || process.env.ZONE; + var challenger = require('./index.js').create({ - username: process.argv[3] || process.env.USERNAME, - password: process.argv[4] || process.env.PASSWORD + token: process.argv[3] || process.env.TOKEN, + account: process.argv[4] || process.env.ACCOUNT }); // The dry-run tests can pass on, literally, 'example.com'