| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | var LE = require('../'); | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | var ipc = {}; // in-process cache
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  | module.exports.create = function (defaults, handlers, backend) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |   var backendDefaults = backend.getDefaults && backend.getDefaults || backend.defaults || {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   defaults.server = defaults.server || LE.liveServer; | 
					
						
							|  |  |  |   handlers.merge = require('./common').merge; | 
					
						
							|  |  |  |   handlers.tplCopy = require('./common').tplCopy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var PromiseA = require('bluebird'); | 
					
						
							|  |  |  |   var RSA = PromiseA.promisifyAll(require('rsa-compat').RSA); | 
					
						
							|  |  |  |   var LeCore = PromiseA.promisifyAll(require('letiny-core')); | 
					
						
							|  |  |  |   var crypto = require('crypto'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |   function attachCertInfo(results) { | 
					
						
							|  |  |  |     var getCertInfo = require('./cert-info').getCertInfo; | 
					
						
							|  |  |  |     // XXX Note: Parsing the certificate info comes at a great cost (~500kb)
 | 
					
						
							|  |  |  |     var certInfo = getCertInfo(results.cert); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //results.issuedAt = arr[3].mtime.valueOf()
 | 
					
						
							|  |  |  |     results.issuedAt = Date(certInfo.notBefore.value).valueOf(); // Date.now()
 | 
					
						
							|  |  |  |     results.expiresAt = Date(certInfo.notAfter.value).valueOf(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return results; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   function createAccount(args, handlers) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |     args.rsaKeySize = args.rsaKeySize || 2048; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return RSA.generateKeypairAsync(args.rsaKeySize, 65537, { public: true, pem: true }).then(function (keypair) { | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return LeCore.registerNewAccountAsync({ | 
					
						
							|  |  |  |         email: args.email | 
					
						
							|  |  |  |       , newRegUrl: args._acmeUrls.newReg | 
					
						
							|  |  |  |       , agreeToTerms: function (tosUrl, agree) { | 
					
						
							|  |  |  |           // args.email = email; // already there
 | 
					
						
							|  |  |  |           args.tosUrl = tosUrl; | 
					
						
							|  |  |  |           handlers.agreeToTerms(args, agree); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       , accountKeypair: keypair | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       , debug: defaults.debug || args.debug || handlers.debug | 
					
						
							|  |  |  |       }).then(function (body) { | 
					
						
							|  |  |  |         // TODO XXX use sha256 (the python client uses md5)
 | 
					
						
							|  |  |  |         // TODO ssh fingerprint (noted on rsa-compat issues page, I believe)
 | 
					
						
							|  |  |  |         keypair.publicKeyMd5 = crypto.createHash('md5').update(RSA.exportPublicPem(keypair)).digest('hex'); | 
					
						
							|  |  |  |         keypair.publicKeySha256 = crypto.createHash('sha256').update(RSA.exportPublicPem(keypair)).digest('hex'); | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         var accountId = keypair.publicKeyMd5; | 
					
						
							|  |  |  |         var regr = { body: body }; | 
					
						
							|  |  |  |         var account = {}; | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         args.accountId = accountId; | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         account.keypair = keypair; | 
					
						
							|  |  |  |         account.regr = regr; | 
					
						
							|  |  |  |         account.accountId = accountId; | 
					
						
							|  |  |  |         account.id = accountId; | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         args.account = account; | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         return backend.setAccountAsync(args, account).then(function () { | 
					
						
							|  |  |  |           return account; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   function getAcmeUrls(args) { | 
					
						
							|  |  |  |     var now = Date.now(); | 
					
						
							| 
									
										
										
										
											2015-12-20 02:01:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     // TODO check response header on request for cache time
 | 
					
						
							|  |  |  |     if ((now - ipc.acmeUrlsUpdatedAt) < 10 * 60 * 1000) { | 
					
						
							|  |  |  |       return PromiseA.resolve(ipc.acmeUrls); | 
					
						
							| 
									
										
										
										
											2015-12-20 03:31:05 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     return LeCore.getAcmeUrlsAsync(args.server).then(function (data) { | 
					
						
							|  |  |  |       ipc.acmeUrlsUpdatedAt = Date.now(); | 
					
						
							|  |  |  |       ipc.acmeUrls = data; | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       return ipc.acmeUrls; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   function getCertificateAsync(args, defaults, handlers) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |     args.rsaKeySize = args.rsaKeySize || 2048; | 
					
						
							|  |  |  |     args.challengeType = args.challengeType || 'http-01'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     function log() { | 
					
						
							|  |  |  |       if (args.debug || defaults.debug) { | 
					
						
							|  |  |  |         console.log.apply(console, arguments); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     var account = args.account; | 
					
						
							|  |  |  |     var promise; | 
					
						
							|  |  |  |     var keypairOpts = { public: true, pem: true }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     promise = backend.getPrivatePem(args).then(function (pem) { | 
					
						
							|  |  |  |       return RSA.import({ privateKeyPem: pem }); | 
					
						
							|  |  |  |     }, function (/*err*/) { | 
					
						
							|  |  |  |       return RSA.generateKeypairAsync(args.rsaKeySize, 65537, keypairOpts).then(function (keypair) { | 
					
						
							|  |  |  |         keypair.privateKeyPem = RSA.exportPrivatePem(keypair); | 
					
						
							|  |  |  |         keypair.privateKeyJwk = RSA.exportPrivateJwk(keypair); | 
					
						
							|  |  |  |         return backend.setPrivatePem(args, keypair); | 
					
						
							| 
									
										
										
										
											2016-08-01 17:11:42 -04:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     return promise.then(function (domainKeypair) { | 
					
						
							|  |  |  |       log("[le/core.js] get certificate"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       args.domainKeypair = domainKeypair; | 
					
						
							|  |  |  |       //args.registration = domainKey;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return LeCore.getCertificateAsync({ | 
					
						
							|  |  |  |         debug: args.debug | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       , newAuthzUrl: args._acmeUrls.newAuthz | 
					
						
							|  |  |  |       , newCertUrl: args._acmeUrls.newCert | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       , accountKeypair: RSA.import(account.keypair) | 
					
						
							|  |  |  |       , domainKeypair: domainKeypair | 
					
						
							|  |  |  |       , domains: args.domains | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |       , challengeType: args.challengeType | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         //
 | 
					
						
							|  |  |  |         // 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) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           var copy = handlers.merge({ domains: [domain] }, defaults, backendDefaults); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |           handlers.tplCopy(copy); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           //args.domains = [domain];
 | 
					
						
							|  |  |  |           args.domains = args.domains || [domain]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (5 !== handlers.setChallenge.length) { | 
					
						
							|  |  |  |             done(new Error("handlers.setChallenge receives the wrong number of arguments." | 
					
						
							|  |  |  |               + " You must define setChallenge as function (opts, domain, key, val, cb) { }")); | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |           handlers.setChallenge(copy, domain, key, value, done); | 
					
						
							| 
									
										
										
										
											2015-12-17 04:44:28 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       , removeChallenge: function (domain, key, done) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           var copy = handlers.merge({ domains: [domain] }, defaults, backendDefaults); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |           handlers.tplCopy(copy); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           if (4 !== handlers.removeChallenge.length) { | 
					
						
							|  |  |  |             done(new Error("handlers.removeChallenge receives the wrong number of arguments." | 
					
						
							|  |  |  |               + " You must define removeChallenge as function (opts, domain, key, cb) { }")); | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |           handlers.removeChallenge(copy, domain, key, done); | 
					
						
							| 
									
										
										
										
											2015-12-17 04:44:28 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |       }).then(attachCertInfo); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     }).then(function (results) { | 
					
						
							|  |  |  |       // { cert, chain, fullchain, privkey }
 | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       args.pems = results; | 
					
						
							|  |  |  |       return backend.setRegistration(args, defaults, handlers); | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   function getOrCreateDomainCertificate(args, defaults, handlers) { | 
					
						
							|  |  |  |     if (args.duplicate) { | 
					
						
							|  |  |  |       // we're forcing a refresh via 'dupliate: true'
 | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  |       return getCertificateAsync(args, defaults, handlers); | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |     return wrapped.fetchAsync(args).then(function (certs) { | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       var halfLife = (certs.expiresAt - certs.issuedAt) / 2; | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       if (!certs || (Date.now() - certs.issuedAt) > halfLife) { | 
					
						
							|  |  |  |         // There is no cert available
 | 
					
						
							|  |  |  |         // Or the cert is more than half-expired
 | 
					
						
							|  |  |  |         return getCertificateAsync(args, defaults, handlers); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       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.issuedA + halfLife).toISOString() + "'. Set { duplicate: true } to force." | 
					
						
							|  |  |  |       )); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   // returns 'account' from lib/accounts { meta, regr, keypair, accountId (id) }
 | 
					
						
							|  |  |  |   function getOrCreateAcmeAccount(args, defaults, handlers) { | 
					
						
							|  |  |  |     function log() { | 
					
						
							|  |  |  |       if (args.debug) { | 
					
						
							|  |  |  |         console.log.apply(console, arguments); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |     return backend.getAccountId(args).then(function (accountId) { | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       // Note: the ACME urls are always fetched fresh on purpose
 | 
					
						
							|  |  |  |       return getAcmeUrls(args).then(function (urls) { | 
					
						
							|  |  |  |         args._acmeUrls = urls; | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         if (accountId) { | 
					
						
							|  |  |  |           log('[le/core.js] use account'); | 
					
						
							| 
									
										
										
										
											2016-08-04 14:26:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |           args.accountId = accountId; | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           return backend.getAccount(args, handlers); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         } else { | 
					
						
							|  |  |  |           log('[le/core.js] create account'); | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |           return createAccount(args, handlers); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   var wrapped = { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |     registerAsync: function (args) { | 
					
						
							|  |  |  |       var utils = require('./lib/common'); | 
					
						
							|  |  |  |       var err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!Array.isArray(args.domains)) { | 
					
						
							|  |  |  |         return PromiseA.reject(new Error('args.domains should be an array of domains')); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!(args.domains.length && args.domains.every(utils.isValidDomain))) { | 
					
						
							|  |  |  |         // NOTE: this library can't assume to handle the http loopback
 | 
					
						
							|  |  |  |         // (or dns-01 validation may be used)
 | 
					
						
							|  |  |  |         // so we do not check dns records or attempt a loopback here
 | 
					
						
							|  |  |  |         err = new Error("invalid domain name(s): '" + args.domains + "'"); | 
					
						
							|  |  |  |         err.code = "INVALID_DOMAIN"; | 
					
						
							|  |  |  |         return PromiseA.reject(err); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var copy = handlers.merge(args, defaults, backendDefaults); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |       handlers.tplCopy(copy); | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |       return getOrCreateAcmeAccount(copy, defaults, handlers).then(function (account) { | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  |         copy.account = account; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         return backend.getOrCreateRenewal(copy).then(function (pyobj) { | 
					
						
							| 
									
										
										
										
											2015-12-20 05:13:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           copy.pyobj = pyobj; | 
					
						
							|  |  |  |           return getOrCreateDomainCertificate(copy, defaults, handlers); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-02-10 15:41:15 -05:00
										 |  |  |       }).then(function (result) { | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |       }, function (err) { | 
					
						
							|  |  |  |         return PromiseA.reject(err); | 
					
						
							| 
									
										
										
										
											2015-12-20 00:27:48 +00:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |   , getOrCreateAccount: function (args) { | 
					
						
							|  |  |  |       return createAccount(args, handlers); | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |   , configureAsync: function (hargs) { | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |       var copy = handlers.merge(hargs, defaults, backendDefaults); | 
					
						
							|  |  |  |       handlers.tplCopy(copy); | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:27:57 -07:00
										 |  |  |       return getOrCreateAcmeAccount(copy, defaults, handlers).then(function (account) { | 
					
						
							|  |  |  |         copy.account = account; | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  |         return backend.getOrCreateRenewal(copy); | 
					
						
							| 
									
										
										
										
											2015-12-20 02:41:17 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-05 04:14:40 -04:00
										 |  |  |   , fetchAsync: function (args) { | 
					
						
							|  |  |  |       var copy = handlers.merge(args, defaults); | 
					
						
							|  |  |  |       handlers.tplCopy(copy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return backend.fetchAsync(copy).then(attachCertInfo); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-12-15 03:37:39 -08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return wrapped; | 
					
						
							|  |  |  | }; |