1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-15 02:18:42 +02:00

service fixes for ciphers

This commit is contained in:
Kyle Spearrin 2017-10-14 14:27:14 -04:00
parent 5a1bf8299f
commit 355a58f67c
5 changed files with 179 additions and 162 deletions

View File

@ -38,7 +38,8 @@ var bg_isBackground = true,
bg_environmentService = new EnvironmentService(bg_constantsService, bg_apiService); bg_environmentService = new EnvironmentService(bg_constantsService, bg_apiService);
bg_userService = new UserService(bg_tokenService, bg_apiService, bg_cryptoService, bg_utilsService); bg_userService = new UserService(bg_tokenService, bg_apiService, bg_cryptoService, bg_utilsService);
bg_settingsService = new SettingsService(bg_userService, bg_utilsService); bg_settingsService = new SettingsService(bg_userService, bg_utilsService);
bg_loginService = new LoginService(bg_cryptoService, bg_userService, bg_apiService, bg_settingsService, bg_utilsService); bg_loginService = new LoginService(bg_cryptoService, bg_userService, bg_apiService, bg_settingsService, bg_utilsService,
bg_constantsService);
bg_folderService = new FolderService(bg_cryptoService, bg_userService, bg_apiService, bg_i18nService, bg_utilsService); bg_folderService = new FolderService(bg_cryptoService, bg_userService, bg_apiService, bg_i18nService, bg_utilsService);
bg_lockService = new LockService(bg_constantsService, bg_cryptoService, bg_folderService, bg_loginService, bg_utilsService, bg_lockService = new LockService(bg_constantsService, bg_cryptoService, bg_folderService, bg_loginService, bg_utilsService,
setIcon, refreshBadgeAndMenu); setIcon, refreshBadgeAndMenu);

View File

