mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			226 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| var A = module.exports;
 | |
| var U = require('./utils.js');
 | |
| var E = require('./errors.js');
 | |
| 
 | |
| var pending = {};
 | |
| 
 | |
| A._getOrCreate = function(gnlck, mconf, db, acme, args) {
 | |
| 	var email =
 | |
| 		args.subscriberEmail ||
 | |
| 		mconf.subscriberEmail ||
 | |
| 		gnlck._defaults.subscriberEmail;
 | |
| 
 | |
| 	if (!email) {
 | |
| 		throw E.NO_SUBSCRIBER('get account', args.subject);
 | |
| 	}
 | |
| 
 | |
| 	// TODO send welcome message with benefit info
 | |
| 	return U._validMx(email)
 | |
| 		.catch(function() {
 | |
| 			throw E.NO_SUBSCRIBER('get account', args.subcriberEmail);
 | |
| 		})
 | |
| 		.then(function() {
 | |
| 			if (pending[email]) {
 | |
| 				return pending[email];
 | |
| 			}
 | |
| 
 | |
| 			pending[email] = A._rawGetOrCreate(
 | |
| 				gnlck,
 | |
| 				mconf,
 | |
| 				db,
 | |
| 				acme,
 | |
| 				args,
 | |
| 				email
 | |
| 			)
 | |
| 				.catch(function(e) {
 | |
| 					delete pending[email];
 | |
| 					throw e;
 | |
| 				})
 | |
| 				.then(function(result) {
 | |
| 					delete pending[email];
 | |
| 					return result;
 | |
| 				});
 | |
| 
 | |
| 			return pending[email];
 | |
| 		});
 | |
| };
 | |
| 
 | |
| // What we really need out of this is the private key and the ACME "key" id
 | |
| A._rawGetOrCreate = function(gnlck, mconf, db, acme, args, email) {
 | |
| 	var p;
 | |
| 	if (db.check) {
 | |
| 		p = A._checkStore(gnlck, mconf, db, acme, args, email);
 | |
| 	} else {
 | |
| 		p = Promise.resolve(null);
 | |
| 	}
 | |
| 
 | |
| 	return p.then(function(fullAccount) {
 | |
| 		if (!fullAccount) {
 | |
| 			return A._newAccount(gnlck, mconf, db, acme, args, email, null);
 | |
| 		}
 | |
| 
 | |
| 		if (fullAccount.keypair && fullAccount.key && fullAccount.key.kid) {
 | |
| 			return fullAccount;
 | |
| 		}
 | |
| 
 | |
| 		return A._newAccount(gnlck, mconf, db, acme, args, email, fullAccount);
 | |
| 	});
 | |
| };
 | |
| 
 | |
