107 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| '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);
 | |
| 	});
 | |
| }
 |