2019-06-07 05:32:22 +00:00
|
|
|
'use strict';
|
|
|
|
|
2019-06-29 08:33:19 +00:00
|
|
|
var dns = require('dns');
|
2019-06-07 05:32:22 +00:00
|
|
|
var request = require('@root/request');
|
|
|
|
request = require('util').promisify(request);
|
|
|
|
|
|
|
|
module.exports.create = function(config) {
|
2019-06-29 08:33:19 +00:00
|
|
|
// config = { baseUrl, token, dnsWait }
|
2019-06-07 05:32:22 +00:00
|
|
|
var authtoken = config.token;
|
2019-06-29 08:33:19 +00:00
|
|
|
var dnsWait = config.dnsWait || 5000;
|
|
|
|
var baseUrl = config.baseUrl || 'https://www.duckdns.org/update';
|
|
|
|
baseUrl = baseUrl.replace(/\/$/, '');
|
|
|
|
|
2019-06-07 05:32:22 +00:00
|
|
|
// return object containing get/set/remove functions
|
|
|
|
return {
|
2019-06-29 08:33:19 +00:00
|
|
|
init: function(opts) {
|
|
|
|
// ignore
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
zones: function(opts) {
|
|
|
|
// DuckDNS does not support listing zones
|
|
|
|
return [];
|
|
|
|
},
|
2019-06-07 05:32:22 +00:00
|
|
|
set: function(data) {
|
|
|
|
var domain_name = data.challenge.identifier.value;
|
|
|
|
var txt = data.challenge.dnsAuthorization;
|
|
|
|
var url =
|
|
|
|
baseUrl +
|
2019-06-29 08:33:19 +00:00
|
|
|
'?domains=' +
|
2019-06-07 05:32:22 +00:00
|
|
|
domain_name +
|
|
|
|
'&token=' +
|
|
|
|
authtoken +
|
|
|
|
'&txt=' +
|
|
|
|
txt;
|
|
|
|
|
|
|
|
// console.log("adding txt", data);
|
|
|
|
return request({
|
|
|
|
method: 'GET',
|
|
|
|
url: url
|
|
|
|
}).then(function(resp) {
|
2019-06-29 08:33:19 +00:00
|
|
|
if (resp.body === 'OK') {
|
2019-06-07 05:32:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-06-29 08:33:19 +00:00
|
|
|
console.error(resp.toJSON());
|
|
|
|
throw new Error(
|
|
|
|
'record did not set. check subdomain, api key, etc'
|
|
|
|
);
|
2019-06-07 05:32:22 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
remove: function(data) {
|
|
|
|
var domain_name = data.challenge.identifier.value;
|
|
|
|
var txt = data.challenge.dnsAuthorization;
|
|
|
|
var url =
|
|
|
|
baseUrl +
|
2019-06-29 08:33:19 +00:00
|
|
|
'?domains=' +
|
2019-06-07 05:32:22 +00:00
|
|
|
domain_name +
|
|
|
|
'&token=' +
|
|
|
|
authtoken +
|
|
|
|
'&txt=' +
|
|
|
|
txt +
|
|
|
|
'&clear=true';
|
|
|
|
|
|
|
|
// console.log("removing txt");
|
|
|
|
return request({
|
|
|
|
method: 'GET',
|
|
|
|
url: url
|
|
|
|
}).then(function(resp) {
|
2019-06-29 08:33:19 +00:00
|
|
|
if (resp.body === 'OK') {
|
2019-06-07 05:32:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
2019-06-29 08:33:19 +00:00
|
|
|
console.error(resp.toJSON());
|
|
|
|
throw new Error(
|
|
|
|
"Couldn't remove record. Check subdomain, api key, etc"
|
|
|
|
);
|
2019-06-07 05:32:22 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
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;
|
2019-06-29 08:33:19 +00:00
|
|
|
return delay(dnsWait).then(function() {
|
|
|
|
// console.log('fetching txt', data);
|
2019-06-07 05:32:22 +00:00
|
|
|
return new Promise(function(resolve, reject) {
|
2019-06-29 08:33:19 +00:00
|
|
|
dns.resolveTxt(domain_name, function(err, txt) {
|
2019-06-07 05:32:22 +00:00
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
reject(null);
|
|
|
|
}
|
|
|
|
// console.log(txt);
|
2019-06-29 08:33:19 +00:00
|
|
|
if (txt && txt[0] && txt[0][0]) {
|
2019-06-07 05:32:22 +00:00
|
|
|
resolve({ dnsAuthorization: txt[0][0] });
|
2019-06-29 08:33:19 +00:00
|
|
|
} else {
|
|
|
|
resolve(null);
|
|
|
|
}
|
2019-06-07 05:32:22 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
function delay(ms) {
|
2019-06-29 08:33:19 +00:00
|
|
|
return new Promise(function(resolve) {
|
|
|
|
setTimeout(resolve, ms);
|
|
|
|
});
|
2019-06-07 05:32:22 +00:00
|
|
|
}
|