diff --git a/src/services/crypto.service.ts b/src/services/crypto.service.ts index 29014f6502..8f0b6808a1 100644 --- a/src/services/crypto.service.ts +++ b/src/services/crypto.service.ts @@ -26,32 +26,28 @@ export default class CryptoService { private privateKey: ArrayBuffer; private orgKeys: Map; - constructor(private utilsService: UtilsService) { - } - async setKey(key: SymmetricCryptoKey) { - const self = this; this.key = key; - const option = await this.utilsService.getObjFromStorage(ConstantsService.lockOptionKey); + const option = await UtilsService.getObjFromStorage(ConstantsService.lockOptionKey); if (option != null) { // if we have a lock option set, we do not store the key return; } - return self.utilsService.saveObjToStorage(Keys.key, key.keyB64); + return UtilsService.saveObjToStorage(Keys.key, key.keyB64); } setKeyHash(keyHash: string): Promise<{}> { this.keyHash = keyHash; - return this.utilsService.saveObjToStorage(Keys.keyHash, keyHash); + return UtilsService.saveObjToStorage(Keys.keyHash, keyHash); } async setEncKey(encKey: string) { if (encKey == null) { return; } - await this.utilsService.saveObjToStorage(Keys.encKey, encKey); + await UtilsService.saveObjToStorage(Keys.encKey, encKey); this.encKey = null; } @@ -60,7 +56,7 @@ export default class CryptoService { return; } - await this.utilsService.saveObjToStorage(Keys.encPrivateKey, encPrivateKey); + await UtilsService.saveObjToStorage(Keys.encPrivateKey, encPrivateKey); this.privateKey = null; } @@ -71,7 +67,7 @@ export default class CryptoService { orgKeys[org.id] = org.key; } - return this.utilsService.saveObjToStorage(Keys.encOrgKeys, orgKeys); + return UtilsService.saveObjToStorage(Keys.encOrgKeys, orgKeys); } async getKey(): Promise { @@ -79,12 +75,12 @@ export default class CryptoService { return this.key; } - const option = await this.utilsService.getObjFromStorage(ConstantsService.lockOptionKey); + const option = await UtilsService.getObjFromStorage(ConstantsService.lockOptionKey); if (option != null) { return null; } - const key = await this.utilsService.getObjFromStorage(Keys.key); + const key = await UtilsService.getObjFromStorage(Keys.key); if (key) { this.key = new SymmetricCryptoKey(key, true); } @@ -97,7 +93,7 @@ export default class CryptoService { return Promise.resolve(this.keyHash); } - return this.utilsService.getObjFromStorage(Keys.keyHash); + return UtilsService.getObjFromStorage(Keys.keyHash); } async getEncKey(): Promise { @@ -105,7 +101,7 @@ export default class CryptoService { return this.encKey; } - const encKey = await this.utilsService.getObjFromStorage(Keys.encKey); + const encKey = await UtilsService.getObjFromStorage(Keys.encKey); if (encKey == null) { return null; } @@ -129,7 +125,7 @@ export default class CryptoService { return this.privateKey; } - const encPrivateKey = await this.utilsService.getObjFromStorage(Keys.encPrivateKey); + const encPrivateKey = await UtilsService.getObjFromStorage(Keys.encPrivateKey); if (encPrivateKey == null) { return null; } @@ -146,34 +142,24 @@ export default class CryptoService { } const self = this; - const encOrgKeys = await this.utilsService.getObjFromStorage(Keys.encOrgKeys); + const encOrgKeys = await UtilsService.getObjFromStorage(Keys.encOrgKeys); if (!encOrgKeys) { return null; } - const decPromises: Array> = []; const orgKeys: Map = new Map(); let setKey = false; for (const orgId in encOrgKeys) { - if (encOrgKeys.hasOwnProperty(orgId)) { - /* jshint ignore:start */ - // tslint:disable-next-line - (function (orgIdInstance) { - const p = self.rsaDecrypt(encOrgKeys[orgIdInstance]).then((decValueB64: string) => { - orgKeys.set(orgIdInstance, new SymmetricCryptoKey(decValueB64, true)); - setKey = true; - }, (e: any) => { - // tslint:disable-next-line - console.log('getOrgKeys error: ' + e); - }); - decPromises.push(p); - })(orgId); - /* jshint ignore:end */ + if (!encOrgKeys.hasOwnProperty(orgId)) { + continue; } + + const decValueB64 = await this.rsaDecrypt(encOrgKeys[orgId]); + orgKeys.set(orgId, new SymmetricCryptoKey(decValueB64, true)); + setKey = true; } - await Promise.all(decPromises); if (setKey) { this.orgKeys = orgKeys; } @@ -196,12 +182,12 @@ export default class CryptoService { clearKey(): Promise { this.key = this.legacyEtmKey = null; - return this.utilsService.removeFromStorage(Keys.key); + return UtilsService.removeFromStorage(Keys.key); } clearKeyHash(): Promise { this.keyHash = null; - return this.utilsService.removeFromStorage(Keys.keyHash); + return UtilsService.removeFromStorage(Keys.keyHash); } clearEncKey(memoryOnly?: boolean): Promise { @@ -209,7 +195,7 @@ export default class CryptoService { if (memoryOnly) { return Promise.resolve(); } - return this.utilsService.removeFromStorage(Keys.encKey); + return UtilsService.removeFromStorage(Keys.encKey); } clearPrivateKey(memoryOnly?: boolean): Promise { @@ -217,7 +203,7 @@ export default class CryptoService { if (memoryOnly) { return Promise.resolve(); } - return this.utilsService.removeFromStorage(Keys.encPrivateKey); + return UtilsService.removeFromStorage(Keys.encPrivateKey); } clearOrgKeys(memoryOnly?: boolean): Promise { @@ -225,7 +211,7 @@ export default class CryptoService { if (memoryOnly) { return Promise.resolve(); } - return this.utilsService.removeFromStorage(Keys.encOrgKeys); + return UtilsService.removeFromStorage(Keys.encOrgKeys); } clearKeys(): Promise { @@ -240,7 +226,7 @@ export default class CryptoService { async toggleKey(): Promise { const key = await this.getKey(); - const option = await this.utilsService.getObjFromStorage(ConstantsService.lockOptionKey); + const option = await UtilsService.getObjFromStorage(ConstantsService.lockOptionKey); if (option != null || option === 0) { // if we have a lock option set, clear the key await this.clearKey(); @@ -282,15 +268,15 @@ export default class CryptoService { let plainValueArr: Uint8Array; if (plainValueEncoding === 'utf8') { - plainValueArr = this.fromUtf8ToArray(plainValue as string); + plainValueArr = UtilsService.fromUtf8ToArray(plainValue as string); } else { plainValueArr = plainValue as Uint8Array; } const encValue = await this.aesEncrypt(plainValueArr.buffer, key); - const iv = this.fromBufferToB64(encValue.iv.buffer); - const ct = this.fromBufferToB64(encValue.ct.buffer); - const mac = encValue.mac ? this.fromBufferToB64(encValue.mac.buffer) : null; + const iv = UtilsService.fromBufferToB64(encValue.iv.buffer); + const ct = UtilsService.fromBufferToB64(encValue.ct.buffer); + const mac = encValue.mac ? UtilsService.fromBufferToB64(encValue.mac.buffer) : null; return new CipherString(encValue.key.encType, iv, ct, mac); } @@ -444,7 +430,7 @@ export default class CryptoService { const ctArr = UtilsService.fromB64ToArray(encPieces[0]); const decBytes = await Subtle.decrypt(padding, privateKey, ctArr.buffer); - const b64DecValue = this.fromBufferToB64(decBytes); + const b64DecValue = UtilsService.fromBufferToB64(decBytes); return b64DecValue; } @@ -600,28 +586,4 @@ export default class CryptoService { return key; } - - private fromBufferToB64(buffer: ArrayBuffer): string { - let binary = ''; - const bytes = new Uint8Array(buffer); - for (let i = 0; i < bytes.byteLength; i++) { - binary += String.fromCharCode(bytes[i]); - } - return window.btoa(binary); - } - - private fromBufferToUtf8(buffer: ArrayBuffer): string { - const bytes = new Uint8Array(buffer); - const encodedString = String.fromCharCode.apply(null, bytes); - return decodeURIComponent(escape(encodedString)); - } - - private fromUtf8ToArray(str: string): Uint8Array { - const strUtf8 = unescape(encodeURIComponent(str)); - const arr = new Uint8Array(strUtf8.length); - for (let i = 0; i < strUtf8.length; i++) { - arr[i] = strUtf8.charCodeAt(i); - } - return arr; - } } diff --git a/src/services/utils.service.ts b/src/services/utils.service.ts index 9f4c42c5e9..f165d04dd5 100644 --- a/src/services/utils.service.ts +++ b/src/services/utils.service.ts @@ -17,6 +17,58 @@ export default class UtilsService { return bytes; } + static fromBufferToB64(buffer: ArrayBuffer): string { + let binary = ''; + const bytes = new Uint8Array(buffer); + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return window.btoa(binary); + } + + static fromBufferToUtf8(buffer: ArrayBuffer): string { + const bytes = new Uint8Array(buffer); + const encodedString = String.fromCharCode.apply(null, bytes); + return decodeURIComponent(escape(encodedString)); + } + + static fromUtf8ToArray(str: string): Uint8Array { + const strUtf8 = unescape(encodeURIComponent(str)); + const arr = new Uint8Array(strUtf8.length); + for (let i = 0; i < strUtf8.length; i++) { + arr[i] = strUtf8.charCodeAt(i); + } + return arr; + } + + 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(key: string): Promise { + return new Promise((resolve) => { + chrome.storage.local.get(key, (obj: any) => { + if (obj && obj[key]) { + resolve(obj[key] as T); + } else { + resolve(null); + } + }); + }); + } + private browserCache: BrowserType = null; private analyticsIdCache: string = null; @@ -231,6 +283,8 @@ export default class UtilsService { theWindow.location.search.indexOf('uilocation=popup') > -1; } + // remove these in favor of static + saveObjToStorage(key: string, obj: any) { return new Promise((resolve) => { chrome.storage.local.set({ [key]: obj }, () => { @@ -247,11 +301,11 @@ export default class UtilsService { }); } - getObjFromStorage(key: string): Promise { + getObjFromStorage(key: string) { return new Promise((resolve) => { chrome.storage.local.get(key, (obj: any) => { if (obj && obj[key]) { - resolve(obj[key] as T); + resolve(obj[key]); } else { resolve(null); }