cv-dialog-sdk
Version:
Catavolt Dialog Javascript API
247 lines (246 loc) • 6.7 kB
JavaScript
import { cryptoUtil } from '../util/CryptoUtil';
export const setCvStorageApi = storageApi => {
ClientStorage.setStorageApi(storageApi);
};
class ClientStorage {
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);
}
}
}
}
getSecureInstance() {
return new SecureStorageAdapter(this);
}
getItem(key) {
return ClientStorage._storage.getItem(key);
}
getJson(key) {
return ClientStorage._storage.getJson(key);
}
setItem(key, value) {
return ClientStorage._storage.setItem(key, value);
}
setJson(key, value) {
return ClientStorage._storage.setJson(key, value);
}
removeItem(key) {
return ClientStorage._storage.removeItem(key);
}
clearAll() {
return ClientStorage._storage.clearAll();
}
getAllKeys() {
return ClientStorage._storage.getAllKeys();
}
multiRemove(keys) {
return ClientStorage._storage.multiRemove(keys);
}
}
class SecureStorageAdapter {
constructor(storage) {
this.storage = storage;
this._secretKey = null;
}
set secretKey(secretKey) {
this._secretKey = secretKey;
}
destroySecretKey() {
delete (this._secretKey);
}
getItem(key) {
return this.storage.getItem(key).then(encValue => {
if (!encValue)
return null;
return cryptoUtil.decrypt(encValue, this.getSecretKey());
});
}
getJson(key) {
return this.getItem(key).then(JSON.parse);
}
setItem(key, value) {
const encValue = value ? cryptoUtil.encrypt(value, this.getSecretKey()) : null;
return this.storage.setItem(key, encValue);
}
setJson(key, value) {
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);
}
removeItem(key) {
return this.storage.removeItem(key);
}
clearAll() {
return this.storage.clearAll();
}
getAllKeys() {
return this.storage.getAllKeys();
}
multiRemove(keys) {
return this.storage.multiRemove(keys);
}
getSecretKey() {
if (this._secretKey)
return this._secretKey;
throw new Error(`Storage::getSecretKey No secret key set in SecureStorageAdapter`);
}
}
class AsyncStorageAdapter {
constructor(api) {
this.api = api;
}
getItem(key) {
return this.api.getItem(key);
}
getJson(key) {
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}`);
}
});
}
setItem(key, value) {
return this.api.setItem(key, value);
}
setJson(key, value) {
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);
}
removeItem(key) {
return this.api.removeItem(key);
}
clearAll() {
return this.api.clear();
}
getAllKeys() {
return this.api.getAllKeys();
}
multiRemove(keys) {
return this.api.multiRemove(keys);
}
}
class LocalStorageAdapter {
constructor(api) {
this.api = api;
}
getItem(key) {
return new Promise((resolve, reject) => {
try {
const value = this.api.getItem(key);
resolve(value);
}
catch (e) {
reject(e);
}
});
}
getJson(key) {
return new Promise((resolve, reject) => {
try {
resolve(JSON.parse(this.api.getItem(key)));
}
catch (err) {
reject(Error(`Storage::getItem('${key}') parse JSON failed`));
}
});
}
setItem(key, value) {
return new Promise((resolve, reject) => {
try {
resolve(this.api.setItem(key, value));
}
catch (e) {
reject(e);
}
});
}
setJson(key, value) {
return new Promise((resolve, reject) => {
try {
const stringVal = JSON.stringify(value);
resolve(this.api.setItem(key, stringVal));
}
catch (e) {
reject(e);
}
});
}
removeItem(key) {
return new Promise((resolve, reject) => {
try {
resolve(this.api.removeItem(key));
}
catch (e) {
reject(e);
}
});
}
clearAll() {
return new Promise((resolve, reject) => {
try {
resolve(this.api.clear());
}
catch (e) {
reject(e);
}
});
}
getAllKeys() {
return new Promise((resolve, reject) => {
try {
const keys = [];
for (let i = 0; i < this.api.length; i++) {
keys.push(this.api.key(i));
}
resolve(keys);
}
catch (e) {
reject(e);
}
});
}
multiRemove(keys) {
return new Promise((resolve, reject) => {
try {
keys.forEach((key) => {
this.api.removeItem(key);
});
resolve();
}
catch (e) {
reject(e);
}
});
}
}
export const storage = new ClientStorage();