forked from mystiq/hydrogen-web
also retry decryption for backfilled entries
as their event ids won't be stored along the missing key (we only store synced items so we don't fill up the missing event ids in the store with undecryptable backfilled event ids)
This commit is contained in:
parent
86dfbbb0c9
commit
96f060c0a9
2 changed files with 21 additions and 10 deletions
|
@ -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.retryDecryption(roomKey, retryEventIds || []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (session?.algorithm) {
|
} else if (session?.algorithm) {
|
||||||
|
|
|
@ -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 retryDecryption(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
|
||||||
|
|
Loading…
Reference in a new issue