mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-24 16:49:26 +01:00
support user encryption key
This commit is contained in:
parent
e282966d64
commit
16098a1743
@ -11,7 +11,8 @@ var userService = new UserService(tokenService, apiService, cryptoService);
|
|||||||
var settingsService = new SettingsService(userService);
|
var settingsService = new SettingsService(userService);
|
||||||
var loginService = new LoginService(cryptoService, userService, apiService, settingsService);
|
var loginService = new LoginService(cryptoService, userService, apiService, settingsService);
|
||||||
var folderService = new FolderService(cryptoService, userService, apiService);
|
var folderService = new FolderService(cryptoService, userService, apiService);
|
||||||
var syncService = new SyncService(loginService, folderService, userService, apiService, settingsService, cryptoService);
|
var syncService = new SyncService(loginService, folderService, userService, apiService, settingsService,
|
||||||
|
cryptoService, logout);
|
||||||
var autofillService = new AutofillService();
|
var autofillService = new AutofillService();
|
||||||
var passwordGenerationService = new PasswordGenerationService();
|
var passwordGenerationService = new PasswordGenerationService();
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
|
|||||||
setIcon();
|
setIcon();
|
||||||
function setIcon() {
|
function setIcon() {
|
||||||
userService.isAuthenticated(function (isAuthenticated) {
|
userService.isAuthenticated(function (isAuthenticated) {
|
||||||
cryptoService.getKey(function (key) {
|
cryptoService.getKey().then(function (key) {
|
||||||
var suffix = '';
|
var suffix = '';
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
suffix = '_gray';
|
suffix = '_gray';
|
||||||
@ -668,7 +669,7 @@ function logout(expired, callback) {
|
|||||||
settingsService.clear(function () {
|
settingsService.clear(function () {
|
||||||
tokenService.clearToken(function () {
|
tokenService.clearToken(function () {
|
||||||
cryptoService.clearKeys(function () {
|
cryptoService.clearKeys(function () {
|
||||||
userService.clearUserIdAndEmail(function () {
|
userService.clear(function () {
|
||||||
loginService.clear(userId, function () {
|
loginService.clear(userId, function () {
|
||||||
folderService.clear(userId, function () {
|
folderService.clear(userId, function () {
|
||||||
chrome.runtime.sendMessage({
|
chrome.runtime.sendMessage({
|
||||||
@ -757,7 +758,7 @@ function checkLock() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cryptoService.getKey(function (key) {
|
cryptoService.getKey().then(function (key) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
// no key so no need to lock
|
// no key so no need to lock
|
||||||
return;
|
return;
|
||||||
|
@ -48,11 +48,12 @@ var TokenRequest = function (email, masterPasswordHash, token, device) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var RegisterRequest = function (email, masterPasswordHash, masterPasswordHint) {
|
var RegisterRequest = function (email, masterPasswordHash, masterPasswordHint, key) {
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.masterPasswordHash = masterPasswordHash;
|
this.masterPasswordHash = masterPasswordHash;
|
||||||
this.masterPasswordHint = masterPasswordHint ? masterPasswordHint : null;
|
this.masterPasswordHint = masterPasswordHint ? masterPasswordHint : null;
|
||||||
|
this.key = key;
|
||||||
};
|
};
|
||||||
|
|
||||||
var PasswordHintRequest = function (email) {
|
var PasswordHintRequest = function (email) {
|
||||||
|
@ -38,6 +38,9 @@ var ProfileResponse = function (response) {
|
|||||||
this.masterPasswordHint = response.MasterPasswordHint;
|
this.masterPasswordHint = response.MasterPasswordHint;
|
||||||
this.culture = response.Culture;
|
this.culture = response.Culture;
|
||||||
this.twoFactorEnabled = response.TwoFactorEnabled;
|
this.twoFactorEnabled = response.TwoFactorEnabled;
|
||||||
|
this.key = response.Key;
|
||||||
|
this.privateKey = response.PrivateKey;
|
||||||
|
this.securityStamp = response.SecurityStamp;
|
||||||
|
|
||||||
this.organizations = [];
|
this.organizations = [];
|
||||||
if (response.Organizations) {
|
if (response.Organizations) {
|
||||||
@ -68,6 +71,7 @@ var IdentityTokenResponse = function (response) {
|
|||||||
this.tokenType = response.token_type;
|
this.tokenType = response.token_type;
|
||||||
|
|
||||||
this.privateKey = response.PrivateKey;
|
this.privateKey = response.PrivateKey;
|
||||||
|
this.key = response.Key;
|
||||||
};
|
};
|
||||||
|
|
||||||
var ListResponse = function (data) {
|
var ListResponse = function (data) {
|
||||||
|
@ -9,13 +9,8 @@ var CipherString = function () {
|
|||||||
var constants = chrome.extension.getBackgroundPage().constantsService;
|
var constants = chrome.extension.getBackgroundPage().constantsService;
|
||||||
|
|
||||||
if (arguments.length >= 2) {
|
if (arguments.length >= 2) {
|
||||||
// ct and optional header
|
// ct and header
|
||||||
if (arguments[0] === constants.encType.AesCbc256_B64) {
|
this.encryptedString = arguments[0] + '.' + arguments[1];
|
||||||
this.encryptedString = arguments[1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.encryptedString = arguments[0] + '.' + arguments[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// iv
|
// iv
|
||||||
if (arguments.length > 2 && arguments[2]) {
|
if (arguments.length > 2 && arguments[2]) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller(
|
.controller(
|
||||||
'accountsRegisterController',
|
'accountsRegisterController',
|
||||||
function ($scope, $state, cryptoService, toastr, $q, apiService, utilsService, $analytics, i18nService) {
|
function ($scope, $state, cryptoService, toastr, $q, apiService, utilsService, $analytics, i18nService) {
|
||||||
$scope.i18n = i18nService;
|
$scope.i18n = i18nService;
|
||||||
|
|
||||||
$scope.model = {};
|
$scope.model = {};
|
||||||
@ -45,15 +45,17 @@
|
|||||||
|
|
||||||
function registerPromise(key, masterPassword, email, hint) {
|
function registerPromise(key, masterPassword, email, hint) {
|
||||||
return $q(function (resolve, reject) {
|
return $q(function (resolve, reject) {
|
||||||
cryptoService.hashPassword(masterPassword, key, function (hashedPassword) {
|
cryptoService.makeEncKey(key).then(function (encKey) {
|
||||||
var request = new RegisterRequest(email, hashedPassword, hint);
|
cryptoService.hashPassword(masterPassword, key, function (hashedPassword) {
|
||||||
apiService.postRegister(request,
|
var request = new RegisterRequest(email, hashedPassword, hint, encKey.encryptedString);
|
||||||
function () {
|
apiService.postRegister(request,
|
||||||
resolve();
|
function () {
|
||||||
},
|
resolve();
|
||||||
function (error) {
|
},
|
||||||
reject(error);
|
function (error) {
|
||||||
});
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
var userService = $injector.get('userService');
|
var userService = $injector.get('userService');
|
||||||
var cryptoService = $injector.get('cryptoService');
|
var cryptoService = $injector.get('cryptoService');
|
||||||
|
|
||||||
cryptoService.getKey(function (key) {
|
cryptoService.getKey().then(function (key) {
|
||||||
userService.isAuthenticated(function (isAuthenticated) {
|
userService.isAuthenticated(function (isAuthenticated) {
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
|
@ -24,12 +24,9 @@
|
|||||||
cryptoService.setKey(key, function () {
|
cryptoService.setKey(key, function () {
|
||||||
cryptoService.setKeyHash(hashedPassword, function () {
|
cryptoService.setKeyHash(hashedPassword, function () {
|
||||||
userService.setUserIdAndEmail(tokenService.getUserId(), tokenService.getEmail(), function () {
|
userService.setUserIdAndEmail(tokenService.getUserId(), tokenService.getEmail(), function () {
|
||||||
if (!response.privateKey) {
|
cryptoService.setEncKey(response.key).then(function () {
|
||||||
loggedIn(deferred);
|
return cryptoService.setEncPrivateKey(response.privateKey);
|
||||||
return;
|
}).then(function () {
|
||||||
}
|
|
||||||
|
|
||||||
cryptoService.setEncPrivateKey(response.privateKey).then(function () {
|
|
||||||
loggedIn(deferred);
|
loggedIn(deferred);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -4,16 +4,16 @@ function ApiService(tokenService, appIdService, utilsService, logoutCallback) {
|
|||||||
//this.identityBaseUrl = 'http://localhost:33656';
|
//this.identityBaseUrl = 'http://localhost:33656';
|
||||||
|
|
||||||
// Desktop external
|
// Desktop external
|
||||||
//this.baseUrl = 'http://192.168.1.8:4000';
|
this.baseUrl = 'http://192.168.1.6:4000';
|
||||||
//this.identityBaseUrl = 'http://192.168.1.8:33656';
|
this.identityBaseUrl = 'http://192.168.1.6:33656';
|
||||||
|
|
||||||
// Preview
|
// Preview
|
||||||
//this.baseUrl = 'https://preview-api.bitwarden.com';
|
//this.baseUrl = 'https://preview-api.bitwarden.com';
|
||||||
//this.identityBaseUrl = 'https://preview-identity.bitwarden.com';
|
//this.identityBaseUrl = 'https://preview-identity.bitwarden.com';
|
||||||
|
|
||||||
// Production
|
// Production
|
||||||
this.baseUrl = 'https://api.bitwarden.com';
|
//this.baseUrl = 'https://api.bitwarden.com';
|
||||||
this.identityBaseUrl = 'https://identity.bitwarden.com';
|
//this.identityBaseUrl = 'https://identity.bitwarden.com';
|
||||||
|
|
||||||
this.tokenService = tokenService;
|
this.tokenService = tokenService;
|
||||||
this.logoutCallback = logoutCallback;
|
this.logoutCallback = logoutCallback;
|
||||||
|
@ -5,6 +5,7 @@ function CryptoService(constantsService) {
|
|||||||
|
|
||||||
function initCryptoService(constantsService) {
|
function initCryptoService(constantsService) {
|
||||||
var _key,
|
var _key,
|
||||||
|
_encKey,
|
||||||
_legacyEtmKey,
|
_legacyEtmKey,
|
||||||
_keyHash,
|
_keyHash,
|
||||||
_privateKey,
|
_privateKey,
|
||||||
@ -47,12 +48,26 @@ function initCryptoService(constantsService) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CryptoService.prototype.setEncKey = function (encKey) {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
chrome.storage.local.set({
|
||||||
|
'encKey': encKey
|
||||||
|
}, function () {
|
||||||
|
_encKey = null;
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
CryptoService.prototype.setEncPrivateKey = function (encPrivateKey) {
|
CryptoService.prototype.setEncPrivateKey = function (encPrivateKey) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
|
||||||
chrome.storage.local.set({
|
chrome.storage.local.set({
|
||||||
'encPrivateKey': encPrivateKey
|
'encPrivateKey': encPrivateKey
|
||||||
}, function () {
|
}, function () {
|
||||||
|
_privateKey = null;
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,21 +91,19 @@ function initCryptoService(constantsService) {
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
CryptoService.prototype.getKey = function (callback) {
|
CryptoService.prototype.getKey = function () {
|
||||||
if (!callback || typeof callback !== 'function') {
|
var deferred = Q.defer();
|
||||||
throw 'callback function required';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_key) {
|
if (_key) {
|
||||||
callback(_key);
|
deferred.resolve(_key);
|
||||||
return;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
||||||
if (obj && (obj[self.constantsService.lockOptionKey] || obj[self.constantsService.lockOptionKey] === 0)) {
|
if (obj && (obj[self.constantsService.lockOptionKey] || obj[self.constantsService.lockOptionKey] === 0)) {
|
||||||
// if we have a lock option set, we do not try to fetch the storage key since it should not even be there
|
// if we have a lock option set, we do not try to fetch the storage key since it should not even be there
|
||||||
callback(null);
|
deferred.resolve(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,9 +112,11 @@ function initCryptoService(constantsService) {
|
|||||||
_key = new SymmetricCryptoKey(obj.key, true);
|
_key = new SymmetricCryptoKey(obj.key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(_key);
|
deferred.resolve(_key);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
CryptoService.prototype.getKeyHash = function (callback) {
|
CryptoService.prototype.getKeyHash = function (callback) {
|
||||||
@ -123,6 +138,33 @@ function initCryptoService(constantsService) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CryptoService.prototype.getEncKey = function () {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
if (_encKey) {
|
||||||
|
deferred.resolve(_encKey);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
chrome.storage.local.get('encKey', function (obj) {
|
||||||
|
if (!obj || !obj.encKey) {
|
||||||
|
deferred.resolve(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.getKey().then(function (key) {
|
||||||
|
return self.decrypt(new CipherString(obj.encKey), key, 'raw');
|
||||||
|
}).then(function (encKey) {
|
||||||
|
_encKey = new SymmetricCryptoKey(encKey);
|
||||||
|
deferred.resolve(_encKey);
|
||||||
|
}, function () {
|
||||||
|
deferred.reject('Cannot get enc key. Decryption failed.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
|
||||||
CryptoService.prototype.getPrivateKey = function () {
|
CryptoService.prototype.getPrivateKey = function () {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
if (_privateKey) {
|
if (_privateKey) {
|
||||||
@ -232,8 +274,26 @@ function initCryptoService(constantsService) {
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CryptoService.prototype.clearEncKey = function () {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
_encKey = null;
|
||||||
|
chrome.storage.local.remove('encKey', function () {
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
|
||||||
CryptoService.prototype.clearPrivateKey = function () {
|
CryptoService.prototype.clearPrivateKey = function () {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
_privateKey = null;
|
_privateKey = null;
|
||||||
|
chrome.storage.local.remove('encPrivateKey', function () {
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
CryptoService.prototype.clearOrgKeys = function (memoryOnly) {
|
CryptoService.prototype.clearOrgKeys = function (memoryOnly) {
|
||||||
@ -258,8 +318,13 @@ function initCryptoService(constantsService) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
Q.all([self.clearKey(), self.clearKeyHash(), self.clearOrgKeys()]).then(function () {
|
Q.all([
|
||||||
self.clearPrivateKey();
|
self.clearKey(),
|
||||||
|
self.clearKeyHash(),
|
||||||
|
self.clearOrgKeys(),
|
||||||
|
self.clearEncKey(),
|
||||||
|
self.clearPrivateKey()
|
||||||
|
]).then(function () {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -270,7 +335,7 @@ function initCryptoService(constantsService) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
self.getKey(function (key) {
|
self.getKey().then(function (key) {
|
||||||
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
chrome.storage.local.get(self.constantsService.lockOptionKey, function (obj) {
|
||||||
if (obj && (obj[self.constantsService.lockOptionKey] || obj[self.constantsService.lockOptionKey] === 0)) {
|
if (obj && (obj[self.constantsService.lockOptionKey] || obj[self.constantsService.lockOptionKey] === 0)) {
|
||||||
// if we have a lock option set, clear the key
|
// if we have a lock option set, clear the key
|
||||||
@ -299,7 +364,7 @@ function initCryptoService(constantsService) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CryptoService.prototype.hashPassword = function (password, key, callback) {
|
CryptoService.prototype.hashPassword = function (password, key, callback) {
|
||||||
this.getKey(function (storedKey) {
|
this.getKey().then(function (storedKey) {
|
||||||
key = key || storedKey;
|
key = key || storedKey;
|
||||||
|
|
||||||
if (!password || !key) {
|
if (!password || !key) {
|
||||||
@ -311,6 +376,11 @@ function initCryptoService(constantsService) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CryptoService.prototype.makeEncKey = function (key) {
|
||||||
|
var bytes = forge.random.getBytesSync(512 / 8);
|
||||||
|
return this.encrypt(bytes, key, 'raw');
|
||||||
|
};
|
||||||
|
|
||||||
CryptoService.prototype.encrypt = function (plainValue, key, plainValueEncoding) {
|
CryptoService.prototype.encrypt = function (plainValue, key, plainValueEncoding) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
@ -319,8 +389,8 @@ function initCryptoService(constantsService) {
|
|||||||
deferred.resolve(null);
|
deferred.resolve(null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.getKey(function (localKey) {
|
getKeyForEncryption(self, key).then(function (keyToUse) {
|
||||||
key = key || localKey;
|
key = keyToUse;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject('Encryption key unavailable.');
|
deferred.reject('Encryption key unavailable.');
|
||||||
return;
|
return;
|
||||||
@ -356,8 +426,8 @@ function initCryptoService(constantsService) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.getKey(function (localKey) {
|
getKeyForEncryption(self, key).then(function (keyToUse) {
|
||||||
key = key || localKey;
|
key = keyToUse;
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject('Encryption key unavailable.');
|
deferred.reject('Encryption key unavailable.');
|
||||||
return;
|
return;
|
||||||
@ -479,6 +549,23 @@ function initCryptoService(constantsService) {
|
|||||||
return b64Output ? forge.util.encode64(mac.getBytes()) : mac.getBytes();
|
return b64Output ? forge.util.encode64(mac.getBytes()) : mac.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getKeyForEncryption(self, key) {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
deferred.resolve(key);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.getEncKey().then(function (encKey) {
|
||||||
|
return encKey || self.getKey();
|
||||||
|
}).then(function (keyToUse) {
|
||||||
|
deferred.resolve(keyToUse);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
// Safely compare two MACs in a way that protects against timing attacks (Double HMAC Verification).
|
// Safely compare two MACs in a way that protects against timing attacks (Double HMAC Verification).
|
||||||
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
|
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
|
||||||
function macsEqual(macKey, mac1, mac2) {
|
function macsEqual(macKey, mac1, mac2) {
|
||||||
|
@ -68,7 +68,7 @@ function initFolderService() {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
cryptoService.getKey(function (key) {
|
cryptoService.getKey().then(function (key) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
return;
|
return;
|
||||||
|
@ -91,7 +91,7 @@ function initLoginService() {
|
|||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
cryptoService.getKey(function (key) {
|
cryptoService.getKey().then(function (key) {
|
||||||
if (!key) {
|
if (!key) {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
return;
|
return;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
function SyncService(loginService, folderService, userService, apiService, settingsService, cryptoService) {
|
function SyncService(loginService, folderService, userService, apiService, settingsService,
|
||||||
|
cryptoService, logoutCallback) {
|
||||||
this.loginService = loginService;
|
this.loginService = loginService;
|
||||||
this.folderService = folderService;
|
this.folderService = folderService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.apiService = apiService;
|
this.apiService = apiService;
|
||||||
this.settingsService = settingsService;
|
this.settingsService = settingsService;
|
||||||
this.cryptoService = settingsService;
|
this.cryptoService = cryptoService;
|
||||||
this.syncInProgress = false;
|
this.syncInProgress = false;
|
||||||
|
this.logoutCallback = logoutCallback;
|
||||||
|
|
||||||
initSyncService();
|
initSyncService();
|
||||||
};
|
};
|
||||||
@ -37,12 +39,12 @@ function initSyncService() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
syncProfile().then(function () {
|
syncProfile(self).then(function () {
|
||||||
return syncFolders(userId);
|
return syncFolders(self, userId);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return syncCiphers(userId);
|
return syncCiphers(self, userId);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return syncSettings(userId);
|
return syncSettings(self, userId);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
self.setLastSync(now, function () {
|
self.setLastSync(now, function () {
|
||||||
self.syncCompleted(true);
|
self.syncCompleted(true);
|
||||||
@ -80,45 +82,37 @@ function initSyncService() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncProfile() {
|
function syncProfile(self) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
|
||||||
|
|
||||||
function setKeys(hasPrivateKey, response, d) {
|
|
||||||
if (response.organizations && response.organizations.length && !hasPrivateKey) {
|
|
||||||
self.apiService.getKeys(function (keysResponse) {
|
|
||||||
if (keysResponse.privateKey) {
|
|
||||||
self.cryptoService.setEncPrivateKey(keysResponse.privateKey).then(function () {
|
|
||||||
return self.cryptoService.setOrgKeys(response.organizations);
|
|
||||||
}, function () {
|
|
||||||
d.reject();
|
|
||||||
}).then(function () {
|
|
||||||
d.resolve();
|
|
||||||
}, function () {
|
|
||||||
d.reject();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
d.resolve();
|
|
||||||
}
|
|
||||||
}, function () {
|
|
||||||
d.reject();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.cryptoService.setOrgKeys(response.organizations).then(function () {
|
|
||||||
d.resolve();
|
|
||||||
}, function () {
|
|
||||||
d.reject();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.apiService.getProfile(function (response) {
|
self.apiService.getProfile(function (response) {
|
||||||
self.cryptoService.getPrivateKey().then(function (privateKey) {
|
self.userService.getSecurityStamp().then(function (stamp) {
|
||||||
setKeys(!!privateKey, response, deferred);
|
if (stamp && stamp != response.securityStamp) {
|
||||||
|
if (self.logoutCallback) {
|
||||||
|
self.logoutCallback(true, function () { });
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.reject();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.cryptoService.setEncKey(response.key);
|
||||||
|
}).then(function () {
|
||||||
|
return self.cryptoService.setEncPrivateKey(response.privateKey);
|
||||||
}, function () {
|
}, function () {
|
||||||
setKeys(true, response, deferred);
|
deferred.reject();
|
||||||
|
}).then(function () {
|
||||||
|
return self.cryptoService.setOrgKeys(response.organizations);
|
||||||
|
}, function () {
|
||||||
|
deferred.reject();
|
||||||
|
}).then(function () {
|
||||||
|
return self.userService.setSecurityStamp(response.securityStamp);
|
||||||
|
}, function () {
|
||||||
|
deferred.reject();
|
||||||
|
}).then(function () {
|
||||||
|
deferred.resolve();
|
||||||
|
}, function () {
|
||||||
|
deferred.reject();
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
deferred.reject();
|
deferred.reject();
|
||||||
@ -127,9 +121,8 @@ function initSyncService() {
|
|||||||
return deferred.promise
|
return deferred.promise
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncFolders(userId) {
|
function syncFolders(self, userId) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.apiService.getFolders(function (response) {
|
self.apiService.getFolders(function (response) {
|
||||||
var folders = {};
|
var folders = {};
|
||||||
@ -148,9 +141,8 @@ function initSyncService() {
|
|||||||
return deferred.promise
|
return deferred.promise
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncCiphers(userId) {
|
function syncCiphers(self, userId) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.apiService.getCiphers(function (response) {
|
self.apiService.getCiphers(function (response) {
|
||||||
var logins = {};
|
var logins = {};
|
||||||
@ -172,9 +164,8 @@ function initSyncService() {
|
|||||||
return deferred.promise
|
return deferred.promise
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncSettings(userId) {
|
function syncSettings(self, userId) {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var ciphers = self.apiService.getIncludedDomains(function (response) {
|
var ciphers = self.apiService.getIncludedDomains(function (response) {
|
||||||
var eqDomains = [];
|
var eqDomains = [];
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
|
|
||||||
function initUserService() {
|
function initUserService() {
|
||||||
var userIdKey = 'userId',
|
var userIdKey = 'userId',
|
||||||
userEmailKey = 'userEmail';
|
userEmailKey = 'userEmail',
|
||||||
|
stampKey = 'securityStamp';
|
||||||
|
|
||||||
var _userId = null,
|
var _userId = null,
|
||||||
_email = null;
|
_email = null,
|
||||||
|
_stamp = null;
|
||||||
|
|
||||||
UserService.prototype.setUserIdAndEmail = function (userId, email, callback) {
|
UserService.prototype.setUserIdAndEmail = function (userId, email, callback) {
|
||||||
if (!callback || typeof callback !== 'function') {
|
if (!callback || typeof callback !== 'function') {
|
||||||
@ -33,6 +35,20 @@ function initUserService() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UserService.prototype.setSecurityStamp = function (stamp) {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
_stamp = stamp;
|
||||||
|
var stampObj = {};
|
||||||
|
stampObj[stampKey] = stamp;
|
||||||
|
|
||||||
|
chrome.storage.local.set(stampObj, function () {
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise
|
||||||
|
};
|
||||||
|
|
||||||
UserService.prototype.getUserId = function (callback) {
|
UserService.prototype.getUserId = function (callback) {
|
||||||
if (!callback || typeof callback !== 'function') {
|
if (!callback || typeof callback !== 'function') {
|
||||||
throw 'callback function required';
|
throw 'callback function required';
|
||||||
@ -69,15 +85,35 @@ function initUserService() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
UserService.prototype.clearUserIdAndEmail = function (callback) {
|
UserService.prototype.getSecurityStamp = function () {
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
if (_stamp) {
|
||||||
|
deferred.resolve(_stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.storage.local.get(stampKey, function (obj) {
|
||||||
|
if (obj && obj[stampKey]) {
|
||||||
|
_stamp = obj[stampKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.resolve(_stamp);
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise
|
||||||
|
};
|
||||||
|
|
||||||
|
UserService.prototype.clear = function (callback) {
|
||||||
if (!callback || typeof callback !== 'function') {
|
if (!callback || typeof callback !== 'function') {
|
||||||
throw 'callback function required';
|
throw 'callback function required';
|
||||||
}
|
}
|
||||||
|
|
||||||
_userId = _email = null;
|
_userId = _email = _stamp = null;
|
||||||
chrome.storage.local.remove(userIdKey, function () {
|
chrome.storage.local.remove(userIdKey, function () {
|
||||||
chrome.storage.local.remove(userEmailKey, function () {
|
chrome.storage.local.remove(userEmailKey, function () {
|
||||||
callback();
|
chrome.storage.local.remove(stampKey, function () {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user