updates for greenlock-express
This commit is contained in:
parent
7fc11f7908
commit
7774d0f8b1
30
README.md
30
README.md
|
@ -65,12 +65,23 @@ var gl = Greenlock.create({
|
|||
});
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| maintainerEmail | the developer contact for critical bug and security notifications |
|
||||
| maintainerUpdates | (default: false) receive occasional non-critical notifications |
|
||||
| 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 |
|
||||
| Parameter | Description |
|
||||
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 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 |
|
||||
| challenges['dns-01'] | provide a dns-01 challenge module |
|
||||
| challenges['tls-alpn-01'] | provide a tls-alpn-01 challenge module |
|
||||
| challenges[type].module | the name of your challenge module |
|
||||
| challenges[type].xxxx | module-specific options |
|
||||
|
||||
### Add Approved Domains
|
||||
|
||||
|
@ -130,15 +141,18 @@ TODO
|
|||
|
||||
</details>
|
||||
|
||||
<!--
|
||||
|
||||
<details>
|
||||
<summary>Node.js</summary>
|
||||
|
||||
```bash
|
||||
npm install --save @root/greenlock
|
||||
npm install --save greenlock-manager-fs
|
||||
npm install --save greenlock-store-fs
|
||||
npm install --save acme-http-01-standalone
|
||||
```
|
||||
|
||||
<!--
|
||||
|
||||
TODO
|
||||
|
||||
</details>
|
||||
|
|
71
accounts.js
71
accounts.js
|
@ -6,8 +6,11 @@ var E = require('./errors.js');
|
|||
|
||||
var pending = {};
|
||||
|
||||
A._getOrCreate = function(greenlock, db, acme, args) {
|
||||
var email = args.subscriberEmail || greenlock._defaults.subscriberEmail;
|
||||
A._getOrCreate = function(gnlck, mconf, db, acme, args) {
|
||||
var email =
|
||||
args.subscriberEmail ||
|
||||
mconf.subscriberEmail ||
|
||||
gnlck._defaults.subscriberEmail;
|
||||
|
||||
if (!email) {
|
||||
throw E.NO_SUBSCRIBER('get account', args.subject);
|
||||
|
@ -23,7 +26,14 @@ A._getOrCreate = function(greenlock, db, acme, args) {
|
|||
return pending[email];
|
||||
}
|
||||
|
||||
pending[email] = A._rawGetOrCreate(greenlock, db, acme, args, email)
|
||||
pending[email] = A._rawGetOrCreate(
|
||||
gnlck,
|
||||
mconf,
|
||||
db,
|
||||
acme,
|
||||
args,
|
||||
email
|
||||
)
|
||||
.catch(function(e) {
|
||||
delete pending[email];
|
||||
throw e;
|
||||
|
@ -38,32 +48,37 @@ A._getOrCreate = function(greenlock, db, acme, args) {
|
|||
};
|
||||
|
||||
// What we really need out of this is the private key and the ACME "key" id
|
||||
A._rawGetOrCreate = function(greenlock, db, acme, args, email) {
|
||||
A._rawGetOrCreate = function(gnlck, mconf, db, acme, args, email) {
|
||||
var p;
|
||||
if (db.check) {
|
||||
p = A._checkStore(greenlock, db, acme, args, email);
|
||||
p = A._checkStore(gnlck, mconf, db, acme, args, email);
|
||||
} else {
|
||||
p = Promise.resolve(null);
|
||||
}
|
||||
|
||||
return p.then(function(fullAccount) {
|
||||
if (!fullAccount) {
|
||||
return A._newAccount(greenlock, db, acme, args, email, null);
|
||||
return A._newAccount(gnlck, mconf, db, acme, args, email, null);
|
||||
}
|
||||
|
||||
if (fullAccount.keypair && fullAccount.key && fullAccount.key.kid) {
|
||||
return fullAccount;
|
||||
}
|
||||
|
||||
return A._newAccount(greenlock, db, acme, args, email, fullAccount);
|
||||
return A._newAccount(gnlck, mconf, db, acme, args, email, fullAccount);
|
||||
});
|
||||
};
|
||||
|
||||
A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
||||
var keyType = args.accountKeyType || greenlock._defaults.accountKeyType;
|
||||
A._newAccount = function(gnlck, mconf, db, acme, args, email, fullAccount) {
|
||||
var keyType =
|
||||
args.accountKeyType ||
|
||||
mconf.accountKeyType ||
|
||||
gnlck._defaults.accountKeyType;
|
||||
var query = {
|
||||
subject: args.subject,
|
||||
email: email,
|
||||
subscriberEmail: email,
|
||||
customerEmail: args.customerEmail,
|
||||
account: fullAccount || {}
|
||||
};
|
||||
|
||||
|
@ -73,8 +88,10 @@ A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
|||
var accReg = {
|
||||
subscriberEmail: email,
|
||||
agreeToTerms:
|
||||
args.agreeToTerms || greenlock._defaults.agreeToTerms,
|
||||
accountKeypair: keypair,
|
||||
args.agreeToTerms ||
|
||||
mconf.agreeToTerms ||
|
||||
gnlck._defaults.agreeToTerms,
|
||||
accountKey: keypair.privateKeyJwk || keypair.private,
|
||||
debug: args.debug
|
||||
};
|
||||
return acme.accounts.create(accReg).then(function(receipt) {
|
||||
|
@ -86,7 +103,9 @@ A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
|||
receipt &&
|
||||
receipt.key &&
|
||||
(receipt.key.kid || receipt.kid),
|
||||
email: args.email
|
||||
email: args.email,
|
||||
subscriberEmail: email,
|
||||
customerEmail: args.customerEmail
|
||||
};
|
||||
|
||||
var keyP;
|
||||
|
@ -95,6 +114,13 @@ A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
|||
} else {
|
||||
query.keypair = keypair;
|
||||
query.receipt = receipt;
|
||||
query.directoryUrl = gnlck._defaults.directoryUrl;
|
||||
/*
|
||||
query.server = gnlck._defaults.directoryUrl.replace(
|
||||
/^https?:\/\//i,
|
||||
''
|
||||
);
|
||||
*/
|
||||
keyP = db.setKeypair(query, keypair);
|
||||
}
|
||||
|
||||
|
@ -109,7 +135,16 @@ A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
|||
{
|
||||
// id to be set by Store
|
||||
email: email,
|
||||
agreeTos: true
|
||||
subscriberEmail: email,
|
||||
customerEmail: args.customerEmail,
|
||||
agreeTos: true,
|
||||
directoryUrl: gnlck._defaults.directoryUrl
|
||||
/*
|
||||
server: gnlck._defaults.directoryUrl.replace(
|
||||
/^https?:\/\//i,
|
||||
''
|
||||
)
|
||||
*/
|
||||
},
|
||||
reg
|
||||
);
|
||||
|
@ -137,7 +172,7 @@ A._newAccount = function(greenlock, db, acme, args, email, fullAccount) {
|
|||
);
|
||||
};
|
||||
|
||||
A._checkStore = function(greenlock, db, acme, args, email) {
|
||||
A._checkStore = function(gnlck, mconf, db, acme, args, email) {
|
||||
if ((args.domain || args.domains) && !args.subject) {
|
||||
console.warn("use 'subject' instead of 'domain'");
|
||||
args.subject = args.domain;
|
||||
|
@ -148,12 +183,12 @@ A._checkStore = function(greenlock, db, acme, args, email) {
|
|||
account = {};
|
||||
}
|
||||
|
||||
if (args.accountKeypair) {
|
||||
if (args.accountKey) {
|
||||
console.warn(
|
||||
'rather than passing accountKeypair, put it directly into your account key store'
|
||||
'rather than passing accountKey, put it directly into your account key store'
|
||||
);
|
||||
// TODO we probably don't need this
|
||||
return U._importKeypair(args.accountKeypair);
|
||||
return U._importKeypair(args.accountKey);
|
||||
}
|
||||
|
||||
if (!db.check) {
|
||||
|
@ -165,6 +200,8 @@ A._checkStore = function(greenlock, db, acme, args, email) {
|
|||
//keypair: undefined,
|
||||
//receipt: undefined,
|
||||
email: email,
|
||||
subscriberEmail: email,
|
||||
customerEmail: args.customerEmail || mconf.customerEmail,
|
||||
account: account
|
||||
})
|
||||
.then(function(fullAccount) {
|
||||
|
|
147
certificates.js
147
certificates.js
|
@ -4,13 +4,27 @@ var C = module.exports;
|
|||
var U = require('./utils.js');
|
||||
var CSR = require('@root/csr');
|
||||
var Enc = require('@root/encoding');
|
||||
var Keypairs = require('@root/keypairs');
|
||||
|
||||
var pending = {};
|
||||
var rawPending = {};
|
||||
|
||||
// What the abbreviations mean
|
||||
//
|
||||
// gnlkc => greenlock
|
||||
// mconf => manager config
|
||||
// db => greenlock store instance
|
||||
// acme => instance of ACME.js
|
||||
// chs => instances of challenges
|
||||
// acc => account
|
||||
// args => site / extra options
|
||||
|
||||
// Certificates
|
||||
C._getOrOrder = function(greenlock, db, acme, challenges, account, args) {
|
||||
var email = args.subscriberEmail || greenlock._defaults.subscriberEmail;
|
||||
C._getOrOrder = function(gnlck, mconf, db, acme, chs, acc, args) {
|
||||
var email =
|
||||
args.subscriberEmail ||
|
||||
mconf.subscriberEmail ||
|
||||
gnlck._defaults.subscriberEmail;
|
||||
|
||||
var id = args.altnames.join(' ');
|
||||
if (pending[id]) {
|
||||
|
@ -18,11 +32,12 @@ C._getOrOrder = function(greenlock, db, acme, challenges, account, args) {
|
|||
}
|
||||
|
||||
pending[id] = C._rawGetOrOrder(
|
||||
greenlock,
|
||||
gnlck,
|
||||
mconf,
|
||||
db,
|
||||
acme,
|
||||
challenges,
|
||||
account,
|
||||
chs,
|
||||
acc,
|
||||
email,
|
||||
args
|
||||
)
|
||||
|
@ -39,33 +54,26 @@ C._getOrOrder = function(greenlock, db, acme, challenges, account, args) {
|
|||
};
|
||||
|
||||
// Certificates
|
||||
C._rawGetOrOrder = function(
|
||||
greenlock,
|
||||
db,
|
||||
acme,
|
||||
challenges,
|
||||
account,
|
||||
email,
|
||||
args
|
||||
) {
|
||||
return C._check(db, args).then(function(pems) {
|
||||
C._rawGetOrOrder = function(gnlck, mconf, db, acme, chs, acc, email, args) {
|
||||
return C._check(gnlck, mconf, db, args).then(function(pems) {
|
||||
// No pems? get some!
|
||||
if (!pems) {
|
||||
return C._rawOrder(
|
||||
greenlock,
|
||||
gnlck,
|
||||
mconf,
|
||||
db,
|
||||
acme,
|
||||
challenges,
|
||||
account,
|
||||
chs,
|
||||
acc,
|
||||
email,
|
||||
args
|
||||
).then(function(newPems) {
|
||||
// do not wait on notify
|
||||
greenlock._notify('cert_issue', {
|
||||
gnlck._notify('cert_issue', {
|
||||
options: args,
|
||||
subject: args.subject,
|
||||
altnames: args.altnames,
|
||||
account: account,
|
||||
account: acc,
|
||||
email: email,
|
||||
pems: newPems
|
||||
});
|
||||
|
@ -74,7 +82,7 @@ C._rawGetOrOrder = function(
|
|||
}
|
||||
|
||||
// Nice and fresh? We're done!
|
||||
if (!C._isStale(greenlock, args, 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';
|
||||
|
@ -82,26 +90,20 @@ C._rawGetOrOrder = function(
|
|||
}
|
||||
|
||||
// Getting stale? Let's renew to freshen up!
|
||||
var p = C._rawOrder(
|
||||
greenlock,
|
||||
db,
|
||||
acme,
|
||||
challenges,
|
||||
account,
|
||||
email,
|
||||
args
|
||||
).then(function(renewedPems) {
|
||||
// do not wait on notify
|
||||
greenlock._notify('cert_renewal', {
|
||||
options: args,
|
||||
subject: args.subject,
|
||||
altnames: args.altnames,
|
||||
account: account,
|
||||
email: email,
|
||||
pems: renewedPems
|
||||
});
|
||||
return renewedPems;
|
||||
});
|
||||
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;
|
||||
}
|
||||
);
|
||||
|
||||
// TODO what should this be?
|
||||
if (args.waitForRenewal) {
|
||||
|
@ -114,7 +116,7 @@ C._rawGetOrOrder = function(
|
|||
|
||||
// we have another promise here because it the optional renewal
|
||||
// may resolve in a different stack than the returned pems
|
||||
C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
||||
C._rawOrder = function(gnlck, mconf, db, acme, chs, acc, email, args) {
|
||||
var id = args.altnames
|
||||
.slice(0)
|
||||
.sort()
|
||||
|
@ -123,10 +125,17 @@ C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
|||
return rawPending[id];
|
||||
}
|
||||
|
||||
var keyType = args.serverKeyType || greenlock._defaults.serverKeyType;
|
||||
var keyType =
|
||||
args.serverKeyType ||
|
||||
mconf.serverKeyType ||
|
||||
gnlck._defaults.serverKeyType;
|
||||
var query = {
|
||||
subject: args.subject,
|
||||
certificate: args.certificate || {}
|
||||
certificate: args.certificate || {},
|
||||
directoryUrl:
|
||||
args.directoryUrl ||
|
||||
mconf.directoryUrl ||
|
||||
gnlck._defaults.directoryUrl
|
||||
};
|
||||
rawPending[id] = U._getOrCreateKeypair(db, args.subject, query, keyType)
|
||||
.then(function(kresult) {
|
||||
|
@ -134,7 +143,7 @@ C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
|||
var domains = args.altnames.slice(0);
|
||||
|
||||
return CSR.csr({
|
||||
jwk: serverKeypair.privateKeyJwk,
|
||||
jwk: serverKeypair.privateKeyJwk || serverKeypair.private,
|
||||
domains: domains,
|
||||
encoding: 'der'
|
||||
})
|
||||
|
@ -144,21 +153,22 @@ C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
|||
})
|
||||
.then(function(csr) {
|
||||
function notify() {
|
||||
greenlock._notify('challenge_status', {
|
||||
gnlck._notify('challenge_status', {
|
||||
options: args,
|
||||
subject: args.subject,
|
||||
altnames: args.altnames,
|
||||
account: account,
|
||||
account: acc,
|
||||
email: email
|
||||
});
|
||||
}
|
||||
var certReq = {
|
||||
debug: args.debug || greenlock._defaults.debug,
|
||||
debug: args.debug || gnlck._defaults.debug,
|
||||
|
||||
challenges: challenges,
|
||||
account: account, // only used if accounts.key.kid exists
|
||||
accountKeypair: account.keypair,
|
||||
keypair: account.keypair, // TODO
|
||||
challenges: chs,
|
||||
account: acc, // only used if accounts.key.kid exists
|
||||
accountKey:
|
||||
acc.keypair.privateKeyJwk || acc.keypair.private,
|
||||
keypair: acc.keypair, // TODO
|
||||
csr: csr,
|
||||
domains: domains, // because ACME.js v3 uses `domains` still, actually
|
||||
onChallengeStatus: notify,
|
||||
|
@ -190,7 +200,7 @@ C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
|||
return db.set(query);
|
||||
})
|
||||
.then(function() {
|
||||
return C._check(db, args);
|
||||
return C._check(gnlck, mconf, db, args);
|
||||
})
|
||||
.then(function(bundle) {
|
||||
// TODO notify Manager
|
||||
|
@ -207,14 +217,17 @@ C._rawOrder = function(greenlock, db, acme, challenges, account, email, args) {
|
|||
};
|
||||
|
||||
// returns pems, if they exist
|
||||
C._check = function(db, args) {
|
||||
C._check = function(gnlck, mconf, db, args) {
|
||||
var query = {
|
||||
subject: args.subject,
|
||||
// may contain certificate.id
|
||||
certificate: args.certificate
|
||||
certificate: args.certificate,
|
||||
directoryUrl:
|
||||
args.directoryUrl ||
|
||||
mconf.directoryUrl ||
|
||||
gnlck._defaults.directoryUrl
|
||||
};
|
||||
return db.check(query).then(function(pems) {
|
||||
console.log('[debug] has pems? (yes)', pems);
|
||||
if (!pems) {
|
||||
return null;
|
||||
}
|
||||
|
@ -235,9 +248,13 @@ C._check = function(db, args) {
|
|||
|
||||
return U._getKeypair(db, args.subject, query)
|
||||
.then(function(keypair) {
|
||||
console.log('[debug get keypair]', Object.keys(keypair));
|
||||
pems.privkey = keypair.privateKeyPem;
|
||||
return pems;
|
||||
return Keypairs.export({
|
||||
jwk: keypair.privateKeyJwk || keypair.private,
|
||||
encoding: 'pem'
|
||||
}).then(function(pem) {
|
||||
pems.privkey = pem;
|
||||
return pems;
|
||||
});
|
||||
})
|
||||
.catch(function() {
|
||||
// TODO report error, but continue the process as with no cert
|
||||
|
@ -247,12 +264,12 @@ C._check = function(db, args) {
|
|||
};
|
||||
|
||||
// Certificates
|
||||
C._isStale = function(greenlock, args, pems) {
|
||||
C._isStale = function(gnlck, mconf, args, pems) {
|
||||
if (args.duplicate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var renewAt = C._renewableAt(greenlock, args, pems);
|
||||
var renewAt = C._renewableAt(gnlck, mconf, args, pems);
|
||||
|
||||
if (Date.now() >= renewAt) {
|
||||
return true;
|
||||
|
@ -261,12 +278,16 @@ C._isStale = function(greenlock, args, pems) {
|
|||
return false;
|
||||
};
|
||||
|
||||
C._renewableAt = function(greenlock, args, pems) {
|
||||
C._renewableAt = function(gnlck, mconf, args, pems) {
|
||||
if (args.renewAt) {
|
||||
return args.renewAt;
|
||||
}
|
||||
|
||||
var renewOffset = args.renewOffset || greenlock._defaults.renewOffset || 0;
|
||||
var renewOffset =
|
||||
args.renewOffset ||
|
||||
mconf.renewOffset ||
|
||||
gnlck._defaults.renewOffset ||
|
||||
0;
|
||||
var week = 1000 * 60 * 60 * 24 * 6;
|
||||
if (!args.force && Math.abs(renewOffset) < week) {
|
||||
throw new Error(
|
||||
|
|
65
greenlock.js
65
greenlock.js
|
@ -65,10 +65,37 @@ G.create = function(gconf) {
|
|||
var defaults = G._defaults(gconf);
|
||||
|
||||
greenlock.manager = Manager.create(defaults);
|
||||
greenlock._init = function() {
|
||||
var p;
|
||||
greenlock._init = function() {
|
||||
return p;
|
||||
};
|
||||
p = greenlock.manager.config().then(function(conf) {
|
||||
var changed = false;
|
||||
if (!conf.challenges) {
|
||||
changed = true;
|
||||
conf.challenges = defaults.challenges;
|
||||
}
|
||||
if (!conf.store) {
|
||||
changed = true;
|
||||
conf.store = defaults.store;
|
||||
}
|
||||
if (changed) {
|
||||
return greenlock.manager.config(conf);
|
||||
}
|
||||
});
|
||||
return p;
|
||||
};
|
||||
greenlock._init();
|
||||
|
||||
// The goal here is to reduce boilerplate, such as error checking
|
||||
// and duration parsing, that a manager must implement
|
||||
greenlock.add = function(args) {
|
||||
return greenlock._init().then(function() {
|
||||
return greenlock._add(args);
|
||||
});
|
||||
};
|
||||
greenlock._add = function(args) {
|
||||
return Promise.resolve().then(function() {
|
||||
// durations
|
||||
if (args.renewOffset) {
|
||||
|
@ -128,23 +155,26 @@ G.create = function(gconf) {
|
|||
|
||||
greenlock._notify = function(ev, params) {
|
||||
var mng = greenlock.manager;
|
||||
if (mng.notif || greenlock._defaults.notify) {
|
||||
if (mng.notify || greenlock._defaults.notify) {
|
||||
try {
|
||||
var p = (mng.notify || greenlock._defaults.notify)(ev, params);
|
||||
if (p && p.catch) {
|
||||
p.catch(function(e) {
|
||||
console.error("Error on event '" + ev + "':");
|
||||
console.error(
|
||||
"Promise Rejection on event '" + ev + "':"
|
||||
);
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error on event '" + ev + "':");
|
||||
console.error("Thrown Exception on event '" + ev + "':");
|
||||
console.error(e);
|
||||
}
|
||||
} else {
|
||||
if (/error/i.test(ev)) {
|
||||
console.error("Error event '" + ev + "':");
|
||||
console.error(params);
|
||||
console.error(params.stack);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -180,6 +210,11 @@ G.create = function(gconf) {
|
|||
|
||||
// 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._renew(mconf, args);
|
||||
});
|
||||
};
|
||||
greenlock._renew = function(mconf, args) {
|
||||
if (!args) {
|
||||
args = {};
|
||||
}
|
||||
|
@ -207,7 +242,7 @@ G.create = function(gconf) {
|
|||
function next() {
|
||||
var site = sites.shift();
|
||||
if (!site) {
|
||||
return null;
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
var order = {
|
||||
|
@ -216,7 +251,7 @@ G.create = function(gconf) {
|
|||
renewedOrFailed.push(order);
|
||||
// TODO merge args + result?
|
||||
return greenlock
|
||||
.order(site)
|
||||
._order(mconf, site)
|
||||
.then(function(pems) {
|
||||
order.pems = pems;
|
||||
})
|
||||
|
@ -237,7 +272,10 @@ G.create = function(gconf) {
|
|||
|
||||
greenlock._acme = function(args) {
|
||||
var acme = ACME.create({
|
||||
debug: args.debug
|
||||
maintainerEmail: greenlock._defaults.maintainerEmail,
|
||||
packageAgent: greenlock._defaults.packageAgent,
|
||||
notify: greenlock._notify,
|
||||
debug: greenlock._defaults.debug || args.debug
|
||||
});
|
||||
var dirUrl = args.directoryUrl || greenlock._defaults.directoryUrl;
|
||||
|
||||
|
@ -266,6 +304,13 @@ G.create = function(gconf) {
|
|||
};
|
||||
|
||||
greenlock.order = function(args) {
|
||||
return greenlock._init().then(function() {
|
||||
return greenlock.manager.config().then(function(mconf) {
|
||||
return greenlock._order(mconf, args);
|
||||
});
|
||||
});
|
||||
};
|
||||
greenlock._order = function(mconf, args) {
|
||||
return greenlock._acme(args).then(function(acme) {
|
||||
var storeConf = args.store || greenlock._defaults.store;
|
||||
return P._load(storeConf.module).then(function(plugin) {
|
||||
|
@ -276,17 +321,18 @@ G.create = function(gconf) {
|
|||
|
||||
return A._getOrCreate(
|
||||
greenlock,
|
||||
mconf,
|
||||
store.accounts,
|
||||
acme,
|
||||
args
|
||||
).then(function(account) {
|
||||
var challengeConfs =
|
||||
args.challenges || greenlock._defaults.challenges;
|
||||
console.log('[debug] challenge confs', challengeConfs);
|
||||
args.challenges ||
|
||||
mconf.challenges ||
|
||||
greenlock._defaults.challenges;
|
||||
return Promise.all(
|
||||
Object.keys(challengeConfs).map(function(typ01) {
|
||||
var chConf = challengeConfs[typ01];
|
||||
console.log('[debug] module', chConf);
|
||||
return P._load(chConf.module).then(function(
|
||||
plugin
|
||||
) {
|
||||
|
@ -305,6 +351,7 @@ G.create = function(gconf) {
|
|||
});
|
||||
return C._getOrOrder(
|
||||
greenlock,
|
||||
mconf,
|
||||
store.certificates,
|
||||
acme,
|
||||
challenges,
|
||||
|
|
|
@ -5,38 +5,15 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@root/acme": {
|
||||
"version": "3.0.0-wip.3",
|
||||
"resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.0-wip.3.tgz",
|
||||
"integrity": "sha512-7Fq9FuO0WQgKPgyYmKHst71EbIqH764A3j6vF1aKemgWXXq2Wqy8G+2SJwt3/MSXhQ7X+qLmWRLLJ7U4Zlygsg==",
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.5.tgz",
|
||||
"integrity": "sha512-qtAE7E0yPlajlhiojT6Fz8PV0BIvq+eNKY1mbG3zFf+idppYn66R7nrn17mvrXsQaRhabZ/C+M9MAk4Xt8UBBA==",
|
||||
"requires": {
|
||||
"@root/csr": "^0.8.1",
|
||||
"@root/encoding": "^1.0.1",
|
||||
"@root/keypairs": "^0.9.0",
|
||||
"@root/pem": "^1.0.4",
|
||||
"@root/request": "^1.3.11",
|
||||
"@root/x509": "^0.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@root/csr": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz",
|
||||
"integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==",
|
||||
"requires": {
|
||||
"@root/asn1": "^1.0.0",
|
||||
"@root/pem": "^1.0.4",
|
||||
"@root/x509": "^0.7.2"
|
||||
}
|
||||
},
|
||||
"@root/keypairs": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz",
|
||||
"integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==",
|
||||
"requires": {
|
||||
"@root/encoding": "^1.0.1",
|
||||
"@root/pem": "^1.0.4",
|
||||
"@root/x509": "^0.7.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@root/asn1": {
|
||||
|
@ -117,6 +94,11 @@
|
|||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
|
||||
"dev": true
|
||||
},
|
||||
"greenlock-manager-fs": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-0.1.0.tgz",
|
||||
"integrity": "sha512-tEt9npVDDR27FThVsh2PizkNPLS9V60ljbxpYnLRUkv5LoMvOTm4hHfNCEanOIL5PY8rfilh96+8v519xeYKQg=="
|
||||
},
|
||||
"greenlock-store-fs": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.0.2.tgz",
|
||||
|
|
|
@ -34,13 +34,15 @@
|
|||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"@root/acme": "^3.0.0-wip.3",
|
||||
"@root/acme": "^3.0.5",
|
||||
"@root/csr": "^0.8.1",
|
||||
"@root/keypairs": "^0.9.0",
|
||||
"@root/mkdirp": "^1.0.0",
|
||||
"@root/request": "^1.3.10",
|
||||
"acme-dns-01-digitalocean": "^3.0.1",
|
||||
"acme-http-01-standalone": "^3.0.0",
|
||||
"cert-info": "^1.5.1",
|
||||
"greenlock-manager-fs": "^0.1.0",
|
||||
"greenlock-store-fs": "^3.0.2",
|
||||
"safe-replace": "^1.1.0"
|
||||
},
|
||||
|
|
28
utils.js
28
utils.js
|
@ -3,7 +3,7 @@
|
|||
var U = module.exports;
|
||||
|
||||
var promisify = require('util').promisify;
|
||||
var resolveSoa = promisify(require('dns').resolveSoa);
|
||||
//var resolveSoa = promisify(require('dns').resolveSoa);
|
||||
var resolveMx = promisify(require('dns').resolveMx);
|
||||
var punycode = require('punycode');
|
||||
var Keypairs = require('@root/keypairs');
|
||||
|
@ -165,18 +165,28 @@ U._genKeypair = function(keyType) {
|
|||
|
||||
// TODO use ACME._importKeypair ??
|
||||
U._importKeypair = function(keypair) {
|
||||
// this should import all formats equally well:
|
||||
// 'object' (JWK), 'string' (private key pem), kp.privateKeyPem, kp.privateKeyJwk
|
||||
if (keypair.private || keypair.d) {
|
||||
return U._jwkToSet(keypair.private || keypair);
|
||||
}
|
||||
if (keypair.privateKeyJwk) {
|
||||
return U._jwkToSet(keypair.privateKeyJwk);
|
||||
}
|
||||
|
||||
if (!keypair.privateKeyPem) {
|
||||
if ('string' !== typeof keypair && !keypair.privateKeyPem) {
|
||||
// TODO put in errors
|
||||
throw new Error('missing private key');
|
||||
}
|
||||
|
||||
return Keypairs.import({ pem: keypair.privateKeyPem }).then(function(priv) {
|
||||
return U._jwkToSet(priv);
|
||||
});
|
||||
return Keypairs.import({ pem: keypair.privateKeyPem || keypair }).then(
|
||||
function(priv) {
|
||||
if (!priv.d) {
|
||||
throw new Error('missing private key');
|
||||
}
|
||||
return U._jwkToSet(priv);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
U._jwkToSet = function(jwk) {
|
||||
|
@ -263,7 +273,9 @@ U._getOrCreateKeypair = function(db, subject, query, keyType, mustExist) {
|
|||
};
|
||||
|
||||
U._getKeypair = function(db, subject, query) {
|
||||
return U._getOrCreateKeypair(db, subject, query, '', true).then(function (result) {
|
||||
return result.keypair;
|
||||
});
|
||||
return U._getOrCreateKeypair(db, subject, query, '', true).then(function(
|
||||
result
|
||||
) {
|
||||
return result.keypair;
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue