diff --git a/demo.js b/demo.js index dffb0c6..0a1d9ac 100644 --- a/demo.js +++ b/demo.js @@ -14,14 +14,8 @@ function initialize() { staging: true, cluster: true, - challenges: { - "dns-01": { - module: "acme-dns-01-digitalocean" - } - }, - notify: function(ev, params) { - console.log(ev, params); + console.info(ev, params); } }; return config; diff --git a/greenlock.js b/greenlock.js index e2eac2e..8efe4c9 100644 --- a/greenlock.js +++ b/greenlock.js @@ -9,33 +9,49 @@ module.exports.create = function(opts) { // TODO move to greenlock proper greenlock.getAcmeHttp01ChallengeResponse = function(opts) { - return greenlock.find({ servername: opts.servername }).then(function(sites) { - if (!sites.length) { - return null; - } - var site = sites[0]; - if (!site.challenges || !site.challenges["http-01"]) { - return null; - } + // TODO some sort of caching to prevent database hits? + return greenlock + ._config({ servername: opts.servername }) + .then(function(site) { + if (!site) { + return null; + } - var plugin; - try { - plugin = require(site.challenges["http-01"].module); - plugin = plugin.create(site.challenges["http-01"]); - } catch (e) { - console.error("error getting acme http-01 plugin"); - console.error(e); - return null; - } + // Hmm... this _should_ be impossible + if (!site.challenges || !site.challenges["http-01"]) { + return null; + } - return plugin.get(opts).then(function(result) { - // TODO is this the right way? - var ch = (result && result.challenge) || result || {}; - return { - keyAuthorization: ch.keyAuthorization - }; + return Greenlock._loadChallenge(site.challenges, "http-01"); + }) + .then(function(plugin) { + return plugin + .get({ + challenge: { + type: opts.type, + //hostname: opts.servername, + altname: opts.servername, + identifier: { value: opts.servername }, + token: opts.token + } + }) + .then(function(result) { + var keyAuth; + if (result) { + // backwards compat that shouldn't be dropped + // because new v3 modules had to do this to be + // backwards compatible with Greenlock v2.7 at + // the time. + if (result.challenge) { + result = challenge; + } + keyAuth = result.keyAuthorization; + } + return { + keyAuthorization: keyAuth + }; + }); }); - }); }; return greenlock; @@ -43,9 +59,9 @@ module.exports.create = function(opts) { function addGreenlockAgent(opts) { // Add greenlock as part of Agent, unless this is greenlock - if (!/^greenlock(-express|-pro)?/.test(opts.packageAgent)) { + if (!/greenlock(-express|-pro)?/i.test(opts.packageAgent)) { var pkg = require("./package.json"); - var packageAgent = pkg.name + "/" + pkg.version; + var packageAgent = "Greenlock_Express/" + pkg.version; opts.packageAgent += " " + packageAgent; } diff --git a/http-middleware.js b/http-middleware.js index 8f6efa3..2608f67 100644 --- a/http-middleware.js +++ b/http-middleware.js @@ -23,11 +23,15 @@ HttpMiddleware.create = function(gl, defaultApp) { var token = req.url.slice(challengePrefix.length); gl.getAcmeHttp01ChallengeResponse({ type: "http-01", servername: hostname, token: token }) - .then(function(result) { - respondWithGrace(res, result, hostname, token); - }) .catch(function(err) { respondToError(gl, res, err, "http_01_middleware_challenge_response", hostname); + return { __done: true }; + }) + .then(function(result) { + if (result && result.__done) { + return; + } + return respondWithGrace(res, result, hostname, token); }); }; }; diff --git a/master.js b/master.js index fdc45a9..b4e945a 100644 --- a/master.js +++ b/master.js @@ -75,7 +75,7 @@ Master._spawnWorkers = function(opts, greenlock) { } } - cluster.on("exit", function() { + cluster.once("exit", function() { setTimeout(function() { process.exit(3); }, 100); @@ -101,7 +101,7 @@ Master._spawnWorkers = function(opts, greenlock) { Master._spawnWorker = function(opts, greenlock) { var w = cluster.fork(); // automatically added to master's `cluster.workers` - w.on("exit", function(code, signal) { + w.once("exit", function(code, signal) { // TODO handle failures // Should test if the first starts successfully // Should exit if failures happen too quickly diff --git a/package-lock.json b/package-lock.json index c4f4f95..9d6b991 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@root/acme": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.6.tgz", - "integrity": "sha512-KfgwcyWDsT90vz+gmWbCwuOBolwV5Gcg0WHsG8/dznDC7a6QF4AmZsil7mIWKGJxHdi6MElkyrHZyK53OhPnug==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.8.tgz", + "integrity": "sha512-VmBvLvWdCDkolkanI9Dzm1ouSWPaAa2eCCwcDZcVQbWoNiUIOqbbd57fcMA/gZxLyuJPStD2WXFuEuSMPDxcww==", "requires": { "@root/encoding": "^1.0.1", "@root/keypairs": "^0.9.0", @@ -40,18 +40,18 @@ "integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" }, "@root/greenlock": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-3.0.1.tgz", - "integrity": "sha512-Hyrnw/gXgmM4Ml7l0SAwYQ1FAq685dwRXpp7zmOxZDieUGWwP+GUcXOrEefph/lpELWJ5igcPzdEkIGtjMCTww==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-3.0.5.tgz", + "integrity": "sha512-2fjtMRel/BDnxOhlIukcxdLjZSwmTSswwBKG8jvTYWwXsXMP5ef1YOdHYR7Vn6gFltaku0gBdE3ecG4KsV+g3A==", "requires": { - "@root/acme": "^3.0.6", + "@root/acme": "^3.0.8", "@root/csr": "^0.8.1", "@root/keypairs": "^0.9.0", "@root/mkdirp": "^1.0.0", "@root/request": "^1.3.10", - "acme-http-01-standalone": "^3.0.0", + "acme-http-01-standalone": "^3.0.5", "cert-info": "^1.5.1", - "greenlock-manager-fs": "^0.6.0", + "greenlock-manager-fs": "^0.6.2", "greenlock-store-fs": "^3.2.0", "safe-replace": "^1.1.0" } @@ -91,9 +91,9 @@ } }, "acme-http-01-standalone": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.0.tgz", - "integrity": "sha512-lZqVab2UZ1Dp36HemfhGEvdYOcVNg5wyVXNjtPUqGSAOVUOKqwi3gDrTGwqz+FBrEEEEpTngDPaZn2g3hfmPLA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz", + "integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg==" }, "cert-info": { "version": "1.5.1", @@ -106,9 +106,9 @@ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "greenlock-manager-fs": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-0.6.0.tgz", - "integrity": "sha512-o5RZ/T4j6eaUXCVnZ2dScE1pAjFuS8/R4ZDn7mCyRkxBjZvXJU7TpYe5Bc/wmN8x+gLHqVUECZWC6VdA/DbShQ==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-0.6.2.tgz", + "integrity": "sha512-hfQvrOsbSBffAe4dcZL2Aju4XQi3ePlGvwHcxOnIpqdxR8o/5ePNYAyvqwPFPt5iryHvRr7aMrPaA2CO2u3X6g==", "requires": { "@root/mkdirp": "^1.0.0", "safe-replace": "^1.1.0" diff --git a/package.json b/package.json index cd7debe..e906ce2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@root/greenlock-express", - "version": "3.0.0", + "version": "3.0.1", "description": "Free SSL and managed or automatic HTTPS for node.js with Express, Koa, Connect, Hapi, and all other middleware systems.", "main": "greenlock-express.js", "homepage": "https://greenlock.domains", @@ -17,7 +17,7 @@ "example": "examples" }, "dependencies": { - "@root/greenlock": "^3.0.1", + "@root/greenlock": "^3.0.5", "redirect-https": "^1.1.5" }, "trulyOptionalDependencies": { diff --git a/sni.js b/sni.js index 3feb283..069882c 100644 --- a/sni.js +++ b/sni.js @@ -118,26 +118,24 @@ sni.create = function(greenlock, secureOpts) { meta.refreshAt = Date.now() + randomRefreshOffset(); } - // TODO greenlock.get({ servername: servername }) // TODO don't get unknown certs at all, rely on auto-updates from greenlock - // Note: greenlock.renew() will return an existing fresh cert or issue a new one - return greenlock.renew({ servername: servername }).then(function(matches) { + // Note: greenlock.get() will return an existing fresh cert or issue a new one + return greenlock.get({ servername: servername }).then(function(result) { var meta = getCachedMeta(servername); if (!meta) { - meta = _cache[servername] = { secureContext: {} }; + meta = _cache[servername] = { secureContext: { _valid: false } }; } // prevent from being punked by bot trolls meta.refreshAt = Date.now() + smallStagger; // nothing to do - if (!matches.length) { + if (!result) { return null; } // we only care about the first one - var pems = matches[0].pems; - var site = matches[0].site; - var match = matches[0]; + var pems = result.pems; + var site = result.site; if (!pems || !pems.cert) { // nothing to do // (and the error should have been reported already) @@ -152,9 +150,10 @@ sni.create = function(greenlock, secureOpts) { cert: pems.cert + "\n" + pems.chain + "\n" }) }; + meta.secureContext._valid = true; // copy this same object into every place - [match.altnames || site.altnames || [match.subject || site.subject]].forEach(function(altname) { + (result.altnames || site.altnames || [result.subject || site.subject]).forEach(function(altname) { _cache[altname] = meta; }); diff --git a/worker.js b/worker.js index ede8b50..5f6a8fa 100644 --- a/worker.js +++ b/worker.js @@ -7,7 +7,7 @@ var msgPrefix = "greenlock:"; Worker.create = function() { var greenlock = {}; - ["getAcmeHttp01ChallengeResponse", "renew", "notify"].forEach(function(k) { + ["getAcmeHttp01ChallengeResponse", "get", "notify"].forEach(function(k) { greenlock[k] = function(args) { return rpc(k, args); }; @@ -40,10 +40,13 @@ function rpc(funcname, msg) { if (msg._id !== id) { return; } + process.removeListener("message", getResponse); clearTimeout(timeout); resolve(msg._result); } + // TODO keep a single listener than just responds + // via a collection of callbacks? or leave as is? process.on("message", getResponse); process.send({ _id: id,