Skip to content

Commit

Permalink
Merge pull request #181 from shekenahglory/feature/identity
Browse files Browse the repository at this point in the history
Feature/identity
  • Loading branch information
geertweening committed Oct 7, 2014
2 parents 0dfd3a0 + 778ccd4 commit ed2da57
Show file tree
Hide file tree
Showing 4 changed files with 395 additions and 69 deletions.
308 changes: 263 additions & 45 deletions src/js/ripple/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ BlobObj.prototype.init = function(fn) {

self.revision = resp.body.revision;
self.encrypted_secret = resp.body.encrypted_secret;
self.identity_id = resp.body.identity_id;
self.missing_fields = resp.body.missing_fields;
//self.attestations = resp.body.attestation_summary;

if (!self.decrypt(resp.body.blob)) {
return fn(new Error('Error while decrypting blob'));
Expand Down Expand Up @@ -561,7 +563,6 @@ BlobObj.prototype.get2FA = function (fn) {
* @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) {
Expand All @@ -572,8 +573,7 @@ BlobObj.prototype.set2FA = function(options, fn) {
data : {
enabled : options.enabled,
phone : options.phone,
country_code : options.country_code,
via : options.via
country_code : options.country_code
}
};

Expand Down Expand Up @@ -1115,48 +1115,6 @@ BlobClient.recoverBlob = function (opts, fn) {
};
};

/**
* updateProfile
* 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 = {
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
Expand Down Expand Up @@ -1320,6 +1278,7 @@ BlobClient.create = function(options, fn) {
if (err) {
fn(err);
} else if (resp.body && resp.body.result === 'success') {
blob.identity_id = resp.body.identity_id;
fn(null, blob, resp.body);
} else if (resp.body && resp.body.result === 'error') {
fn(new Error(resp.body.message));
Expand Down Expand Up @@ -1363,4 +1322,263 @@ BlobClient.deleteBlob = function(options, fn) {
});
};

/*** identity related functions ***/

/**
* updateProfile
* update information stored outside the blob - HMAC signed
* @param {object}
* @param {string} opts.url
* @param {string} opts.auth_secret
* @param {srring} opts.blob_id
* @param {object} opts.profile
* @param {array} opts.profile.attributes (optional, array of attribute objects)
* @param {array} opts.profile.addresses (optional, array of address objects)
*
* @param {string} attribute.id ... id of existing attribute
* @param {string} attribute.name ... attribute name i.e. ripple_address
* @param {string} attribute.type ... optional, sub-type of attribute
* @param {string} attribute.value ... value of attribute
* @param {string} attribute.domain ... corresponding domain
* @param {string} attribute.status ... “current”, “removed”, etc.
* @param {string} attribute.visibitlity ... “public”, ”private”
*/

BlobClient.updateProfile = function (opts, fn) {
var config = {
method: 'POST',
url: opts.url + '/v1/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);
fn(new Error('Failed to update profile'));
} else {
fn(new Error('Failed to update profile'));
}
});
};

/**
* getProfile
* @param {Object} opts
* @param {string} opts.url
* @param {string} opts.auth_secret
* @param {srring} opts.blob_id
*/

BlobClient.getProfile = function (opts, fn) {
var config = {
method: 'GET',
url: opts.url + '/v1/profile/'
};

var signedRequest = new SignedRequest(config);
var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id);

request.get(signed.url)
.send(signed.data)
.end(function(err, resp) {

if (err) {
log.error('getProfile:', err);
fn(new Error('Failed to get profile - XHR error'));
} else if (resp.body && resp.body.result === 'success') {
fn(null, resp.body);
} else if (resp.body) {
log.error('getProfile:', resp.body);
fn(new Error('Failed to get profile'));
} else {
fn(new Error('Failed to get profile'));
}
});
};

/**
* getAttestation
* @param {Object} opts
* @param {string} opts.url
* @param {string} opts.auth_secret
* @param {string} opts.blob_id
* @param {string} opts.type (email,phone,basic_identity)
* @param {object} opts.phone (required for type 'phone')
* @param {string} opts.email (required for type 'email')
*/

