2016-08-10 03:32:39 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
module.exports.create = function (defaults) {
|
|
|
|
var handlers = {
|
|
|
|
getOptions: function () {
|
|
|
|
return defaults;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// set,get,remove challenges
|
|
|
|
//
|
|
|
|
// Note: this is fine for a one-off CLI tool
|
|
|
|
// but a webserver using node-cluster or multiple
|
|
|
|
// servers should use a database of some sort
|
|
|
|
, _challenges: {}
|
|
|
|
, set: function (args, domain, token, secret, cb) {
|
|
|
|
handlers._challenges[token] = secret;
|
|
|
|
cb(null);
|
|
|
|
}
|
|
|
|
, get: function (args, domain, token, cb) {
|
|
|
|
// TODO keep in mind that, generally get args are just args.domains
|
|
|
|
// and it is disconnected from the flow of setChallenge and removeChallenge
|
|
|
|
cb(null, handlers._challenges[token]);
|
|
|
|
}
|
|
|
|
, remove: function (args, domain, token, cb) {
|
|
|
|
delete handlers._challenges[token];
|
|
|
|
cb(null);
|
|
|
|
}
|
|
|
|
|
2019-05-16 07:26:21 +00:00
|
|
|
, loopback: function (defaults, domain, challenge, done) {
|
|
|
|
var hostname = domain + (defaults.loopbackPort ? ':' + defaults.loopbackPort : '');
|
|
|
|
var urlstr = 'http://' + hostname + '/.well-known/acme-challenge/' + key;
|
|
|
|
|
|
|
|
require('http').get(urlstr, function (res) {
|
|
|
|
if (200 !== res.statusCode) {
|
|
|
|
done(new Error("local loopback failed with statusCode " + res.statusCode));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var chunks = [];
|
|
|
|
res.on('data', function (chunk) {
|
|
|
|
chunks.push(chunk);
|
|
|
|
});
|
|
|
|
res.on('end', function () {
|
|
|
|
var str = Buffer.concat(chunks).toString('utf8').trim();
|
|
|
|
done(null, str);
|
|
|
|
});
|
|
|
|
}).setTimeout(defaults.loopbackTimeout, function () {
|
|
|
|
done(new Error("loopback timeout, could not reach server"));
|
|
|
|
}).on('error', function (err) {
|
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
, test: function (args, domain, challenge, keyAuthorization, done) {
|
|
|
|
var me = this;
|
|
|
|
var key = keyAuthorization || challenge;
|
|
|
|
|
|
|
|
me.set(args, domain, challenge, key, function (err) {
|
|
|
|
if (err) { done(err); return; }
|
|
|
|
|
|
|
|
myDefaults.loopbackPort = args.loopbackPort;
|
|
|
|
myDefaults.webrootPath = args.webrootPath;
|
|
|
|
me.loopback(args, domain, challenge, function (err, _key) {
|
|
|
|
if (err) { done(err); return; }
|
|
|
|
|
|
|
|
if (key !== _key) {
|
|
|
|
err = new Error("keyAuthorization [original] '" + key + "'"
|
|
|
|
+ " did not match [result] '" + _key + "'");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
me.remove(myDefaults, domain, challenge, function (_err) {
|
|
|
|
if (_err) { done(_err); return; }
|
|
|
|
|
|
|
|
done(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-10 03:32:39 +00:00
|
|
|
};
|
|
|
|
|
2019-05-16 07:26:21 +00:00
|
|
|
|
2016-08-10 03:32:39 +00:00
|
|
|
return handlers;
|
|
|
|
};
|