AJ ONeal c8b895633c Fix regression with set challenges being ignored
Backwards compatibility madness.
When you Greenlock.create({ }), challenges will be set by default if
not available.  This is good... ish.

When you approveDomains() and set opts.challenges, however, those must
be able to override the defaults.

This was just recently broken and the fix seems to be to make the prior
defaults inaccessible, otherwise it becomes really confusing as to why
a set DNS challenge for local, wild, or private domains is not being
preferred to the (failing) http.

All this crap will be cleaned up in v3...
2019-06-14 03:21:03 -06:00

158 lines
3.8 KiB
JavaScript

'use strict';
require('./compat.js');
var path = require('path');
var homeRe = new RegExp("^~(\\/|\\\\|\\" + path.sep + ")");
// very basic check. Allows *.example.com.
var re = /^(\*\.)?[a-zA-Z0-9\.\-]+$/;
var punycode = require('punycode');
var dnsResolveMxAsync = require('util').promisify(require('dns').resolveMx);
module.exports.attachCertInfo = function (results) {
var certInfo = require('cert-info').info(results.cert);
// subject, altnames, issuedAt, expiresAt
Object.keys(certInfo).forEach(function (key) {
results[key] = certInfo[key];
});
return results;
};
module.exports.certHasDomain = function (certInfo, _domain) {
var names = (certInfo.altnames || []).slice(0);
names.push(certInfo.subject);
return names.some(function (name) {
var domain = _domain.toLowerCase();
name = name.toLowerCase();
if ('*.' === name.substr(0, 2)) {
name = name.substr(2);
domain = domain.split('.').slice(1).join('.');
}
return name === domain;
});
};
module.exports.isValidDomain = function (domain) {
if (re.test(domain)) {
return domain;
}
domain = punycode.toASCII(domain);
if (re.test(domain)) {
return domain;
}
return '';
};
module.exports.merge = function (/*defaults, args*/) {
var allDefaults = Array.prototype.slice.apply(arguments);
var args = allDefaults.shift();
var copy = {};
allDefaults.forEach(function (defaults) {
Object.keys(defaults).forEach(function (key) {
/*
if ('challenges' === key && copy[key] && defaults[key]) {
Object.keys(defaults[key]).forEach(function (k) {
copy[key][k] = defaults[key][k];
});
} else {
copy[key] = defaults[key];
}
*/
copy[key] = defaults[key];
});
});
Object.keys(args).forEach(function (key) {
/*
if ('challenges' === key && copy[key] && args[key]) {
Object.keys(args[key]).forEach(function (k) {
copy[key][k] = args[key][k];
});
} else {
copy[key] = args[key];
}
*/
copy[key] = args[key];
});
return copy;
};
module.exports.tplCopy = function (copy) {
var homedir = require('os').homedir();
var tplKeys;
copy.hostnameGet = function (copy) {
return copy.subject || (copy.domains || [])[0] || copy.domain;
};
Object.keys(copy).forEach(function (key) {
var newName;
if (!/Get$/.test(key)) {
return;
}
newName = key.replace(/Get$/, '');
copy[newName] = copy[newName] || copy[key](copy);
});
tplKeys = Object.keys(copy);
tplKeys.sort(function (a, b) {
return b.length - a.length;
});
tplKeys.forEach(function (key) {
if ('string' !== typeof copy[key]) {
return;
}
copy[key] = copy[key].replace(homeRe, homedir + path.sep);
});
tplKeys.forEach(function (key) {
if ('string' !== typeof copy[key]) {
return;
}
tplKeys.forEach(function (tplname) {
if (!copy[tplname]) {
// what can't be templated now may be templatable later
return;
}
copy[key] = copy[key].replace(':' + tplname, copy[tplname]);
});
});
return copy;
};
module.exports.testEmail = function (email) {
var parts = (email||'').split('@');
var err;
if (2 !== parts.length || !parts[0] || !parts[1]) {
err = new Error("malformed email address '" + email + "'");
err.code = 'E_EMAIL';
return Promise.reject(err);
}
return dnsResolveMxAsync(parts[1]).then(function (records) {
// records only returns when there is data
if (!records.length) {
throw new Error("sanity check fail: success, but no MX records returned");
}
return email;
}, function (err) {
if ('ENODATA' === err.code) {
err = new Error("no MX records found for '" + parts[1] + "'");
err.code = 'E_EMAIL';
return Promise.reject(err);
}
});
};