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