@root/greenlock
Advanced tools
Comparing version 3.0.1 to 3.0.2
@@ -181,3 +181,3 @@ 'use strict'; | ||
// trim leading and trailing '-' | ||
bag = bag.replace(/^-+/g, '').replace(/-+$/g, '') | ||
bag = bag.replace(/^-+/g, '').replace(/-+$/g, ''); | ||
return toCamel(bag) + 'Opts'; // '--bag-option-' => bagOptionOpts | ||
@@ -184,0 +184,0 @@ } |
@@ -7,4 +7,4 @@ #!/usr/bin/env node | ||
if ('certonly' === args[0]) { | ||
require('./certonly.js'); | ||
return; | ||
require('./certonly.js'); | ||
return; | ||
} |
@@ -59,52 +59,39 @@ 'use strict'; | ||
return C._check(gnlck, mconf, db, args).then(function(pems) { | ||
// No pems? get some! | ||
if (!pems) { | ||
return C._rawOrder( | ||
gnlck, | ||
mconf, | ||
db, | ||
acme, | ||
chs, | ||
acc, | ||
email, | ||
args | ||
).then(function(newPems) { | ||
// do not wait on notify | ||
gnlck._notify('cert_issue', { | ||
options: args, | ||
subject: args.subject, | ||
altnames: args.altnames, | ||
account: acc, | ||
email: email, | ||
pems: newPems | ||
}); | ||
return newPems; | ||
}); | ||
} | ||
// Nice and fresh? We're done! | ||
if (!C._isStale(gnlck, mconf, args, pems)) { | ||
// return existing unexpired (although potentially stale) certificates when available | ||
// there will be an additional .renewing property if the certs are being asynchronously renewed | ||
//pems._type = 'current'; | ||
return pems; | ||
if (pems) { | ||
if (!C._isStale(gnlck, mconf, args, pems)) { | ||
// return existing unexpired (although potentially stale) certificates when available | ||
// there will be an additional .renewing property if the certs are being asynchronously renewed | ||
//pems._type = 'current'; | ||
return pems; | ||
} | ||
} | ||
// Getting stale? Let's renew to freshen up! | ||
var p = C._rawOrder(gnlck, mconf, db, acme, chs, acc, email, args).then( | ||
function(renewedPems) { | ||
// do not wait on notify | ||
gnlck._notify('cert_renewal', { | ||
options: args, | ||
subject: args.subject, | ||
altnames: args.altnames, | ||
account: acc, | ||
email: email, | ||
pems: renewedPems | ||
}); | ||
return renewedPems; | ||
// We're either starting fresh or freshening up... | ||
var p = C._rawOrder(gnlck, mconf, db, acme, chs, acc, email, args); | ||
var evname = pems ? 'cert_renewal' : 'cert_issue'; | ||
p.then(function(newPems) { | ||
// notify in the background | ||
var renewAt = C._renewableAt(gnlck, mconf, args, newPems); | ||
gnlck._notify(evname, { | ||
renewAt: renewAt, | ||
subject: args.subject, | ||
altnames: args.altnames | ||
}); | ||
}).catch(function(err) { | ||
if (!err.context) { | ||
err.context = evname; | ||
} | ||
); | ||
err.subject = args.subject; | ||
err.altnames = args.altnames; | ||
gnlck._notify('error', err); | ||
}); | ||
// TODO what should this be? | ||
// No choice but to hang tight and wait for it | ||
if (!pems) { | ||
return p; | ||
} | ||
// Wait it out | ||
// TODO should we call this waitForRenewal? | ||
if (args.waitForRenewal) { | ||
@@ -114,2 +101,3 @@ return p; | ||
// Let the certs renew in the background | ||
return pems; | ||
@@ -182,2 +170,11 @@ }); | ||
.then(function(pems) { | ||
var renewAt = C._renewableAt(gnlck, mconf, args, pems); | ||
gnlck._notify('_cert_issue', { | ||
renewAt: renewAt, | ||
subject: args.subject, | ||
altnames: args.altnames, | ||
pems: pems | ||
}); | ||
if (kresult.exists) { | ||
@@ -184,0 +181,0 @@ return pems; |
267
greenlock.js
@@ -68,2 +68,3 @@ 'use strict'; | ||
greenlock.manager = Manager.create(defaults); | ||
//console.log('debug greenlock.manager', Object.keys(greenlock.manager)); | ||
greenlock._init = function() { | ||
@@ -74,3 +75,3 @@ var p; | ||
}; | ||
p = greenlock.manager.config().then(function(conf) { | ||
p = greenlock.manager.defaults().then(function(conf) { | ||
var changed = false; | ||
@@ -86,3 +87,3 @@ if (!conf.challenges) { | ||
if (changed) { | ||
return greenlock.manager.config(conf); | ||
return greenlock.manager.defaults(conf); | ||
} | ||
@@ -160,2 +161,22 @@ }); | ||
var mng = greenlock.manager; | ||
if ('_' === String(ev)[0]) { | ||
if ('_cert_issue' === ev) { | ||
try { | ||
mng.update({ | ||
subject: params.subject, | ||
renewAt: params.renewAt | ||
}).catch(function(e) { | ||
e.context = '_cert_issue'; | ||
greenlock._notify('error', e); | ||
}); | ||
} catch (e) { | ||
e.context = '_cert_issue'; | ||
greenlock._notify('error', e); | ||
} | ||
} | ||
// trap internal events internally | ||
return; | ||
} | ||
if (mng.notify || greenlock._defaults.notify) { | ||
@@ -200,2 +221,3 @@ try { | ||
UserEvents.notify({ | ||
/* | ||
// maintainer should be only on pre-publish, or maybe install, I think | ||
@@ -205,3 +227,3 @@ maintainerEmail: greenlock._defaults._maintainerEmail, | ||
version: greenlock._defaults._maintainerPackageVersion, | ||
action: params.pems._type, | ||
//action: params.pems._type, | ||
domains: params.altnames, | ||
@@ -212,2 +234,3 @@ subscriberEmail: greenlock._defaults._subscriberEmail, | ||
telemetry: greenlock._defaults.telemetry | ||
*/ | ||
}); | ||
@@ -217,5 +240,89 @@ } | ||
greenlock._single = function(args) { | ||
if (!args.servername) { | ||
return Promise.reject(new Error('no servername given')); | ||
} | ||
if ( | ||
args.servernames || | ||
args.subject || | ||
args.renewBefore || | ||
args.issueBefore || | ||
args.expiresBefore | ||
) { | ||
return Promise.reject( | ||
new Error( | ||
'bad arguments, did you mean to call greenlock.renew()?' | ||
) | ||
); | ||
} | ||
// duplicate, force, and others still allowed | ||
return Promise.resolve(args); | ||
}; | ||
greenlock.get = function(args) { | ||
return greenlock | ||
._single(args) | ||
.then(function() { | ||
args._includePems = true; | ||
return greenlock.renew(args); | ||
}) | ||
.then(function(results) { | ||
if (!results || !results.length) { | ||
return null; | ||
} | ||
// just get the first one | ||
var result = results[0]; | ||
// (there should be only one, ideally) | ||
if (results.length > 1) { | ||
var err = new Error( | ||
"a search for '" + | ||
args.servername + | ||
"' returned multiple certificates" | ||
); | ||
err.context = 'duplicate_certs'; | ||
err.servername = args.servername; | ||
err.subjects = results.map(function(r) { | ||
return (r.site || {}).subject || 'N/A'; | ||
}); | ||
greenlock._notify('warning', err); | ||
} | ||
if (result.error) { | ||
return Promise.reject(result.error); | ||
} | ||
// site for plugin options, such as http-01 challenge | ||
// pems for the obvious reasons | ||
return result; | ||
}); | ||
}; | ||
greenlock._config = function(args) { | ||
return greenlock | ||
._single(args) | ||
.then(function() { | ||
return greenlock.manager.find(args); | ||
}) | ||
.then(function(sites) { | ||
if (!sites || !sites.length) { | ||
return null; | ||
} | ||
var site = sites[0]; | ||
site = JSON.parse(JSON.stringify(site)); | ||
if (!site.store) { | ||
site.store = greenlock._defaults.store; | ||
} | ||
if (!site.challenges) { | ||
site.challenges = greenlock._defaults.challenges; | ||
} | ||
return site; | ||
}); | ||
}; | ||
// needs to get info about the renewal, such as which store and challenge(s) to use | ||
greenlock.renew = function(args) { | ||
return greenlock.manager.config().then(function(mconf) { | ||
return greenlock.manager.defaults().then(function(mconf) { | ||
return greenlock._renew(mconf, args); | ||
@@ -237,11 +344,12 @@ }); | ||
if (args.domain) { | ||
if (args.servername) { | ||
// this doesn't have to be the subject, it can be anything | ||
// however, not sure how useful this really is... | ||
args.domain = args.toLowerCase(); | ||
args.servername = args.servername.toLowerCase(); | ||
} | ||
args.defaults = greenlock.defaults; | ||
//console.log('greenlock._renew find', args); | ||
return greenlock.manager.find(args).then(function(sites) { | ||
// Note: the manager must guaranteed that these are mutable copies | ||
//console.log('greenlock._renew found', sites); | ||
@@ -256,5 +364,3 @@ var renewedOrFailed = []; | ||
var order = { | ||
site: site | ||
}; | ||
var order = { site: site }; | ||
renewedOrFailed.push(order); | ||
@@ -265,7 +371,12 @@ // TODO merge args + result? | ||
.then(function(pems) { | ||
order.pems = pems; | ||
if (args._includePems) { | ||
order.pems = pems; | ||
} | ||
}) | ||
.catch(function(err) { | ||
order.error = err; | ||
// For greenlock express serialization | ||
err.toJSON = errorToJSON; | ||
err.context = err.context || 'cert_order'; | ||
err.subject = site.subject; | ||
@@ -276,3 +387,3 @@ if (args.servername) { | ||
// for debugging, but not to be relied on | ||
err._order = order; | ||
err._site = site; | ||
// TODO err.context = err.context || 'renew_certificate' | ||
@@ -327,3 +438,3 @@ greenlock._notify('error', err); | ||
return greenlock._init().then(function() { | ||
return greenlock.manager.config().then(function(mconf) { | ||
return greenlock.manager.defaults().then(function(mconf) { | ||
return greenlock._order(mconf, args); | ||
@@ -334,10 +445,6 @@ }); | ||
greenlock._order = function(mconf, args) { | ||
// packageAgent, maintainerEmail | ||
return greenlock._acme(args).then(function(acme) { | ||
var storeConf = args.store || greenlock._defaults.store; | ||
return P._load(storeConf.module).then(function(plugin) { | ||
var store = Greenlock._normalizeStore( | ||
storeConf.module, | ||
plugin.create(storeConf) | ||
); | ||
return P._loadStore(storeConf).then(function(store) { | ||
return A._getOrCreate( | ||
@@ -356,13 +463,3 @@ greenlock, | ||
Object.keys(challengeConfs).map(function(typ01) { | ||
var chConf = challengeConfs[typ01]; | ||
return P._load(chConf.module).then(function( | ||
plugin | ||
) { | ||
var ch = Greenlock._normalizeChallenge( | ||
chConf.module, | ||
plugin.create(chConf) | ||
); | ||
ch._type = typ01; | ||
return ch; | ||
}); | ||
return P._loadChallenge(challengeConfs, typ01); | ||
}) | ||
@@ -408,2 +505,4 @@ ).then(function(arr) { | ||
G._loadChallenge = P._loadChallenge; | ||
G._defaults = function(opts) { | ||
@@ -522,110 +621,2 @@ var defaults = {}; | ||
Greenlock._normalizeStore = function(name, store) { | ||
var acc = store.accounts; | ||
var crt = store.certificates; | ||
var warned = false; | ||
function warn() { | ||
if (warned) { | ||
return; | ||
} | ||
warned = true; | ||
console.warn( | ||
"'" + | ||
name + | ||
"' may have incorrect function signatures, or contains deprecated use of callbacks" | ||
); | ||
} | ||
// accs | ||
if (acc.check && 2 === acc.check.length) { | ||
warn(); | ||
acc._thunk_check = acc.check; | ||
acc.check = promisify(acc._thunk_check); | ||
} | ||
if (acc.set && 3 === acc.set.length) { | ||
warn(); | ||
acc._thunk_set = acc.set; | ||
acc.set = promisify(acc._thunk_set); | ||
} | ||
if (2 === acc.checkKeypair.length) { | ||
warn(); | ||
acc._thunk_checkKeypair = acc.checkKeypair; | ||
acc.checkKeypair = promisify(acc._thunk_checkKeypair); | ||
} | ||
if (3 === acc.setKeypair.length) { | ||
warn(); | ||
acc._thunk_setKeypair = acc.setKeypair; | ||
acc.setKeypair = promisify(acc._thunk_setKeypair); | ||
} | ||
// certs | ||
if (2 === crt.check.length) { | ||
warn(); | ||
crt._thunk_check = crt.check; | ||
crt.check = promisify(crt._thunk_check); | ||
} | ||
if (3 === crt.set.length) { | ||
warn(); | ||
crt._thunk_set = crt.set; | ||
crt.set = promisify(crt._thunk_set); | ||
} | ||
if (2 === crt.checkKeypair.length) { | ||
warn(); | ||
crt._thunk_checkKeypair = crt.checkKeypair; | ||
crt.checkKeypair = promisify(crt._thunk_checkKeypair); | ||
} | ||
if (2 === crt.setKeypair.length) { | ||
warn(); | ||
crt._thunk_setKeypair = crt.setKeypair; | ||
crt.setKeypair = promisify(crt._thunk_setKeypair); | ||
} | ||
return store; | ||
}; | ||
Greenlock._normalizeChallenge = function(name, ch) { | ||
var warned = false; | ||
function warn() { | ||
if (warned) { | ||
return; | ||
} | ||
warned = true; | ||
console.warn( | ||
"'" + | ||
name + | ||
"' may have incorrect function signatures, or contains deprecated use of callbacks" | ||
); | ||
} | ||
// init, zones, set, get, remove | ||
if (ch.init && 2 === ch.init.length) { | ||
warn(); | ||
ch._thunk_init = ch.init; | ||
ch.init = promisify(ch._thunk_init); | ||
} | ||
if (ch.zones && 2 === ch.zones.length) { | ||
warn(); | ||
ch._thunk_zones = ch.zones; | ||
ch.zones = promisify(ch._thunk_zones); | ||
} | ||
if (2 === ch.set.length) { | ||
warn(); | ||
ch._thunk_set = ch.set; | ||
ch.set = promisify(ch._thunk_set); | ||
} | ||
if (2 === ch.remove.length) { | ||
warn(); | ||
ch._thunk_remove = ch.remove; | ||
ch.remove = promisify(ch._thunk_remove); | ||
} | ||
if (ch.get && 2 === ch.get.length) { | ||
warn(); | ||
ch._thunk_get = ch.get; | ||
ch.get = promisify(ch._thunk_get); | ||
} | ||
return ch; | ||
}; | ||
function errorToJSON(e) { | ||
@@ -632,0 +623,0 @@ var error = {}; |
172
order.js
@@ -1,97 +0,95 @@ | ||
var accountKeypair = await Keypairs.generate({ kty: accKty }); | ||
if (config.debug) { | ||
console.info('Account Key Created'); | ||
console.info(JSON.stringify(accountKeypair, null, 2)); | ||
console.info(); | ||
console.info(); | ||
} | ||
var accountKeypair = await Keypairs.generate({ kty: accKty }); | ||
if (config.debug) { | ||
console.info('Account Key Created'); | ||
console.info(JSON.stringify(accountKeypair, null, 2)); | ||
console.info(); | ||
console.info(); | ||
} | ||
var account = await acme.accounts.create({ | ||
agreeToTerms: agree, | ||
// TODO detect jwk/pem/der? | ||
accountKeypair: { privateKeyJwk: accountKeypair.private }, | ||
subscriberEmail: config.email | ||
}); | ||
var account = await acme.accounts.create({ | ||
agreeToTerms: agree, | ||
// TODO detect jwk/pem/der? | ||
accountKeypair: { privateKeyJwk: accountKeypair.private }, | ||
subscriberEmail: config.email | ||
}); | ||
// TODO top-level agree | ||
function agree(tos) { | ||
if (config.debug) { | ||
console.info('Agreeing to Terms of Service:'); | ||
console.info(tos); | ||
console.info(); | ||
console.info(); | ||
} | ||
agreed = true; | ||
return Promise.resolve(tos); | ||
} | ||
// TODO top-level agree | ||
function agree(tos) { | ||
if (config.debug) { | ||
console.info('New Subscriber Account'); | ||
console.info(JSON.stringify(account, null, 2)); | ||
console.info('Agreeing to Terms of Service:'); | ||
console.info(tos); | ||
console.info(); | ||
console.info(); | ||
} | ||
if (!agreed) { | ||
throw new Error('Failed to ask the user to agree to terms'); | ||
} | ||
agreed = true; | ||
return Promise.resolve(tos); | ||
} | ||
if (config.debug) { | ||
console.info('New Subscriber Account'); | ||
console.info(JSON.stringify(account, null, 2)); | ||
console.info(); | ||
console.info(); | ||
} | ||
if (!agreed) { | ||
throw new Error('Failed to ask the user to agree to terms'); | ||
} | ||
var certKeypair = await Keypairs.generate({ kty: srvKty }); | ||
var pem = await Keypairs.export({ | ||
jwk: certKeypair.private, | ||
encoding: 'pem' | ||
}); | ||
if (config.debug) { | ||
console.info('Server Key Created'); | ||
console.info('privkey.jwk.json'); | ||
console.info(JSON.stringify(certKeypair, null, 2)); | ||
// This should be saved as `privkey.pem` | ||
console.info(); | ||
console.info('privkey.' + srvKty.toLowerCase() + '.pem:'); | ||
console.info(pem); | ||
console.info(); | ||
} | ||
var certKeypair = await Keypairs.generate({ kty: srvKty }); | ||
var pem = await Keypairs.export({ | ||
jwk: certKeypair.private, | ||
encoding: 'pem' | ||
}); | ||
if (config.debug) { | ||
console.info('Server Key Created'); | ||
console.info('privkey.jwk.json'); | ||
console.info(JSON.stringify(certKeypair, null, 2)); | ||
// This should be saved as `privkey.pem` | ||
console.info(); | ||
console.info('privkey.' + srvKty.toLowerCase() + '.pem:'); | ||
console.info(pem); | ||
console.info(); | ||
} | ||
// 'subject' should be first in list | ||
var domains = randomDomains(rnd); | ||
if (config.debug) { | ||
console.info('Get certificates for random domains:'); | ||
console.info( | ||
domains | ||
.map(function(puny) { | ||
var uni = punycode.toUnicode(puny); | ||
if (puny !== uni) { | ||
return puny + ' (' + uni + ')'; | ||
} | ||
return puny; | ||
}) | ||
.join('\n') | ||
); | ||
console.info(); | ||
} | ||
// 'subject' should be first in list | ||
var domains = randomDomains(rnd); | ||
if (config.debug) { | ||
console.info('Get certificates for random domains:'); | ||
console.info( | ||
domains | ||
.map(function(puny) { | ||
var uni = punycode.toUnicode(puny); | ||
if (puny !== uni) { | ||
return puny + ' (' + uni + ')'; | ||
} | ||
return puny; | ||
}) | ||
.join('\n') | ||
); | ||
console.info(); | ||
} | ||
// Create CSR | ||
var csrDer = await CSR.csr({ | ||
jwk: certKeypair.private, | ||
domains: domains, | ||
encoding: 'der' | ||
}); | ||
var csr = Enc.bufToUrlBase64(csrDer); | ||
var csrPem = PEM.packBlock({ | ||
type: 'CERTIFICATE REQUEST', | ||
bytes: csrDer /* { jwk: jwk, domains: opts.domains } */ | ||
}); | ||
if (config.debug) { | ||
console.info('Certificate Signing Request'); | ||
console.info(csrPem); | ||
console.info(); | ||
} | ||
// Create CSR | ||
var csrDer = await CSR.csr({ | ||
jwk: certKeypair.private, | ||
domains: domains, | ||
encoding: 'der' | ||
}); | ||
var csr = Enc.bufToUrlBase64(csrDer); | ||
var csrPem = PEM.packBlock({ | ||
type: 'CERTIFICATE REQUEST', | ||
bytes: csrDer /* { jwk: jwk, domains: opts.domains } */ | ||
}); | ||
if (config.debug) { | ||
console.info('Certificate Signing Request'); | ||
console.info(csrPem); | ||
console.info(); | ||
} | ||
var results = await acme.certificates.create({ | ||
account: account, | ||
accountKeypair: { privateKeyJwk: accountKeypair.private }, | ||
csr: csr, | ||
domains: domains, | ||
challenges: challenges, // must be implemented | ||
customerEmail: null | ||
}); | ||
var results = await acme.certificates.create({ | ||
account: account, | ||
accountKeypair: { privateKeyJwk: accountKeypair.private }, | ||
csr: csr, | ||
domains: domains, | ||
challenges: challenges, // must be implemented | ||
customerEmail: null | ||
}); |
{ | ||
"name": "@root/greenlock", | ||
"version": "3.0.1", | ||
"version": "3.0.2", | ||
"description": "The easiest Let's Encrypt client for Node.js and Browsers", | ||
@@ -43,3 +43,3 @@ "homepage": "https://rootprojects.org/greenlock/", | ||
"@root/request": "^1.3.10", | ||
"acme-http-01-standalone": "^3.0.0", | ||
"acme-http-01-standalone": "^3.0.5", | ||
"cert-info": "^1.5.1", | ||
@@ -46,0 +46,0 @@ "greenlock-manager-fs": "^0.6.0", |
161
plugins.js
@@ -11,3 +11,18 @@ 'use strict'; | ||
P._load = function(modname) { | ||
P._loadStore = function(storeConf) { | ||
return P._loadHelper(storeConf.module).then(function(plugin) { | ||
return P._normalizeStore(storeConf.module, plugin.create(storeConf)); | ||
}); | ||
}; | ||
P._loadChallenge = function(chConfs, typ01) { | ||
return P._loadHelper(chConfs[typ01].module).then(function(plugin) { | ||
var ch = P._normalizeChallenge( | ||
chConfs[typ01].module, | ||
plugin.create(chConfs[typ01]) | ||
); | ||
ch._type = typ01; | ||
return ch; | ||
}); | ||
}; | ||
P._loadHelper = function(modname) { | ||
try { | ||
@@ -22,2 +37,146 @@ return Promise.resolve(require(modname)); | ||
P._normalizeStore = function(name, store) { | ||
var acc = store.accounts; | ||
var crt = store.certificates; | ||
var warned = false; | ||
function warn() { | ||
if (warned) { | ||
return; | ||
} | ||
warned = true; | ||
console.warn( | ||
"'" + | ||
name + | ||
"' may have incorrect function signatures, or contains deprecated use of callbacks" | ||
); | ||
} | ||
// accs | ||
if (acc.check && 2 === acc.check.length) { | ||
warn(); | ||
acc._thunk_check = acc.check; | ||
acc.check = promisify(acc._thunk_check); | ||
} | ||
if (acc.set && 3 === acc.set.length) { | ||
warn(); | ||
acc._thunk_set = acc.set; | ||
acc.set = promisify(acc._thunk_set); | ||
} | ||
if (2 === acc.checkKeypair.length) { | ||
warn(); | ||
acc._thunk_checkKeypair = acc.checkKeypair; | ||
acc.checkKeypair = promisify(acc._thunk_checkKeypair); | ||
} | ||
if (3 === acc.setKeypair.length) { | ||
warn(); | ||
acc._thunk_setKeypair = acc.setKeypair; | ||
acc.setKeypair = promisify(acc._thunk_setKeypair); | ||
} | ||
// certs | ||
if (2 === crt.check.length) { | ||
warn(); | ||
crt._thunk_check = crt.check; | ||
crt.check = promisify(crt._thunk_check); | ||
} | ||
if (3 === crt.set.length) { | ||
warn(); | ||
crt._thunk_set = crt.set; | ||
crt.set = promisify(crt._thunk_set); | ||
} | ||
if (2 === crt.checkKeypair.length) { | ||
warn(); | ||
crt._thunk_checkKeypair = crt.checkKeypair; | ||
crt.checkKeypair = promisify(crt._thunk_checkKeypair); | ||
} | ||
if (2 === crt.setKeypair.length) { | ||
warn(); | ||
crt._thunk_setKeypair = crt.setKeypair; | ||
crt.setKeypair = promisify(crt._thunk_setKeypair); | ||
} | ||
return store; | ||
}; | ||
P._normalizeChallenge = function(name, ch) { | ||
var gch = {}; | ||
var warned = false; | ||
function warn() { | ||
if (warned) { | ||
return; | ||
} | ||
warned = true; | ||
console.warn( | ||
"'" + | ||
name + | ||
"' may have incorrect function signatures, or contains deprecated use of callbacks" | ||
); | ||
} | ||
var warned2 = false; | ||
function warn2() { | ||
if (warned2) { | ||
return; | ||
} | ||
warned2 = true; | ||
console.warn( | ||
"'" + | ||
name + | ||
"' did not return a Promise when called. This should be fixed by the maintainer." | ||
); | ||
} | ||
function wrappy(fn) { | ||
return function(_params) { | ||
return Promise.resolve().then(function() { | ||
var result = fn.call(ch, _params); | ||
if (!result || !result.then) { | ||
warn2(); | ||
} | ||
return result; | ||
}); | ||
}; | ||
} | ||
// init, zones, set, get, remove | ||
if (ch.init) { | ||
if (2 === ch.init.length) { | ||
warn(); | ||
ch._thunk_init = ch.init; | ||
ch.init = promisify(ch._thunk_init); | ||
} | ||
gch.init = wrappy(ch.init); | ||
} | ||
if (ch.zones) { | ||
if (2 === ch.zones.length) { | ||
warn(); | ||
ch._thunk_zones = ch.zones; | ||
ch.zones = promisify(ch._thunk_zones); | ||
} | ||
gch.zones = wrappy(ch.zones); | ||
} | ||
if (2 === ch.set.length) { | ||
warn(); | ||
ch._thunk_set = ch.set; | ||
ch.set = promisify(ch._thunk_set); | ||
} | ||
gch.set = wrappy(ch.set); | ||
if (2 === ch.remove.length) { | ||
warn(); | ||
ch._thunk_remove = ch.remove; | ||
ch.remove = promisify(ch._thunk_remove); | ||
} | ||
gch.remove = wrappy(ch.remove); | ||
if (ch.get) { | ||
if (2 === ch.get.length) { | ||
warn(); | ||
ch._thunk_get = ch.get; | ||
ch.get = promisify(ch._thunk_get); | ||
} | ||
gch.get = wrappy(ch.get); | ||
} | ||
return gch; | ||
}; | ||
P._loadSync = function(modname) { | ||
@@ -24,0 +183,0 @@ var mod; |
@@ -58,9 +58,24 @@ # @root/greenlock | ||
// Optionally, you may receive other (very few) updates, such as important new features | ||
maintainerEmail: 'jon@example.com', | ||
maintainerUpdates: true, // default: false | ||
maintainerEmail: 'jon@example.com' | ||
}); | ||
``` | ||
| Parameter | Description | | ||
| --------------- | ------------------------------------------------------------------------------------ | | ||
| maintainerEmail | the developer contact for critical bug and security notifications | | ||
| packageAgent | if you publish your package for others to use, `require('./package.json').name` here | | ||
<!-- | ||
| maintainerUpdates | (default: false) receive occasional non-critical notifications | | ||
maintainerUpdates: true // default: false | ||
--> | ||
### Add Approved Domains | ||
```js | ||
greenlock.manager.defaults({ | ||
// The "Let's Encrypt Subscriber" (often the same as the maintainer) | ||
// NOT the end customer (except where that is also the maintainer) | ||
subscriberEmail: 'jon@example.com', | ||
agreeToTerms: true // default: false | ||
agreeToTerms: true | ||
}); | ||
@@ -71,12 +86,3 @@ ``` | ||
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| servername | the default servername to use for non-sni requests (many IoT clients) | | ||
| maintainerEmail | the developer contact for critical bug and security notifications | | ||
| maintainerUpdates | (default: false) receive occasional non-critical notifications | | ||
| maintainerPackage | if you publish your package for others to use, `require('./package.json').name` here | | ||
| maintainerPackageVersion | if you publish your package for others to use, `require('./package.json').version` here | | ||
| subscriberEmail | the contact who agrees to the Let's Encrypt Subscriber Agreement and the Greenlock Terms of Service<br>this contact receives renewal failure notifications | | ||
| agreeToTerms | (default: false) either 'true' or a function that presents the Terms of Service and returns it once accepted | | ||
| store | override the default storage module | | ||
| store.module | the name of your storage module | | ||
| store.xxxx | options specific to your storage module | | ||
| challenges['http-01'] | provide an http-01 challenge module | | ||
@@ -87,5 +93,14 @@ | challenges['dns-01'] | provide a dns-01 challenge module | | ||
| challenges[type].xxxx | module-specific options | | ||
| servername | the default servername to use for non-sni requests (many IoT clients) | | ||
| subscriberEmail | the contact who agrees to the Let's Encrypt Subscriber Agreement and the Greenlock Terms of Service<br>this contact receives renewal failure notifications | | ||
| store | override the default storage module | | ||
| store.module | the name of your storage module | | ||
| store.xxxx | options specific to your storage module | | ||
### Add Approved Domains | ||
<!-- | ||
| serverId | an arbitrary name to distinguish this server within a cluster of servers | | ||
--> | ||
```js | ||
@@ -110,22 +125,20 @@ gl.add({ | ||
```js | ||
return greenlock | ||
.renew() | ||
.then(function(pems) { | ||
console.info(pems); | ||
}) | ||
.then(function(results) { | ||
results.forEach(function(site) { | ||
if (site.error) { | ||
console.error(site.subject, site.error); | ||
return; | ||
} | ||
}); | ||
return greenlock.renew().then(function(results) { | ||
results.forEach(function(site) { | ||
if (site.error) { | ||
console.error(site.subject, site.error); | ||
return; | ||
} | ||
}); | ||
}); | ||
``` | ||
| Parameter | Type | Description | | ||
| ---------- | ---- | ---------------------------------------------------------- | | ||
| (optional) | - | ALL parameters are optional, but some should be paired | | ||
| force | bool | force silly options, such as tiny durations | | ||
| duplicate | bool | force the domain to renew, regardless of age or expiration | | ||
| Parameter | Type | Description | | ||
| ------------- | ---- | ------------------------------------------------------------------------------- | | ||
| (optional) | | ALL parameters are optional, but some should be paired | | ||
| force | bool | force silly options, such as tiny durations | | ||
| duplicate | bool | force the domain to renew, regardless of age or expiration | | ||
| issuedBefore | ms | Check domains issued before the given date in milliseconds | | ||
| expiresBefore | ms | Check domains that expire before the given date in milliseconds | | ||
| renewBefore | ms | Check domains that are scheduled to renew before the given date in milliseconds | | ||
@@ -132,0 +145,0 @@ <!-- |
82403
2245
245
14