|
|
@ -1,5 +1,14 @@ |
|
|
|
'use strict'; |
|
|
|
|
|
|
|
function log(debug) { |
|
|
|
if (debug) { |
|
|
|
var args = Array.prototype.slice.call(arguments); |
|
|
|
args.shift(); |
|
|
|
args.unshift("[le/lib/core.js]"); |
|
|
|
console.log.apply(console, args); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
module.exports.create = function (le) { |
|
|
|
var PromiseA = require('bluebird'); |
|
|
|
var utils = require('./utils'); |
|
|
@ -55,8 +64,10 @@ module.exports.create = function (le) { |
|
|
|
var keypairOpts = { public: true, pem: true }; |
|
|
|
|
|
|
|
var promise = le.store.accounts.checkKeypairAsync(args).then(function (keypair) { |
|
|
|
return RSA.import(keypair); |
|
|
|
}, function (/*err*/) { |
|
|
|
if (keypair) { |
|
|
|
return RSA.import(keypair); |
|
|
|
} |
|
|
|
|
|
|
|
if (args.accountKeypair) { |
|
|
|
return le.store.accounts.setKeypairAsync(args, RSA.import(args.accountKeypair)); |
|
|
|
} |
|
|
@ -169,6 +180,8 @@ module.exports.create = function (le) { |
|
|
|
return PromiseA.reject(err); |
|
|
|
} |
|
|
|
|
|
|
|
// TODO renewal cb
|
|
|
|
// accountId and or email
|
|
|
|
return core.accounts.getAsync(copy).then(function (account) { |
|
|
|
copy.account = account; |
|
|
|
|
|
|
@ -176,8 +189,10 @@ module.exports.create = function (le) { |
|
|
|
var keypairOpts = { public: true, pem: true }; |
|
|
|
|
|
|
|
var promise = le.store.certificates.checkKeypairAsync(args).then(function (keypair) { |
|
|
|
return RSA.import(keypair); |
|
|
|
}, function (/*err*/) { |
|
|
|
if (keypair) { |
|
|
|
return RSA.import(keypair); |
|
|
|
} |
|
|
|
|
|
|
|
if (args.domainKeypair) { |
|
|
|
return le.store.certificates.setKeypairAsync(args, RSA.import(args.domainKeypair)); |
|
|
|
} |
|
|
@ -199,7 +214,10 @@ module.exports.create = function (le) { |
|
|
|
return core.getAcmeUrlsAsync(args).then(function (urls) { |
|
|
|
args._acmeUrls = urls; |
|
|
|
|
|
|
|
return le.acme.getCertificateAsync({ |
|
|
|
log(args.debug, 'BEFORE CERT'); |
|
|
|
log(args.debug, args); |
|
|
|
throw new Error("Stop! Don't do it!"); |
|
|
|
var certReq = { |
|
|
|
debug: args.debug || le.debug |
|
|
|
|
|
|
|
, newAuthzUrl: args._acmeUrls.newAuthz |
|
|
@ -209,43 +227,35 @@ module.exports.create = function (le) { |
|
|
|
, domainKeypair: domainKeypair |
|
|
|
, domains: args.domains |
|
|
|
, challengeType: args.challengeType |
|
|
|
|
|
|
|
//
|
|
|
|
// IMPORTANT
|
|
|
|
//
|
|
|
|
// setChallenge and removeChallenge are handed defaults
|
|
|
|
// instead of args because getChallenge does not have
|
|
|
|
// access to args
|
|
|
|
// (args is per-request, defaults is per instance)
|
|
|
|
//
|
|
|
|
, setChallenge: function (domain, key, value, done) { |
|
|
|
var copy = utils.merge({ domains: [domain] }, le); |
|
|
|
utils.tplCopy(copy); |
|
|
|
|
|
|
|
//args.domains = [domain];
|
|
|
|
args.domains = args.domains || [domain]; |
|
|
|
|
|
|
|
if (5 !== le.challenger.set.length) { |
|
|
|
done(new Error("le.challenger.set receives the wrong number of arguments." |
|
|
|
+ " You must define setChallenge as function (opts, domain, key, val, cb) { }")); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
le.challenger.set(copy, domain, key, value, done); |
|
|
|
} |
|
|
|
, removeChallenge: function (domain, key, done) { |
|
|
|
var copy = utils.merge({ domains: [domain] }, le); |
|
|
|
utils.tplCopy(copy); |
|
|
|
|
|
|
|
if (4 !== le.challenger.remove.length) { |
|
|
|
done(new Error("le.challenger.remove receives the wrong number of arguments." |
|
|
|
+ " You must define removeChallenge as function (opts, domain, key, cb) { }")); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
le.challenger.remove(copy, domain, key, done); |
|
|
|
} |
|
|
|
}).then(utils.attachCertInfo); |
|
|
|
}; |
|
|
|
|
|
|
|
//
|
|
|
|
// IMPORTANT
|
|
|
|
//
|
|
|
|
// setChallenge and removeChallenge are handed defaults
|
|
|
|
// instead of args because getChallenge does not have
|
|
|
|
// access to args
|
|
|
|
// (args is per-request, defaults is per instance)
|
|
|
|
//
|
|
|
|
// Each of these fires individually for each domain,
|
|
|
|
// even though the certificate on the whole may have many domains
|
|
|
|
//
|
|
|
|
certReq.setChallenge = function (domain, key, value, done) { |
|
|
|
log(args.debug, "setChallenge called for '" + domain + "'"); |
|
|
|
var copy = utils.merge({ domains: [domain] }, le); |
|
|
|
utils.tplCopy(copy); |
|
|
|
|
|
|
|
le.challenge.set(copy, domain, key, value, done); |
|
|
|
}; |
|
|
|
certReq.removeChallenge = function (domain, key, done) { |
|
|
|
log(args.debug, "setChallenge called for '" + domain + "'"); |
|
|
|
var copy = utils.merge({ domains: [domain] }, le); |
|
|
|
utils.tplCopy(copy); |
|
|
|
|
|
|
|
le.challenge.remove(copy, domain, key, done); |
|
|
|
}; |
|
|
|
|
|
|
|
return le.acme.getCertificateAsync(certReq).then(utils.attachCertInfo); |
|
|
|
}); |
|
|
|
}).then(function (results) { |
|
|
|
// { cert, chain, privkey }
|
|
|
@ -260,6 +270,7 @@ module.exports.create = function (le) { |
|
|
|
// Certificates
|
|
|
|
, renewAsync: function (args) { |
|
|
|
// TODO fetch email address (accountBydomain) if not present
|
|
|
|
// store.config.getAsync(args.domains).then(function (config) { /*...*/ });
|
|
|
|
return core.certificates.registerAsync(args); |
|
|
|
} |
|
|
|
// Certificates
|
|
|
@ -284,6 +295,7 @@ module.exports.create = function (le) { |
|
|
|
return core.certificates.checkAsync(args).then(function (certs) { |
|
|
|
if (!certs) { |
|
|
|
// There is no cert available
|
|
|
|
log(args.debug, "no certificate found"); |
|
|
|
return core.certificates.registerAsync(args); |
|
|
|
} |
|
|
|
|
|
|
@ -291,16 +303,26 @@ module.exports.create = function (le) { |
|
|
|
//var halfLife = (certs.expiresAt - certs.issuedAt) / 2;
|
|
|
|
//var renewable = (Date.now() - certs.issuedAt) > halfLife;
|
|
|
|
|
|
|
|
log(args.debug, "Expires At", new Date(certs.expiresAt).toISOString()); |
|
|
|
log(args.debug, "Renewable At", new Date(renewableAt).toISOString()); |
|
|
|
if (args.duplicate || Date.now() >= renewableAt) { |
|
|
|
// The cert is more than half-expired
|
|
|
|
// We're forcing a refresh via 'dupliate: true'
|
|
|
|
log(args.debug, "Renewing!"); |
|
|
|
if (Array.isArray(certs.domains) && certs.domains.length && args.domains.length <= 2) { |
|
|
|
// this is a renewal, therefore we should renewal ALL of the domains
|
|
|
|
// associated with this certificate, unless args.domains is a list larger
|
|
|
|
// than example.com,www.example.com
|
|
|
|
// TODO check www. prefix
|
|
|
|
args.domains = certs.domains; |
|
|
|
} |
|
|
|
return core.certificates.renewAsync(args); |
|
|
|
} |
|
|
|
|
|
|
|
return PromiseA.reject(new Error( |
|
|
|
"[ERROR] Certificate issued at '" |
|
|
|
+ new Date(certs.issuedAt).toISOString() + "' and expires at '" |
|
|
|
+ new Date(certs.expiresAt).toISOString() + "'. Ignoring renewal attempt until half-life at '" |
|
|
|
+ new Date(certs.expiresAt).toISOString() + "'. Ignoring renewal attempt until '" |
|
|
|
+ new Date(renewableAt).toISOString() + "'. Set { duplicate: true } to force." |
|
|
|
)); |
|
|
|
}).then(function (results) { |
|
|
|