mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 19:55:51 +00:00
Merge pull request #103 from shekenahglory/develop
[FEATURE] vault client: updateProfile and deleteBlob
This commit is contained in:
@@ -11,6 +11,14 @@ data stored using credentials originally obtained at ripple.com
|
||||
## Vault Client Usage
|
||||
|
||||
vaultClient = new ripple.VaultClient(domain);
|
||||
|
||||
vaultClient.getAuthInfo(username, callback);
|
||||
|
||||
vaultClient.getRippleName(address, url, callback);
|
||||
|
||||
vaultClient.exists(username, callback);
|
||||
|
||||
|
||||
|
||||
vaultClient.login(username, password, callback);
|
||||
|
||||
@@ -20,20 +28,24 @@ data stored using credentials originally obtained at ripple.com
|
||||
|
||||
vaultClient.loginAndUnlock(username, password, callback);
|
||||
|
||||
vaultClient.exists(username, callback);
|
||||
|
||||
|
||||
vaultClient.register(options, callback);
|
||||
|
||||
vaultClient.deleteBlob(options, callback);
|
||||
|
||||
vaultClient.recoverBlob(options, callback);
|
||||
|
||||
vaultClient.rename(options, callback);
|
||||
|
||||
vaultClient.changePassword(options, callback);
|
||||
|
||||
vaultClient.recoverBlob(options, callback);
|
||||
|
||||
|
||||
vaultClient.verify(username, token, callback);
|
||||
|
||||
vaultClient.resendEmail(options, callback);
|
||||
|
||||
vaultClient.updateProfile(options, fn);
|
||||
|
||||
|
||||
# Blob Methods
|
||||
|
||||
@@ -102,48 +114,55 @@ data stored using credentials originally obtained at ripple.com
|
||||
|
||||
Run `npm test` to test the high-level behavior specs
|
||||
|
||||
Ripple Txt
|
||||
✓ should get the context of a ripple.txt file from a given domain
|
||||
Ripple Txt
|
||||
✓ should get the content of a ripple.txt file from a given domain
|
||||
✓ should get currencies from a ripple.txt file for a given domain
|
||||
✓ should get the domain from a given url
|
||||
|
||||
AuthInfo
|
||||
✓ should get authinfo given a domain and username
|
||||
AuthInfo
|
||||
✓ should get auth info
|
||||
|
||||
Ripple Vault Client
|
||||
#initialization
|
||||
✓ should be initialized with a domain
|
||||
✓ should default to ripple.com without a domain
|
||||
#login
|
||||
✓ with username and password should retrive the blob, crypt key, and id
|
||||
#relogin
|
||||
✓ should retrieve the decrypted blob with id and crypt key
|
||||
#unlock
|
||||
✓ should access the wallet secret using encryption secret, username and password
|
||||
#loginAndUnlock
|
||||
✓ should get the decrypted blob and decrypted secret given name and password
|
||||
VaultClient
|
||||
#initialization
|
||||
✓ should be initialized with a domain
|
||||
✓ should default to ripple.com without a domain
|
||||
#exists
|
||||
✓ should determine if a username exists on the domain
|
||||
#login
|
||||
✓ with username and password should retrive the blob, crypt key, and id
|
||||
#relogin
|
||||
✓ should retrieve the decrypted blob with blob vault url, id, and crypt key
|
||||
#unlock
|
||||
✓ should access the wallet secret using encryption secret, username and password
|
||||
#loginAndUnlock
|
||||
✓ should get the decrypted blob and decrypted secret given name and password
|
||||
#register
|
||||
✓ should create a new blob
|
||||
#deleteBlob
|
||||
✓ should remove an existing blob
|
||||
#updateProfile
|
||||
✓ should update profile parameters associated with a blob
|
||||
|
||||
|
||||
Blob
|
||||
#set
|
||||
✓ should set a new property in the blob
|
||||
#extend
|
||||
✓ should extend an object in the blob
|
||||
#unset
|
||||
✓ should remove a property from the blob
|
||||
#unshift
|
||||
✓ should prepend an item to an array in the blob
|
||||
#filter
|
||||
✓ should find a specific entity in an array and apply subcommands to it
|
||||
#consolidate
|
||||
✓ should consolidate and save changes to the blob
|
||||
|
||||
|
||||
#identity_set
|
||||
✓ should set an identity property
|
||||
#identity_get
|
||||
✓ should retreive an identity property given the property name and encryption key
|
||||
#identity_getAll
|
||||
✓ should retreive all identity properties given the encryption key
|
||||
#identity_getFullAddress
|
||||
✓ should retreive the address as a string
|
||||
#identity_unset
|
||||
✓ should remove an identity property
|
||||
Blob
|
||||
✓ #set
|
||||
✓ #extend
|
||||
✓ #unset
|
||||
✓ #unshift
|
||||
✓ #filter
|
||||
✓ #consolidate
|
||||
#rename
|
||||
✓ should change the username of a blob
|
||||
#changePassword
|
||||
✓ should change the password and keys of a blob
|
||||
#recoverBlob
|
||||
✓ should recover the blob given a username and secret
|
||||
#verifyEmail
|
||||
✓ should verify an email given a username and token
|
||||
#resendVerifcationEmail
|
||||
✓ should resend a verification given options
|
||||
identity
|
||||
✓ #identity_set
|
||||
✓ #identity_get
|
||||
✓ #identity_getAll
|
||||
✓ #identity_getFullAddress
|
||||
✓ #identity_unset
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
var crypt = require('./crypt').Crypt;
|
||||
var SignedRequest = require('./signedrequest').SignedRequest;
|
||||
var request = require('superagent');
|
||||
var extend = require("extend");
|
||||
var async = require("async");
|
||||
|
||||
var request = require('superagent');
|
||||
var extend = require("extend");
|
||||
var async = require("async");
|
||||
var log = require('./log').sub('blob');
|
||||
var BlobClient = {};
|
||||
|
||||
//Blob object class
|
||||
@@ -865,12 +865,12 @@ BlobClient.resendEmail = function (opts, fn) {
|
||||
.send(signed.data)
|
||||
.end(function(err, resp) {
|
||||
if (err) {
|
||||
console.log("blob: could not resend the token:", err);
|
||||
log.error("resendEmail:", err);
|
||||
fn(new Error("Failed to resend the token"));
|
||||
} else if (resp.body && resp.body.result === 'success') {
|
||||
fn(null, resp.body);
|
||||
} else if (resp.body && resp.body.result === 'error') {
|
||||
console.log("blob: could not resend the token:", resp.body.message);
|
||||
log.error("resendEmail:", resp.body.message);
|
||||
fn(new Error("Failed to resend the token"));
|
||||
} else {
|
||||
fn(new Error("Failed to resend the token"));
|
||||
@@ -944,6 +944,39 @@ BlobClient.recoverBlob = function (opts, fn) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* updateProfile
|
||||
* update information stored outside the blob
|
||||
*/
|
||||
|
||||
BlobClient.updateProfile = function (opts, fn) {
|
||||
var config = {
|
||||
method: 'POST',
|
||||
url: opts.url + '/v1/user/' + opts.username + '/profile',
|
||||
dataType: 'json',
|
||||
data: opts.profile
|
||||
};
|
||||
|
||||
var signedRequest = new SignedRequest(config);
|
||||
var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id);
|
||||
|
||||
request.post(signed.url)
|
||||
.send(signed.data)
|
||||
.end(function(err, resp) {
|
||||
if (err) {
|
||||
log.error('updateProfile:', err);
|
||||
fn(new Error('Failed to update profile - XHR error'));
|
||||
} else if (resp.body && resp.body.result === 'success') {
|
||||
fn(null, resp.body);
|
||||
} else if (resp.body) {
|
||||
log.error('updateProfile:', resp.body);
|
||||
} else {
|
||||
fn(new Error('Failed to update profile'));
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* updateKeys
|
||||
* Change the blob encryption keys
|
||||
@@ -979,10 +1012,10 @@ BlobClient.updateKeys = function (opts, fn) {
|
||||
.send(signed.data)
|
||||
.end(function(err, resp) {
|
||||
if (err) {
|
||||
console.log("blob: could not update blob:", err);
|
||||
log.error("updateKeys:", err);
|
||||
fn(new Error('Failed to update blob - XHR error'));
|
||||
} else if (!resp.body || resp.body.result !== 'success') {
|
||||
console.log("blob: could not update blob:", resp.body ? resp.body.message : null);
|
||||
log.error("updateKeys:", resp.body ? resp.body.message : null);
|
||||
fn(new Error('Failed to update blob - bad result'));
|
||||
} else {
|
||||
fn(null, resp.body);
|
||||
@@ -1027,12 +1060,12 @@ BlobClient.rename = function (opts, fn) {
|
||||
.send(signed.data)
|
||||
.end(function(err, resp) {
|
||||
if (err) {
|
||||
console.log("blob: could not rename:", err);
|
||||
log.error("rename:", err);
|
||||
fn(new Error("Failed to rename"));
|
||||
} else if (resp.body && resp.body.result === 'success') {
|
||||
fn(null, resp.body);
|
||||
} else if (resp.body && resp.body.result === 'error') {
|
||||
console.log("blob: could not rename:", resp.body.message);
|
||||
log.error("rename:", resp.body.message);
|
||||
fn(new Error("Failed to rename"));
|
||||
} else {
|
||||
fn(new Error("Failed to rename"));
|
||||
@@ -1110,4 +1143,32 @@ BlobClient.create = function(options, fn) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* deleteBlob
|
||||
*/
|
||||
|
||||
BlobClient.deleteBlob = function(options, fn) {
|
||||
|
||||
var config = {
|
||||
method : 'DELETE',
|
||||
url : options.url + '/v1/user/' + options.username,
|
||||
};
|
||||
|
||||
var signedRequest = new SignedRequest(config);
|
||||
var signed = signedRequest.signAsymmetric(options.masterkey, options.account_id, options.blob_id);
|
||||
|
||||
request.del(signed.url)
|
||||
.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('Could not delete blob'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.BlobClient = BlobClient;
|
||||
|
||||
@@ -105,6 +105,23 @@ VaultClient.prototype.getRippleName = function(address, url, callback) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check blobvault for existance of username
|
||||
*
|
||||
* @param {string} username
|
||||
* @param {function} fn - Callback function
|
||||
*/
|
||||
|
||||
VaultClient.prototype.exists = function(username, callback) {
|
||||
AuthInfo.get(this.domain, username.toLowerCase(), function(err, authInfo) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null, !!authInfo.exists);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticate and retrieve a decrypted blob using a ripple name and password
|
||||
*
|
||||
@@ -334,23 +351,6 @@ VaultClient.prototype.loginAndUnlock = function(username, password, fn) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Check blobvault for existance of username
|
||||
*
|
||||
* @param {string} username
|
||||
* @param {function} fn - Callback function
|
||||
*/
|
||||
|
||||
VaultClient.prototype.exists = function(username, callback) {
|
||||
AuthInfo.get(this.domain, username.toLowerCase(), function(err, authInfo) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
callback(null, !!authInfo.exists);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Verify an email address for an existing user
|
||||
*
|
||||
@@ -387,6 +387,39 @@ 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
|
||||
|
||||
@@ -125,7 +125,8 @@ var mockUpdate;
|
||||
var mockRecover;
|
||||
var mockVerify;
|
||||
var mockEmail;
|
||||
|
||||
var mockProfile;
|
||||
var mockDelete;
|
||||
|
||||
if (!online) {
|
||||
mockRippleTxt = nock('https://' + exampleData.domain)
|
||||
@@ -148,7 +149,14 @@ if (!online) {
|
||||
.reply(200, { result: 'error', message: 'User already exists' }, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
|
||||
mockDelete = nock('https://id.staging.ripple.com').persist();
|
||||
mockDelete.filteringPath(/(v1\/user\/(.+))/g, 'delete/')
|
||||
.delete('/delete/')
|
||||
.reply(200, { result: 'success' }, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
mockBlob = nock('https://id.staging.ripple.com').persist();
|
||||
mockBlob.get('/v1/authinfo?domain=' + exampleData.domain + '&username=' + exampleData.username.toLowerCase())
|
||||
.reply(200, JSON.stringify(authInfoRes.body), {
|
||||
@@ -200,6 +208,13 @@ if (!online) {
|
||||
.reply(200, {result:'success'}, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
|
||||
mockProfile = nock('https://id.staging.ripple.com/v1/user').persist();
|
||||
mockProfile.filteringPath(/((.+)\/profile(.+))/g, 'profile/')
|
||||
.post('profile/')
|
||||
.reply(200, {result:'success'}, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
describe('Ripple Txt', function () {
|
||||
@@ -364,6 +379,60 @@ describe('VaultClient', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#deleteBlob', function () {
|
||||
it('should remove an existing blob', function (done) {
|
||||
this.timeout(10000);
|
||||
|
||||
var options = {
|
||||
url : exampleData.blob.url,
|
||||
blob_id : exampleData.blob.id,
|
||||
username : online ? "" : exampleData.username,
|
||||
account_id : exampleData.blob.data.account_id,
|
||||
masterkey : exampleData.masterkey
|
||||
}
|
||||
|
||||
client.deleteBlob(options, function(err, resp) {
|
||||
if (online) {
|
||||
//removing the username will result in an error from the server
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual(resp, void(0));
|
||||
} else {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(typeof resp, 'object');
|
||||
assert.strictEqual(typeof resp.result, 'string');
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#updateProfile', function () {
|
||||
it('should update profile parameters associated with a blob', function (done) {
|
||||
this.timeout(10000);
|
||||
|
||||
var options = {
|
||||
url : exampleData.blob.url,
|
||||
blob_id : exampleData.blob.id,
|
||||
username : exampleData.username,
|
||||
auth_secret : exampleData.blob.data.auth_secret,
|
||||
profile : {
|
||||
city : "San Francisco",
|
||||
phone : "555-555-5555"
|
||||
}
|
||||
}
|
||||
|
||||
client.updateProfile(options, function(err, resp) {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(typeof resp, 'object');
|
||||
assert.strictEqual(typeof resp.result, 'string');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user