Skip to content

Commit 3d82d83

Browse files
committed
Refactor to instead create a new storage per device, rather than deleting old storage.
1 parent 959e603 commit 3d82d83

File tree

3 files changed

+32
-18
lines changed

3 files changed

+32
-18
lines changed

src/e2ee/CryptoClient.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import {
77
Attachment,
88
EncryptedAttachment,
99
} from "@matrix-org/matrix-sdk-crypto-nodejs";
10-
import { rm } from "fs/promises";
11-
import * as path from 'path';
1210

1311
import { MatrixClient } from "../MatrixClient";
1412
import { LogService } from "../logging/LogService";
@@ -80,17 +78,7 @@ export class CryptoClient {
8078
throw new Error("Encryption not possible: server not revealing device ID");
8179
}
8280

83-
if (storedDeviceId && storedDeviceId !== deviceId) {
84-
LogService.warn("CryptoClient", `Device ID for ${userId} has changed from ${storedDeviceId} to ${deviceId}`);
85-
// Clear storage for old device.
86-
try {
87-
await rm(path.join(this.storage.storagePath, "matrix-sdk-crypto.sqlite3"));
88-
} catch (ex) {
89-
if (ex.code !== 'ENOENT') {
90-
throw ex;
91-
}
92-
}
93-
}
81+
const storagePath = await this.storage.getMachineStoragePath(deviceId);
9482

9583
if (storedDeviceId !== deviceId) {
9684
this.client.cryptoStore.setDeviceId(deviceId);
@@ -102,7 +90,7 @@ export class CryptoClient {
10290
const machine = await OlmMachine.initialize(
10391
new UserId(userId),
10492
new DeviceId(this.deviceId),
105-
this.storage.storagePath, "",
93+
storagePath, "",
10694
this.storage.storageType,
10795
);
10896
this.engine = new RustEngine(machine, this.client);

src/storage/IAppserviceStorageProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ export interface IAppserviceStorageProvider {
4747
export interface IAppserviceCryptoStorageProvider {
4848
/**
4949
* Gets a storage provider to use for the given user ID.
50-
* @param {string} userId The user ID.
51-
* @returns {ICryptoStorageProvider} The storage provider.
50+
* @param userId The user ID.
51+
* @returns The storage provider.
5252
*/
5353
storageForUser(userId: string): ICryptoStorageProvider;
5454
}

src/storage/RustSdkCryptoStorageProvider.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import * as lowdb from "lowdb";
22
import * as FileSync from "lowdb/adapters/FileSync";
33
import * as mkdirp from "mkdirp";
44
import * as path from "path";
5+
import { stat, rename, mkdir } from "fs/promises";
6+
import { PathLike } from "fs";
57
import * as sha512 from "hash.js/lib/hash/sha/512";
68
import * as sha256 from "hash.js/lib/hash/sha/256";
79
import { StoreType as RustSdkCryptoStoreType } from "@matrix-org/matrix-sdk-crypto-nodejs";
@@ -12,6 +14,10 @@ import { ICryptoRoomInformation } from "../e2ee/ICryptoRoomInformation";
1214

1315
export { RustSdkCryptoStoreType };
1416

17+
async function doesFileExist(path: PathLike) {
18+
return stat(path).then(() => true).catch(() => false);
19+
}
20+
1521
/**
1622
* A crypto storage provider for the file-based rust-sdk store.
1723
* @category Storage providers
@@ -40,6 +46,26 @@ export class RustSdkCryptoStorageProvider implements ICryptoStorageProvider {
4046
});
4147
}
4248

49+
public async getMachineStoragePath(deviceId: string): Promise<string> {
50+
const newPath = path.join(this.storagePath, sha256().update(deviceId).digest('hex'));
51+
if (await doesFileExist(newPath)) {
52+
// Already exists, short circuit.
53+
return newPath;
54+
} // else: If the path does NOT exist we might need to perform a migration.
55+
56+
const legacyFilePath = path.join(this.storagePath, 'matrix-sdk-crypto.sqlite3');
57+
// XXX: Slightly gross cross-dependency file name expectations.
58+
if (await doesFileExist(legacyFilePath) === false) {
59+
// No machine files at all, we can skip.
60+
return newPath;
61+
}
62+
63+
// We need to move the file.
64+
await mkdir(newPath);
65+
await rename(legacyFilePath, path.join(newPath, 'matrix-sdk-crypto.sqlite3'));
66+
return newPath;
67+
}
68+
4369
public async getDeviceId(): Promise<string> {
4470
return this.db.get('deviceId').value();
4571
}
@@ -75,7 +101,7 @@ export class RustSdkAppserviceCryptoStorageProvider extends RustSdkCryptoStorage
75101

76102
public storageForUser(userId: string): ICryptoStorageProvider {
77103
// 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);
104+
const storagePath = path.join(this.baseStoragePath, sha256().update(userId).digest('hex'));
105+
return new RustSdkCryptoStorageProvider(storagePath, this.storageType);
80106
}
81107
}

0 commit comments

Comments
 (0)