[CHORE] limit identity to defined fields

This commit is contained in:
Matthew Fettig
2014-05-30 10:03:49 -07:00
parent 0e5c29269f
commit 58e14f3bb3

View File

@@ -12,8 +12,6 @@ var BlobObj = function (url, id, key) {
this.identity = new Identity(this); this.identity = new Identity(this);
}; };
var identityRoot = '/identityVault';
// Blob operations // Blob operations
// Do NOT change the mapping of existing ops // Do NOT change the mapping of existing ops
BlobObj.ops = { BlobObj.ops = {
@@ -40,6 +38,43 @@ for (var name in BlobObj.ops) {
} }
//Identity fields
var identityRoot = 'identityVault';
var identityFields = [
'name',
'entityType',
'email',
'phone',
'address',
'nationalID',
'birthday',
'birthplace'
];
var addressFields = [
'contact',
'line1',
'line2',
'city',
'region', //state/province/region
'postalCode',
'country'
];
var nationalIDFields = [
'number',
'type',
'country',
]
var idTypeFields = [
'ssn',
'taxID',
'passport',
'driversLicense',
'other'
]
/* /*
* Initialize a new blob object * Initialize a new blob object
* @param {function} fn - Callback function * @param {function} fn - Callback function
@@ -507,7 +542,7 @@ var Identity = function(blob) {
self.validate = function(fn) { self.validate = function(fn) {
if (!self.blob) return fn(new Error("Identity must be associated with a blob")); if (!self.blob) return fn(new Error("Identity must be associated with a blob"));
else if (!self.blob.data) return fn(new Error("Invalid Blob")); else if (!self.blob.data) return fn(new Error("Invalid Blob"));
else if (!self.blob.data.identityVault) { else if (!self.blob.data[identityRoot]) {
self.blob.set(identityRoot, {}, function(err, res){ self.blob.set(identityRoot, {}, function(err, res){
if (err) return fn(err); if (err) return fn(err);
else return fn(null, true); else return fn(null, true);
@@ -517,6 +552,32 @@ var Identity = function(blob) {
} }
/**
* getFullAddress
* returns the address formed into a text string
* @param {string} key - Encryption key
*/
Identity.prototype.getFullAddress = function (key) {
if (!this.blob ||
!this.blob.data ||
!this.blob.data[identityRoot] ||
!this.blob.data[identityRoot].address) {
return "";
}
var address = this.get('address', key);
var text = "";
if (address.value.contact) text += address.value.contact;
if (address.value.line1) text += " " + address.value.line1;
if (address.value.line2) text += " " + address.value.line2;
if (address.value.city) text += " " + address.value.city;
if (address.value.region) text += " " + address.value.region;
if (address.value.postalCode) text += " " + address.value.postalCode;
if (address.value.country) text += " " + address.value.country;
return text;
}
/** /**
* getAll * getAll
* get and decrypt all identity fields * get and decrypt all identity fields
@@ -525,6 +586,16 @@ var Identity = function(blob) {
*/ */
Identity.prototype.getAll = function (key) { Identity.prototype.getAll = function (key) {
if (!this.blob || !this.blob.data || !this.blob.data[identityRoot]) {
return {};
}
var result = {}, identity = this.blob.data[identityRoot];
for (var i in identity) {
result[i] = this.get(i, key);
}
return result;
} }
@@ -535,35 +606,47 @@ Identity.prototype.getAll = function(key) {
* @param {string} key - Encryption key * @param {string} key - Encryption key
*/ */
Identity.prototype.get = function (pointer, key) { Identity.prototype.get = function (pointer, key) {
if (!this.blob || !this.blob.data || !this.blob.data.identityVault) { if (!this.blob || !this.blob.data || !this.blob.data[identityRoot]) {
return null; return null;
} }
var data = this.blob.data.identityVault[pointer]; var data = this.blob.data[identityRoot][pointer];
if (data && data.encrypted) { if (data && data.encrypted) {
return decrypt(key, data);
return {
encrypted : data.encrypted,
value : decrypt(key, data.value)
}
} else if (data) { } else if (data) {
return data; return data;
} else {
return null;
} }
function decrypt (key, value) { function decrypt (key, data) {
value = crypt.decrypt(key, value); var value;
var result = {encrypted : true};
try { try {
return JSON.parse(value); value = crypt.decrypt(key, data.value);
} catch (e) { } catch (e) {
return value; result.value = data.value;
result.error = e;
return result;
} }
try {
result.value = JSON.parse(value);
} catch (e) {
result.value = value;
}
return result;
} }
} }
/** /**
* set * set
* set and encrypt a single identity field * set and encrypt a single identity field.
* @param {string} pointer - Field to set * @param {string} pointer - Field to set
* @param {string} key - Encryption key * @param {string} key - Encryption key
* @param {string} value - Unencrypted data * @param {string} value - Unencrypted data
@@ -572,16 +655,61 @@ Identity.prototype.get = function(pointer, key) {
Identity.prototype.set = function (pointer, key, value, fn) { Identity.prototype.set = function (pointer, key, value, fn) {
var self = this; var self = this;
//check fields for validity
if (identityFields.indexOf(pointer) === -1) {
return fn(new Error("invalid identity field"));
//validate address fields
} else if (pointer === 'address') {
if (typeof value !== 'object') {
return fn(new Error("address must be an object"));
}
for (var addressField in value) {
if (addressFields.indexOf(addressField) === -1) {
return fn(new Error("invalid address field"));
}
}
//validate nationalID fields
} else if (pointer === 'nationalID') {
if (typeof value !== 'object') {
return fn(new Error("nationalID must be an object"));
}
for (var idField in value) {
if (nationalIDFields.indexOf(idField) === -1) {
return fn(new Error("invalid nationalID field"));
}
if (idField === 'type') {
for (var idType in value.type) {
if (idTypeFields.indexOf(idType) === -1) {
return fn(new Error("invalid nationalID type"));
}
}
}
}
}
this.validate(function(err, res){ this.validate(function(err, res){
if (err) return fn(err); if (err) return fn(err);
//NOTE: currently we will overwrite if it already exists
//the other option would be to require decrypting with the
//existing key as a form of authorization
//var current = self.get(pointer, key);
//if (current && current.error) {
// return fn ? fn(current.error) : undefined;
//}
var data = {}; var data = {};
data[pointer] = { data[pointer] = {
encrypted : key ? true : false, encrypted : key ? true : false,
value : key ? encrypt(key, value) : value value : key ? encrypt(key, value) : value
} }
self.blob.extend(identityRoot, data, fn); self.blob.extend("/" + identityRoot, data, fn);
}); });
function encrypt (key, value) { function encrypt (key, value) {
@@ -601,6 +729,14 @@ Identity.prototype.set = function(pointer, key, value, fn) {
*/ */
Identity.prototype.unset = function (pointer, key, fn) { Identity.prototype.unset = function (pointer, key, fn) {
//NOTE: this is rather useless since you can overwrite
//without an encryption key
var data = this.get(pointer, key);
if (data && data.error) {
return fn(data.error);
}
this.blob.unset("/" + identityRoot+"/" + pointer, fn);
} }
@@ -662,8 +798,7 @@ module.exports.verify = function (url, username, token, fn) {
* @param {object} options.oldUserBlob * @param {object} options.oldUserBlob
* @param {function} fn * @param {function} fn
*/ */
module.exports.create = function (options, fn) module.exports.create = function (options, fn) {
{
var blob = new BlobObj(options.url, options.id, options.crypt); var blob = new BlobObj(options.url, options.id, options.crypt);