@@ -2,16 +2,23 @@ import * as lowdb from "lowdb";
22import * as FileSync from "lowdb/adapters/FileSync" ;
33import * as mkdirp from "mkdirp" ;
44import * as path from "path" ;
5+ import { stat , rename , mkdir } from "fs/promises" ;
6+ import { PathLike } from "fs" ;
57import * as sha512 from "hash.js/lib/hash/sha/512" ;
68import * as sha256 from "hash.js/lib/hash/sha/256" ;
79import { StoreType as RustSdkCryptoStoreType } from "@matrix-org/matrix-sdk-crypto-nodejs" ;
810
911import { ICryptoStorageProvider } from "./ICryptoStorageProvider" ;
1012import { IAppserviceCryptoStorageProvider } from "./IAppserviceStorageProvider" ;
1113import { ICryptoRoomInformation } from "../e2ee/ICryptoRoomInformation" ;
14+ import { LogService } from "../logging/LogService" ;
1215
1316export { RustSdkCryptoStoreType } ;
1417
18+ async function doesFileExist ( path : PathLike ) {
19+ return stat ( path ) . then ( ( ) => true ) . catch ( ( ) => false ) ;
20+ }
21+
1522/**
1623 * A crypto storage provider for the file-based rust-sdk store.
1724 * @category Storage providers
@@ -40,6 +47,37 @@ export class RustSdkCryptoStorageProvider implements ICryptoStorageProvider {
4047 } ) ;
4148 }
4249
50+ public async getMachineStoragePath ( deviceId : string ) : Promise < string > {
51+ const newPath = path . join ( this . storagePath , sha256 ( ) . update ( deviceId ) . digest ( 'hex' ) ) ;
52+ if ( await doesFileExist ( newPath ) ) {
53+ // Already exists, short circuit.
54+ return newPath ;
55+ } // else: If the path does NOT exist we might need to perform a migration.
56+
57+ const legacyFilePath = path . join ( this . storagePath , 'matrix-sdk-crypto.sqlite3' ) ;
58+ // XXX: Slightly gross cross-dependency file name expectations.
59+ if ( await doesFileExist ( legacyFilePath ) === false ) {
60+ // No machine files at all, we can skip.
61+ return newPath ;
62+ }
63+ const legacyDeviceId = await this . getDeviceId ( ) ;
64+ // We need to move the file.
65+ const previousDevicePath = path . join ( this . storagePath , sha256 ( ) . update ( legacyDeviceId ) . digest ( 'hex' ) ) ;
66+ LogService . warn ( "RustSdkCryptoStorageProvider" , `Migrating path for SDK database for legacy device ${ legacyDeviceId } ` ) ;
67+ await mkdir ( previousDevicePath ) ;
68+ await rename ( legacyFilePath , path . join ( previousDevicePath , 'matrix-sdk-crypto.sqlite3' ) ) . catch ( ( ex ) =>
69+ LogService . warn ( "RustSdkCryptoStorageProvider" , `Could not migrate matrix-sdk-crypto.sqlite3` , ex ) ,
70+ ) ;
71+ await rename ( legacyFilePath , path . join ( previousDevicePath , 'matrix-sdk-crypto.sqlite3-shm' ) ) . catch ( ( ex ) =>
72+ LogService . warn ( "RustSdkCryptoStorageProvider" , `Could not migrate matrix-sdk-crypto.sqlite3-shm` , ex ) ,
73+ ) ;
74+ await rename ( legacyFilePath , path . join ( previousDevicePath , 'matrix-sdk-crypto.sqlite3-wal' ) ) . catch ( ( ex ) =>
75+ LogService . warn ( "RustSdkCryptoStorageProvider" , `Could not migrate matrix-sdk-crypto.sqlite3-wal` , ex ) ,
76+ ) ;
77+
78+ return newPath ;
79+ }
80+
4381 public async getDeviceId ( ) : Promise < string > {
4482 return this . db . get ( 'deviceId' ) . value ( ) ;
4583 }
@@ -75,7 +113,7 @@ export class RustSdkAppserviceCryptoStorageProvider extends RustSdkCryptoStorage
75113
76114 public storageForUser ( userId : string ) : ICryptoStorageProvider {
77115 // sha256 because sha512 is a bit big for some operating systems
78- const key = sha256 ( ) . update ( userId ) . digest ( 'hex' ) ;
79- return new RustSdkCryptoStorageProvider ( path . join ( this . baseStoragePath , key ) , this . storageType ) ;
116+ const storagePath = path . join ( this . baseStoragePath , sha256 ( ) . update ( userId ) . digest ( 'hex' ) ) ;
117+ return new RustSdkCryptoStorageProvider ( storagePath , this . storageType ) ;
80118 }
81119}
0 commit comments