BlobClient.getAttestation = function (opts, fn) {
var params = { };

if (opts.phone) params.phone = opts.phone;
if (opts.email) params.email = opts.email;

var config = {
method: 'POST',
url: opts.url + '/v1/attestation/' + opts.type,
dataType: 'json',
data: params
};

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('attest:', err);
fn(new Error('attestation error - XHR error'));
} else if (resp.body && resp.body.result === 'success') {
if (resp.body.attestation) {
resp.body.decoded = BlobClient.parseAttestation(resp.body.attestation);
}

fn(null, resp.body);
} else if (resp.body) {
log.error('attestation:', resp.body);
fn(new Error('attestation error: ' + resp.body.message || ""));
} else {
fn(new Error('attestation error'));
}
});
};

/**
* getAttestationSummary
* @param {Object} opts
* @param {string} opts.url
* @param {string} opts.auth_secret
* @param {string} opts.blob_id
*/

BlobClient.getAttestationSummary = function (opts, fn) {


var config = {
method: 'GET',
url: opts.url + '/v1/attestation/summary',
dataType: 'json'
};

if (opts.full) config.url += '?full=true';

var signedRequest = new SignedRequest(config);
var signed = signedRequest.signHmac(opts.auth_secret, opts.blob_id);

request.get(signed.url)
.send(signed.data)
.end(function(err, resp) {

if (err) {
log.error('attest:', err);
fn(new Error('attestation error - XHR error'));
} else if (resp.body && resp.body.result === 'success') {
if (resp.body.attestation) {
resp.body.decoded = BlobClient.parseAttestation(resp.body.attestation);
}

fn(null, resp.body);
} else if (resp.body) {
log.error('attestation:', resp.body);
fn(new Error('attestation error: ' + resp.body.message || ""));
} else {
fn(new Error('attestation error'));
}
});
};

/**
* updateAttestation
* @param {Object} opts
* @param {string} opts.url
* @param {string} opts.auth_secret
* @param {string} opts.blob_id
* @param {string} opts.type (email,phone,profile,identity)
* @param {object} opts.phone (required for type 'phone')
* @param {object} opts.profile (required for type 'profile')
* @param {string} opts.email (required for type 'email')
* @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 = { };

if (opts.phone) params.phone = opts.phone;
if (opts.profile) params.profile = opts.profile;
if (opts.email) params.email = opts.email;
if (opts.token) params.token = opts.token;
if (opts.answers) params.answers = opts.answers;

var config = {
method: 'POST',
url: opts.url + '/v1/attestation/' + opts.type + '/update',
dataType: 'json',
data: params
};

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('attest:', err);
fn(new Error('attestation error - XHR error'));
} else if (resp.body && resp.body.result === 'success') {
if (resp.body.attestation) {
resp.body.decoded = BlobClient.parseAttestation(resp.body.attestation);
}

fn(null, resp.body);
} else if (resp.body) {
log.error('attestation:', resp.body);
fn(new Error('attestation error: ' + resp.body.message || ""));
} else {
fn(new Error('attestation error'));
}
});
};

/**
* parseAttestation
* @param {Object} attestation
*/

BlobClient.parseAttestation = function (attestation) {
var segments = attestation.split('.');
var decoded;

// base64 decode and parse JSON
try {
decoded = {
header : JSON.parse(crypt.decodeBase64(segments[0])),
payload : JSON.parse(crypt.decodeBase64(segments[1])),
signature : segments[2]
};

} catch (e) {
console.log("invalid attestation:", e);
}

return decoded;
};

exports.BlobClient = BlobClient;
8 changes: 8 additions & 0 deletions src/js/ripple/crypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
8 changes: 6 additions & 2 deletions src/js/ripple/vaultclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,6 @@ VaultClient.prototype.generateDeviceID = function () {

VaultClient.prototype.resendEmail = blobClient.resendEmail;

VaultClient.prototype.updateProfile = blobClient.updateProfile;

VaultClient.prototype.recoverBlob = blobClient.recoverBlob;

VaultClient.prototype.deleteBlob = blobClient.deleteBlob;
Expand All @@ -585,5 +583,11 @@ VaultClient.prototype.requestToken = blobClient.requestToken;

VaultClient.prototype.verifyToken = blobClient.verifyToken;

VaultClient.prototype.getAttestation = blobClient.getAttestation;

VaultClient.prototype.updateAttestation = blobClient.updateAttestation;

VaultClient.prototype.getAttestationSummary = blobClient.getAttestationSummary;

//export by name
exports.VaultClient = VaultClient;
Loading

0 comments on commit ed2da57

Please sign in to comment.