You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
Signal key backup in cache (#3928)
* Signal key backup in cache * code review * quick doc * code review
This commit is contained in:
@@ -1259,14 +1259,11 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
|
||||
|
||||
const requestId = await requestPromises.get("m.megolm_backup.v1");
|
||||
|
||||
const keyBackupIsCached = emitPromise(aliceClient, CryptoEvent.KeyBackupDecryptionKeyCached);
|
||||
|
||||
await sendBackupGossipAndExpectVersion(requestId!, BACKUP_DECRYPTION_KEY_BASE64, matchingBackupInfo);
|
||||
|
||||
// We are lacking a way to signal that the secret has been received, so we wait a bit..
|
||||
jest.useRealTimers();
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 500);
|
||||
});
|
||||
jest.useFakeTimers();
|
||||
await keyBackupIsCached;
|
||||
|
||||
// the backup secret should be cached
|
||||
const cachedKey = await aliceClient.getCrypto()!.getSessionBackupPrivateKey();
|
||||
|
||||
@@ -951,6 +951,7 @@ type CryptoEvents =
|
||||
| CryptoEvent.KeyBackupStatus
|
||||
| CryptoEvent.KeyBackupFailed
|
||||
| CryptoEvent.KeyBackupSessionsRemaining
|
||||
| CryptoEvent.KeyBackupDecryptionKeyCached
|
||||
| CryptoEvent.RoomKeyRequest
|
||||
| CryptoEvent.RoomKeyRequestCancellation
|
||||
| CryptoEvent.VerificationRequest
|
||||
@@ -2359,6 +2360,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
CryptoEvent.KeyBackupStatus,
|
||||
CryptoEvent.KeyBackupSessionsRemaining,
|
||||
CryptoEvent.KeyBackupFailed,
|
||||
CryptoEvent.KeyBackupDecryptionKeyCached,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,6 +232,18 @@ export enum CryptoEvent {
|
||||
KeyBackupStatus = "crypto.keyBackupStatus",
|
||||
KeyBackupFailed = "crypto.keyBackupFailed",
|
||||
KeyBackupSessionsRemaining = "crypto.keyBackupSessionsRemaining",
|
||||
|
||||
/**
|
||||
* Fires when a new valid backup decryption key is in cache.
|
||||
* This will happen when a secret is received from another session, from secret storage,
|
||||
* or when a new backup is created from this session.
|
||||
*
|
||||
* The payload is the version of the backup for which we have the key for.
|
||||
*
|
||||
* This event is only fired by the rust crypto backend.
|
||||
*/
|
||||
KeyBackupDecryptionKeyCached = "crypto.keyBackupDecryptionKeyCached",
|
||||
|
||||
KeySignatureUploadFailure = "crypto.keySignatureUploadFailure",
|
||||
/** @deprecated Use `VerificationRequestReceived`. */
|
||||
VerificationRequest = "crypto.verification.request",
|
||||
@@ -297,6 +309,13 @@ export type CryptoEventHandlerMap = {
|
||||
[CryptoEvent.KeyBackupStatus]: (enabled: boolean) => void;
|
||||
[CryptoEvent.KeyBackupFailed]: (errcode: string) => void;
|
||||
[CryptoEvent.KeyBackupSessionsRemaining]: (remaining: number) => void;
|
||||
|
||||
/**
|
||||
* Fires when the backup decryption key is received and cached.
|
||||
*
|
||||
* @param version - The version of the backup for which we have the key for.
|
||||
*/
|
||||
[CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void;
|
||||
[CryptoEvent.KeySignatureUploadFailure]: (
|
||||
failures: IUploadKeySignaturesResponse["failures"],
|
||||
source: "checkOwnCrossSigningTrust" | "afterCrossSigningLocalKeyChange" | "setDeviceVerification",
|
||||
|
||||
@@ -154,8 +154,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
|
||||
logger.info(
|
||||
`handleBackupSecretReceived: A valid backup decryption key has been received and stored in cache.`,
|
||||
);
|
||||
|
||||
await this.olmMachine.saveBackupDecryptionKey(backupDecryptionKey, backupCheck.backupInfo.version);
|
||||
await this.saveBackupDecryptionKey(backupDecryptionKey, backupCheck.backupInfo.version);
|
||||
return true;
|
||||
} catch (e) {
|
||||
logger.warn("handleBackupSecretReceived: Invalid backup decryption key", e);
|
||||
@@ -164,6 +163,16 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
|
||||
return false;
|
||||
}
|
||||
|
||||
public async saveBackupDecryptionKey(
|
||||
backupDecryptionKey: RustSdkCryptoJs.BackupDecryptionKey,
|
||||
version: string,
|
||||
): Promise<void> {
|
||||
await this.olmMachine.saveBackupDecryptionKey(backupDecryptionKey, version);
|
||||
// Emit an event that we have a new backup decryption key, so that the sdk can start
|
||||
// importing keys from backup if needed.
|
||||
this.emit(CryptoEvent.KeyBackupDecryptionKeyCached, version);
|
||||
}
|
||||
|
||||
private keyBackupCheckInProgress: Promise<KeyBackupCheck | null> | null = null;
|
||||
|
||||
/** Helper for `checkKeyBackup` */
|
||||
@@ -393,7 +402,7 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
|
||||
},
|
||||
);
|
||||
|
||||
this.olmMachine.saveBackupDecryptionKey(randomKey, res.version);
|
||||
await this.saveBackupDecryptionKey(randomKey, res.version);
|
||||
|
||||
return {
|
||||
version: res.version,
|
||||
@@ -503,10 +512,12 @@ export class RustBackupDecryptor implements BackupDecryptor {
|
||||
export type RustBackupCryptoEvents =
|
||||
| CryptoEvent.KeyBackupStatus
|
||||
| CryptoEvent.KeyBackupSessionsRemaining
|
||||
| CryptoEvent.KeyBackupFailed;
|
||||
| CryptoEvent.KeyBackupFailed
|
||||
| CryptoEvent.KeyBackupDecryptionKeyCached;
|
||||
|
||||
export type RustBackupCryptoEventMap = {
|
||||
[CryptoEvent.KeyBackupStatus]: (enabled: boolean) => void;
|
||||
[CryptoEvent.KeyBackupSessionsRemaining]: (remaining: number) => void;
|
||||
[CryptoEvent.KeyBackupFailed]: (errCode: string) => void;
|
||||
[CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void;
|
||||
};
|
||||
|
||||
@@ -150,6 +150,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
||||
CryptoEvent.KeyBackupStatus,
|
||||
CryptoEvent.KeyBackupSessionsRemaining,
|
||||
CryptoEvent.KeyBackupFailed,
|
||||
CryptoEvent.KeyBackupDecryptionKeyCached,
|
||||
]);
|
||||
|
||||
this.crossSigningIdentity = new CrossSigningIdentity(olmMachine, this.outgoingRequestProcessor, secretStorage);
|
||||
@@ -1148,7 +1149,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
||||
throw new Error("storeSessionBackupPrivateKey: version is required");
|
||||
}
|
||||
|
||||
await this.olmMachine.saveBackupDecryptionKey(
|
||||
await this.backupManager.saveBackupDecryptionKey(
|
||||
RustSdkCryptoJs.BackupDecryptionKey.fromBase64(base64Key),
|
||||
version,
|
||||
);
|
||||
@@ -1867,4 +1868,6 @@ type RustCryptoEventMap = {
|
||||
* Fires when the trust status of a user changes.
|
||||
*/
|
||||
[CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserVerificationStatus) => void;
|
||||
|
||||
[CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void;
|
||||
} & RustBackupCryptoEventMap;
|
||||
|
||||
Reference in New Issue
Block a user