mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15: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
|
## Vault Client Usage
|
||||||
|
|
||||||
vaultClient = new ripple.VaultClient(domain);
|
vaultClient = new ripple.VaultClient(domain);
|
||||||
|
|
||||||
|
vaultClient.getAuthInfo(username, callback);
|
||||||
|
|
||||||
|
vaultClient.getRippleName(address, url, callback);
|
||||||
|
|
||||||
|
vaultClient.exists(username, callback);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vaultClient.login(username, password, 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.loginAndUnlock(username, password, callback);
|
||||||
|
|
||||||
vaultClient.exists(username, callback);
|
|
||||||
|
|
||||||
vaultClient.register(options, callback);
|
vaultClient.register(options, callback);
|
||||||
|
|
||||||
|
vaultClient.deleteBlob(options, callback);
|
||||||
|
|
||||||
|
vaultClient.recoverBlob(options, callback);
|
||||||
|
|
||||||
vaultClient.rename(options, callback);
|
vaultClient.rename(options, callback);
|
||||||
|
|
||||||
vaultClient.changePassword(options, callback);
|
vaultClient.changePassword(options, callback);
|
||||||
|
|
||||||
vaultClient.recoverBlob(options, callback);
|
|
||||||
|
|
||||||
vaultClient.verify(username, token, callback);
|
vaultClient.verify(username, token, callback);
|
||||||
|
|
||||||
vaultClient.resendEmail(options, callback);
|
vaultClient.resendEmail(options, callback);
|
||||||
|
|
||||||
|
vaultClient.updateProfile(options, fn);
|
||||||
|
|
||||||
|
|
||||||
# Blob Methods
|
# 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
|
Run `npm test` to test the high-level behavior specs
|
||||||
|
|
||||||
Ripple Txt
|
Ripple Txt
|
||||||
✓ should get the context of a ripple.txt file from a given domain
|
✓ 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
|
AuthInfo
|
||||||
✓ should get authinfo given a domain and username
|
✓ should get auth info
|
||||||
|
|
||||||
Ripple Vault Client
|
VaultClient
|
||||||
#initialization
|
#initialization
|
||||||
✓ should be initialized with a domain
|
✓ should be initialized with a domain
|
||||||
✓ should default to ripple.com without a domain
|
✓ should default to ripple.com without a domain
|
||||||
#login
|
#exists
|
||||||
✓ with username and password should retrive the blob, crypt key, and id
|
✓ should determine if a username exists on the domain
|
||||||
#relogin
|
#login
|
||||||
✓ should retrieve the decrypted blob with id and crypt key
|
✓ with username and password should retrive the blob, crypt key, and id
|
||||||
#unlock
|
#relogin
|
||||||
✓ should access the wallet secret using encryption secret, username and password
|
✓ should retrieve the decrypted blob with blob vault url, id, and crypt key
|
||||||
#loginAndUnlock
|
#unlock
|
||||||
✓ should get the decrypted blob and decrypted secret given name and password
|
✓ 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
|
||||||
Blob
|
✓ #set
|
||||||
#set
|
✓ #extend
|
||||||
✓ should set a new property in the blob
|
✓ #unset
|
||||||
#extend
|
✓ #unshift
|
||||||
✓ should extend an object in the blob
|
✓ #filter
|
||||||
#unset
|
✓ #consolidate
|
||||||
✓ should remove a property from the blob
|
#rename
|
||||||
#unshift
|
✓ should change the username of a blob
|
||||||
✓ should prepend an item to an array in the blob
|
#changePassword
|
||||||
#filter
|
✓ should change the password and keys of a blob
|
||||||
✓ should find a specific entity in an array and apply subcommands to it
|
#recoverBlob
|
||||||
#consolidate
|
✓ should recover the blob given a username and secret
|
||||||
✓ should consolidate and save changes to the blob
|
#verifyEmail
|
||||||
|
✓ should verify an email given a username and token
|
||||||
|
#resendVerifcationEmail
|
||||||
#identity_set
|
✓ should resend a verification given options
|
||||||
✓ should set an identity property
|
identity
|
||||||
#identity_get
|
✓ #identity_set
|
||||||
✓ should retreive an identity property given the property name and encryption key
|
✓ #identity_get
|
||||||
#identity_getAll
|
✓ #identity_getAll
|
||||||
✓ should retreive all identity properties given the encryption key
|
✓ #identity_getFullAddress
|
||||||
#identity_getFullAddress
|
✓ #identity_unset
|
||||||
✓ should retreive the address as a string
|
|
||||||
#identity_unset
|
|
||||||
✓ should remove an identity property
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
var crypt = require('./crypt').Crypt;
|
var crypt = require('./crypt').Crypt;
|
||||||
var SignedRequest = require('./signedrequest').SignedRequest;
|
var SignedRequest = require('./signedrequest').SignedRequest;
|
||||||
var request = require('superagent');
|
var request = require('superagent');
|
||||||
var extend = require("extend");
|
var extend = require("extend");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
|
var log = require('./log').sub('blob');
|
||||||
var BlobClient = {};
|
var BlobClient = {};
|
||||||
|
|
||||||
//Blob object class
|
//Blob object class
|
||||||
@@ -865,12 +865,12 @@ BlobClient.resendEmail = function (opts, fn) {
|
|||||||
.send(signed.data)
|
.send(signed.data)
|
||||||
.end(function(err, resp) {
|
.end(function(err, resp) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log("blob: could not resend the token:", err);
|
log.error("resendEmail:", err);
|
||||||
fn(new Error("Failed to resend the token"));
|
fn(new Error("Failed to resend the token"));
|
||||||
} else if (resp.body && resp.body.result === 'success') {
|
} else if (resp.body && resp.body.result === 'success') {
|
||||||
fn(null, resp.body);
|
fn(null, resp.body);
|
||||||
} else if (resp.body && resp.body.result === 'error') {
|
} 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"));
|
fn(new Error("Failed to resend the token"));
|
||||||
} else {
|
} else {
|
||||||
fn(new Error("Failed to resend the token"));
|
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
|
* updateKeys
|
||||||
* Change the blob encryption keys
|
* Change the blob encryption keys
|
||||||
@@ -979,10 +1012,10 @@ BlobClient.updateKeys = function (opts, fn) {
|
|||||||
.send(signed.data)
|
.send(signed.data)
|
||||||
.end(function(err, resp) {
|
.end(function(err, resp) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log("blob: could not update blob:", err);
|
log.error("updateKeys:", err);
|
||||||
fn(new Error('Failed to update blob - XHR error'));
|
fn(new Error('Failed to update blob - XHR error'));
|
||||||
} else if (!resp.body || resp.body.result !== 'success') {
|
} 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'));
|
fn(new Error('Failed to update blob - bad result'));
|
||||||
} else {
|
} else {
|
||||||
fn(null, resp.body);
|
fn(null, resp.body);
|
||||||
@@ -1027,12 +1060,12 @@ BlobClient.rename = function (opts, fn) {
|
|||||||
.send(signed.data)
|
.send(signed.data)
|
||||||
.end(function(err, resp) {
|
.end(function(err, resp) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log("blob: could not rename:", err);
|
log.error("rename:", err);
|
||||||
fn(new Error("Failed to rename"));
|
fn(new Error("Failed to rename"));
|
||||||
} else if (resp.body && resp.body.result === 'success') {
|
} else if (resp.body && resp.body.result === 'success') {
|
||||||
fn(null, resp.body);
|
fn(null, resp.body);
|
||||||
} else if (resp.body && resp.body.result === 'error') {
|
} 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"));
|
fn(new Error("Failed to rename"));
|
||||||
} else {
|
} else {
|
||||||
fn(new Error("Failed to rename"));
|
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;
|
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
|
* 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
|
* Verify an email address for an existing user
|
||||||
*
|
*
|
||||||
@@ -387,6 +387,39 @@ VaultClient.prototype.resendEmail = function (options, fn) {
|
|||||||
blobClient.resendEmail(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
|
* recoverBlob
|
||||||
* recover blob with account secret
|
* recover blob with account secret
|
||||||
|
|||||||
@@ -125,7 +125,8 @@ var mockUpdate;
|
|||||||
var mockRecover;
|
var mockRecover;
|
||||||
var mockVerify;
|
var mockVerify;
|
||||||
var mockEmail;
|
var mockEmail;
|
||||||
|
var mockProfile;
|
||||||
|
var mockDelete;
|
||||||
|
|
||||||
if (!online) {
|
if (!online) {
|
||||||
mockRippleTxt = nock('https://' + exampleData.domain)
|
mockRippleTxt = nock('https://' + exampleData.domain)
|
||||||
@@ -148,7 +149,14 @@ if (!online) {
|
|||||||
.reply(200, { result: 'error', message: 'User already exists' }, {
|
.reply(200, { result: 'error', message: 'User already exists' }, {
|
||||||
'Content-Type': 'application/json'
|
'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 = nock('https://id.staging.ripple.com').persist();
|
||||||
mockBlob.get('/v1/authinfo?domain=' + exampleData.domain + '&username=' + exampleData.username.toLowerCase())
|
mockBlob.get('/v1/authinfo?domain=' + exampleData.domain + '&username=' + exampleData.username.toLowerCase())
|
||||||
.reply(200, JSON.stringify(authInfoRes.body), {
|
.reply(200, JSON.stringify(authInfoRes.body), {
|
||||||
@@ -200,6 +208,13 @@ if (!online) {
|
|||||||
.reply(200, {result:'success'}, {
|
.reply(200, {result:'success'}, {
|
||||||
'Content-Type': 'application/json'
|
'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 () {
|
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