1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-12-19 15:57:42 +01:00

abstract storage service

This commit is contained in:
Kyle Spearrin 2018-01-04 10:51:08 -05:00
parent 2ca0f6702e
commit ac0126b210
23 changed files with 222 additions and 195 deletions

View File

@ -14,6 +14,7 @@ import WindowsBackground from './windows.background';
import ApiService from '../services/api.service';
import AppIdService from '../services/appId.service';
import AutofillService from '../services/autofill.service';
import ChromeStorageService from '../services/chromeStorage.service';
import CipherService from '../services/cipher.service';
import CollectionService from '../services/collection.service';
import ConstantsService from '../services/constants.service';
@ -30,7 +31,10 @@ import TotpService from '../services/totp.service';
import UserService from '../services/user.service';
import UtilsService from '../services/utils.service';
import { StorageService } from '../services/abstractions/storage.service';
export default class MainBackground {
storageService: StorageService;
i18nService: any;
utilsService: UtilsService;
constantsService: ConstantsService;
@ -69,29 +73,31 @@ export default class MainBackground {
constructor() {
// Services
this.storageService = new ChromeStorageService();
this.utilsService = new UtilsService();
this.i18nService = i18nService(this.utilsService);
this.constantsService = new ConstantsService(this.i18nService, this.utilsService);
this.cryptoService = new CryptoService();
this.tokenService = new TokenService();
this.appIdService = new AppIdService();
this.cryptoService = new CryptoService(this.storageService, this.storageService);
this.tokenService = new TokenService(this.storageService);
this.appIdService = new AppIdService(this.storageService);
this.apiService = new ApiService(this.tokenService, this.utilsService,
(expired: boolean) => this.logout(expired));
this.environmentService = new EnvironmentService(this.apiService);
this.userService = new UserService(this.tokenService);
this.settingsService = new SettingsService(this.userService);
this.environmentService = new EnvironmentService(this.apiService, this.storageService);
this.userService = new UserService(this.tokenService, this.storageService);
this.settingsService = new SettingsService(this.userService, this.storageService);
this.cipherService = new CipherService(this.cryptoService, this.userService, this.settingsService,
this.apiService);
this.apiService, this.storageService);
this.folderService = new FolderService(this.cryptoService, this.userService, this.i18nService,
this.apiService);
this.collectionService = new CollectionService(this.cryptoService, this.userService);
this.apiService, this.storageService);
this.collectionService = new CollectionService(this.cryptoService, this.userService, this.storageService);
this.lockService = new LockService(this.cipherService, this.folderService, this.collectionService,
this.cryptoService, this.utilsService, () => this.setIcon(), () => this.refreshBadgeAndMenu());
this.cryptoService, this.utilsService, this.storageService,
() => this.setIcon(), () => this.refreshBadgeAndMenu());
this.syncService = new SyncService(this.userService, this.apiService, this.settingsService,
this.folderService, this.cipherService, this.cryptoService, this.collectionService,
(expired: boolean) => this.logout(expired));
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService);
this.totpService = new TotpService();
this.storageService, (expired: boolean) => this.logout(expired));
this.passwordGenerationService = new PasswordGenerationService(this.cryptoService, this.storageService);
this.totpService = new TotpService(this.storageService);
this.autofillService = new AutofillService(this.cipherService, this.tokenService,
this.totpService, this.utilsService);
@ -152,7 +158,7 @@ export default class MainBackground {
return;
}
const disabled = await this.utilsService.getObjFromStorage<boolean>(ConstantsService.disableContextMenuItemKey);
const disabled = await this.storageService.get<boolean>(ConstantsService.disableContextMenuItemKey);
if (!disabled) {
await this.buildContextMenu();
await this.contextMenuReady(tab, true);

View File

@ -1,4 +1,5 @@
import { CryptoService } from '../../../services/abstractions/crypto.service';
import { StorageService } from '../../../services/abstractions/storage.service';
import { UtilsService } from '../../../services/abstractions/utils.service';
function getBackgroundService<T>(service: string) {
@ -8,6 +9,7 @@ function getBackgroundService<T>(service: string) {
};
}
export const storageService = getBackgroundService<StorageService>('storageService');
export const tokenService = getBackgroundService<any>('tokenService');
export const cryptoService = getBackgroundService<any>('cryptoService');
export const userService = getBackgroundService<any>('userService');

View File

@ -10,6 +10,7 @@ export default angular
.service('validationService', ValidationService)
.service('authService', AuthService)
.factory('storageService', backgroundServices.storageService)
.factory('tokenService', backgroundServices.tokenService)
.factory('cryptoService', backgroundServices.cryptoService)
.factory('userService', backgroundServices.userService)

View File

@ -1,16 +1,14 @@
import { UtilsService } from '../../../services/abstractions/utils.service';
import { StorageService } from '../../../services/abstractions/storage.service';
class StateService {
private state: any = {};
constructor(private utilsService: UtilsService, private constantsService: any) {
constructor(private storageService: StorageService, private constantsService: any) {
}
async init() {
const faviconsDisabled = await this.utilsService
.getObjFromStorage<boolean>(this.constantsService.disableFaviconKey);
this.saveState('faviconEnabled', !faviconsDisabled);
const iconsDisabled = await this.storageService.get<boolean>(this.constantsService.disableFaviconKey);
this.saveState('faviconEnabled', !iconsDisabled);
}
saveState(key: string, data: any) {

View File

@ -1,4 +1,5 @@
import * as angular from 'angular';
import { StorageService } from '../../../services/abstractions/storage.service';
import { UtilsService } from '../../../services/abstractions/utils.service';
import StateService from '../services/state.service';
import * as template from './options.component.html';
@ -14,7 +15,7 @@ export class OptionsController {
constructor(private i18nService: any, private $analytics: any, private constantsService: any,
private utilsService: UtilsService, private totpService: any, private stateService: StateService,
private $timeout: ng.ITimeoutService) {
private storageService: StorageService, private $timeout: ng.ITimeoutService) {
this.i18n = i18nService;
$timeout(() => {
@ -25,22 +26,22 @@ export class OptionsController {
}
async loadSettings() {
this.enableAutoFillOnPageLoad = await this.utilsService.getObjFromStorage<boolean>(
this.enableAutoFillOnPageLoad = await this.storageService.get<boolean>(
this.constantsService.enableAutoFillOnPageLoadKey);
const disableGa = await this.utilsService.getObjFromStorage<boolean>(
const disableGa = await this.storageService.get<boolean>(
this.constantsService.disableGaKey);
this.disableGa = disableGa || (this.utilsService.isFirefox() && disableGa === undefined);
this.disableAddLoginNotification = await this.utilsService.getObjFromStorage<boolean>(
this.disableAddLoginNotification = await this.storageService.get<boolean>(
this.constantsService.disableAddLoginNotificationKey);
this.disableContextMenuItem = await this.utilsService.getObjFromStorage<boolean>(
this.disableContextMenuItem = await this.storageService.get<boolean>(
this.constantsService.disableContextMenuItemKey);
this.disableAutoTotpCopy = !await this.totpService.isAutoCopyEnabled();
this.disableFavicon = await this.utilsService.getObjFromStorage<boolean>(
this.disableFavicon = await this.storageService.get<boolean>(
this.constantsService.disableFaviconKey);
}
@ -50,18 +51,18 @@ export class OptionsController {
}
updateGa() {
this.utilsService.saveObjToStorage(this.constantsService.disableGaKey, this.disableGa);
this.storageService.save(this.constantsService.disableGaKey, this.disableGa);
this.callAnalytics('Analytics', !this.disableGa);
}
updateAddLoginNotification() {
this.utilsService.saveObjToStorage(this.constantsService.disableAddLoginNotificationKey,
this.storageService.save(this.constantsService.disableAddLoginNotificationKey,
this.disableAddLoginNotification);
this.callAnalytics('Add Login Notification', !this.disableAddLoginNotification);
}
updateDisableContextMenuItem() {
this.utilsService.saveObjToStorage(this.constantsService.disableContextMenuItemKey,
this.storageService.save(this.constantsService.disableContextMenuItemKey,
this.disableContextMenuItem).then(() => {
chrome.runtime.sendMessage({
command: 'bgUpdateContextMenu',
@ -71,18 +72,18 @@ export class OptionsController {
}
updateAutoTotpCopy() {
this.utilsService.saveObjToStorage(this.constantsService.disableAutoTotpCopyKey, this.disableAutoTotpCopy);
this.storageService.save(this.constantsService.disableAutoTotpCopyKey, this.disableAutoTotpCopy);
this.callAnalytics('Auto Copy TOTP', !this.disableAutoTotpCopy);
}
updateAutoFillOnPageLoad() {
this.utilsService.saveObjToStorage(this.constantsService.enableAutoFillOnPageLoadKey,
this.storageService.save(this.constantsService.enableAutoFillOnPageLoadKey,
this.enableAutoFillOnPageLoad);
this.callAnalytics('Auto-fill Page Load', this.enableAutoFillOnPageLoad);
}
updateDisableFavicon() {
this.utilsService.saveObjToStorage(this.constantsService.disableFaviconKey, this.disableFavicon);
this.storageService.save(this.constantsService.disableFaviconKey, this.disableFavicon);
this.stateService.saveState('faviconEnabled', !this.disableFavicon);
this.callAnalytics('Favicon', !this.disableFavicon);
}

View File

@ -1,6 +1,7 @@
import * as angular from 'angular';
import { BrowserType } from '../../../enums/browserType.enum';
import { CryptoService } from '../../../services/abstractions/crypto.service';
import { StorageService } from '../../../services/abstractions/storage.service';
import { UtilsService } from '../../../services/abstractions/utils.service';
import ConstantsService from '../../../services/constants.service';
@ -28,7 +29,8 @@ export class SettingsController {
constructor(private $state: any, private SweetAlert: any, private utilsService: UtilsService,
private $analytics: any, private i18nService: any, private constantsService: ConstantsService,
private cryptoService: CryptoService, private lockService: any, private $timeout: ng.ITimeoutService) {
private cryptoService: CryptoService, private lockService: any, private storageService: StorageService,
private $timeout: ng.ITimeoutService) {
this.i18n = i18nService;
$timeout(() => {
@ -36,7 +38,7 @@ export class SettingsController {
}, 500);
this.showOnLocked = !utilsService.isFirefox() && !utilsService.isEdge();
this.utilsService.getObjFromStorage(constantsService.lockOptionKey).then((lockOption: number) => {
this.storageService.get(constantsService.lockOptionKey).then((lockOption: number) => {
if (lockOption != null) {
let option = lockOption.toString();
if (option === '-2' && !this.showOnLocked) {
@ -51,7 +53,7 @@ export class SettingsController {
changeLockOption() {
const option = this.lockOption && this.lockOption !== '' ? parseInt(this.lockOption, 10) : null;
this.utilsService.saveObjToStorage(this.constantsService.lockOptionKey, option).then(() => {
this.storageService.save(this.constantsService.lockOptionKey, option).then(() => {
return this.cryptoService.getKeyHash();
}).then((keyHash) => {
if (keyHash) {

View File

@ -0,0 +1,5 @@
export interface StorageService {
get<T>(key: string): Promise<T>;
save(key: string, obj: any): Promise<any>;
remove(key: string): Promise<any>;
}

View File

@ -16,7 +16,4 @@ export interface UtilsService {
inTab(theWindow: Window): boolean;
inPopout(theWindow: Window): boolean;
inPopup(theWindow: Window): boolean;
saveObjToStorage(key: string, obj: any): Promise<any>;
removeFromStorage(key: string): Promise<any>;
getObjFromStorage<T>(key: string): Promise<T>;
}

View File

@ -1,31 +1,27 @@
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
export default class AppIdService {
static getAppId(): Promise<string> {
return AppIdService.makeAndGetAppId('appId');
constructor(private storageService: StorageService) {
}
static getAnonymousAppId(): Promise<string> {
return AppIdService.makeAndGetAppId('anonymousAppId');
getAppId(): Promise<string> {
return this.makeAndGetAppId('appId');
}
private static async makeAndGetAppId(key: string) {
const existingId = await UtilsService.getObjFromStorage<string>(key);
getAnonymousAppId(): Promise<string> {
return this.makeAndGetAppId('anonymousAppId');
}
private async makeAndGetAppId(key: string) {
const existingId = await this.storageService.get<string>(key);
if (existingId != null) {
return existingId;
}
const guid = UtilsService.newGuid();
await UtilsService.saveObjToStorage(key, guid);
await this.storageService.save(key, guid);
return guid;
}
// TODO: remove these in favor of static methods
getAppId(): Promise<string> {
return AppIdService.getAppId();
}
getAnonymousAppId(): Promise<string> {
return AppIdService.getAnonymousAppId();
}
}

View File

@ -0,0 +1,31 @@
import { StorageService as StorageServiceInterface } from './abstractions/storage.service';
export default class ChromeStorageService implements StorageServiceInterface {
get<T>(key: string): Promise<T> {
return new Promise((resolve) => {
chrome.storage.local.get(key, (obj: any) => {
if (obj && (typeof obj[key] !== 'undefined') && obj[key] !== null) {
resolve(obj[key] as T);
} else {
resolve(null);
}
});
});
}
save(key: string, obj: any): Promise<any> {
return new Promise((resolve) => {
chrome.storage.local.set({ [key]: obj }, () => {
resolve();
});
});
}
remove(key: string): Promise<any> {
return new Promise((resolve) => {
chrome.storage.local.remove(key, () => {
resolve();
});
});
}
}

View File

@ -16,7 +16,8 @@ import ConstantsService from './constants.service';
import CryptoService from './crypto.service';
import SettingsService from './settings.service';
import UserService from './user.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
ciphersPrefix: 'ciphers_',
@ -68,7 +69,8 @@ export default class CipherService {
decryptedCipherCache: any[];
constructor(private cryptoService: CryptoService, private userService: UserService,
private settingsService: SettingsService, private apiService: ApiService) {
private settingsService: SettingsService, private apiService: ApiService,
private storageService: StorageService) {
}
clearCache(): void {
@ -131,8 +133,8 @@ export default class CipherService {
async get(id: string): Promise<Cipher> {
const userId = await this.userService.getUserId();
const localData = await UtilsService.getObjFromStorage<any>(Keys.localData);
const ciphers = await UtilsService.getObjFromStorage<{ [id: string]: CipherData; }>(
const localData = await this.storageService.get<any>(Keys.localData);
const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
Keys.ciphersPrefix + userId);
if (ciphers == null || !ciphers.hasOwnProperty(id)) {
return null;
@ -143,8 +145,8 @@ export default class CipherService {
async getAll(): Promise<Cipher[]> {
const userId = await this.userService.getUserId();
const localData = await UtilsService.getObjFromStorage<any>(Keys.localData);
const ciphers = await UtilsService.getObjFromStorage<{ [id: string]: CipherData; }>(
const localData = await this.storageService.get<any>(Keys.localData);
const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
Keys.ciphersPrefix + userId);
const response: Cipher[] = [];
for (const id in ciphers) {
@ -243,7 +245,7 @@ export default class CipherService {
}
async updateLastUsedDate(id: string): Promise<void> {
let ciphersLocalData = await UtilsService.getObjFromStorage<any>(Keys.localData);
let ciphersLocalData = await this.storageService.get<any>(Keys.localData);
if (!ciphersLocalData) {
ciphersLocalData = {};
}
@ -256,7 +258,7 @@ export default class CipherService {
};
}
await UtilsService.saveObjToStorage(Keys.localData, ciphersLocalData);
await this.storageService.save(Keys.localData, ciphersLocalData);
if (this.decryptedCipherCache == null) {
return;
@ -276,12 +278,12 @@ export default class CipherService {
return;
}
let domains = await UtilsService.getObjFromStorage<{ [id: string]: any; }>(Keys.neverDomains);
let domains = await this.storageService.get<{ [id: string]: any; }>(Keys.neverDomains);
if (!domains) {
domains = {};
}
domains[domain] = null;
await UtilsService.saveObjToStorage(Keys.neverDomains, domains);
await this.storageService.save(Keys.neverDomains, domains);
}
async saveWithServer(cipher: Cipher): Promise<any> {
@ -339,7 +341,7 @@ export default class CipherService {
async upsert(cipher: CipherData | CipherData[]): Promise<any> {
const userId = await this.userService.getUserId();
let ciphers = await UtilsService.getObjFromStorage<{ [id: string]: CipherData; }>(
let ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
Keys.ciphersPrefix + userId);
if (ciphers == null) {
ciphers = {};
@ -354,24 +356,24 @@ export default class CipherService {
});
}
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);
await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);
this.decryptedCipherCache = null;
}
async replace(ciphers: { [id: string]: CipherData; }): Promise<any> {
const userId = await this.userService.getUserId();
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);
await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);
this.decryptedCipherCache = null;
}
async clear(userId: string): Promise<any> {
await UtilsService.removeFromStorage(Keys.ciphersPrefix + userId);
await this.storageService.remove(Keys.ciphersPrefix + userId);
this.decryptedCipherCache = null;
}
async delete(id: string | string[]): Promise<any> {
const userId = await this.userService.getUserId();
const ciphers = await UtilsService.getObjFromStorage<{ [id: string]: CipherData; }>(
const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
Keys.ciphersPrefix + userId);
if (ciphers == null) {
return;
@ -386,7 +388,7 @@ export default class CipherService {
});
}
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);
await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);
this.decryptedCipherCache = null;
}
@ -397,7 +399,7 @@ export default class CipherService {
async deleteAttachment(id: string, attachmentId: string): Promise<void> {
const userId = await this.userService.getUserId();
const ciphers = await UtilsService.getObjFromStorage<{ [id: string]: CipherData; }>(
const ciphers = await this.storageService.get<{ [id: string]: CipherData; }>(
Keys.ciphersPrefix + userId);
if (ciphers == null || !ciphers.hasOwnProperty(id) || ciphers[id].attachments == null) {
@ -410,7 +412,7 @@ export default class CipherService {
}
}
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);
await this.storageService.save(Keys.ciphersPrefix + userId, ciphers);
this.decryptedCipherCache = null;
}

View File

@ -5,7 +5,8 @@ import { CollectionData } from '../models/data/collectionData';
import CryptoService from './crypto.service';
import UserService from './user.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
collectionsPrefix: 'collections_',
@ -14,7 +15,8 @@ const Keys = {
export default class CollectionService {
decryptedCollectionCache: any[];
constructor(private cryptoService: CryptoService, private userService: UserService) {
constructor(private cryptoService: CryptoService, private userService: UserService,
private storageService: StorageService) {
}
clearCache(): void {
@ -23,7 +25,7 @@ export default class CollectionService {
async get(id: string): Promise<Collection> {
const userId = await this.userService.getUserId();
const collections = await UtilsService.getObjFromStorage<{ [id: string]: CollectionData; }>(
const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(
Keys.collectionsPrefix + userId);
if (collections == null || !collections.hasOwnProperty(id)) {
return null;
@ -34,7 +36,7 @@ export default class CollectionService {
async getAll(): Promise<Collection[]> {
const userId = await this.userService.getUserId();
const collections = await UtilsService.getObjFromStorage<{ [id: string]: CollectionData; }>(
const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(
Keys.collectionsPrefix + userId);
const response: Collection[] = [];
for (const id in collections) {
@ -71,7 +73,7 @@ export default class CollectionService {
async upsert(collection: CollectionData | CollectionData[]): Promise<any> {
const userId = await this.userService.getUserId();
let collections = await UtilsService.getObjFromStorage<{ [id: string]: CollectionData; }>(
let collections = await this.storageService.get<{ [id: string]: CollectionData; }>(
Keys.collectionsPrefix + userId);
if (collections == null) {
collections = {};
@ -86,24 +88,24 @@ export default class CollectionService {
});
}
await UtilsService.saveObjToStorage(Keys.collectionsPrefix + userId, collections);
await this.storageService.save(Keys.collectionsPrefix + userId, collections);
this.decryptedCollectionCache = null;
}
async replace(collections: { [id: string]: CollectionData; }): Promise<any> {
const userId = await this.userService.getUserId();
await UtilsService.saveObjToStorage(Keys.collectionsPrefix + userId, collections);
await this.storageService.save(Keys.collectionsPrefix + userId, collections);
this.decryptedCollectionCache = null;
}
async clear(userId: string): Promise<any> {
await UtilsService.removeFromStorage(Keys.collectionsPrefix + userId);
await this.storageService.remove(Keys.collectionsPrefix + userId);
this.decryptedCollectionCache = null;
}
async delete(id: string | string[]): Promise<any> {
const userId = await this.userService.getUserId();
const collections = await UtilsService.getObjFromStorage<{ [id: string]: CollectionData; }>(
const collections = await this.storageService.get<{ [id: string]: CollectionData; }>(
Keys.collectionsPrefix + userId);
if (collections == null) {
return;
@ -118,7 +120,7 @@ export default class CollectionService {
});
}
await UtilsService.saveObjToStorage(Keys.collectionsPrefix + userId, collections);
await this.storageService.save(Keys.collectionsPrefix + userId, collections);
this.decryptedCollectionCache = null;
}
}

View File

@ -11,6 +11,7 @@ import ConstantsService from './constants.service';
import UtilsService from './utils.service';
import { CryptoService as CryptoServiceInterface } from './abstractions/crypto.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
key: 'key',
@ -40,28 +41,31 @@ export default class CryptoService implements CryptoServiceInterface {
private privateKey: ArrayBuffer;
private orgKeys: Map<string, SymmetricCryptoKey>;
constructor(private storageService: StorageService, private secureStorageService: StorageService) {
}
async setKey(key: SymmetricCryptoKey): Promise<any> {
this.key = key;
const option = await UtilsService.getObjFromStorage<number>(ConstantsService.lockOptionKey);
const option = await this.storageService.get<number>(ConstantsService.lockOptionKey);
if (option != null) {
// if we have a lock option set, we do not store the key
return;
}
return UtilsService.saveObjToStorage(Keys.key, key.keyB64);
return this.secureStorageService.save(Keys.key, key.keyB64);
}
setKeyHash(keyHash: string): Promise<{}> {
this.keyHash = keyHash;
return UtilsService.saveObjToStorage(Keys.keyHash, keyHash);
return this.storageService.save(Keys.keyHash, keyHash);
}
async setEncKey(encKey: string): Promise<{}> {
if (encKey == null) {
return;
}
await UtilsService.saveObjToStorage(Keys.encKey, encKey);
await this.storageService.save(Keys.encKey, encKey);
this.encKey = null;
}
@ -70,7 +74,7 @@ export default class CryptoService implements CryptoServiceInterface {
return;
}
await UtilsService.saveObjToStorage(Keys.encPrivateKey, encPrivateKey);
await this.storageService.save(Keys.encPrivateKey, encPrivateKey);
this.privateKey = null;
}
@ -80,7 +84,7 @@ export default class CryptoService implements CryptoServiceInterface {
orgKeys[org.id] = org.key;
});
return UtilsService.saveObjToStorage(Keys.encOrgKeys, orgKeys);
return this.storageService.save(Keys.encOrgKeys, orgKeys);
}
async getKey(): Promise<SymmetricCryptoKey> {
@ -88,12 +92,12 @@ export default class CryptoService implements CryptoServiceInterface {
return this.key;
}
const option = await UtilsService.getObjFromStorage<number>(ConstantsService.lockOptionKey);
const option = await this.storageService.get<number>(ConstantsService.lockOptionKey);
if (option != null) {
return null;
}
const key = await UtilsService.getObjFromStorage<string>(Keys.key);
const key = await this.secureStorageService.get<string>(Keys.key);
if (key) {
this.key = new SymmetricCryptoKey(key, true);
}
@ -106,7 +110,7 @@ export default class CryptoService implements CryptoServiceInterface {
return Promise.resolve(this.keyHash);
}
return UtilsService.getObjFromStorage<string>(Keys.keyHash);
return this.storageService.get<string>(Keys.keyHash);
}
async getEncKey(): Promise<SymmetricCryptoKey> {
@ -114,7 +118,7 @@ export default class CryptoService implements CryptoServiceInterface {
return this.encKey;
}
const encKey = await UtilsService.getObjFromStorage<string>(Keys.encKey);
const encKey = await this.storageService.get<string>(Keys.encKey);
if (encKey == null) {
return null;
}
@ -138,7 +142,7 @@ export default class CryptoService implements CryptoServiceInterface {
return this.privateKey;
}
const encPrivateKey = await UtilsService.getObjFromStorage<string>(Keys.encPrivateKey);
const encPrivateKey = await this.storageService.get<string>(Keys.encPrivateKey);
if (encPrivateKey == null) {
return null;
}
@ -155,7 +159,7 @@ export default class CryptoService implements CryptoServiceInterface {
}
const self = this;
const encOrgKeys = await UtilsService.getObjFromStorage<any>(Keys.encOrgKeys);
const encOrgKeys = await this.storageService.get<any>(Keys.encOrgKeys);
if (!encOrgKeys) {
return null;
}
@ -195,12 +199,12 @@ export default class CryptoService implements CryptoServiceInterface {
clearKey(): Promise<any> {
this.key = this.legacyEtmKey = null;
return UtilsService.removeFromStorage(Keys.key);
return this.secureStorageService.remove(Keys.key);
}
clearKeyHash(): Promise<any> {
this.keyHash = null;
return UtilsService.removeFromStorage(Keys.keyHash);
return this.storageService.remove(Keys.keyHash);
}
clearEncKey(memoryOnly?: boolean): Promise<any> {
@ -208,7 +212,7 @@ export default class CryptoService implements CryptoServiceInterface {
if (memoryOnly) {
return Promise.resolve();
}
return UtilsService.removeFromStorage(Keys.encKey);
return this.storageService.remove(Keys.encKey);
}
clearPrivateKey(memoryOnly?: boolean): Promise<any> {
@ -216,7 +220,7 @@ export default class CryptoService implements CryptoServiceInterface {
if (memoryOnly) {
return Promise.resolve();
}
return UtilsService.removeFromStorage(Keys.encPrivateKey);
return this.storageService.remove(Keys.encPrivateKey);
}
clearOrgKeys(memoryOnly?: boolean): Promise<any> {
@ -224,7 +228,7 @@ export default class CryptoService implements CryptoServiceInterface {
if (memoryOnly) {
return Promise.resolve();
}
return UtilsService.removeFromStorage(Keys.encOrgKeys);
return this.storageService.remove(Keys.encOrgKeys);
}
clearKeys(): Promise<any> {
@ -239,7 +243,7 @@ export default class CryptoService implements CryptoServiceInterface {
async toggleKey(): Promise<any> {
const key = await this.getKey();
const option = await UtilsService.getObjFromStorage(ConstantsService.lockOptionKey);
const option = await this.storageService.get(ConstantsService.lockOptionKey);
if (option != null || option === 0) {
// if we have a lock option set, clear the key
await this.clearKey();

View File

@ -1,6 +1,7 @@
import ApiService from './api.service';
import ConstantsService from './constants.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
import EnvironmentUrls from '../models/domain/environmentUrls';
@ -11,11 +12,11 @@ export default class EnvironmentService {
identityUrl: string;
iconsUrl: string;
constructor(private apiService: ApiService) {
constructor(private apiService: ApiService, private storageService: StorageService) {
}
async setUrlsFromStorage(): Promise<void> {
const urlsObj: any = await UtilsService.getObjFromStorage(ConstantsService.environmentUrlsKey);
const urlsObj: any = await this.storageService.get(ConstantsService.environmentUrlsKey);
const urls = urlsObj || {
base: null,
api: null,
@ -46,7 +47,7 @@ export default class EnvironmentService {
urls.identity = this.formatUrl(urls.identity);
urls.icons = this.formatUrl(urls.icons);
await UtilsService.saveObjToStorage(ConstantsService.environmentUrlsKey, {
await this.storageService.save(ConstantsService.environmentUrlsKey, {
base: urls.base,
api: urls.api,
identity: urls.identity,

View File

@ -9,7 +9,8 @@ import { FolderResponse } from '../models/response/folderResponse';
import ApiService from './api.service';
import CryptoService from './crypto.service';
import UserService from './user.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
foldersPrefix: 'folders_',
@ -19,7 +20,7 @@ export default class FolderService {
decryptedFolderCache: any[];
constructor(private cryptoService: CryptoService, private userService: UserService,
private i18nService: any, private apiService: ApiService) {
private i18nService: any, private apiService: ApiService, private storageService: StorageService) {
}
clearCache(): void {
@ -35,7 +36,7 @@ export default class FolderService {
async get(id: string): Promise<Folder> {
const userId = await this.userService.getUserId();
const folders = await UtilsService.getObjFromStorage<{ [id: string]: FolderData; }>(
const folders = await this.storageService.get<{ [id: string]: FolderData; }>(
Keys.foldersPrefix + userId);
if (folders == null || !folders.hasOwnProperty(id)) {
return null;
@ -46,7 +47,7 @@ export default class FolderService {
async getAll(): Promise<Folder[]> {
const userId = await this.userService.getUserId();
const folders = await UtilsService.getObjFromStorage<{ [id: string]: FolderData; }>(
const folders = await this.storageService.get<{ [id: string]: FolderData; }>(
Keys.foldersPrefix + userId);
const response: Folder[] = [];
for (const id in folders) {
@ -103,7 +104,7 @@ export default class FolderService {
async upsert(folder: FolderData | FolderData[]): Promise<any> {
const userId = await this.userService.getUserId();
let folders = await UtilsService.getObjFromStorage<{ [id: string]: FolderData; }>(
let folders = await this.storageService.get<{ [id: string]: FolderData; }>(
Keys.foldersPrefix + userId);
if (folders == null) {
folders = {};
@ -118,24 +119,24 @@ export default class FolderService {
});
}
await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders);
await this.storageService.save(Keys.foldersPrefix + userId, folders);
this.decryptedFolderCache = null;
}
async replace(folders: { [id: string]: FolderData; }): Promise<any> {
const userId = await this.userService.getUserId();
await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders);
await this.storageService.save(Keys.foldersPrefix + userId, folders);
this.decryptedFolderCache = null;
}
async clear(userId: string): Promise<any> {
await UtilsService.removeFromStorage(Keys.foldersPrefix + userId);
await this.storageService.remove(Keys.foldersPrefix + userId);
this.decryptedFolderCache = null;
}
async delete(id: string | string[]): Promise<any> {
const userId = await this.userService.getUserId();
const folders = await UtilsService.getObjFromStorage<{ [id: string]: FolderData; }>(
const folders = await this.storageService.get<{ [id: string]: FolderData; }>(
Keys.foldersPrefix + userId);
if (folders == null) {
return;
@ -150,7 +151,7 @@ export default class FolderService {
});
}
await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders);
await this.storageService.save(Keys.foldersPrefix + userId, folders);
this.decryptedFolderCache = null;
}

View File

@ -5,10 +5,13 @@ import CryptoService from './crypto.service';
import FolderService from './folder.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
export default class LockService {
constructor(private cipherService: CipherService, private folderService: FolderService,
private collectionService: CollectionService, private cryptoService: CryptoService,
private utilsService: UtilsService, private setIcon: Function, private refreshBadgeAndMenu: Function) {
private utilsService: UtilsService, private storageService: StorageService,
private setIcon: Function, private refreshBadgeAndMenu: Function) {
this.checkLock();
setInterval(() => this.checkLock(), 10 * 1000); // check every 10 seconds
@ -16,7 +19,7 @@ export default class LockService {
if ((window as any).chrome.idle && (window as any).chrome.idle.onStateChanged) {
(window as any).chrome.idle.onStateChanged.addListener(async (newState: string) => {
if (newState === 'locked') {
const lockOption = await UtilsService.getObjFromStorage<number>(ConstantsService.lockOptionKey);
const lockOption = await this.storageService.get<number>(ConstantsService.lockOptionKey);
if (lockOption === -2) {
self.lock();
}
@ -42,12 +45,12 @@ export default class LockService {
return;
}
const lockOption = await UtilsService.getObjFromStorage<number>(ConstantsService.lockOptionKey);
const lockOption = await this.storageService.get<number>(ConstantsService.lockOptionKey);
if (lockOption == null || lockOption < 0) {
return;
}
const lastActive = await UtilsService.getObjFromStorage<number>(ConstantsService.lastActiveKey);
const lastActive = await this.storageService.get<number>(ConstantsService.lastActiveKey);
if (lastActive == null) {
return;
}

View File

@ -4,6 +4,8 @@ import PasswordHistory from '../models/domain/passwordHistory';
import CryptoService from './crypto.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const DefaultOptions = {
length: 14,
ambiguous: false,
@ -145,8 +147,8 @@ export default class PasswordGenerationService {
optionsCache: any;
history: PasswordHistory[] = [];
constructor(private cryptoService: CryptoService) {
UtilsService.getObjFromStorage<PasswordHistory[]>(Keys.history).then((encrypted) => {
constructor(private cryptoService: CryptoService, private storageService: StorageService) {
storageService.get<PasswordHistory[]>(Keys.history).then((encrypted) => {
return this.decryptHistory(encrypted);
}).then((history) => {
this.history = history;
@ -159,7 +161,7 @@ export default class PasswordGenerationService {
async getOptions() {
if (this.optionsCache == null) {
const options = await UtilsService.getObjFromStorage(Keys.options);
const options = await this.storageService.get(Keys.options);
if (options == null) {
this.optionsCache = DefaultOptions;
} else {
@ -171,7 +173,7 @@ export default class PasswordGenerationService {
}
async saveOptions(options: any) {
await UtilsService.saveObjToStorage(Keys.options, options);
await this.storageService.save(Keys.options, options);
this.optionsCache = options;
}
@ -193,12 +195,12 @@ export default class PasswordGenerationService {
}
const newHistory = await this.encryptHistory();
return await UtilsService.saveObjToStorage(Keys.history, newHistory);
return await this.storageService.save(Keys.history, newHistory);
}
async clear(): Promise<any> {
this.history = [];
return await UtilsService.removeFromStorage(Keys.history);
return await this.storageService.remove(Keys.history);
}
private async encryptHistory(): Promise<PasswordHistory[]> {

View File

@ -1,5 +1,6 @@
import UserService from './user.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
settingsPrefix: 'settings_',
@ -9,7 +10,7 @@ const Keys = {
export default class SettingsService {
private settingsCache: any;
constructor(private userService: UserService) {
constructor(private userService: UserService, private storageService: StorageService) {
}
clearCache(): void {
@ -25,7 +26,7 @@ export default class SettingsService {
}
async clear(userId: string): Promise<void> {
await UtilsService.removeFromStorage(Keys.settingsPrefix + userId);
await this.storageService.remove(Keys.settingsPrefix + userId);
this.settingsCache = null;
}
@ -34,7 +35,7 @@ export default class SettingsService {
private async getSettings(): Promise<any> {
if (this.settingsCache == null) {
const userId = await this.userService.getUserId();
this.settingsCache = UtilsService.getObjFromStorage(Keys.settingsPrefix + userId);
this.settingsCache = this.storageService.get(Keys.settingsPrefix + userId);
}
return this.settingsCache;
}
@ -55,7 +56,7 @@ export default class SettingsService {
}
settings[key] = value;
await UtilsService.saveObjToStorage(Keys.settingsPrefix + userId, settings);
await this.storageService.save(Keys.settingsPrefix + userId, settings);
this.settingsCache = settings;
}
}

View File

@ -16,7 +16,8 @@ import CryptoService from './crypto.service';
import FolderService from './folder.service';
import SettingsService from './settings.service';
import UserService from './user.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
lastSyncPrefix: 'lastSync_',
@ -28,12 +29,13 @@ export default class SyncService {
constructor(private userService: UserService, private apiService: ApiService,
private settingsService: SettingsService, private folderService: FolderService,
private cipherService: CipherService, private cryptoService: CryptoService,
private collectionService: CollectionService, private logoutCallback: Function) {
private collectionService: CollectionService, private storageService: StorageService,
private logoutCallback: Function) {
}
async getLastSync() {
const userId = await this.userService.getUserId();
const lastSync = await UtilsService.getObjFromStorage<any>(Keys.lastSyncPrefix + userId);
const lastSync = await this.storageService.get<any>(Keys.lastSyncPrefix + userId);
if (lastSync) {
return new Date(lastSync);
}
@ -43,7 +45,7 @@ export default class SyncService {
async setLastSync(date: Date) {
const userId = await this.userService.getUserId();
await UtilsService.saveObjToStorage(Keys.lastSyncPrefix + userId, date.toJSON());
await this.storageService.save(Keys.lastSyncPrefix + userId, date.toJSON());
}
syncStarted() {

View File

@ -1,6 +1,8 @@
import ConstantsService from './constants.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
accessToken: 'accessToken',
refreshToken: 'refreshToken',
@ -12,6 +14,9 @@ export default class TokenService {
decodedToken: any;
refreshToken: string;
constructor(private storageService: StorageService) {
}
setTokens(accessToken: string, refreshToken: string): Promise<any> {
return Promise.all([
this.setToken(accessToken),
@ -22,7 +27,7 @@ export default class TokenService {
setToken(token: string): Promise<any> {
this.token = token;
this.decodedToken = null;
return UtilsService.saveObjToStorage(Keys.accessToken, token);
return this.storageService.save(Keys.accessToken, token);
}
async getToken(): Promise<string> {
@ -30,13 +35,13 @@ export default class TokenService {
return this.token;
}
this.token = await UtilsService.getObjFromStorage<string>(Keys.accessToken);
this.token = await this.storageService.get<string>(Keys.accessToken);
return this.token;
}
setRefreshToken(refreshToken: string): Promise<any> {
this.refreshToken = refreshToken;
return UtilsService.saveObjToStorage(Keys.refreshToken, refreshToken);
return this.storageService.save(Keys.refreshToken, refreshToken);
}
async getRefreshToken(): Promise<string> {
@ -44,20 +49,20 @@ export default class TokenService {
return this.refreshToken;
}
this.refreshToken = await UtilsService.getObjFromStorage<string>(Keys.refreshToken);
this.refreshToken = await this.storageService.get<string>(Keys.refreshToken);
return this.refreshToken;
}
setTwoFactorToken(token: string, email: string): Promise<any> {
return UtilsService.saveObjToStorage(Keys.twoFactorTokenPrefix + email, token);
return this.storageService.save(Keys.twoFactorTokenPrefix + email, token);
}
getTwoFactorToken(email: string): Promise<string> {
return UtilsService.getObjFromStorage<string>(Keys.twoFactorTokenPrefix + email);
return this.storageService.get<string>(Keys.twoFactorTokenPrefix + email);
}
clearTwoFactorToken(email: string): Promise<any> {
return UtilsService.removeFromStorage(Keys.twoFactorTokenPrefix + email);
return this.storageService.remove(Keys.twoFactorTokenPrefix + email);
}
clearToken(): Promise<any> {
@ -66,8 +71,8 @@ export default class TokenService {
this.refreshToken = null;
return Promise.all([
UtilsService.removeFromStorage(Keys.accessToken),
UtilsService.removeFromStorage(Keys.refreshToken),
this.storageService.remove(Keys.accessToken),
this.storageService.remove(Keys.refreshToken),
]);
}

View File

@ -1,5 +1,6 @@
import ConstantsService from './constants.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const b32Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
@ -9,6 +10,9 @@ const TotpAlgorithm = {
};
export default class TotpService {
constructor(private storageService: StorageService) {
}
async getCode(keyb32: string): Promise<string> {
const epoch = Math.round(new Date().getTime() / 1000.0);
const timeHex = this.leftpad(this.dec2hex(Math.floor(epoch / 30)), 16, '0');
@ -32,7 +36,7 @@ export default class TotpService {
}
async isAutoCopyEnabled(): Promise<boolean> {
return !(await UtilsService.getObjFromStorage<boolean>(ConstantsService.disableAutoTotpCopyKey));
return !(await this.storageService.get<boolean>(ConstantsService.disableAutoTotpCopyKey));
}
// Helpers

View File

@ -1,5 +1,6 @@
import TokenService from './token.service';
import UtilsService from './utils.service';
import { StorageService } from './abstractions/storage.service';
const Keys = {
userId: 'userId',
@ -12,7 +13,7 @@ export default class UserService {
email: string;
stamp: string;
constructor(private tokenService: TokenService) {
constructor(private tokenService: TokenService, private storageService: StorageService) {
}
setUserIdAndEmail(userId: string, email: string): Promise<any> {
@ -20,14 +21,14 @@ export default class UserService {
this.userId = userId;
return Promise.all([
UtilsService.saveObjToStorage(Keys.userEmail, email),
UtilsService.saveObjToStorage(Keys.userId, userId),
this.storageService.save(Keys.userEmail, email),
this.storageService.save(Keys.userId, userId),
]);
}
setSecurityStamp(stamp: string): Promise<any> {
this.stamp = stamp;
return UtilsService.saveObjToStorage(Keys.stamp, stamp);
return this.storageService.save(Keys.stamp, stamp);
}
async getUserId(): Promise<string> {
@ -35,7 +36,7 @@ export default class UserService {
return this.userId;
}
this.userId = await UtilsService.getObjFromStorage<string>(Keys.userId);
this.userId = await this.storageService.get<string>(Keys.userId);
return this.userId;
}
@ -44,7 +45,7 @@ export default class UserService {
return this.email;
}
this.email = await UtilsService.getObjFromStorage<string>(Keys.userEmail);
this.email = await this.storageService.get<string>(Keys.userEmail);
return this.email;
}
@ -53,15 +54,15 @@ export default class UserService {
return this.stamp;
}
this.stamp = await UtilsService.getObjFromStorage<string>(Keys.stamp);
this.stamp = await this.storageService.get<string>(Keys.stamp);
return this.stamp;
}
async clear(): Promise<any> {
await Promise.all([
UtilsService.removeFromStorage(Keys.userId),
UtilsService.removeFromStorage(Keys.userEmail),
UtilsService.removeFromStorage(Keys.stamp),
this.storageService.remove(Keys.userId),
this.storageService.remove(Keys.userEmail),
this.storageService.remove(Keys.stamp),
]);
this.userId = this.email = this.stamp = null;

View File

@ -136,34 +136,6 @@ export default class UtilsService implements UtilsServiceInterface {
return decodeURIComponent(escape(encodedString));
}
static saveObjToStorage(key: string, obj: any) {
return new Promise((resolve) => {
chrome.storage.local.set({ [key]: obj }, () => {
resolve();
});
});
}
static removeFromStorage(key: string) {
return new Promise((resolve) => {
chrome.storage.local.remove(key, () => {
resolve();
});
});
}
static getObjFromStorage<T>(key: string): Promise<T> {
return new Promise((resolve) => {
chrome.storage.local.get(key, (obj: any) => {
if (obj && (typeof obj[key] !== 'undefined') && obj[key] !== null) {
resolve(obj[key] as T);
} else {
resolve(null);
}
});
});
}
static getDomain(uriString: string): string {
if (uriString == null) {
return null;
@ -392,16 +364,4 @@ export default class UtilsService implements UtilsServiceInterface {
return theWindow.location.search === '' || theWindow.location.search.indexOf('uilocation=') === -1 ||
theWindow.location.search.indexOf('uilocation=popup') > -1;
}
saveObjToStorage(key: string, obj: any): Promise<any> {
return UtilsService.saveObjToStorage(key, obj);
}
removeFromStorage(key: string): Promise<any> {
return UtilsService.removeFromStorage(key);
}
getObjFromStorage<T>(key: string): Promise<T> {
return UtilsService.getObjFromStorage<T>(key);
}
}