From 9218e518f1748d58fd7a4d9705f41bf7ccb6333c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 22 Nov 2017 16:41:52 +0000 Subject: [PATCH] Add LocalStorageCryptoStore To avoid throwing away all the data for anyone running firefox in one of the modes where indexedDB is broken. --- src/crypto/store/indexeddb-crypto-store.js | 8 ++- src/crypto/store/localStorage-crypto-store.js | 59 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/crypto/store/localStorage-crypto-store.js diff --git a/src/crypto/store/indexeddb-crypto-store.js b/src/crypto/store/indexeddb-crypto-store.js index b950e3a5b..ff07dd42d 100644 --- a/src/crypto/store/indexeddb-crypto-store.js +++ b/src/crypto/store/indexeddb-crypto-store.js @@ -16,6 +16,7 @@ limitations under the License. import Promise from 'bluebird'; +import LocalStorageCryptoStore from './localStorage-crypto-store'; import MemoryCryptoStore from './memory-crypto-store'; import * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend'; @@ -93,7 +94,12 @@ export default class IndexedDBCryptoStore { }).catch((e) => { console.warn( `unable to connect to indexeddb ${this._dbName}` + - `: falling back to in-memory store: ${e}`, + `: falling back to localStorage store: ${e}`, + ); + return new LocalStorageCryptoStore(); + }).catch((e) => { + console.warn( + `unable to open localStorage: falling back to in-memory store: ${e}`, ); return new MemoryCryptoStore(); }); diff --git a/src/crypto/store/localStorage-crypto-store.js b/src/crypto/store/localStorage-crypto-store.js new file mode 100644 index 000000000..94e7b9c72 --- /dev/null +++ b/src/crypto/store/localStorage-crypto-store.js @@ -0,0 +1,59 @@ +/* +Copyright 2017 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import Promise from 'bluebird'; +import MemoryCryptoStore from './memory-crypto-store.js'; + +/** + * Internal module. Partial localStorage backed storage for e2e. + * This is not a full crypto store, just the in-memory store with + * some things backed by localStorage. It exists because indexedDB + * is broken in Firefox private mode or set to, "will not remember + * history". + * + * + * @module + */ + +const E2E_PREFIX = "crypto."; +const KEY_END_TO_END_ACCOUNT = E2E_PREFIX + "account"; + +/** + * @implements {module:crypto/store/base~CryptoStore} + */ +export default class LocalStorageCryptoStore extends MemoryCryptoStore { + constructor() { + super(); + this.store = global.localStorage; + } + + /** + * Delete all data from this store. + * + * @returns {Promise} Promise which resolves when the store has been cleared. + */ + deleteAllData() { + this.store.removeItem(KEY_END_TO_END_ACCOUNT); + return Promise.resolve(); + } + + endToEndAccountTransaction(func) { + const account = this.store.getItem(KEY_END_TO_END_ACCOUNT); + return Promise.resolve(func(account, (newData) => { + this.store.setItem(KEY_END_TO_END_ACCOUNT, newData); + })); + } +}