initial commit
This commit is contained in:
commit
ed4a83d788
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"printWidth": 80,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": true
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
# [acme-dns-01-duckdns](https://git.rootprojects.org/root/acme-dns-01-duckdns) | a [Root](https://rootrpojects.org) project
|
||||||
|
|
||||||
|
DuckDNS for Let's Encrypt / ACME dns-01 challenges with ACME.js and Greenlock.js (Node.js).
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
|
||||||
|
```
|
||||||
|
# node ./test.js domain-zone api-token
|
||||||
|
node ./test.js example.com xxxxxx
|
||||||
|
```
|
|
@ -0,0 +1,3 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = require('./lib/index.js');
|
|
@ -0,0 +1,87 @@
|
||||||
|
'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));
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "acme-dns-01-duckdns",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"description": "DuckDNS for Let's Encrypt / ACME dns-01 challenges with ACME.js and Greenlock.js",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node ./test.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.rootprojects.org/root/acme-dns-01-duckdns.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"duckdns",
|
||||||
|
"duck",
|
||||||
|
"dns",
|
||||||
|
"dns-01",
|
||||||
|
"letsencrypt",
|
||||||
|
"acme",
|
||||||
|
"greenlock"
|
||||||
|
],
|
||||||
|
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@root/request": "^1.3.11"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"acme-challenge-test": "^3.1.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// See https://git.coolaj86.com/coolaj86/acme-challenge-test.js
|
||||||
|
var tester = require('acme-challenge-test');
|
||||||
|
|
||||||
|
// Usage: node ./test.js example.com xxxxxxxxx
|
||||||
|
var zone = process.argv[2];
|
||||||
|
var challenger = require('./index.js').create({
|
||||||
|
token: process.argv[3]
|
||||||
|
});
|
||||||
|
|
||||||
|
// The dry-run tests can pass on, literally, 'example.com'
|
||||||
|
// but the integration tests require that you have control over the domain
|
||||||
|
tester
|
||||||
|
.testZone('dns-01', zone, challenger)
|
||||||
|
.then(function() {
|
||||||
|
console.info('PASS', zone);
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
|
console.error(e.message);
|
||||||
|
console.error(e.stack);
|
||||||
|
});
|
Loading…
Reference in New Issue