Skip to content

Commit

Permalink
Get backup info from a specific version
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Nov 7, 2024
1 parent a70ee65 commit db068a4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
4 changes: 4 additions & 0 deletions spec/integ/crypto/megolm-backup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("megolm-keys backup (%s)", (backe

beforeEach(async () => {
fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA);
fetchMock.get(
`path:/_matrix/client/v3/room_keys/version/${testData.SIGNED_BACKUP_DATA.version}`,
testData.SIGNED_BACKUP_DATA,
);

aliceClient = await initTestClient();
aliceCrypto = aliceClient.getCrypto()!;
Expand Down
23 changes: 18 additions & 5 deletions src/rust-crypto/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,14 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
}

/**
* Get information about the current key backup from the server
*
* Get information about a key backup from the server
* - If version is provided, get information about that backup version.
* - If no version is provided, get information about the latest backup.
* @param version -
* @returns Information object from API or null if there is no active backup.
*/
private async requestKeyBackupVersion(): Promise<KeyBackupInfo | null> {
return await requestKeyBackupVersion(this.http);
public async requestKeyBackupVersion(version?: string): Promise<KeyBackupInfo | null> {
return await requestKeyBackupVersion(this.http, version);
}

/**
Expand Down Expand Up @@ -798,11 +800,22 @@ export class RustBackupDecryptor implements BackupDecryptor {
}
}

/**
* Fetch a key backup info from the server.
* - If `version` is provided call GET /room_keys/version/$version and get the backup info for that version.
* https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3room_keysversionversion
* - If not, call GET /room_keys/version and get the latest backup info.
* https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3room_keysversion
* @param http
* @param version - the specific version of the backup info to fetch
*/
export async function requestKeyBackupVersion(
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
version?: string,
): Promise<KeyBackupInfo | null> {
try {
return await http.authedRequest<KeyBackupInfo>(Method.Get, "/room_keys/version", undefined, undefined, {
const path = version ? encodeUri("/room_keys/version/$version", { $version: version }) : "/room_keys/version";
return await http.authedRequest<KeyBackupInfo>(Method.Get, path, undefined, undefined, {
prefix: ClientPrefix.V3,
});
} catch (e) {
Expand Down
16 changes: 15 additions & 1 deletion src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,15 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
return Buffer.from(backupKeys.decryptionKey.toBase64(), "base64");
}

/**
* Fetch the backup version we have saved in our store.
* @returns the backup version, if any, or null
*/
private async getSessionBackupVersion(): Promise<string | null> {
const backupKeys: RustSdkCryptoJs.BackupKeys = await this.olmMachine.getBackupKeys();
return backupKeys.backupVersion || null;
}

/**
* Store the backup decryption key.
*
Expand Down Expand Up @@ -1325,10 +1334,15 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
* Implementation of {@link CryptoApi#restoreKeyBackup}.
*/
public async restoreKeyBackup(opts?: KeyBackupRestoreOpts): Promise<KeyBackupRestoreResult> {
// Get the decryption key from the cache
const privateKeyFromCache = await this.getSessionBackupPrivateKey();
if (!privateKeyFromCache) throw new Error("No decryption key found in cache");

const backupInfo = await this.backupManager.getServerBackupInfo();
// Get the backup version from the cache
const backupVersion = await this.getSessionBackupVersion();
if (!backupVersion) throw new Error("No backup version found in cache");

const backupInfo = await this.backupManager.requestKeyBackupVersion(backupVersion);
if (!backupInfo?.version) throw new Error("Missing version in backup info");

const backupDecryptor = await this.getBackupDecryptor(backupInfo, privateKeyFromCache);
Expand Down

0 comments on commit db068a4

Please sign in to comment.