From 778ccd4805053eb72cd459094e06f3137b36a4a0 Mon Sep 17 00:00:00 2001 From: Matthew Fettig Date: Mon, 6 Oct 2014 18:03:52 -0700 Subject: [PATCH] [TASK] vault client: tests for attestation routes and full summary --- src/js/ripple/blob.js | 12 +++- src/js/ripple/crypt.js | 8 +++ test/vault-test.js | 124 +++++++++++++++++++++++++++-------------- 3 files changed, 100 insertions(+), 44 deletions(-) diff --git a/src/js/ripple/blob.js b/src/js/ripple/blob.js index c8dc4d10..5024bc96 100644 --- a/src/js/ripple/blob.js +++ b/src/js/ripple/blob.js @@ -1322,7 +1322,6 @@ BlobClient.deleteBlob = function(options, fn) { }); }; - /*** identity related functions ***/ /** @@ -1381,6 +1380,7 @@ BlobClient.updateProfile = function (opts, fn) { * @param {string} opts.auth_secret * @param {srring} opts.blob_id */ + BlobClient.getProfile = function (opts, fn) { var config = { method: 'GET', @@ -1418,6 +1418,7 @@ BlobClient.getProfile = function (opts, fn) { * @param {object} opts.phone (required for type 'phone') * @param {string} opts.email (required for type 'email') */ + BlobClient.getAttestation = function (opts, fn) { var params = { }; @@ -1463,6 +1464,7 @@ BlobClient.getAttestation = function (opts, fn) { * @param {string} opts.auth_secret * @param {string} opts.blob_id */ + BlobClient.getAttestationSummary = function (opts, fn) { @@ -1472,6 +1474,8 @@ BlobClient.getAttestationSummary = function (opts, fn) { dataType: 'json' }; + if (opts.full) config.url += '?full=true'; + var signedRequest = new SignedRequest(config); var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id); @@ -1510,6 +1514,7 @@ BlobClient.getAttestationSummary = function (opts, fn) { * @param {string} opts.answers (required for type 'identity') * @param {string} opts.token (required for completing email or phone attestations) */ + BlobClient.updateAttestation = function (opts, fn) { var params = { }; @@ -1556,6 +1561,7 @@ BlobClient.updateAttestation = function (opts, fn) { * parseAttestation * @param {Object} attestation */ + BlobClient.parseAttestation = function (attestation) { var segments = attestation.split('.'); var decoded; @@ -1563,8 +1569,8 @@ BlobClient.parseAttestation = function (attestation) { // base64 decode and parse JSON try { decoded = { - header : JSON.parse(atob(segments[0])), - payload : JSON.parse(atob(segments[1])), + header : JSON.parse(crypt.decodeBase64(segments[0])), + payload : JSON.parse(crypt.decodeBase64(segments[1])), signature : segments[2] }; diff --git a/src/js/ripple/crypt.js b/src/js/ripple/crypt.js index 6395f77c..c6d29665 100644 --- a/src/js/ripple/crypt.js +++ b/src/js/ripple/crypt.js @@ -322,4 +322,12 @@ Crypt.base64UrlToBase64 = function(encodedData) { return encodedData; }; +/** + * base64 to UTF8 + */ + +Crypt.decodeBase64 = function (data) { + return sjcl.codec.utf8String.fromBits(sjcl.codec.base64.toBits(data)); +} + exports.Crypt = Crypt; diff --git a/test/vault-test.js b/test/vault-test.js index 5bd85e6c..0aaf9a7a 100644 --- a/test/vault-test.js +++ b/test/vault-test.js @@ -151,14 +151,12 @@ var mockDelete; if (!online) { mockRippleTxt = nock('https://ripple.com') - .persist() .get('/ripple.txt') .reply(200, rippleTxtRes, { 'Content-Type': 'text/plain' }); mockRippleTxt2 = nock('https://' + exampleData.domain) - .persist() .get('/ripple.txt') .reply(200, rippleTxtRes, { 'Content-Type': 'text/plain' @@ -171,21 +169,21 @@ if (!online) { 'Content-Type': 'text/plain' }); - mockRegister = nock('https://id.staging.ripple.com').persist(); + mockRegister = nock('https://id.staging.ripple.com'); mockRegister.filteringPath(/(v1\/user\?signature(.+))/g, 'register/') .post('/register/') .reply(200, { result: 'error', message: 'User already exists' }, { 'Content-Type': 'application/json' }); - mockDelete = nock('https://id.staging.ripple.com').persist(); + mockDelete = nock('https://id.staging.ripple.com'); 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'); mockBlob.get('/v1/authinfo?domain=' + exampleData.domain + '&username=' + exampleData.username.toLowerCase()) .reply(200, JSON.stringify(authInfoRes.body), { 'Content-Type': 'application/json' @@ -203,47 +201,40 @@ if (!online) { 'Content-Type': 'application/json' }); - mockRename = nock('https://id.staging.ripple.com/v1/user/').persist(); + mockRename = nock('https://id.staging.ripple.com/v1/user/'); mockRename.filteringPath(/((.+)\/rename(.+))/g, 'rename/') .post('rename/') .reply(200, {result:'success',message:'rename'}, { 'Content-Type': 'application/json' }); - mockUpdate = nock('https://id.staging.ripple.com/v1/user/').persist(); - mockUpdate.filteringPath(/((.+)\/update(.+))/g, 'update/') + mockUpdate = nock('https://id.staging.ripple.com/v1/user/'); + mockUpdate.filteringPath(/((.+)\/updatekeys(.+))/g, 'update/') .post('update/') .reply(200, {result:'success',message:'updateKeys'}, { 'Content-Type': 'application/json' }); - mockRecover = nock('https://id.staging.ripple.com/').persist(); + mockRecover = nock('https://id.staging.ripple.com/') mockRecover.filteringPath(/((.+)user\/recov\/(.+))/g, 'recov/') .get('recov/') .reply(200, recoverRes.body, { 'Content-Type': 'application/json' }); - - mockVerify = nock('https://id.staging.ripple.com/v1/user/').persist(); + + mockVerify = nock('https://id.staging.ripple.com/v1/user/'); mockVerify.filteringPath(/((.+)\/verify(.+))/g, 'verify/') .get('verify/') .reply(200, {result:'error', message:'invalid token'}, { 'Content-Type': 'application/json' }); - mockEmail = nock('https://id.staging.ripple.com/v1/user').persist(); + mockEmail = nock('https://id.staging.ripple.com/v1/user'); mockEmail.filteringPath(/((.+)\/email(.+))/g, 'email/') .post('email/') .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 () { @@ -437,6 +428,7 @@ describe('VaultClient', function () { }); }); +/* describe('#updateProfile', function () { it('should update profile parameters associated with a blob', function (done) { this.timeout(10000); @@ -460,7 +452,7 @@ describe('VaultClient', function () { }); }); }); - +*/ }); @@ -713,39 +705,89 @@ describe('Blob', function () { }); describe('identityVault', function() { - it('#identity-getProfile', function (done) { + it('#identity - Get Attestation', function (done) { var options = { - url : blob.url, + url : blob.url, auth_secret : blob.data.auth_secret, - blob_id :blob.id, - identity_id : blob.identity_id, + blob_id : blob.id, }; - options.profile = { - attributes : [{ - name : 'email', - value : 'example@example.com', - visibility : 'public' - }] - }; + options.type = 'identity'; - client.getProfile(options, function(err, resp) { - console.log(err, resp); + nock('https://id.staging.ripple.com') + .filteringPath(/(v1\/attestation\/identity(.+))/g, '') + .post('/') + .reply(200, { + result: 'success', + status: 'verified', + attestation: 'eyJ6IjoieiJ9.eyJ6IjoieiJ9.sig', + blinded:'eyJ6IjoieiJ9.eyJ6IjoieiJ9.sig' + }, {'Content-Type': 'application/json'}); + + client.getAttestation(options, function(err, resp) { + assert.ifError(err); + assert.strictEqual(resp.result, 'success'); + assert.strictEqual(typeof resp.attestation, 'string'); + assert.strictEqual(typeof resp.blinded, 'string'); + assert.deepEqual(resp.decoded, {"header":{"z":"z"},"payload":{"z":"z"},"signature":"sig"}) done(); }); }); - it('#identity-updateProfile', function (done) { - done(); + it('#identity - Update Attestation', function (done) { + + var options = { + url : blob.url, + auth_secret : blob.data.auth_secret, + blob_id : blob.id, + }; + + options.type = 'identity'; + + nock('https://id.staging.ripple.com') + .filteringPath(/(v1\/attestation\/identity\/update(.+))/g, '') + .post('/') + .reply(200, { + result: 'success', + status: 'verified', + attestation: 'eyJ6IjoieiJ9.eyJ6IjoieiJ9.sig', + blinded:'eyJ6IjoieiJ9.eyJ6IjoieiJ9.sig' + }, {'Content-Type': 'application/json'}); + + client.updateAttestation(options, function(err, resp) { + assert.ifError(err); + assert.strictEqual(resp.result, 'success'); + assert.strictEqual(typeof resp.attestation, 'string'); + assert.strictEqual(typeof resp.blinded, 'string'); + assert.deepEqual(resp.decoded, {"header":{"z":"z"},"payload":{"z":"z"},"signature":"sig"}) + done(); + }); }); - it('#identity-getAttestations', function (done) { - done(); - }); + it('#identity - Get Attestation Summary', function (done) { - it('#identity-attest', function (done) { - done(); - }); + var options = { + url : blob.url, + auth_secret : blob.data.auth_secret, + blob_id : blob.id, + }; + + nock('https://id.staging.ripple.com') + .filteringPath(/(v1\/attestation\/summary(.+))/g, '') + .get('/') + .reply(200, { + result: 'success', + attestation: 'eyJ6IjoieiJ9.eyJ6IjoieiJ9.sig', + }, {'Content-Type': 'application/json'}); + + client.getAttestationSummary(options, function(err, resp) { + assert.ifError(err); + assert.strictEqual(resp.result, 'success'); + assert.strictEqual(typeof resp.attestation, 'string'); + assert.deepEqual(resp.decoded, {"header":{"z":"z"},"payload":{"z":"z"},"signature":"sig"}) + done(); + }); + }); }); //only do these offline