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;
 | 
						|
        });
 | 
						|
};
 |