@ -6,8 +6,9 @@
this.notes = cipher.notes ? cipher.notes.encryptedString : null; this.notes = cipher.notes ? cipher.notes.encryptedString : null;
this.favorite = cipher.favorite; this.favorite = cipher.favorite;
var constantsService = chrome.extension.getBackgroundPage().bg_constantsService;
switch (type) { switch (type) {
case 1: // cipherType.login case constantsService.cipherType.login:
this.login = { this.login = {
uri: cipher.login.uri ? cipher.login.uri.encryptedString : null, uri: cipher.login.uri ? cipher.login.uri.encryptedString : null,
username: cipher.login.username ? cipher.login.username.encryptedString : null, username: cipher.login.username ? cipher.login.username.encryptedString : null,
@ -15,12 +16,12 @@
totp: cipher.login.totp ? cipher.login.totp.encryptedString : null totp: cipher.login.totp ? cipher.login.totp.encryptedString : null
}; };
break; break;
case 2: // cipherType.secureNote case constantsService.cipherType.secureNote:
this.secureNote = { this.secureNote = {
type: cipher.secureNote.type type: cipher.secureNote.type
}; };
break; break;
case 3: // cipherType.card case constantsService.cipherType.card:
this.card = { this.card = {
cardholderName: cipher.card.cardholderName ? cipher.card.cardholderName.encryptedString : null, cardholderName: cipher.card.cardholderName ? cipher.card.cardholderName.encryptedString : null,
brand: cipher.card.brand ? cipher.card.brand.encryptedString : null, brand: cipher.card.brand ? cipher.card.brand.encryptedString : null,
@ -30,7 +31,7 @@
code: cipher.card.code ? cipher.card.code.encryptedString : null code: cipher.card.code ? cipher.card.code.encryptedString : null
}; };
break; break;
case 4: // cipherType.identity case constantsService.cipherType.identity:
this.identity = { this.identity = {
title: cipher.identity.title ? cipher.identity.title.encryptedString : null, title: cipher.identity.title ? cipher.identity.title.encryptedString : null,
firstName: cipher.identity.firstName ? cipher.identity.firstName.encryptedString : null, firstName: cipher.identity.firstName ? cipher.identity.firstName.encryptedString : null,

View File

@ -62,17 +62,18 @@ var CipherData = function (response, userId) {
this.name = response.data.Name; this.name = response.data.Name;
this.notes = response.notes = response.data.Notes; this.notes = response.notes = response.data.Notes;
var constantsService = chrome.extension.getBackgroundPage().bg_constantsService;
switch (this.type) { switch (this.type) {
case 1: // cipherType.login case constantsService.cipherType.login:
this.login = new LoginData2(response.data); this.login = new LoginData2(response.data);
break; break;
case 2: // cipherType.secureNote case constantsService.cipherType.secureNote:
this.secureNote = new SecureNoteData(response.data); this.secureNote = new SecureNoteData(response.data);
break; break;
case 3: // cipherType.card case constantsService.cipherType.card:
this.card = new CardData(response.data); this.card = new CardData(response.data);
break; break;
case 4: // cipherType.identity case constantsService.cipherType.identity:
this.identity = new IdentityData(response.data); this.identity = new IdentityData(response.data);
break; break;
default: default:

View File

@ -5,6 +5,7 @@ var CipherString = function () {
this.cipherText = null; this.cipherText = null;
this.initializationVector = null; this.initializationVector = null;
this.mac = null; this.mac = null;
this.cryptoService = chrome.extension.getBackgroundPage().bg_cryptoService;
var constants = chrome.extension.getBackgroundPage().bg_constantsService; var constants = chrome.extension.getBackgroundPage().bg_constantsService;
@ -138,12 +139,14 @@ var Login = function (obj, alreadyEncrypted, localData) {
}; };
var Cipher = function (obj, alreadyEncrypted, localData) { var Cipher = function (obj, alreadyEncrypted, localData) {
this.constantsService = chrome.extension.getBackgroundPage().bg_constantsService;
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
id: 'id', id: null,
organizationId: 'organizationId', organizationId: null,
folderId: 'folderId', folderId: null,
name: 'name', name: null,
notes: 'notes' notes: null
}, alreadyEncrypted, ['id', 'organizationId', 'folderId']); }, alreadyEncrypted, ['id', 'organizationId', 'folderId']);
this.type = obj.type; this.type = obj.type;
@ -153,16 +156,16 @@ var Cipher = function (obj, alreadyEncrypted, localData) {
this.localData = localData; this.localData = localData;
switch (this.type) { switch (this.type) {
case 1: // cipherType.login case this.constantsService.cipherType.login:
this.login = new Login2(obj.login, alreadyEncrypted); this.login = new Login2(obj.login, alreadyEncrypted);
break; break;
case 2: // cipherType.secureNote case this.constantsService.cipherType.secureNote:
this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted); this.secureNote = new SecureNote(obj.secureNote, alreadyEncrypted);
break; break;
case 3: // cipherType.card case this.constantsService.cipherType.card:
this.card = new Card(obj.card, alreadyEncrypted); this.card = new Card(obj.card, alreadyEncrypted);
break; break;
case 4: // cipherType.identity case this.constantsService.cipherType.identity:
this.identity = new Identity(obj.identity, alreadyEncrypted); this.identity = new Identity(obj.identity, alreadyEncrypted);
break; break;
default: default:
@ -193,44 +196,44 @@ var Cipher = function (obj, alreadyEncrypted, localData) {
var Login2 = function (obj, alreadyEncrypted) { var Login2 = function (obj, alreadyEncrypted) {
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
uri: 'uri', uri: null,
username: 'username', username: null,
password: 'password', password: null,
totp: 'totp' totp: null
}, alreadyEncrypted, []); }, alreadyEncrypted, []);
}; };
var Identity = function (obj, alreadyEncrypted) { var Identity = function (obj, alreadyEncrypted) {
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
title: 'title', title: null,
firstName: 'firstName', firstName: null,
middleName: 'middleName', middleName: null,
lastName: 'lastName', lastName: null,
address1: 'address1', address1: null,
address2: 'address2', address2: null,
address3: 'address3', address3: null,
city: 'city', city: null,
state: 'state', state: null,
postalCode: 'postalCode', postalCode: null,
country: 'country', country: null,
company: 'company', company: null,
email: 'email', email: null,
phone: 'phone', phone: null,
ssn: 'ssn', ssn: null,
username: 'username', username: null,
passportNumber: 'passportNumber', passportNumber: null,
licenseNumber: 'licenseNumber' licenseNumber: null
}, alreadyEncrypted, []); }, alreadyEncrypted, []);
}; };
var Card = function (obj, alreadyEncrypted) { var Card = function (obj, alreadyEncrypted) {
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
cardholderName: 'cardholderName', cardholderName: null,
brand: 'brand', brand: null,
number: 'number', number: null,
expMonth: 'expMonth', expMonth: null,
expYear: 'expYear', expYear: null,
code: 'code' code: null
}, alreadyEncrypted, []); }, alreadyEncrypted, []);
}; };
@ -241,25 +244,25 @@ var SecureNote = function (obj, alreadyEncrypted) {
var Field = function (obj, alreadyEncrypted) { var Field = function (obj, alreadyEncrypted) {
this.type = obj.type; this.type = obj.type;
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
name: 'name', name: null,
value: 'value' value: null
}, alreadyEncrypted, []); }, alreadyEncrypted, []);
}; };
var Attachment = function (obj, alreadyEncrypted) { var Attachment = function (obj, alreadyEncrypted) {
this.size = obj.size; this.size = obj.size;
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
id: 'id', id: null,
url: 'url', url: null,
sizeName: 'sizeName', sizeName: null,
fileName: 'fileName' fileName: null
}, alreadyEncrypted, ['id', 'url', 'sizeName']); }, alreadyEncrypted, ['id', 'url', 'sizeName']);
}; };
var Folder = function (obj, alreadyEncrypted) { var Folder = function (obj, alreadyEncrypted) {
buildDomainModel(this, obj, { buildDomainModel(this, obj, {
id: 'id', id: null,
name: 'name' name: null
}, alreadyEncrypted, ['id']); }, alreadyEncrypted, ['id']);
}; };
@ -267,11 +270,12 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
notEncList = notEncList || []; notEncList = notEncList || [];
for (var prop in map) { for (var prop in map) {
if (map.hasOwnProperty(prop)) { if (map.hasOwnProperty(prop)) {
var objProp = obj[(map[prop] || prop)];
if (alreadyEncrypted === true || notEncList.indexOf(prop) > -1) { if (alreadyEncrypted === true || notEncList.indexOf(prop) > -1) {
model[prop] = obj[map[prop]] ? obj[map[prop]] : null; model[prop] = objProp ? objProp : null;
} }
else { else {
model[prop] = obj[map[prop]] ? new CipherString(obj[map[prop]]) : null; model[prop] = objProp ? new CipherString(objProp) : null;
} }
} }
} }
@ -283,10 +287,9 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
return Q(this.decryptedValue); return Q(this.decryptedValue);
} }
var self = this, var self = this;
cryptoService = chrome.extension.getBackgroundPage().bg_cryptoService; return self.cryptoService.getOrgKey(orgId).then(function (orgKey) {
return cryptoService.getOrgKey(orgId).then(function (orgKey) { return self.cryptoService.decrypt(self, orgKey);
return cryptoService.decrypt(self, orgKey);
}).then(function (decValue) { }).then(function (decValue) {
self.decryptedValue = decValue; self.decryptedValue = decValue;
return self.decryptedValue; return self.decryptedValue;
@ -380,6 +383,7 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
Cipher.prototype.decrypt = function () { Cipher.prototype.decrypt = function () {
var self = this; var self = this;
var model = { var model = {
id: self.id, id: self.id,
organizationId: self.organizationId, organizationId: self.organizationId,
@ -393,36 +397,36 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
var fields = []; var fields = [];
return decryptObj(model, this, { return decryptObj(model, this, {
name: 'name', name: null,
notes: 'notes' notes: null
}, null).then(function () { }, self.organizationId).then(function () {
switch (self.type) { switch (self.type) {
case 1: // cipherType.login case self.constantsService.cipherType.login:
return self.login.decrypt(self.organizationId); return self.login.decrypt(self.organizationId);
case 2: // cipherType.secureNote case self.constantsService.cipherType.secureNote:
return self.secureNote.decrypt(self.organizationId); return self.secureNote.decrypt(self.organizationId);
case 3: // cipherType.card case self.constantsService.cipherType.card:
return self.card.decrypt(self.organizationId); return self.card.decrypt(self.organizationId);
case 4: // cipherType.identity case self.constantsService.cipherType.identity:
return self.identity.decrypt(self.organizationId); return self.identity.decrypt(self.organizationId);
default: default:
return; return;
} }
}).then(function (decObj) { }).then(function (decObj) {
switch (self.type) { switch (self.type) {
case 1: // cipherType.login case self.constantsService.cipherType.login:
model.login = decObj; model.login = decObj;
model.subTitle = model.login.username; model.subTitle = model.login.username;
break; break;
case 2: // cipherType.secureNote case self.constantsService.cipherType.secureNote:
model.secureNote = decObj; model.secureNote = decObj;
model.subTitle = '-'; model.subTitle = '-';
break; break;
case 3: // cipherType.card case self.constantsService.cipherType.card:
model.card = decObj; model.card = decObj;
model.subTitle = model.identity.brand; model.subTitle = model.identity.brand;
break; break;
case 4: // cipherType.identity case self.constantsService.cipherType.identity:
model.identity = decObj; model.identity = decObj;
model.subTitle = model.identity.firstName; model.subTitle = model.identity.firstName;
break; break;
@ -464,21 +468,21 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
Login2.prototype.decrypt = function (orgId) { Login2.prototype.decrypt = function (orgId) {
return decryptObj({}, this, { return decryptObj({}, this, {
uri: 'uri', uri: null,
username: 'username', username: null,
password: 'password', password: null,
totp: 'totp' totp: null
}, orgId); }, orgId);
}; };
Card.prototype.decrypt = function (orgId) { Card.prototype.decrypt = function (orgId) {
return decryptObj({}, this, { return decryptObj({}, this, {
cardholderName: 'cardholderName', cardholderName: null,
brand: 'brand', brand: null,
number: 'number', number: null,
expMonth: 'expMonth', expMonth: null,
expYear: 'expYear', expYear: null,
code: 'code' code: null
}, orgId); }, orgId);
}; };
@ -490,24 +494,24 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
Identity.prototype.decrypt = function (orgId) { Identity.prototype.decrypt = function (orgId) {
return decryptObj({}, this, { return decryptObj({}, this, {
title: 'title', title: null,
firstName: 'firstName', firstName: null,
middleName: 'middleName', middleName: null,
lastName: 'lastName', lastName: null,
address1: 'address1', address1: null,
address2: 'address2', address2: null,
address3: 'address3', address3: null,
city: 'city', city: null,
state: 'state', state: null,
postalCode: 'postalCode', postalCode: null,
country: 'country', country: null,
company: 'company', company: null,
email: 'email', email: null,
phone: 'phone', phone: null,
ssn: 'ssn', ssn: null,
username: 'username', username: null,
passportNumber: 'passportNumber', passportNumber: null,
licenseNumber: 'licenseNumber' licenseNumber: null
}, orgId); }, orgId);
}; };
@ -517,8 +521,8 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
}; };
return decryptObj(model, this, { return decryptObj(model, this, {
name: 'name', name: null,
value: 'value' value: null
}, orgId); }, orgId);
}; };
@ -531,7 +535,7 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
}; };
return decryptObj(model, this, { return decryptObj(model, this, {
fileName: 'fileName' fileName: null
}, orgId); }, orgId);
}; };
@ -542,7 +546,7 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
}; };
return decryptObj(model, this, { return decryptObj(model, this, {
name: 'name' name: null
}, null); }, null);
}; };
@ -553,8 +557,9 @@ function buildDomainModel(model, obj, map, alreadyEncrypted, notEncList) {
/* jshint ignore:start */ /* jshint ignore:start */
(function (theProp) { (function (theProp) {
var promise = Q().then(function () { var promise = Q().then(function () {
if (self[map[theProp]]) { var mapProp = map[theProp] || theProp;
return self[map[theProp]].decrypt(orgId); if (self[mapProp]) {
return self[mapProp].decrypt(orgId);
} }
return null; return null;
}).then(function (val) { }).then(function (val) {

View File

@ -1,11 +1,13 @@
function LoginService(cryptoService, userService, apiService, settingsService, utilsService) { function LoginService(cryptoService, userService, apiService, settingsService, utilsService, constantsService) {
this.cryptoService = cryptoService; this.cryptoService = cryptoService;
this.userService = userService; this.userService = userService;
this.apiService = apiService; this.apiService = apiService;
this.settingsService = settingsService; this.settingsService = settingsService;
this.utilsService = utilsService; this.utilsService = utilsService;
this.constantsService = constantsService;
this.decryptedCipherCache = null; this.decryptedCipherCache = null;
this.localDataKey = 'sitesLocalData'; this.localDataKey = 'sitesLocalData';
this.neverDomainsKey = 'neverDomains';
initLoginService(); initLoginService();
} }
@ -28,62 +30,58 @@ function initLoginService() {
function encryptCipherData(cipher, model, key, self) { function encryptCipherData(cipher, model, key, self) {
switch (cipher.type) { switch (cipher.type) {
case 1: // cipherType.login case constantsService.cipherType.login:
return encryptObjProperty(cipher.login, model.login, { return encryptObjProperty(cipher.login, model.login, {
uri: 'uri', uri: null,
username: 'username', username: null,
password: 'password', password: null,
totp: 'totp' totp: null
}, key, self); }, key, self);
break; case constantsService.cipherType.secureNote:
case 2: // cipherType.secureNote
model.secureNote = { model.secureNote = {
type: cipher.secureNote.type type: cipher.secureNote.type
}; };
return Q(); return Q();
break; case constantsService.cipherType.card:
case 3: // cipherType.card
return encryptObjProperty(cipher.card, model.card, { return encryptObjProperty(cipher.card, model.card, {
cardholderName: 'cardholderName', cardholderName: null,
brand: 'brand', brand: null,
number: 'number', number: null,
expMonth: 'expMonth', expMonth: null,
expYear: 'expYear', expYear: null,
code: 'code' code: null
}, key, self); }, key, self);
break; case constantsService.cipherType.identity:
case 4: // cipherType.identity
return encryptObjProperty(cipher.identity, model.identity, { return encryptObjProperty(cipher.identity, model.identity, {
title: 'title', title: null,
firstName: 'firstName', firstName: null,
middleName: 'middleName', middleName: null,
lastName: 'lastName', lastName: null,
address1: 'address1', address1: null,
address2: 'address2', address2: null,
address3: 'address3', address3: null,
city: 'city', city: null,
state: 'state', state: null,
postalCode: 'postalCode', postalCode: null,
country: 'country', country: null,
company: 'company', company: null,
email: 'email', email: null,
phone: 'phone', phone: null,
ssn: 'ssn', ssn: null,
username: 'username', username: null,
passportNumber: 'passportNumber', passportNumber: null,
licenseNumber: 'licenseNumber' licenseNumber: null
}, key, self); }, key, self);
break;
default: default:
break; throw 'Unknown type.';
} }
} }
return self.cryptoService.getOrgKey(login.organizationId).then(function (key) { return self.cryptoService.getOrgKey(login.organizationId).then(function (key) {
return Q.all([ return Q.all([
encryptObjProperty(login, model, { encryptObjProperty(login, model, {
name: 'name', name: null,
notes: 'notes' notes: null
}, key, self), }, key, self),
encryptCipherData(login, model, key), encryptCipherData(login, model, key),
self.encryptFields(login.fields, key).then(function (fields) { self.encryptFields(login.fields, key).then(function (fields) {
@ -121,8 +119,8 @@ function initLoginService() {
}; };
return encryptObjProperty(field, model, { return encryptObjProperty(field, model, {
name: 'name', name: null,
value: 'value' value: null
}, key, self).then(function () { }, key, self).then(function () {
return model; return model;
}); });
@ -136,8 +134,9 @@ function initLoginService() {
/* jshint ignore:start */ /* jshint ignore:start */
(function (theProp) { (function (theProp) {
var promise = Q().then(function () { var promise = Q().then(function () {
if (obj[map[theProp]] && obj[map[theProp]] !== '') { var objProb = obj[(map[theProp] || theProp)];
return self.cryptoService.encrypt(obj[map[theProp]], key); if (objProb && objProb !== '') {
return self.cryptoService.encrypt(objProb, key);
} }
return null; return null;
}).then(function (val) { }).then(function (val) {
@ -204,22 +203,26 @@ function initLoginService() {
}; };
LoginService.prototype.getAllDecrypted = function () { LoginService.prototype.getAllDecrypted = function () {
var self = this, if (this.decryptedCipherCache) {
decCiphers = []; return Q(this.decryptedCipherCache);
}
return self.cryptoService.getKey().then(function (key) { var deferred = Q.defer(),
decCiphers = [],
self = this;
self.cryptoService.getKey().then(function (key) {
if (!key) { if (!key) {
deferred.reject(); deferred.reject();
return; return true;
}
if (self.decryptedCipherCache) {
deferred.resolve(self.decryptedCipherCache);
return;
} }
return self.getAll(); return self.getAll();
}).then(function (ciphers) { }).then(function (ciphers) {
if (ciphers === true) {
return;
}
var promises = []; var promises = [];
for (var i = 0; i < ciphers.length; i++) { for (var i = 0; i < ciphers.length; i++) {
/* jshint ignore:start */ /* jshint ignore:start */
@ -230,10 +233,16 @@ function initLoginService() {
} }
return Q.all(promises); return Q.all(promises);
}).then(function () { }).then(function (stop) {
if (stop === true) {
return;
}
self.decryptedCipherCache = decCiphers; self.decryptedCipherCache = decCiphers;
return self.decryptedCipherCache; deferred.resolve(self.decryptedCipherCache);
}); });
return deferred.promise;
}; };
LoginService.prototype.getAllDecryptedForFolder = function (folderId) { LoginService.prototype.getAllDecryptedForFolder = function (folderId) {
@ -460,8 +469,8 @@ function initLoginService() {
return Q(); return Q();
} }
var key = 'neverDomains'; var self = this;
return self.utilsService.getObjFromStorage(key).then(function (domains) { return self.utilsService.getObjFromStorage(self.neverDomainsKey).then(function (domains) {
if (!domains) { if (!domains) {
domains = {}; domains = {};
} }