UNPKG

cv-dialog-sdk

Version:

Catavolt Dialog Javascript API

284 lines (231 loc) 7.74 kB
import { Storage } from './Storage'; import { SecureStorage } from './SecureStorage'; import { cryptoUtil } from '../util/CryptoUtil'; export const setCvStorageApi = storageApi => { ClientStorage.setStorageApi(storageApi); }; class ClientStorage implements Storage { private static _storage:Storage; public static setStorageApi(storageApi) { if (storageApi) { if (storageApi.getAllKeys) { // Assume AsyncStorage ClientStorage._storage = new AsyncStorageAdapter(storageApi); } else { // Assume window.localStorage ClientStorage._storage = new LocalStorageAdapter(storageApi); } } } constructor() { // Attempt to set the default storage backend to localStorage if (!ClientStorage._storage) { if (typeof(localStorage) !== 'undefined') { if (localStorage && localStorage.getItem) { ClientStorage.setStorageApi(localStorage); } } } } public getSecureInstance(): SecureStorage { return new SecureStorageAdapter(this); } public getItem(key: string): Promise<string> { return ClientStorage._storage.getItem(key); } public getJson(key: string): Promise<any> { return ClientStorage._storage.getJson(key); } public setItem(key: string, value: string): Promise<void> { return ClientStorage._storage.setItem(key, value); } public setJson(key: string, value: any): Promise<void> { return ClientStorage._storage.setJson(key, value); } public removeItem(key: string): Promise<void> { return ClientStorage._storage.removeItem(key); } public clearAll(): Promise<void> { return ClientStorage._storage.clearAll(); } public getAllKeys(): Promise<string[]> { return ClientStorage._storage.getAllKeys(); } public multiRemove(keys: Array<string>): Promise<void> { return ClientStorage._storage.multiRemove(keys); } } class SecureStorageAdapter implements SecureStorage { private _secretKey:string = null; constructor(readonly storage:Storage){} public set secretKey(secretKey:string) { this._secretKey = secretKey; } public destroySecretKey() { delete(this._secretKey); } public getItem(key: string): Promise<string> { return this.storage.getItem(key).then( encValue => { if(!encValue) return null; return cryptoUtil.decrypt(encValue, this.getSecretKey()) } ); } public getJson(key: string): Promise<any> { return this.getItem(key).then(JSON.parse); } public setItem(key: string, value: string): Promise<void> { const encValue = value ? cryptoUtil.encrypt(value, this.getSecretKey()) : null; return this.storage.setItem(key, encValue); } public setJson(key: string, value: any): Promise<void> { let stringVal = null; try { stringVal = JSON.stringify(value); } catch (err) { return Promise.reject(new Error(`Storage::setItem(${key}) failed to stringify JSON value`)); } return this.setItem(key, stringVal); } public removeItem(key: string): Promise<void> { return this.storage.removeItem(key); } public clearAll(): Promise<void> { return this.storage.clearAll(); } public getAllKeys(): Promise<string[]> { return this.storage.getAllKeys(); } public multiRemove(keys: Array<string>): Promise<void> { return this.storage.multiRemove(keys); } private getSecretKey():string { if(this._secretKey) return this._secretKey; throw new Error(`Storage::getSecretKey No secret key set in SecureStorageAdapter`); } } class AsyncStorageAdapter implements Storage { constructor(readonly api:any){} public getItem(key: string) { return this.api.getItem(key); } public getJson(key: string) { return this.api.getItem(key).then(value => { try { return JSON.parse(value); } catch (err) { throw new Error(`Storage::getItem('${key}') parse JSON failed for: ${value}`); } }); } public setItem(key: string, value: string) { return this.api.setItem(key, value); } public setJson(key: string, value: any) { let stringVal = null; try { stringVal = JSON.stringify(value); } catch (err) { return Promise.reject(new Error(`Storage::setItem(${key}) failed to stringify JSON value`)); } return this.api.setItem(key, stringVal); } public removeItem(key: string) { return this.api.removeItem(key); } public clearAll() { return this.api.clear(); } public getAllKeys() { return this.api.getAllKeys(); } public multiRemove(keys: Array<string>) { return this.api.multiRemove(keys); } } class LocalStorageAdapter implements Storage { constructor(readonly api){} public getItem(key: string):Promise<string> { return new Promise((resolve, reject) => { try { const value:string = this.api.getItem(key); resolve(value); } catch (e) { reject(e); } }); } public getJson(key: string):Promise<any> { return new Promise((resolve, reject) => { try { resolve(JSON.parse(this.api.getItem(key))); } catch (err) { reject(Error(`Storage::getItem('${key}') parse JSON failed`)); } }); } public setItem(key: string, value: string):Promise<void> { return new Promise((resolve, reject) => { try { resolve(this.api.setItem(key, value)); } catch (e) { reject(e); } }); } public setJson(key: string, value: any):Promise<void> { return new Promise((resolve, reject) => { try { const stringVal = JSON.stringify(value); resolve(this.api.setItem(key, stringVal)); } catch (e) { reject(e); } }); } public removeItem(key: string):Promise<void> { return new Promise((resolve, reject) => { try { resolve(this.api.removeItem(key)); } catch (e) { reject(e); } }); } public clearAll():Promise<void> { return new Promise((resolve, reject) => { try { resolve(this.api.clear()); } catch (e) { reject(e); } }); } public getAllKeys():Promise<string[]> { return new Promise((resolve, reject) => { try { const keys:Array<string> = []; for(let i:number = 0; i < this.api.length; i++) { keys.push(this.api.key(i)); } resolve(keys); } catch (e) { reject(e); } }); } public multiRemove(keys: Array<string>):Promise<void> { return new Promise((resolve, reject) => { try { keys.forEach((key) => { this.api.removeItem(key); }); resolve(); } catch (e) { reject(e); } }); } } export const storage: ClientStorage = new ClientStorage();