'use strict'; var dns = require('dns'); var request = require('@root/request'); request = require('util').promisify(request); module.exports.create = function(config) { // config = { baseUrl, token, dnsWait } var authtoken = config.token; var dnsWait = config.dnsWait || 5000; var baseUrl = config.baseUrl || 'https://www.duckdns.org/update'; baseUrl = baseUrl.replace(/\/$/, ''); // return object containing get/set/remove functions return { init: function(opts) { // ignore return null; }, zones: function(opts) { // DuckDNS does not support listing zones return []; }, set: function(data) { var domain_name = data.challenge.identifier.value; var txt = data.challenge.dnsAuthorization; var url = baseUrl + '?domains=' + domain_name + '&token=' + authtoken + '&txt=' + txt; // console.log("adding txt", data); return request({ method: 'GET', url: url }).then(function(resp) { if (resp.body === 'OK') { return true; } console.error(resp.toJSON()); throw new Error( 'record did not set. check subdomain, api key, etc' ); }); }, remove: function(data) { var domain_name = data.challenge.identifier.value; var txt = data.challenge.dnsAuthorization; var url = baseUrl + '?domains=' + domain_name + '&token=' + authtoken + '&txt=' + txt + '&clear=true'; // console.log("removing txt"); return request({ method: 'GET', url: url }).then(function(resp) { if (resp.body === 'OK') { return true; } console.error(resp.toJSON()); throw new Error( "Couldn't remove record. Check subdomain, api key, etc" ); }); }, get: function(data) { // the duckdns doesnt provide an API to fetch DNS records so we are using Node DNS library to get TXT record. // We need to add manual delay as the DNS records do not get updated instantly. var domain_name = data.challenge.identifier.value; return delay(dnsWait).then(function() { // console.log('fetching txt', data); return new Promise(function(resolve, reject) { dns.resolveTxt(domain_name, function(err, txt) { if (err) { console.error(err); reject(null); } // console.log(txt); if (txt && txt[0] && txt[0][0]) { resolve({ dnsAuthorization: txt[0][0] }); } else { resolve(null); } }); }); }); } }; }; function delay(ms) { return new Promise(function(resolve) { setTimeout(resolve, ms); }); }