From c70f48f0da46184852efd89dce6100783be78235 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 23 Oct 2023 17:45:50 +0100 Subject: [PATCH] Element-R: reduce log spam when checking server key backup Fixes a lot of spam in the logs about "uncaught in promise: No room_keys found". --- src/rust-crypto/backup.ts | 2 +- src/rust-crypto/rust-crypto.ts | 92 +++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/rust-crypto/backup.ts b/src/rust-crypto/backup.ts index 784e5b59995..87bc89ad8a9 100644 --- a/src/rust-crypto/backup.ts +++ b/src/rust-crypto/backup.ts @@ -460,7 +460,7 @@ export class RustBackupDecryptor implements BackupDecryptor { for (const [sessionId, sessionData] of Object.entries(ciphertexts)) { try { const decrypted = JSON.parse( - await this.decryptionKey.decryptV1( + this.decryptionKey.decryptV1( sessionData.session_data.ephemeral, sessionData.session_data.mac, sessionData.session_data.ciphertext, diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 378d79b579f..6c61f637a42 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -161,43 +161,73 @@ export class RustCrypto extends TypedEventEmitter { - const backupKeys: RustSdkCryptoJs.BackupKeys = await this.olmMachine.getBackupKeys(); - if (!backupKeys.decryptionKey) return; - const version = backupKeys.backupVersion; - + public startQueryKeyBackupRateLimited(targetRoomId: string, targetSessionId: string): void { const now = new Date().getTime(); - if ( - !this.sessionLastCheckAttemptedTime[targetSessionId!] || - now - this.sessionLastCheckAttemptedTime[targetSessionId!] > KEY_BACKUP_CHECK_RATE_LIMIT - ) { + const lastCheck = this.sessionLastCheckAttemptedTime[targetSessionId]; + if (!lastCheck || now - lastCheck > KEY_BACKUP_CHECK_RATE_LIMIT) { this.sessionLastCheckAttemptedTime[targetSessionId!] = now; - - const path = encodeUri("/room_keys/keys/$roomId/$sessionId", { - $roomId: targetRoomId, - $sessionId: targetSessionId, + this.queryKeyBackup(targetRoomId, targetSessionId).catch((e) => { + this.logger.error(`Unhandled error while checking key backup for session ${targetSessionId}`, e); }); + } else { + this.logger.debug( + `Not checking key backup for session ${targetSessionId} (last checked at ${new Date( + lastCheck, + ).toISOString()})`, + ); + } + } + + /** + * Helper for {@link RustCrypto#startQueryKeyBackupRateLimited}. + * + * Requests the backup and imports it. Doesn't do any rate-limiting. + * + * @param targetRoomId - ID of the room that the session is used in. + * @param targetSessionId - ID of the session for which to check backup. + */ + private async queryKeyBackup(targetRoomId: string, targetSessionId: string): Promise { + const backupKeys: RustSdkCryptoJs.BackupKeys = await this.olmMachine.getBackupKeys(); + if (!backupKeys.decryptionKey) { + this.logger.debug(`Not checking key backup for session ${targetSessionId} (no decryption key)`); + return; + } + + this.logger.debug(`Checking key backup for session ${targetSessionId}`); + + const version = backupKeys.backupVersion; + const path = encodeUri("/room_keys/keys/$roomId/$sessionId", { + $roomId: targetRoomId, + $sessionId: targetSessionId, + }); - const res = await this.http.authedRequest(Method.Get, path, { version }, undefined, { + let res: KeyBackupSession; + try { + res = await this.http.authedRequest(Method.Get, path, { version }, undefined, { prefix: ClientPrefix.V3, }); + } catch (e) { + this.logger.info(`No luck requesting key backup for session ${targetSessionId}: ${e}`); + return; + } - if (this.stopped) return; + if (this.stopped) return; - const backupDecryptor = new RustBackupDecryptor(backupKeys.decryptionKey); - if (res) { - const sessionsToImport: Record = {}; - sessionsToImport[targetSessionId] = res; - const keys = await backupDecryptor.decryptSessions(sessionsToImport); - for (const k of keys) { - k.room_id = targetRoomId!; - } - await this.importRoomKeys(keys); - } + const backupDecryptor = new RustBackupDecryptor(backupKeys.decryptionKey); + const sessionsToImport: Record = { [targetSessionId]: res }; + const keys = await backupDecryptor.decryptSessions(sessionsToImport); + for (const k of keys) { + k.room_id = targetRoomId; } + await this.importRoomKeys(keys); } /** @@ -1619,7 +1649,10 @@ class EventDecryptor { session: content.sender_key + "|" + content.session_id, }, ); - this.crypto.queryKeyBackupRateLimited(event.getRoomId()!, event.getWireContent().session_id!); + this.crypto.startQueryKeyBackupRateLimited( + event.getRoomId()!, + event.getWireContent().session_id!, + ); break; } case RustSdkCryptoJs.DecryptionErrorCode.UnknownMessageIndex: { @@ -1630,7 +1663,10 @@ class EventDecryptor { session: content.sender_key + "|" + content.session_id, }, ); - this.crypto.queryKeyBackupRateLimited(event.getRoomId()!, event.getWireContent().session_id!); + this.crypto.startQueryKeyBackupRateLimited( + event.getRoomId()!, + event.getWireContent().session_id!, + ); break; } // We don't map MismatchedIdentityKeys for now, as there is no equivalent in legacy.