| A._newAccount = function(gnlck, mconf, db, acme, args, email, fullAccount) {
 | |
| 	var keyType =
 | |
| 		args.accountKeyType ||
 | |
| 		mconf.accountKeyType ||
 | |
| 		gnlck._defaults.accountKeyType;
 | |
| 	var query = {
 | |
| 		subject: args.subject,
 | |
| 		email: email,
 | |
| 		subscriberEmail: email,
 | |
| 		customerEmail: args.customerEmail,
 | |
| 		account: fullAccount || {},
 | |
| 		directoryUrl:
 | |
| 			args.directoryUrl ||
 | |
| 			mconf.directoryUrl ||
 | |
| 			gnlck._defaults.directoryUrl
 | |
| 	};
 | |
| 
 | |
| 	return U._getOrCreateKeypair(db, args.subject, query, keyType).then(
 | |
| 		function(kresult) {
 | |
| 			var keypair = kresult.keypair;
 | |
| 			var accReg = {
 | |
| 				subscriberEmail: email,
 | |
| 				agreeToTerms:
 | |
| 					args.agreeToTerms ||
 | |
| 					mconf.agreeToTerms ||
 | |
| 					gnlck._defaults.agreeToTerms,
 | |
| 				accountKey: keypair.privateKeyJwk || keypair.private,
 | |
| 				debug: args.debug
 | |
| 			};
 | |
| 			return acme.accounts.create(accReg).then(function(receipt) {
 | |
| 				var reg = {
 | |
| 					keypair: keypair,
 | |
| 					receipt: receipt,
 | |
| 					// shudder... not actually a KeyID... but so it is called anyway...
 | |
| 					kid:
 | |
| 						receipt &&
 | |
| 						receipt.key &&
 | |
| 						(receipt.key.kid || receipt.kid),
 | |
| 					email: args.email,
 | |
| 					subscriberEmail: email,
 | |
| 					customerEmail: args.customerEmail
 | |
| 				};
 | |
| 
 | |
| 				var keyP;
 | |
| 				if (kresult.exists) {
 | |
| 					keyP = Promise.resolve();
 | |
| 				} else {
 | |
| 					query.keypair = keypair;
 | |
| 					query.receipt = receipt;
 | |
| 					/*
 | |
| 					query.server = gnlck._defaults.directoryUrl.replace(
 | |
| 						/^https?:\/\//i,
 | |
| 						''
 | |
| 					);
 | |
|           */
 | |
| 					keyP = db.setKeypair(query, keypair);
 | |
| 				}
 | |
| 
 | |
| 				return keyP
 | |
| 					.then(function() {
 | |
| 						if (!db.set) {
 | |
| 							return Promise.resolve({
 | |
| 								keypair: keypair
 | |
| 							});
 | |
| 						}
 | |
| 						return db.set(
 | |
| 							{
 | |
| 								// id to be set by Store
 | |
| 								email: email,
 | |
| 								subscriberEmail: email,
 | |
| 								customerEmail: args.customerEmail,
 | |
| 								agreeTos: true,
 | |
| 								agreeToTerms: true,
 | |
| 								directoryUrl:
 | |
| 									args.directoryUrl ||
 | |
| 									mconf.directoryUrl ||
 | |
| 									gnlck._defaults.directoryUrl
 | |
| 								/*
 | |
| 								server: gnlck._defaults.directoryUrl.replace(
 | |
| 									/^https?:\/\//i,
 | |
| 									''
 | |
| 								)
 | |
|                 */
 | |
| 							},
 | |
| 							reg
 | |
| 						);
 | |
| 					})
 | |
| 					.then(function(fullAccount) {
 | |
| 						if (fullAccount && 'object' !== typeof fullAccount) {
 | |
| 							throw new Error(
 | |
| 								"accounts.set should either return 'null' or an object with an 'id' string"
 | |
| 							);
 | |
| 						}
 | |
| 
 | |
| 						if (!fullAccount) {
 | |
| 							fullAccount = {};
 | |
| 						}
 | |
| 						fullAccount.keypair = keypair;
 | |
| 						if (!fullAccount.key) {
 | |
| 							fullAccount.key = {};
 | |
| 						}
 | |
| 						fullAccount.key.kid = reg.kid;
 | |
| 
 | |
| 						return fullAccount;
 | |
| 					});
 | |
| 			});
 | |
| 		}
 | |
| 	);
 | |
| };
 | |
| 
 | |
| A._checkStore = function(gnlck, mconf, db, acme, args, email) {
 | |
| 	if ((args.domain || args.domains) && !args.subject) {
 | |
| 		console.warn("use 'subject' instead of 'domain'");
 | |
| 		args.subject = args.domain;
 | |
| 	}
 | |
| 
 | |
| 	var account = args.account;
 | |
| 	if (!account) {
 | |
| 		account = {};
 | |
| 	}
 | |
| 
 | |
| 	if (args.accountKey) {
 | |
| 		console.warn(
 | |
| 			'rather than passing accountKey, put it directly into your account key store'
 | |
| 		);
 | |
| 		// TODO we probably don't need this
 | |
| 		return U._importKeypair(args.accountKey);
 | |
| 	}
 | |
| 
 | |
| 	if (!db.check) {
 | |
| 		return Promise.resolve(null);
 | |
| 	}
 | |
| 
 | |
| 	return db
 | |
| 		.check({
 | |
| 			//keypair: undefined,
 | |
| 			//receipt: undefined,
 | |
| 			email: email,
 | |
| 			subscriberEmail: email,
 | |
| 			customerEmail: args.customerEmail || mconf.customerEmail,
 | |
| 			account: account,
 | |
| 			directoryUrl:
 | |
| 				args.directoryUrl ||
 | |
| 				mconf.directoryUrl ||
 | |
| 				gnlck._defaults.directoryUrl
 | |
| 		})
 | |
| 		.then(function(fullAccount) {
 | |
| 			if (!fullAccount) {
 | |
| 				return null;
 | |
| 			}
 | |
| 
 | |
| 			return fullAccount;
 | |
| 		});
 | |
| };
 |