acme-dns-01-cli.js/index.js

138 lines
4.5 KiB
JavaScript
Raw Normal View History

2016-09-07 20:58:25 +00:00
'use strict';
/*global Promise*/
2016-09-07 20:58:25 +00:00
var Challenge = module.exports;
// If your implementation needs config options, set them. Otherwise, don't bother (duh).
Challenge.create = function (config) {
var challenger = {};
// Note: normally you'd these right in the method body, but for the sake of
// "Table of Contents"-style documentation, I've pulled them out.
// Note: All of these methods can be synchronous, async, Promise, and callback-style
// (the calling functions check function.length and then Promisify accordingly)
// Called when it's tiem to set the challenge
challenger.set = function (opts, cb) {
return Challenge._setDns(opts, cb);
};
// Called when it's time to remove the challenge
challenger.remove = function (opts) {
return Challenge._removeDns(opts);
};
// Optional (only really useful for http)
// Called when the challenge needs to be retrieved
challenger.get = function (opts) {
return Challenge._getDns(opts);
2016-09-07 20:58:25 +00:00
};
// Whatever you assign to 'options' will be merged into the incoming 'opts' beforehand
// (for convenience, so you don't have to do the if (!x) { x = y; } dance)
// (also, some defaults are layered, so it's good to set it any that you have)
challenger.options = { debug: config.debug };
return challenger;
2016-09-07 20:58:25 +00:00
};
2016-10-15 02:08:21 +00:00
// Show the user the token and key and wait for them to be ready to continue
Challenge._setDns = function (args, cb) {
2019-04-04 16:35:06 +00:00
// if you need per-run / per-domain options set them in approveDomains() and they'll be on 'args' here.
2019-04-03 02:59:11 +00:00
if (!args.challenge) {
console.error("You must be using Greenlock v2.7+ to use le-challenge-dns v3+");
2019-04-03 02:59:11 +00:00
process.exit();
}
var ch = args.challenge;
console.info("");
console.info("[ACME dns-01 '" + ch.altname + "' CHALLENGE]");
console.info("You're about to receive the following DNS query:");
console.info("");
console.info("\tTXT\t" + ch.dnsHost + "\t" + ch.dnsAuthorization + "\tTTL 60");
console.info("");
if (ch.debug) {
console.info("Debug Info:");
2017-06-19 22:44:55 +00:00
console.info("");
console.info(JSON.stringify(dnsChallengeToJson(ch), null, ' ').replace(/^/gm, '\t'));
2017-06-19 22:44:55 +00:00
console.info("");
}
console.info("Go set that DNS record, wait a few seconds for it to propagate, and then continue when ready");
console.info("[Press the ANY key to continue...]");
process.stdin.resume();
process.stdin.once('data', function () {
process.stdin.pause();
cb(null);
});
2016-09-07 20:58:25 +00:00
};
// might as well tell the user that whatever they were setting up has been checked
Challenge._removeDns = function (args) {
var ch = args.challenge;
console.info("");
console.info("[ACME http-01 '" + ch.altname + "' COMPLETE]: " + ch.status);
console.info("Challenge complete. You may now remove the DNS-01 challenge record:");
console.info("");
console.info("\tTXT\t" + args.challenge.altname + "\t" + args.challenge.dnsAuthorization);
console.info("");
return null;
2016-09-07 20:58:25 +00:00
};
// This is implemented here for completeness (and perhaps some possible use in testing),
// but it's not something you would implement because the Greenlock server isn't the NameServer.
Challenge._getDns = function (args) {
var ch = args.challenge;
if (!Challenge._getCache[ch.altname + ':' + ch.token]) {
Challenge._getCache[ch.altname + ':' + ch.token] = true;
console.info("");
console.info("[ACME " + ch.type + " '" + ch.altname + "' REQUEST]: " + ch.status);
console.info("The '" + ch.type + "' challenge request has arrived!");
console.info('dig TXT ' + ch.dnsHost);
console.info("(paste in the \"DNS Authorization\" you received a moment ago to respond)");
process.stdout.write("> ");
}
return new Promise(function (resolve, reject) {
process.stdin.resume();
process.stdin.once('error', reject);
process.stdin.once('data', function (chunk) {
process.stdin.pause();
var result = chunk.toString('utf8');
try {
result = JSON.parse(result);
} catch(e) {
args.challenge.dnsAuthorization = result;
result = args.challenge;
}
if (result.dnsAuthorization) {
resolve(result);
return;
}
// The return value will checked. It must not be 'undefined'.
resolve(null);
});
});
2016-09-07 20:58:25 +00:00
};
function dnsChallengeToJson(ch) {
return {
type: ch.type
, altname: ch.altname
, identifier: ch.identifier
, wildcard: ch.wildcard
, expires: ch.expires
, token: ch.token
, thumbprint: ch.thumbprint
, keyAuthorization: ch.keyAuthorization
, dnsHost: ch.dnsHost
, dnsAuthorization: ch.dnsAuthorization
};
}