greenlock-manager-test.js/tester.js

442 lines
13 KiB
JavaScript

"use strict";
var request = require("@root/request");
// For most tests
var siteSubject = "xx.com";
var siteAltname = "www.foo.xx.com";
var siteWildname = "*.xx.com";
var siteMatch = "foo.xx.com";
var domains = [siteSubject, siteAltname, siteWildname];
// Similar, but non-matching subjects
var noExistWild = "*.foo.xx.com";
var noExistAlt = "bar.xx.com";
// For wildcard-as-subject test
var siteWildnameNet = "*.xx.net";
var siteMatchNet = "foo.xx.net";
module.exports.test = async function(pkg, config) {
if ("function" !== typeof pkg.create) {
throw new Error(
"must have a create function that accepts a single options object"
);
}
var features = {
altnames: false,
wildcard: false,
renewal: false
};
var manager = pkg.create(config);
var initVal;
if (manager.init) {
initVal = await manager.init({
request: request
});
if (!initVal && initVal !== null) {
console.warn(
"WARN: `init()` returned `undefined`, but should return `null`"
);
}
}
console.info("PASS: init(deps)");
await manager.set({
subject: siteSubject,
altnames: domains
});
var site = await manager.get({
servername: siteSubject
// *.com is an invalid wildname
});
if (!site || site.subject !== siteSubject) {
throw new Error(
"set({ subject: '" +
siteSubject +
"'}), but could not `get()` or `find()` it"
);
}
//
// Test for altname support
//
site = await get({
servername: siteAltname,
wildname: untame(siteAltname)
});
if (site) {
if (site.subject !== siteSubject) {
throw new Error("found incorrect site");
}
features.altnames = true;
} else {
console.warn("WARN: Does not support altnames.");
console.warn(
" (searched for %s but did not find site '%s')",
siteAltname,
domains.join(" ")
);
}
//
// Test for wildcard support
//
if (features.altnames) {
// Set the wildcard as an altname
site = await get({
servername: siteMatch,
wildname: siteWildname
});
if (site) {
if (site.subject !== siteSubject) {
throw new Error(
"found %s when looking for %s",
site.subject,
siteSubject
);
}
features.wildcard = true;
} else {
console.warn("WARN: Does not support wildcard domains.");
console.warn(
" (searched for %s but did not find site %s)",
siteMatch,
siteSubject
);
}
}
// Set the wildcard as the subject
await manager.set({
subject: siteWildnameNet,
altnames: [siteWildnameNet]
});
site = await get({
servername: siteMatchNet,
wildname: siteWildnameNet
});
if (site) {
if (site.subject !== siteWildnameNet) {
throw new Error("found incorrect site");
}
features.wildcard = true;
} else {
if (features.wildcard) {
throw new Error(
"searched for wildcard subject " +
siteWildnameNet +
" but did not find it"
);
}
if (!features.altnames) {
console.warn(
"WARN: Does not support wildcard domains as certificate subjects."
);
console.warn(
" (searched for %s as %s but did not find site %s)",
siteMatchNet,
siteWildnameNet,
siteWildnameNet
);
}
}
await remove({ subject: siteWildnameNet });
var wasSet = false;
if (manager.find) {
await manager.find({}).then(function(results) {
if (!results.length) {
//console.error(results);
throw new Error("should have found all managed sites");
}
wasSet = results.some(function(site) {
return site.subject === siteSubject;
});
if (!wasSet) {
throw new Error("should have found " + siteSubject);
}
});
}
if (manager.get) {
await manager.get({ servername: siteSubject }).then(function(site) {
if (!site || site.subject !== siteSubject) {
throw new Error("should have found " + siteSubject);
}
wasSet = true;
});
if (features.altnames) {
wasSet = false;
await manager.get({ servername: siteAltname }).then(function(site) {
if (!site || site.subject !== siteSubject) {
throw new Error("should have found " + siteAltname);
}
});
await manager
.get({ servername: siteMatch, wildname: siteWildname })
.then(function(site) {
if (!site || site.subject !== siteSubject) {
throw new Error(
"did not find " +
siteMatch +
", which matches " +
siteWildname
);
}
wasSet = true;
});
}
console.info("PASS: get({ servername, wildname })");
} else {
console.info("[skip] get({ servername, wildname }) not implemented");
}
if (wasSet) {
console.info("PASS: set({ subject })");
} else {
throw new Error("neither `get()` nor `find()` was implemented");
}
if (manager.find) {
await manager.find({ subject: siteAltname }).then(function(results) {
if (results.length) {
console.error(results);
throw new Error(
"shouldn't find what doesn't exist, exactly, by subject"
);
}
});
await manager
.find({ servernames: [siteAltname], altnames: [siteAltname] })
.then(function(results) {
if (!results.length) {
console.error(results);
throw new Error("should have found sites matching altname");
}
});
console.info("PASS: find({ servernames, renewBefore })");
} else {
console.info(
"[skip] find({ servernames, renewBefore }) not implemented"
);
}
await remove({ subject: noExistWild }).then(function(result) {
if (result) {
console.error(siteWildname, result);
throw new Error(
"should not return prior object when deleting non-existing wildcard domain: " +
noExistWild
);
}
});
await remove({ subject: noExistAlt }).then(function(result) {
if (result) {
throw new Error(
"should not return prior object when deleting non-existing site: " +
noExistAlt
);
}
});
await remove({ subject: siteWildname }).then(function(result) {
if (result) {
throw new Error("should not delete by wildname: " + siteWildname);
}
});
await remove({ subject: siteAltname }).then(function(result) {
if (result) {
throw new Error("should not delete by altname: " + siteAltname);
}
});
await remove({ subject: siteSubject }).then(function(result) {
if (!result || !result.subject || !result.altnames) {
throw new Error("should return prior object when deleting site");
}
});
if (!manager.remove) {
console.info(
"[skip] remove() not implemented - using set({ deletedAt }) instead"
);
}
await manager.set({ subject: siteSubject, altnames: domains.slice(0, 2) });
if (manager.find) {
await manager
.find({ servernames: [noExistWild], altnames: [noExistWild] })
.then(function(results) {
if (results.length) {
console.error(results);
throw new Error(
"should only find an exact (literal) wildcard match"
);
}
});
}
await remove({ subject: siteSubject }).then(function(result) {
if (!result || !result.subject || !result.altnames) {
console.error(
"Could not find",
siteSubject,
"to delete it:",
result
);
throw new Error("should return prior object when deleting site");
}
});
if (manager.find) {
await manager
.find({ servernames: domains, altnames: domains })
.then(function(results) {
if (results.length) {
console.error(results);
throw new Error("should not find() deleted sites");
}
});
} else {
await get({ servername: siteAltname }).then(function(result) {
if (result) {
console.error(result);
throw new Error("should not get() deleted sites");
}
});
}
console.info("PASS: remove({ subject })");
var originalInput = {
serverKeyType: "RSA-2048",
accountKeyType: "P-256",
subscriberEmail: "jon@example.com",
agreeToTerms: true,
store: { module: "/path/to/store-module", foo: "foo" },
challenges: {
"http-01": { module: "/path/to/http-01-module", bar: "bar" },
"dns-01": { module: "/path/to/dns-01-module", baz: "baz" },
"tls-alpn-01": {
module: "/path/to/tls-alpn-01-module",
qux: "quux"
}
},
customerEmail: "jane@example.com"
};
//var backup = JSON.parse(JSON.stringify(originalInput));
var configUpdate = {
renewOffset: "45d",
renewStagger: "12h",
subscriberEmail: "pat@example.com"
};
var internalConfig;
if (manager.defaults) {
await manager.defaults().then(function(result) {
internalConfig = result;
if (!result) {
throw new Error(
"should at least return an empty object, perhaps one with some defaults set"
);
}
});
await manager.defaults(originalInput).then(function(result) {
// can't say much... what _should_ this return?
// probably nothing? or maybe the full config object?
if (internalConfig === result) {
console.warn(
"WARN: should return a new copy, not the same internal object"
);
}
if (originalInput === result) {
console.warn(
"WARN: should probably return a copy, not the original input"
);
}
});
await manager.defaults().then(function(result) {
if (originalInput === result) {
console.warn(
"WARN: should probably return a copy, not the prior input"
);
}
});
await manager.defaults(configUpdate).then(function() {
if (originalInput.renewOffset) {
console.warn("WARN: should probably modify the prior input");
}
});
console.info("PASS: defaults(conf)");
await manager.defaults().then(function(result) {
if (!result.subscriberEmail || !result.renewOffset) {
throw new Error("should merge config values together");
}
});
console.info("PASS: defaults()");
} else {
console.info(
"[skip] defaults({ store, challenges, ... }) not implemented"
);
}
features.renewal = !!manager.find;
var featureNames = {
altnames: "Multiple Domains per Certificate",
wildcard:
"Wildcard Certificates" +
(features.altnames ? "" : " (subject only)"),
renewal: "Fully Automatic Renewal"
};
return Object.keys(features).map(function(k) {
return {
name: k,
description: featureNames[k],
supported: features[k]
};
});
function get(opts) {
if (manager.get) {
opts.servername = opts.servername || opts.subject;
delete opts.subject;
return manager.get(opts);
} else {
return manager.find(opts);
}
}
function remove(opts) {
if (manager.remove) {
return manager.remove(opts);
} else {
return get(opts).then(function(site) {
// get matches servername, but remove should only match subject
if (site && site.subject === opts.servername) {
site.deletedAt = Date.now();
return manager.set(site).then(function() {
return site;
});
}
return null;
});
}
}
function untame(str) {
return (
"*." +
str
.split(".")
.slice(1)
.join(".")
);
}
};