'use strict'; var request = require('@root/request'); request = require('util').promisify(request); var dns = require('dns'); module.exports.create = function(config) { // config = { baseUrl, token, apiTimeout } var baseUrl = config.baseUrl || 'https://www.duckdns.org'; var authtoken = config.token; var apiTimeout = config.apiTimeout || 5000; // return object containing get/set/remove functions return { set: function(data) { var domain_name = data.challenge.identifier.value; var txt = data.challenge.dnsAuthorization; var url = baseUrl + '/update?domains=' + domain_name + '&token=' + authtoken + '&txt=' + txt; // console.log("adding txt", data); return request({ method: 'GET', url: url }).then(function(resp) { if (resp === 'OK') { return true; } 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 + '/update?domains=' + domain_name + '&token=' + authtoken + '&txt=' + txt + '&clear=true'; // console.log("removing txt"); return request({ method: 'GET', url: url }).then(function(resp) { if (resp === 'OK') { return true; } throw new Error('Couldnt 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(apiTimeout).then(function() { console.log('fetching txt', data); return new Promise(function(resolve, reject) { dns.resolveTxt(domain_name, (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(resolve => setTimeout(resolve, ms)); }