mirror of
				https://github.com/therootcompany/greenlock.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			220 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			6.8 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;
 | |
| 
 | |
|     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;
 | |
|     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;
 | |
|         });
 | |
| };
 |