@@ -22,26 +22,20 @@ import { Features } from "../settings/Settings";
2222
2323const localStorage = window . localStorage ;
2424
25- // just *accessing* indexedDB throws an exception in firefox with
26- // indexeddb disabled.
27- let indexedDB : IDBFactory ;
28- try {
29- indexedDB = window . indexedDB ;
30- } catch ( e ) { }
25+ // make this lazy in order to make testing easier
26+ function getIndexedDb ( ) : IDBFactory | undefined {
27+ // just *accessing* _indexedDB throws an exception in firefox with
28+ // indexeddb disabled.
29+ try {
30+ return window . indexedDB ;
31+ } catch ( e ) { }
32+ }
3133
3234// The JS SDK will add a prefix of "matrix-js-sdk:" to the sync store name.
3335const SYNC_STORE_NAME = "riot-web-sync" ;
3436const LEGACY_CRYPTO_STORE_NAME = "matrix-js-sdk:crypto" ;
3537const RUST_CRYPTO_STORE_NAME = "matrix-js-sdk::matrix-sdk-crypto" ;
3638
37- function cryptoStoreName ( ) : string {
38- if ( SettingsStore . getValue ( Features . RustCrypto ) ) {
39- return RUST_CRYPTO_STORE_NAME ;
40- } else {
41- return LEGACY_CRYPTO_STORE_NAME ;
42- }
43- }
44-
4539function log ( msg : string ) : void {
4640 logger . log ( `StorageManager: ${ msg } ` ) ;
4741}
@@ -74,7 +68,7 @@ export async function checkConsistency(): Promise<{
7468} > {
7569 log ( "Checking storage consistency" ) ;
7670 log ( `Local storage supported? ${ ! ! localStorage } ` ) ;
77- log ( `IndexedDB supported? ${ ! ! indexedDB } ` ) ;
71+ log ( `IndexedDB supported? ${ ! ! getIndexedDb ( ) } ` ) ;
7872
7973 let dataInLocalStorage = false ;
8074 let dataInCryptoStore = false ;
@@ -92,7 +86,7 @@ export async function checkConsistency(): Promise<{
9286 error ( "Local storage cannot be used on this browser" ) ;
9387 }
9488
95- if ( indexedDB && localStorage ) {
89+ if ( getIndexedDb ( ) && localStorage ) {
9690 const results = await checkSyncStore ( ) ;
9791 if ( ! results . healthy ) {
9892 healthy = false ;
@@ -102,7 +96,7 @@ export async function checkConsistency(): Promise<{
10296 error ( "Sync store cannot be used on this browser" ) ;
10397 }
10498
105- if ( indexedDB ) {
99+ if ( getIndexedDb ( ) ) {
106100 const results = await checkCryptoStore ( ) ;
107101 dataInCryptoStore = results . exists ;
108102 if ( ! results . healthy ) {
@@ -144,7 +138,7 @@ interface StoreCheck {
144138async function checkSyncStore ( ) : Promise < StoreCheck > {
145139 let exists = false ;
146140 try {
147- exists = await IndexedDBStore . exists ( indexedDB , SYNC_STORE_NAME ) ;
141+ exists = await IndexedDBStore . exists ( getIndexedDb ( ) ! , SYNC_STORE_NAME ) ;
148142 log ( `Sync store using IndexedDB contains data? ${ exists } ` ) ;
149143 return { exists, healthy : true } ;
150144 } catch ( e ) {
@@ -155,23 +149,56 @@ async function checkSyncStore(): Promise<StoreCheck> {
155149}
156150
157151async function checkCryptoStore ( ) : Promise < StoreCheck > {
158- let exists = false ;
159- try {
160- exists = await IndexedDBCryptoStore . exists ( indexedDB , cryptoStoreName ( ) ) ;
161- log ( `Crypto store using IndexedDB contains data? ${ exists } ` ) ;
162- return { exists, healthy : true } ;
163- } catch ( e ) {
164- error ( "Crypto store using IndexedDB inaccessible" , e ) ;
165- }
166- try {
167- exists = LocalStorageCryptoStore . exists ( localStorage ) ;
168- log ( `Crypto store using local storage contains data? ${ exists } ` ) ;
169- return { exists, healthy : true } ;
170- } catch ( e ) {
171- error ( "Crypto store using local storage inaccessible" , e ) ;
152+ if ( await SettingsStore . getValue ( Features . RustCrypto ) ) {
153+ // check first if there is a rust crypto store
154+ try {
155+ const rustDbExists = await IndexedDBCryptoStore . exists ( getIndexedDb ( ) ! , RUST_CRYPTO_STORE_NAME ) ;
156+ log ( `Rust Crypto store using IndexedDB contains data? ${ rustDbExists } ` ) ;
157+
158+ if ( rustDbExists ) {
159+ // There was an existing rust database, so consider it healthy.
160+ return { exists : true , healthy : true } ;
161+ } else {
162+ // No rust store, so let's check if there is a legacy store not yet migrated.
163+ try {
164+ const legacyIdbExists = await IndexedDBCryptoStore . existsAndIsNotMigrated (
165+ getIndexedDb ( ) ! ,
166+ LEGACY_CRYPTO_STORE_NAME ,
167+ ) ;
168+ log ( `Legacy Crypto store using IndexedDB contains non migrated data? ${ legacyIdbExists } ` ) ;
169+ return { exists : legacyIdbExists , healthy : true } ;
170+ } catch ( e ) {
171+ error ( "Legacy crypto store using IndexedDB inaccessible" , e ) ;
172+ }
173+
174+ // No need to check local storage or memory as rust stack doesn't support them.
175+ // Given that rust stack requires indexeddb, set healthy to false.
176+ return { exists : false , healthy : false } ;
177+ }
178+ } catch ( e ) {
179+ error ( "Rust crypto store using IndexedDB inaccessible" , e ) ;
180+ return { exists : false , healthy : false } ;
181+ }
182+ } else {
183+ let exists = false ;
184+ // legacy checks
185+ try {
186+ exists = await IndexedDBCryptoStore . exists ( getIndexedDb ( ) ! , LEGACY_CRYPTO_STORE_NAME ) ;
187+ log ( `Crypto store using IndexedDB contains data? ${ exists } ` ) ;
188+ return { exists, healthy : true } ;
189+ } catch ( e ) {
190+ error ( "Crypto store using IndexedDB inaccessible" , e ) ;
191+ }
192+ try {
193+ exists = LocalStorageCryptoStore . exists ( localStorage ) ;
194+ log ( `Crypto store using local storage contains data? ${ exists } ` ) ;
195+ return { exists, healthy : true } ;
196+ } catch ( e ) {
197+ error ( "Crypto store using local storage inaccessible" , e ) ;
198+ }
199+ log ( "Crypto store using memory only" ) ;
200+ return { exists, healthy : false } ;
172201 }
173- log ( "Crypto store using memory only" ) ;
174- return { exists, healthy : false } ;
175202}
176203
177204/**
@@ -194,11 +221,11 @@ export function setCryptoInitialised(cryptoInited: boolean): void {
194221let idb : IDBDatabase | null = null ;
195222
196223async function idbInit ( ) : Promise < void > {
197- if ( ! indexedDB ) {
224+ if ( ! getIndexedDb ( ) ) {
198225 throw new Error ( "IndexedDB not available" ) ;
199226 }
200227 idb = await new Promise ( ( resolve , reject ) => {
201- const request = indexedDB . open ( "matrix-react-sdk" , 1 ) ;
228+ const request = getIndexedDb ( ) ! . open ( "matrix-react-sdk" , 1 ) ;
202229 request . onerror = reject ;
203230 request . onsuccess = ( ) : void => {
204231 resolve ( request . result ) ;
0 commit comments