Merge pull request #277 from vector-im/bwindels/alsoretrydecryptionfortimeline

Also retry decryption for backfilled entries
This commit is contained in:
Bruno Windels 2021-03-15 13:37:05 +00:00 committed by GitHub
commit 7ba979eee6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 10 deletions

View file

@ -210,11 +210,12 @@ export class RoomEncryption {
} }
let roomKey = this._megolmDecryption.roomKeyFromBackup(this._room.id, sessionId, session); let roomKey = this._megolmDecryption.roomKeyFromBackup(this._room.id, sessionId, session);
if (roomKey) { if (roomKey) {
let keyIsBestOne = false;
let retryEventIds; let retryEventIds;
try { try {
const txn = await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]); const txn = await this._storage.readWriteTxn([this._storage.storeNames.inboundGroupSessions]);
try { try {
const keyIsBestOne = await this._megolmDecryption.writeRoomKey(roomKey, txn); keyIsBestOne = await this._megolmDecryption.writeRoomKey(roomKey, txn);
if (keyIsBestOne) { if (keyIsBestOne) {
retryEventIds = roomKey.eventIds; retryEventIds = roomKey.eventIds;
} }
@ -228,8 +229,8 @@ export class RoomEncryption {
// this is just clearing the internal sessionInfo // this is just clearing the internal sessionInfo
roomKey.dispose(); roomKey.dispose();
} }
if (retryEventIds?.length) { if (keyIsBestOne) {
await this._room.retryDecryption(retryEventIds); await this._room.notifyRoomKey(roomKey, retryEventIds || []);
} }
} }
} else if (session?.algorithm) { } else if (session?.algorithm) {

View file

@ -66,13 +66,22 @@ export class Room extends EventEmitter {
return retryEntries; return retryEntries;
} }
_getAdditionalTimelineRetryEntries(otherRetryEntries, roomKeys) {
let retryTimelineEntries = this._roomEncryption.filterUndecryptedEventEntriesForKeys(this._timeline.remoteEntries, roomKeys);
// filter out any entries already in retryEntries so we don't decrypt them twice
const existingIds = otherRetryEntries.reduce((ids, e) => {ids.add(e.id); return ids;}, new Set());
retryTimelineEntries = retryTimelineEntries.filter(e => !existingIds.has(e.id));
return retryTimelineEntries;
}
/** /**
* Used for retrying decryption from other sources than sync, like key backup. * Used for retrying decryption from other sources than sync, like key backup.
* @internal * @internal
* @param {Array<string>} eventIds * @param {RoomKey} roomKey
* @param {Array<string>} eventIds any event ids that should be retried. There might be more in the timeline though for this key.
* @return {Promise} * @return {Promise}
*/ */
async retryDecryption(eventIds) { async notifyRoomKey(roomKey, eventIds) {
if (!this._roomEncryption) { if (!this._roomEncryption) {
return; return;
} }
@ -80,7 +89,11 @@ export class Room extends EventEmitter {
this._storage.storeNames.timelineEvents, this._storage.storeNames.timelineEvents,
this._storage.storeNames.inboundGroupSessions, this._storage.storeNames.inboundGroupSessions,
]); ]);
const retryEntries = await this._eventIdsToEntries(eventIds, txn); let retryEntries = await this._eventIdsToEntries(eventIds, txn);
if (this._timeline) {
const retryTimelineEntries = this._getAdditionalTimelineRetryEntries(retryEntries, [roomKey]);
retryEntries = retryEntries.concat(retryTimelineEntries);
}
if (retryEntries.length) { if (retryEntries.length) {
const decryptRequest = this._decryptEntries(DecryptionSource.Retry, retryEntries, txn); const decryptRequest = this._decryptEntries(DecryptionSource.Retry, retryEntries, txn);
// this will close txn while awaiting decryption // this will close txn while awaiting decryption
@ -166,10 +179,7 @@ export class Room extends EventEmitter {
// We want to decrypt all events we can though if the user is looking // We want to decrypt all events we can though if the user is looking
// at them when the timeline is open // at them when the timeline is open
if (this._timeline) { if (this._timeline) {
let retryTimelineEntries = this._roomEncryption.filterUndecryptedEventEntriesForKeys(this._timeline.remoteEntries, newKeys); const retryTimelineEntries = this._getAdditionalTimelineRetryEntries(retryEntries, newKeys);
// filter out any entries already in retryEntries so we don't decrypt them twice
const existingIds = retryEntries.reduce((ids, e) => {ids.add(e.id); return ids;}, new Set());
retryTimelineEntries = retryTimelineEntries.filter(e => !existingIds.has(e.id));
// make copies so we don't modify the original entry in writeSync, before the afterSync stage // make copies so we don't modify the original entry in writeSync, before the afterSync stage
const retryTimelineEntriesCopies = retryTimelineEntries.map(e => e.clone()); const retryTimelineEntriesCopies = retryTimelineEntries.map(e => e.clone());
// add to other retry entries // add to other retry entries