[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);
};
var identityRoot = '/identityVault';
// Blob operations
// Do NOT change the mapping of existing 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
* @param {function} fn - Callback function
@@ -499,7 +534,7 @@ function normalizeSubcommands(subcommands, compress) {
* Identity class
*
*/
var Identity = function(blob) {
var Identity = function (blob) {
var self = this;
self.blob = blob;
@@ -507,7 +542,7 @@ var Identity = function(blob) {
self.validate = function(fn) {
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.identityVault) {
else if (!self.blob.data[identityRoot]) {
self.blob.set(identityRoot, {}, function(err, res){
if (err) return fn(err);
else return fn(null, true);
@@ -517,14 +552,50 @@ 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
* get and decrypt all identity fields
* @param {string} key - Encryption key
* @param {function} fn - Callback function
*/
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;
}
@@ -534,54 +605,111 @@ Identity.prototype.getAll = function(key) {
* @param {string} pointer - Field to retrieve
* @param {string} key - Encryption key
*/
Identity.prototype.get = function(pointer, key) {
if (!this.blob || !this.blob.data || !this.blob.data.identityVault) {
Identity.prototype.get = function (pointer, key) {
if (!this.blob || !this.blob.data || !this.blob.data[identityRoot]) {
return null;
}
var data = this.blob.data.identityVault[pointer];
var data = this.blob.data[identityRoot][pointer];
if (data && data.encrypted) {
return decrypt(key, data);
return {
encrypted : data.encrypted,
value : decrypt(key, data.value)
}
} else if (data) {
return data;
} else {
return null;
}
function decrypt (key, value) {
value = crypt.decrypt(key, value);
function decrypt (key, data) {
var value;
var result = {encrypted : true};
try {
return JSON.parse(value);
value = crypt.decrypt(key, data.value);
} 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 and encrypt a single identity field
* set and encrypt a single identity field.
* @param {string} pointer - Field to set
* @param {string} key - Encryption key
* @param {string} value - Unencrypted data
* @param {function} fn - Callback function
*/
Identity.prototype.set = function(pointer, key, value, fn) {
Identity.prototype.set = function (pointer, key, value, fn) {
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){
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 = {};
data[pointer] = {
encrypted : key ? true : false,
value : key ? encrypt(key, value) : value
}
self.blob.extend(identityRoot, data, fn);
self.blob.extend("/" + identityRoot, data, fn);
});
function encrypt (key, value) {
@@ -601,6 +729,14 @@ Identity.prototype.set = function(pointer, key, value, 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 {function} fn
*/
module.exports.create = function (options, fn)
{
module.exports.create = function (options, fn) {
var blob = new BlobObj(options.url, options.id, options.crypt);