[FEATURE] vault client: function for 2FA settings

This commit is contained in:
Matthew Fettig
2014-07-07 10:21:04 -07:00
parent aea75f2beb
commit 7be13bebfc
3 changed files with 161 additions and 94 deletions

View File

@@ -7,12 +7,15 @@ var log = require('./log').sub('blob');
var BlobClient = {};
//Blob object class
function BlobObj(url, id, key) {
this.url = url;
this.id = id;
this.key = key;
this.identity = new Identity(this);
this.data = { };
function BlobObj(options) {
if (!options) options = { };
this.device_id = options.device_id;
this.url = options.url;
this.id = options.blob_id;
this.key = options.key;
this.identity = new Identity(this);
this.data = { };
};
// Blob operations
@@ -96,11 +99,16 @@ BlobObj.prototype.init = function(fn) {
self.url = 'http://' + url;
}
url = self.url + '/v1/blob/' + self.id;
url = self.url + '/v1/blob/' + self.id;
url += '?'
request.get(url, function(err, resp) {
if (err || !resp.body || resp.body.result !== 'success') {
if (err) {
return fn(new Error(err.message || 'Could not retrieve blob'));
} else if (!resp.body) {
return fn(new Error('Could not retrieve blob'));
} else if (resp.body.result !== 'success') {
return fn(new Error('Incorrect username or password'));
}
self.revision = resp.body.revision;
@@ -513,6 +521,50 @@ BlobObj.prototype.postUpdate = function(op, pointer, params, fn) {
});
};
/**
* set2FA
* modify 2 factor auth settings
* @params {object} options
* @params {string}
* @params {boolean} options.remember_me //remember for 30 days
* @params {boolean} options.enabled
* @params {string} options.phone
* @params {string} options.country_code
* @params {string} options.via //sms, etc
*/
BlobObj.prototype.set2FA = function(options, fn) {
var config = {
method : 'POST',
url : this.url + '/v1/blob/' + this.id + '/2FA',
data : {
remember_me : options.remember_me,
enabled : options.enabled,
phone : options.phone,
country_code : options.country_code,
via : options.via
}
};
var signedRequest = new SignedRequest(config);
var signed = signedRequest.signAsymmetric(options.masterkey, this.data.account_id, this.id);
request.post(signed.url)
.send(signed.data)
.end(function(err, resp) {
if (err) {
fn(err);
} else if (resp.body && resp.body.result === 'success') {
fn(null, resp.body);
} else if (resp.body && resp.body.result === 'error') {
fn(new Error(resp.body.message));
} else {
fn(new Error('Unable to update settings.'));
}
});
};
/***** helper functions *****/
function normalizeSubcommands(subcommands, compress) {
@@ -796,7 +848,7 @@ exports.Blob = BlobObj;
* Get ripple name for a given address
*/
exports.getRippleName = function(url, address, fn) {
BlobClient.getRippleName = function(url, address, fn) {
if (!crypt.isValidAddress(address)) {
return fn (new Error('Invalid ripple address'));
}
@@ -817,10 +869,15 @@ exports.getRippleName = function(url, address, fn) {
/**
* Retrive a blob with url, id and key
* @params {object} options
* @params {string} options.url
* @params {string} options.blob_id
* @params {string} options.key
* @params {string} options.device_id //optional
*/
BlobClient.get = function (url, id, crypt, fn) {
var blob = new BlobObj(url, id, crypt);
BlobClient.get = function (options, fn) {
var blob = new BlobObj(options);
blob.init(fn);
};
@@ -842,8 +899,15 @@ BlobClient.verify = function(url, username, token, fn) {
};
/**
* ResendEmail
* resend verification email
* resendEmail
* send a new verification email
* @param {object} opts
* @param {string} opts.id
* @param {string} opts.username
* @param {string} opts.account_id
* @param {string} opts.email
* @param {string} opts.activateLink
* @param {function} fn - Callback
*/
BlobClient.resendEmail = function (opts, fn) {
@@ -916,9 +980,14 @@ BlobClient.recoverBlob = function (opts, fn) {
});
function handleRecovery (resp) {
//decrypt crypt key
var crypt = decryptBlobCrypt(opts.masterkey, resp.body.encrypted_blobdecrypt_key);
var blob = new BlobObj(opts.url, resp.body.blob_id, crypt);
var params = {
url : opts.url,
blob_id : resp.body.blob_id,
key : decryptBlobCrypt(opts.masterkey, resp.body.encrypted_blobdecrypt_key)
}
var blob = new BlobObj(params);
blob.revision = resp.body.revision;
blob.encrypted_secret = resp.body.encrypted_secret;
@@ -946,8 +1015,18 @@ BlobClient.recoverBlob = function (opts, fn) {
/**
* updateProfile
* update information stored outside the blob
*/
* update information stored outside the blob - HMAC signed
* @param {object}
* @param {string} opts.url
* @param {string} opts.username
* @param {string} opts.auth_secret
* @param {srring} opts.blob_id
* @param {object} opts.profile
* @param {string} opts.profile.phone - optional
* @param {string} opts.profile.country - optional
* @param {string} opts.profile.region - optional
* @param {string} opts.profile.city - optional
*/
BlobClient.updateProfile = function (opts, fn) {
var config = {
@@ -1088,7 +1167,12 @@ BlobClient.rename = function (opts, fn) {
*/
BlobClient.create = function(options, fn) {
var blob = new BlobObj(options.url, options.id, options.crypt);
var params = {
url : options.url,
blob_id : options.id,
key : options.crypt
}
var blob = new BlobObj(params);
blob.revision = 0;
@@ -1144,7 +1228,13 @@ BlobClient.create = function(options, fn) {
};
/**
* deleteBlob
* deleteBlob
* @param {object} options
* @param {string} options.url
* @param {string} options.username
* @param {string} options.blob_id
* @param {string} options.account_id
* @param {string} options.masterkey
*/
BlobClient.deleteBlob = function(options, fn) {

View File

@@ -133,7 +133,7 @@ VaultClient.prototype.exists = function(username, callback) {
* @param {function} fn - Callback function
*/
VaultClient.prototype.login = function(username, password, callback) {
VaultClient.prototype.login = function(username, password, device_id, callback) {
var self = this;
var steps = [
@@ -156,7 +156,14 @@ VaultClient.prototype.login = function(username, password, callback) {
}
function getBlob(authInfo, password, keys, callback) {
blobClient.get(authInfo.blobvault, keys.id, keys.crypt, function(err, blob) {
var options = {
url : authInfo.blobvault,
blob_id : keys.id,
key : keys.crypt,
device_id : device_id
};
blobClient.get(options, function(err, blob) {
if (err) {
return callback(err);
}
@@ -218,7 +225,7 @@ VaultClient.prototype.login = function(username, password, callback) {
* @param {function} fn - Callback function
*/
VaultClient.prototype.relogin = function(url, id, key, callback) {
VaultClient.prototype.relogin = function(url, id, key, device_id, callback) {
//use the url from previously retrieved authInfo, if necessary
if (!url && this.infos[id]) {
url = this.infos[id].blobvault;
@@ -228,7 +235,14 @@ VaultClient.prototype.relogin = function(url, id, key, callback) {
return callback(new Error('Blob vault URL is required'));
}
blobClient.get(url, id, key, function(err, blob) {
var options = {
url : url,
blob_id : id,
key : key,
device_id : device_id
};
blobClient.get(options, function(err, blob) {
if (err) {
callback(err);
} else {
@@ -293,7 +307,7 @@ VaultClient.prototype.unlock = function(username, password, encryptSecret, fn) {
* @param {function} fn - Callback function
*/
VaultClient.prototype.loginAndUnlock = function(username, password, fn) {
VaultClient.prototype.loginAndUnlock = function(username, password, device_id, fn) {
var self = this;
var steps = [
@@ -305,7 +319,7 @@ VaultClient.prototype.loginAndUnlock = function(username, password, fn) {
async.waterfall(steps, fn);
function login (callback) {
self.login(username, password, function(err, resp) {
self.login(username, password, device_id, function(err, resp) {
if (err) {
return callback(err);
@@ -374,69 +388,6 @@ VaultClient.prototype.verify = function(username, token, callback) {
});
};
/**
* resendEmail
* send a new verification email
* @param {object} options
* @param {string} options.id
* @param {string} options.username
* @param {string} options.account_id
* @param {string} options.email
* @param {string} options.activateLink
* @param {function} fn - Callback
*/
VaultClient.prototype.resendEmail = function (options, fn) {
blobClient.resendEmail(options, fn);
};
/**
* deleteBlob
* @param {object} options
* @param {string} options.url
* @param {string} options.username
* @param {string} options.blob_id
* @param {string} options.account_id
* @param {string} options.masterkey
*/
VaultClient.prototype.deleteBlob = function (options, fn) {
blobClient.deleteBlob(options, fn);
};
/**
* updateProfile
* update information stored outside the blob
* @param {object}
* @param {string} options.url
* @param {string} options.username
* @param {string} options.auth_secret
* @param {srring} options.blob_id
* @param {object} options.profile
* @param {string} options.profile.phone - optional
* @param {string} options.profile.country - optional
* @param {string} options.profile.region - optional
* @param {string} options.profile.city - optional
*/
VaultClient.prototype.updateProfile = function (options, fn) {
blobClient.updateProfile(options, fn);
};
/**
* recoverBlob
* recover blob with account secret
* @param {object} options
* @param {string} options.url
* @param {string} options.username
* @param {string} options.masterkey
* @param {function}
*/
VaultClient.prototype.recoverBlob = function (options, fn) {
blobClient.recoverBlob(options, fn);
};
/*
* changePassword
* @param {object} options
@@ -581,6 +532,11 @@ VaultClient.prototype.register = function(options, fn) {
};
};
/**
* validateUsername
* check username for validity
*/
VaultClient.prototype.validateUsername = function (username) {
username = String(username).trim();
var result = {
@@ -607,4 +563,24 @@ VaultClient.prototype.validateUsername = function (username) {
return result;
};
/**
* generateDeviceID
* create a new random device ID for 2FA
*/
VaultClient.prototype.generateDeviceID = function () {
return crypt.createSecret(4);
};
/*** pass thru some blob client function ***/
VaultClient.prototype.resendEmail = blobClient.resendEmail;
VaultClient.prototype.updateProfile = blobClient.updateProfile;
VaultClient.prototype.recoverBlob = blobClient.recoverBlob;
VaultClient.prototype.deleteBlob = blobClient.deleteBlob;
//export by name
exports.VaultClient = VaultClient;