| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  | // TODO handle www and no-www together somehow?
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-12 15:05:45 +00:00
										 |  |  | var PromiseA = require('bluebird'); | 
					
						
							| 
									
										
										
										
											2015-12-17 04:59:47 +00:00
										 |  |  | var leCore = require('letiny-core'); | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | var merge = require('./lib/common').merge; | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  | var tplCopy = require('./lib/common').tplCopy; | 
					
						
							| 
									
										
										
										
											2015-12-12 15:05:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  | var LE = module.exports; | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  | LE.productionServerUrl = leCore.productionServerUrl; | 
					
						
							| 
									
										
										
										
											2015-12-17 04:59:47 +00:00
										 |  |  | LE.stagingServerUrl = leCore.stagingServerUrl; | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  | LE.configDir = leCore.configDir; | 
					
						
							| 
									
										
										
										
											2015-12-16 10:07:00 +00:00
										 |  |  | LE.logsDir = leCore.logsDir; | 
					
						
							|  |  |  | LE.workDir = leCore.workDir; | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  | LE.acmeChallengPrefix = leCore.acmeChallengPrefix; | 
					
						
							|  |  |  | LE.knownEndpoints = leCore.knownEndpoints; | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  | LE.privkeyPath = ':config/live/:hostname/privkey.pem'; | 
					
						
							|  |  |  | LE.fullchainPath = ':config/live/:hostname/fullchain.pem'; | 
					
						
							|  |  |  | LE.certPath = ':config/live/:hostname/cert.pem'; | 
					
						
							|  |  |  | LE.chainPath = ':config/live/:hostname/chain.pem'; | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  | LE.renewalPath = ':config/renewal/:hostname.conf'; | 
					
						
							|  |  |  | LE.accountsDir = ':config/accounts/:server'; | 
					
						
							| 
									
										
										
										
											2016-02-12 21:33:50 -05:00
										 |  |  | LE.defaults = { | 
					
						
							|  |  |  |   privkeyPath: LE.privkeyPath | 
					
						
							|  |  |  | , fullchainPath: LE.fullchainPath | 
					
						
							|  |  |  | , certPath: LE.certPath | 
					
						
							|  |  |  | , chainPath: LE.chainPath | 
					
						
							|  |  |  | , renewalPath: LE.renewalPath | 
					
						
							|  |  |  | , accountsDir: LE.accountsDir | 
					
						
							|  |  |  | , server: LE.productionServerUrl | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  | // backwards compat
 | 
					
						
							| 
									
										
										
										
											2015-12-17 04:59:47 +00:00
										 |  |  | LE.stagingServer = leCore.stagingServerUrl; | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  | LE.liveServer = leCore.productionServerUrl; | 
					
						
							|  |  |  | LE.knownUrls = leCore.knownEndpoints; | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | LE.merge = require('./lib/common').merge; | 
					
						
							|  |  |  | LE.tplConfigDir = require('./lib/common').tplConfigDir; | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 01:11:31 -08:00
										 |  |  |                     // backend, defaults, handlers
 | 
					
						
							|  |  |  | LE.create = function (defaults, handlers, backend) { | 
					
						
							|  |  |  |   var d, b, h; | 
					
						
							|  |  |  |   // backwards compat for <= v1.0.2
 | 
					
						
							|  |  |  |   if (defaults.registerAsync || defaults.create) { | 
					
						
							|  |  |  |     b = defaults; d = handlers; h = backend; | 
					
						
							|  |  |  |     defaults = d; handlers = h; backend = b; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-19 02:13:10 -08:00
										 |  |  |   if (!backend) { backend = require('./lib/core'); } | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |   if (!handlers) { handlers = {}; } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   if (!handlers.lifetime) { handlers.lifetime = 90 * 24 * 60 * 60 * 1000; } | 
					
						
							|  |  |  |   if (!handlers.renewWithin) { handlers.renewWithin = 3 * 24 * 60 * 60 * 1000; } | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |   if (!handlers.memorizeFor) { handlers.memorizeFor = 1 * 24 * 60 * 60 * 1000; } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   if (!handlers.sniRegisterCallback) { | 
					
						
							|  |  |  |     handlers.sniRegisterCallback = function (args, cache, cb) { | 
					
						
							|  |  |  |       // TODO when we have ECDSA, just do this automatically
 | 
					
						
							|  |  |  |       cb(null, null); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:40:44 +00:00
										 |  |  |   if (!handlers.getChallenge) { | 
					
						
							| 
									
										
										
										
											2015-12-16 12:57:53 +00:00
										 |  |  |     if (!defaults.manual && !defaults.webrootPath) { | 
					
						
							| 
									
										
										
										
											2015-12-15 15:40:44 +00:00
										 |  |  |       // GET /.well-known/acme-challenge/{{challengeKey}} should return {{tokenValue}}
 | 
					
						
							|  |  |  |       throw new Error("handlers.getChallenge or defaults.webrootPath must be set"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     handlers.getChallenge = function (hostname, key, done) { | 
					
						
							|  |  |  |       // TODO associate by hostname?
 | 
					
						
							|  |  |  |       // hmm... I don't think there's a direct way to associate this with
 | 
					
						
							|  |  |  |       // the request it came from... it's kinda stateless in that way
 | 
					
						
							|  |  |  |       // but realistically there only needs to be one handler and one
 | 
					
						
							|  |  |  |       // "directory" for this. It's not that big of a deal.
 | 
					
						
							|  |  |  |       var defaultos = LE.merge(defaults, {}); | 
					
						
							| 
									
										
										
										
											2015-12-17 04:44:28 +00:00
										 |  |  |       var getChallenge = require('./lib/default-handlers').getChallenge; | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |       var copy = merge(defaults, { domains: [hostname] }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |       tplCopy(copy); | 
					
						
							| 
									
										
										
										
											2015-12-15 15:40:44 +00:00
										 |  |  |       defaultos.domains = [hostname]; | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 04:44:28 +00:00
										 |  |  |       if (3 === getChallenge.length) { | 
					
						
							|  |  |  |         getChallenge(defaultos, key, done); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (4 === getChallenge.length) { | 
					
						
							|  |  |  |         getChallenge(defaultos, hostname, key, done); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         done(new Error("handlers.getChallenge [1] receives the wrong number of arguments")); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:40:44 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-15 03:38:21 -08:00
										 |  |  |   if (!handlers.setChallenge) { | 
					
						
							|  |  |  |     if (!defaults.webrootPath) { | 
					
						
							|  |  |  |       // GET /.well-known/acme-challenge/{{challengeKey}} should return {{tokenValue}}
 | 
					
						
							|  |  |  |       throw new Error("handlers.setChallenge or defaults.webrootPath must be set"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 12:01:05 +00:00
										 |  |  |     handlers.setChallenge = require('./lib/default-handlers').setChallenge; | 
					
						
							| 
									
										
										
										
											2015-12-15 03:38:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!handlers.removeChallenge) { | 
					
						
							|  |  |  |     if (!defaults.webrootPath) { | 
					
						
							|  |  |  |       // GET /.well-known/acme-challenge/{{challengeKey}} should return {{tokenValue}}
 | 
					
						
							| 
									
										
										
										
											2015-12-15 15:40:44 +00:00
										 |  |  |       throw new Error("handlers.removeChallenge or defaults.webrootPath must be set"); | 
					
						
							| 
									
										
										
										
											2015-12-15 03:38:21 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 12:01:46 +00:00
										 |  |  |     handlers.removeChallenge = require('./lib/default-handlers').removeChallenge; | 
					
						
							| 
									
										
										
										
											2015-12-15 03:38:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (!handlers.agreeToTerms) { | 
					
						
							|  |  |  |     if (defaults.agreeTos) { | 
					
						
							|  |  |  |       console.warn("[WARN] Agreeing to terms by default is risky business..."); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 13:12:16 +00:00
										 |  |  |     handlers.agreeToTerms = require('./lib/default-handlers').agreeToTerms; | 
					
						
							| 
									
										
										
										
											2015-12-15 03:38:21 -08:00
										 |  |  |   } | 
					
						
							|  |  |  |   if ('function' === typeof backend.create) { | 
					
						
							|  |  |  |     backend = backend.create(defaults, handlers); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     // ignore
 | 
					
						
							|  |  |  |     // this backend was created the v1.0.0 way
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // replaces strings of workDir, certPath, etc
 | 
					
						
							|  |  |  |   // if they have :config/etc/live or :conf/etc/archive
 | 
					
						
							|  |  |  |   // to instead have the path of the configDir
 | 
					
						
							|  |  |  |   LE.tplConfigDir(defaults.configDir, defaults); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   backend = PromiseA.promisifyAll(backend); | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  |   var utils = require('./lib/common'); | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  |   //var attempts = {};  // should exist in master process only
 | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |   var le; | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-12 15:05:45 +00:00
										 |  |  |   // TODO check certs on initial load
 | 
					
						
							|  |  |  |   // TODO expect that certs expire every 90 days
 | 
					
						
							|  |  |  |   // TODO check certs with setInterval?
 | 
					
						
							|  |  |  |   //options.cacheContextsFor = options.cacheContextsFor || (1 * 60 * 60 * 1000);
 | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |   le = { | 
					
						
							| 
									
										
										
										
											2015-12-15 12:12:15 +00:00
										 |  |  |     backend: backend | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |   , pyToJson: function (pyobj) { | 
					
						
							|  |  |  |       if (!pyobj) { | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var jsobj = {}; | 
					
						
							|  |  |  |       Object.keys(pyobj).forEach(function (key) { | 
					
						
							|  |  |  |         jsobj[key] = pyobj[key]; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       jsobj.__lines = undefined; | 
					
						
							|  |  |  |       jsobj.__keys = undefined; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return jsobj; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 12:12:15 +00:00
										 |  |  |   , validate: function (hostnames, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-12 15:05:45 +00:00
										 |  |  |       // TODO check dns, etc
 | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |       if ((!hostnames.length && hostnames.every(le.isValidDomain))) { | 
					
						
							|  |  |  |         cb(new Error("node-letsencrypt: invalid hostnames: " + hostnames.join(','))); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-13 06:00:30 +00:00
										 |  |  |       //
 | 
					
						
							|  |  |  |       // IMPORTANT
 | 
					
						
							|  |  |  |       //
 | 
					
						
							|  |  |  |       // Before attempting a dynamic registration you need to validate that
 | 
					
						
							|  |  |  |       //
 | 
					
						
							|  |  |  |       //   * these are hostnames that you expected to exist on the system
 | 
					
						
							|  |  |  |       //   * their A records currently point to this ip
 | 
					
						
							|  |  |  |       //   * this system's ip hasn't changed
 | 
					
						
							|  |  |  |       //
 | 
					
						
							|  |  |  |       //  If you do not check these things, then someone could attack you
 | 
					
						
							|  |  |  |       //  and cause you, in return, to have your ip be rate-limit blocked
 | 
					
						
							|  |  |  |       //
 | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  |       //console.warn("\n[TODO]: node-letsencrypt: `validate(hostnames, cb)` needs to be implemented");
 | 
					
						
							|  |  |  |       //console.warn("(it'll work fine without it, but for security - and convenience - it should be implemented\n");
 | 
					
						
							|  |  |  |       // UPDATE:
 | 
					
						
							|  |  |  |       // it's actually probably better that we don't do this here and instead
 | 
					
						
							|  |  |  |       // take care of it in the approveRegistrationCallback in letsencrypt-express
 | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |       cb(null, true); | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   , _registerHelper: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |       var copy = LE.merge(defaults, args); | 
					
						
							|  |  |  |       var err; | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (!utils.isValidDomain(args.domains[0])) { | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |         err = new Error("invalid domain"); | 
					
						
							|  |  |  |         err.code = "INVALID_DOMAIN"; | 
					
						
							|  |  |  |         cb(err); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |       le.validate(args.domains, function (err) { | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |         if (err) { | 
					
						
							|  |  |  |           cb(err); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |         if (defaults.debug || args.debug) { | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |           console.log("[NLE]: begin registration"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |         return backend.registerAsync(copy).then(function (pems) { | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |           if (defaults.debug || args.debug) { | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |             console.log("[NLE]: end registration"); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |           cb(null, pems); | 
					
						
							|  |  |  |           //return le.fetch(args, cb);
 | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |         }, cb); | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   , _fetchHelper: function (args, cb) { | 
					
						
							|  |  |  |       return backend.fetchAsync(args).then(function (certInfo) { | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |         if (args.debug) { | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |           console.log('[LE] raw fetch certs', certInfo && Object.keys(certInfo)); | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (!certInfo) { cb(null, null); return; } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // key, cert, issuedAt, lifetime, expiresAt
 | 
					
						
							|  |  |  |         if (!certInfo.expiresAt) { | 
					
						
							|  |  |  |           certInfo.expiresAt = certInfo.issuedAt + (certInfo.lifetime || handlers.lifetime); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!certInfo.lifetime) { | 
					
						
							|  |  |  |           certInfo.lifetime = (certInfo.lifetime || handlers.lifetime); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // a pretty good hard buffer
 | 
					
						
							|  |  |  |         certInfo.expiresAt -= (1 * 24 * 60 * 60 * 100); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |         cb(null, certInfo); | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |       }, cb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |   , fetch: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] fetch'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |       le._fetchHelper(args, cb); | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |   , renew: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] renew'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-17 05:44:41 +00:00
										 |  |  |       args.duplicate = false; | 
					
						
							|  |  |  |       le.register(args, cb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |   , getConfig: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] getConfig'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |       backend.getConfigAsync(args).then(function (pyobj) { | 
					
						
							|  |  |  |         cb(null, le.pyToJson(pyobj)); | 
					
						
							|  |  |  |       }, function (err) { | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |         console.error("[letsencrypt/index.js] getConfig"); | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |         console.error(err.stack); | 
					
						
							|  |  |  |         return cb(null, []); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , getConfigs: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] getConfigs'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |       backend.getConfigsAsync(args).then(function (configs) { | 
					
						
							|  |  |  |         cb(null, configs.map(le.pyToJson)); | 
					
						
							|  |  |  |       }, function (err) { | 
					
						
							|  |  |  |         if ('ENOENT' === err.code) { | 
					
						
							|  |  |  |           cb(null, []); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |           console.error("[letsencrypt/index.js] getConfigs"); | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |           console.error(err.stack); | 
					
						
							|  |  |  |           cb(err); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   , setConfig: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] setConfig'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |       backend.configureAsync(args).then(function (pyobj) { | 
					
						
							|  |  |  |         cb(null, le.pyToJson(pyobj)); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |   , register: function (args, cb) { | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       if (defaults.debug || args.debug) { | 
					
						
							|  |  |  |         console.log('[LE] register'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-16 12:57:53 +00:00
										 |  |  |       if (!Array.isArray(args.domains)) { | 
					
						
							|  |  |  |         cb(new Error('args.domains should be an array of domains')); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |       // this may be run in a cluster environment
 | 
					
						
							|  |  |  |       // in that case it should NOT check the cache
 | 
					
						
							|  |  |  |       // but ensure that it has the most fresh copy
 | 
					
						
							|  |  |  |       // before attempting a renew
 | 
					
						
							|  |  |  |       le._fetchHelper(args, function (err, hit) { | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |         var now = Date.now(); | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |         if (err) { | 
					
						
							|  |  |  |           // had a bad day
 | 
					
						
							|  |  |  |           cb(err); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (hit) { | 
					
						
							| 
									
										
										
										
											2015-12-17 09:17:27 +00:00
										 |  |  |           if (!args.duplicate && (now - hit.issuedAt) < ((hit.lifetime || handlers.lifetime) * 0.65)) { | 
					
						
							|  |  |  |             console.warn("\ntried to renew a certificate with over 1/3 of its lifetime left, ignoring"); | 
					
						
							|  |  |  |             console.warn("(use --duplicate or opts.duplicate to override\n"); | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |             cb(null, hit); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |         le._registerHelper(args, function (err/*, pems*/) { | 
					
						
							| 
									
										
										
										
											2015-12-13 05:03:48 +00:00
										 |  |  |           if (err) { | 
					
						
							|  |  |  |             cb(err); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  |           // Sanity Check
 | 
					
						
							|  |  |  |           le._fetchHelper(args, function (err, pems) { | 
					
						
							|  |  |  |             if (pems) { | 
					
						
							|  |  |  |               cb(null, pems); | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |             // still couldn't read the certs after success... that's weird
 | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |             console.error("still couldn't read certs after success... that's weird"); | 
					
						
							| 
									
										
										
										
											2015-12-13 01:04:12 +00:00
										 |  |  |             cb(err, null); | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-12 14:20:12 +00:00
										 |  |  |   return le; | 
					
						
							| 
									
										
										
										
											2015-12-11 06:22:46 -08:00
										 |  |  | }; |