@@ -22,26 +22,20 @@ import { Features } from "../settings/Settings";
22
22
23
23
const localStorage = window . localStorage ;
24
24
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
+ }
31
33
32
34
// The JS SDK will add a prefix of "matrix-js-sdk:" to the sync store name.
33
35
const SYNC_STORE_NAME = "riot-web-sync" ;
34
36
const LEGACY_CRYPTO_STORE_NAME = "matrix-js-sdk:crypto" ;
35
37
const RUST_CRYPTO_STORE_NAME = "matrix-js-sdk::matrix-sdk-crypto" ;
36
38
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
-
45
39
function log ( msg : string ) : void {
46
40
logger . log ( `StorageManager: ${ msg } ` ) ;
47
41
}
@@ -74,7 +68,7 @@ export async function checkConsistency(): Promise<{
74
68
} > {
75
69
log ( "Checking storage consistency" ) ;
76
70
log ( `Local storage supported? ${ ! ! localStorage } ` ) ;
77
- log ( `IndexedDB supported? ${ ! ! indexedDB } ` ) ;
71
+ log ( `IndexedDB supported? ${ ! ! getIndexedDb ( ) } ` ) ;
78
72
79
73
let dataInLocalStorage = false ;
80
74
let dataInCryptoStore = false ;
@@ -92,7 +86,7 @@ export async function checkConsistency(): Promise<{
92
86
error ( "Local storage cannot be used on this browser" ) ;
93
87
}
94
88
95
- if ( indexedDB && localStorage ) {
89
+ if ( getIndexedDb ( ) && localStorage ) {
96
90
const results = await checkSyncStore ( ) ;
97
91
if ( ! results . healthy ) {
98
92
healthy = false ;
@@ -102,7 +96,7 @@ export async function checkConsistency(): Promise<{
102
96
error ( "Sync store cannot be used on this browser" ) ;
103
97
}
104
98
105
- if ( indexedDB ) {
99
+ if ( getIndexedDb ( ) ) {
106
100
const results = await checkCryptoStore ( ) ;
107
101
dataInCryptoStore = results . exists ;
108
102
if ( ! results . healthy ) {
@@ -144,7 +138,7 @@ interface StoreCheck {
144
138
async function checkSyncStore ( ) : Promise < StoreCheck > {
145
139
let exists = false ;
146
140
try {
147
- exists = await IndexedDBStore . exists ( indexedDB , SYNC_STORE_NAME ) ;
141
+ exists = await IndexedDBStore . exists ( getIndexedDb ( ) ! , SYNC_STORE_NAME ) ;
148
142
log ( `Sync store using IndexedDB contains data? ${ exists } ` ) ;
149
143
return { exists, healthy : true } ;
150
144
} catch ( e ) {
@@ -155,23 +149,56 @@ async function checkSyncStore(): Promise<StoreCheck> {
155
149
}
156
150
157
151
async 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 } ;
172
201
}
173
- log ( "Crypto store using memory only" ) ;
174
- return { exists, healthy : false } ;
175
202
}
176
203
177
204
/**
@@ -194,11 +221,11 @@ export function setCryptoInitialised(cryptoInited: boolean): void {
194
221
let idb : IDBDatabase | null = null ;
195
222
196
223
async function idbInit ( ) : Promise < void > {
197
- if ( ! indexedDB ) {
224
+ if ( ! getIndexedDb ( ) ) {
198
225
throw new Error ( "IndexedDB not available" ) ;
199
226
}
200
227
idb = await new Promise ( ( resolve , reject ) => {
201
- const request = indexedDB . open ( "matrix-react-sdk" , 1 ) ;
228
+ const request = getIndexedDb ( ) ! . open ( "matrix-react-sdk" , 1 ) ;
202
229
request . onerror = reject ;
203
230
request . onsuccess = ( ) : void => {
204
231
resolve ( request . result ) ;
0 commit comments