diff --git a/master.js b/lib/master.js similarity index 100% rename from master.js rename to lib/master.js diff --git a/lib/sni-callback.js b/lib/sni-callback.js deleted file mode 100644 index d70b879..0000000 --- a/lib/sni-callback.js +++ /dev/null @@ -1,114 +0,0 @@ -'use strict'; - -// opts = { notBefore, notAfter, renew, register, httpsOptions } -module.exports.create = function (opts) { - - if (!opts.notBefore) { throw new Error("must supply options.notBefore (and options.notAfter)"); } - if (!opts.notAfter) { opts.notAfter = opts.notBefore - (3 * 24 * 60 * 60 * 1000); } - if (!opts.httpsOptions) { opts.httpOptions = {}; } - - - - - //opts.renewWithin = opts.notBefore; // i.e. 15 days - opts.renewWindow = opts.notBefore - opts.notAfter; // i.e. 1 day - //opts.renewRatio = opts.notBefore = opts.renewWindow; // i.e. 1/15 (6.67%) - - - - - var tls = require('tls'); - - - - - var snicb = { - - - - - // in-process cache - _ipc: {} - // just to account for clock skew - , _fiveMin: 5 * 60 * 1000 - - - - - // cache and format incoming certs - , cacheCerts: function (certs) { - var meta = { - certs: certs - , tlsContext: tls.createSecureContext({ - key: certs.privkey - , cert: certs.cert + certs.chain - , rejectUnauthorized: opts.httpsOptions.rejectUnauthorized - - , requestCert: opts.httpsOptions.requestCert // request peer verification - , ca: opts.httpsOptions.ca // this chain is for incoming peer connctions - , crl: opts.httpsOptions.crl // this crl is for incoming peer connections - }) - - , subject: certs.subject - // stagger renewal time by a little bit of randomness - , renewAt: (certs.expiresAt - (opts.notBefore - (opts.renewWindow * Math.random()))) - // err just barely on the side of safety - , expiresNear: certs.expiresAt - snicb._fiveMin - }; - - certs.altnames.forEach(function (domain) { - snicb._ipc[domain] = { subject: certs.subject }; - }); - snicb._ipc[certs.subject] = meta; - - return meta; - } - - - - - // automate certificate registration on request - , sniCallback: function (domain, cb) { - var certMeta = snicb._ipc[domain]; - var promise; - var now = Date.now(); - - if (certMeta && certMeta.subject !== domain) { - certMeta = snicb._ipc[domain]; - } - - if (!certMeta) { - // we don't have a cert and must get one - promise = opts.register(domain); - } - else if (now >= certMeta.expiresNear) { - // we have a cert, but it's no good for the average user - promise = opts.renew(domain, certMeta.certs); - } else { - - // we could stand to try to renew the cert - if (now >= certMeta.renewAt) { - // give the cert some time to be validated and replaced before trying again - certMeta.renewAt = Date.now() + (2 * 60 * 60 * 1000) + (3 * 60 * 60 * 1000 * Math.random()); - // let the update happen in the background - opts.renew(domain, certMeta.certs).then(snicb.cacheCerts); - } - - // return the valid cert right away - cb(null, certMeta.certs); - return; - } - - // promise the non-existent or expired cert - promise.then(snicb.cacheCerts).then(function (certMeta) { - cb(null, certMeta.tlsContext); - }, cb); - } - - - - - }; - - return snicb; -}; diff --git a/lib/worker.js b/lib/worker.js new file mode 100644 index 0000000..a62673a --- /dev/null +++ b/lib/worker.js @@ -0,0 +1,20 @@ +'use strict'; + +module.exports.create = function (opts) { + + opts.workerSniCallback = require('le-sni-auto').create({ + getCertificates: function (domain, certs, cb) { + opts.approveDomains(domain, certs, function (err, certs) { + process.send({ type: 'LE_REQUEST', domain: domain, certs: certs }); + + process.on('message', function (msg) { + if (msg.domain === domain) { + cb(msg.certs); + } + }); + }); + } + }).sniCallback; + + return opts; +};