greenlock.js/accounts.js

215 lines
4.7 KiB
JavaScript
Raw Normal View History

2019-10-20 08:51:19 +00:00
'use strict';
var A = module.exports;
var U = require('./utils.js');
var E = require('./errors.js');
var pending = {};
2019-10-27 10:38:05 +00:00
A._getOrCreate = function(gnlck, mconf, db, acme, args) {
var email =
args.subscriberEmail ||
mconf.subscriberEmail ||
gnlck._defaults.subscriberEmail;
2019-10-20 08:51:19 +00:00
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];
}
2019-10-27 10:38:05 +00:00
pending[email] = A._rawGetOrCreate(
gnlck,
mconf,
db,
acme,
args,
email
)
2019-10-20 08:51:19 +00:00
.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
2019-10-27 10:38:05 +00:00
A._rawGetOrCreate = function(gnlck, mconf, db, acme, args, email) {
2019-10-20 08:51:19 +00:00
var p;
if (db.check) {
2019-10-27 10:38:05 +00:00
p = A._checkStore(gnlck, mconf, db, acme, args, email);
2019-10-20 08:51:19 +00:00
} else {
p = Promise.resolve(null);
}
return p.then(function(fullAccount) {
if (!fullAccount) {
2019-10-27 10:38:05 +00:00
return A._newAccount(gnlck, mconf, db, acme, args, email, null);
2019-10-20 08:51:19 +00:00
}
if (fullAccount.keypair && fullAccount.key && fullAccount.key.kid) {
return fullAccount;
}
2019-10-27 10:38:05 +00:00
return A._newAccount(gnlck, mconf, db, acme, args, email, fullAccount);
2019-10-20 08:51:19 +00:00
});
};
2019-10-27 10:38:05 +00:00
A._newAccount = function(gnlck, mconf, db, acme, args, email, fullAccount) {
var keyType =
args.accountKeyType ||
mconf.accountKeyType ||
gnlck._defaults.accountKeyType;
2019-10-20 08:51:19 +00:00
var query = {
subject: args.subject,
email: email,
2019-10-27 10:38:05 +00:00
subscriberEmail: email,
customerEmail: args.customerEmail,
2019-10-20 08:51:19 +00:00
account: fullAccount || {}
};
return U._getOrCreateKeypair(db, args.subject, query, keyType).then(
function(kresult) {
var keypair = kresult.keypair;
var accReg = {
subscriberEmail: email,
agreeToTerms:
2019-10-27 10:38:05 +00:00
args.agreeToTerms ||
mconf.agreeToTerms ||
gnlck._defaults.agreeToTerms,
accountKey: keypair.privateKeyJwk || keypair.private,
2019-10-20 08:51:19 +00:00
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),
2019-10-27 10:38:05 +00:00
email: args.email,
subscriberEmail: email,
customerEmail: args.customerEmail
2019-10-20 08:51:19 +00:00
};
var keyP;
if (kresult.exists) {
keyP = Promise.resolve();
} else {
query.keypair = keypair;
query.receipt = receipt;
2019-10-27 10:38:05 +00:00
query.directoryUrl = gnlck._defaults.directoryUrl;
/*
query.server = gnlck._defaults.directoryUrl.replace(
/^https?:\/\//i,
''
);
*/
2019-10-20 08:51:19 +00:00
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,
2019-10-27 10:38:05 +00:00
subscriberEmail: email,
customerEmail: args.customerEmail,
agreeTos: true,
directoryUrl: gnlck._defaults.directoryUrl
/*
server: gnlck._defaults.directoryUrl.replace(
/^https?:\/\//i,
''
)
*/
2019-10-20 08:51:19 +00:00
},
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;
});
});
}
);
};
2019-10-27 10:38:05 +00:00
A._checkStore = function(gnlck, mconf, db, acme, args, email) {
2019-10-20 08:51:19 +00:00
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 = {};
}
2019-10-27 10:38:05 +00:00
if (args.accountKey) {
2019-10-20 08:51:19 +00:00
console.warn(
2019-10-27 10:38:05 +00:00
'rather than passing accountKey, put it directly into your account key store'
2019-10-20 08:51:19 +00:00
);
// TODO we probably don't need this
2019-10-27 10:38:05 +00:00
return U._importKeypair(args.accountKey);
2019-10-20 08:51:19 +00:00
}
if (!db.check) {
return Promise.resolve(null);
}
return db
.check({
//keypair: undefined,
//receipt: undefined,
email: email,
2019-10-27 10:38:05 +00:00
subscriberEmail: email,
customerEmail: args.customerEmail || mconf.customerEmail,
2019-10-20 08:51:19 +00:00
account: account
})
.then(function(fullAccount) {
if (!fullAccount) {
return null;
}
return fullAccount;
});
};