1
1
/*
2
- Copyright 2023 The Matrix.org Foundation C.I.C.
2
+ Copyright 2023-2024 The Matrix.org Foundation C.I.C.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -22,10 +22,14 @@ import { IndexedDBCryptoStore } from "../crypto/store/indexeddb-crypto-store";
22
22
import { decryptAES , IEncryptedPayload } from "../crypto/aes" ;
23
23
import { IHttpOpts , MatrixHttpApi } from "../http-api" ;
24
24
import { requestKeyBackupVersion } from "./backup" ;
25
+ import { IRoomEncryption } from "../crypto/RoomList" ;
25
26
26
27
/**
27
28
* Determine if any data needs migrating from the legacy store, and do so.
28
29
*
30
+ * This migrates the base account data, and olm and megolm sessions. It does *not* migrate the room list, which should
31
+ * happen after an `OlmMachine` is created, via {@link migrateRoomSettingsFromLegacyCrypto}.
32
+ *
29
33
* @param args - Arguments object.
30
34
*/
31
35
export async function migrateFromLegacyCrypto ( args : {
@@ -76,8 +80,8 @@ export async function migrateFromLegacyCrypto(args: {
76
80
await legacyStore . startup ( ) ;
77
81
let migrationState = await legacyStore . getMigrationState ( ) ;
78
82
79
- if ( migrationState == = MigrationState . MEGOLM_SESSIONS_MIGRATED ) {
80
- // All migration is done.
83
+ if ( migrationState > = MigrationState . MEGOLM_SESSIONS_MIGRATED ) {
84
+ // All migration is done for now. The room list comes later, once we have an OlmMachine .
81
85
return ;
82
86
}
83
87
@@ -255,6 +259,72 @@ async function migrateMegolmSessions(
255
259
}
256
260
}
257
261
262
+ /**
263
+ * Determine if any room settings need migrating from the legacy store, and do so.
264
+ *
265
+ * @param args - Arguments object.
266
+ */
267
+ export async function migrateRoomSettingsFromLegacyCrypto ( {
268
+ logger,
269
+ legacyStore,
270
+ olmMachine,
271
+ } : {
272
+ /** A `Logger` instance that will be used for debug output. */
273
+ logger : Logger ;
274
+
275
+ /** Store to migrate data from. */
276
+ legacyStore : CryptoStore ;
277
+
278
+ /** OlmMachine to store the new data on. */
279
+ olmMachine : RustSdkCryptoJs . OlmMachine ;
280
+ } ) : Promise < void > {
281
+ if ( ! ( await legacyStore . containsData ( ) ) ) {
282
+ // This store was never used. Nothing to migrate.
283
+ return ;
284
+ }
285
+
286
+ const migrationState = await legacyStore . getMigrationState ( ) ;
287
+
288
+ if ( migrationState >= MigrationState . ROOM_SETTINGS_MIGRATED ) {
289
+ // We've already migrated the room settings.
290
+ return ;
291
+ }
292
+
293
+ let rooms : Record < string , IRoomEncryption > = { } ;
294
+
295
+ await legacyStore . doTxn ( "readwrite" , [ IndexedDBCryptoStore . STORE_ROOMS ] , ( txn ) => {
296
+ legacyStore . getEndToEndRooms ( txn , ( result ) => {
297
+ rooms = result ;
298
+ } ) ;
299
+ } ) ;
300
+
301
+ logger . debug ( `Migrating ${ Object . keys ( rooms ) . length } sets of room settings` ) ;
302
+ for ( const [ roomId , legacySettings ] of Object . entries ( rooms ) ) {
303
+ try {
304
+ const rustSettings = new RustSdkCryptoJs . RoomSettings ( ) ;
305
+
306
+ if ( legacySettings . algorithm !== "m.megolm.v1.aes-sha2" ) {
307
+ logger . warn ( `Room ${ roomId } : ignoring room with invalid algorithm ${ legacySettings . algorithm } ` ) ;
308
+ continue ;
309
+ }
310
+ rustSettings . algorithm = RustSdkCryptoJs . EncryptionAlgorithm . MegolmV1AesSha2 ;
311
+ rustSettings . sessionRotationPeriodMs = legacySettings . rotation_period_ms ;
312
+ rustSettings . sessionRotationPeriodMessages = legacySettings . rotation_period_msgs ;
313
+ await olmMachine . setRoomSettings ( new RustSdkCryptoJs . RoomId ( roomId ) , rustSettings ) ;
314
+
315
+ // We don't attempt to clear out the settings from the old store, or record where we've gotten up to,
316
+ // which means that if the app gets restarted while we're in the middle of this migration, we'll start
317
+ // again from scratch. So be it. Given that legacy crypto loads the whole room list into memory on startup
318
+ // anyway, we know it can't be that big.
319
+ } catch ( e ) {
320
+ logger . warn ( `Room ${ roomId } : ignoring settings ${ JSON . stringify ( legacySettings ) } which caused error ${ e } ` ) ;
321
+ }
322
+ }
323
+
324
+ logger . debug ( `Completed room settings migration` ) ;
325
+ await legacyStore . setMigrationState ( MigrationState . ROOM_SETTINGS_MIGRATED ) ;
326
+ }
327
+
258
328
async function getAndDecryptCachedSecretKey (
259
329
legacyStore : CryptoStore ,
260
330
legacyPickleKey : Uint8Array ,
0 commit comments