forked from mystiq/hydrogen-web
reattempt decryption for timeline items
This commit is contained in:
parent
061e7abd50
commit
8d080163b3
3 changed files with 53 additions and 5 deletions
|
@ -400,6 +400,18 @@ export class RoomEncryption {
|
|||
await hsApi.sendToDevice(type, payload, txnId, {log}).response();
|
||||
}
|
||||
|
||||
filterEventEntriesForKeys(entries, keys) {
|
||||
return entries.filter(entry => {
|
||||
const {event} = entry;
|
||||
if (event) {
|
||||
const senderKey = event.content?.["sender_key"];
|
||||
const sessionId = event.content?.["session_id"];
|
||||
return keys.some(key => senderKey === key.senderKey && sessionId === key.sessionId);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
this._megolmBackfillCache.dispose();
|
||||
|
|
|
@ -189,10 +189,22 @@ export class Room extends EventEmitter {
|
|||
roomEncryption = this._createRoomEncryption(this, summaryChanges.encryption);
|
||||
}
|
||||
|
||||
let retryEntries;
|
||||
let decryptPreparation;
|
||||
if (roomEncryption) {
|
||||
// also look for events in timeline here
|
||||
let events = roomResponse?.timeline?.events || [];
|
||||
// when new keys arrive, also see if any events currently loaded in the timeline
|
||||
// can now be retried to decrypt
|
||||
if (this._timeline && newKeys) {
|
||||
retryEntries = roomEncryption.filterEventEntriesForKeys(
|
||||
this._timeline.remoteEntries, newKeys);
|
||||
if (retryEntries.length) {
|
||||
log.set("retry", retryEntries.length);
|
||||
events = events.concat(retryEntries.map(entry => entry.event));
|
||||
}
|
||||
}
|
||||
|
||||
if (events.length) {
|
||||
const eventsToDecrypt = events.filter(event => {
|
||||
return event?.type === EVENT_ENCRYPTED_TYPE;
|
||||
|
@ -207,6 +219,7 @@ export class Room extends EventEmitter {
|
|||
summaryChanges,
|
||||
decryptPreparation,
|
||||
decryptChanges: null,
|
||||
retryEntries
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -221,13 +234,24 @@ export class Room extends EventEmitter {
|
|||
}
|
||||
|
||||
/** @package */
|
||||
async writeSync(roomResponse, isInitialSync, {summaryChanges, decryptChanges, roomEncryption}, txn, log) {
|
||||
async writeSync(roomResponse, isInitialSync, {summaryChanges, decryptChanges, roomEncryption, retryEntries}, txn, log) {
|
||||
log.set("id", this.id);
|
||||
const {entries, newLiveKey, memberChanges} =
|
||||
await log.wrap("syncWriter", log => this._syncWriter.writeSync(roomResponse, txn, log), log.level.Detail);
|
||||
if (decryptChanges) {
|
||||
const decryption = await decryptChanges.write(txn);
|
||||
decryption.applyToEntries(entries);
|
||||
// now prepend updated copies of retryEntries
|
||||
// so the originals don't get modified by the decryption
|
||||
// (not needed for entries as they were just created by syncWriter)
|
||||
if (retryEntries?.length) {
|
||||
// TODO: this will modify existing timeline entries (which we should not do in writeSync),
|
||||
// but it is a temporary way of reattempting decryption while timeline is open
|
||||
// won't need copies when tracking missing sessions properly
|
||||
const updatedEntries = decryption.applyToEntries(retryEntries);
|
||||
// prepend the retried entries, as we know they are older (not that it should matter much for the summary)
|
||||
entries.unshift(...updatedEntries);
|
||||
}
|
||||
}
|
||||
// pass member changes to device tracker
|
||||
if (roomEncryption && this.isTrackingMembers && memberChanges?.size) {
|
||||
|
@ -255,7 +279,7 @@ export class Room extends EventEmitter {
|
|||
return {
|
||||
summaryChanges,
|
||||
roomEncryption,
|
||||
newTimelineEntries: entries,
|
||||
newAndUpdatedEntries: entries,
|
||||
newLiveKey,
|
||||
removedPendingEvents,
|
||||
memberChanges,
|
||||
|
@ -268,7 +292,7 @@ export class Room extends EventEmitter {
|
|||
* Called with the changes returned from `writeSync` to apply them and emit changes.
|
||||
* No storage or network operations should be done here.
|
||||
*/
|
||||
afterSync({summaryChanges, newTimelineEntries, newLiveKey, removedPendingEvents, memberChanges, heroChanges, roomEncryption}, log) {
|
||||
afterSync({summaryChanges, newAndUpdatedEntries, newLiveKey, removedPendingEvents, memberChanges, heroChanges, roomEncryption}, log) {
|
||||
log.set("id", this.id);
|
||||
this._syncWriter.afterSync(newLiveKey);
|
||||
this._setEncryption(roomEncryption);
|
||||
|
@ -301,10 +325,10 @@ export class Room extends EventEmitter {
|
|||
this._emitUpdate();
|
||||
}
|
||||
if (this._timeline) {
|
||||
this._timeline.appendLiveEntries(newTimelineEntries);
|
||||
this._timeline.appendLiveEntries(newAndUpdatedEntries);
|
||||
}
|
||||
if (this._observedEvents) {
|
||||
this._observedEvents.updateEvents(newTimelineEntries);
|
||||
this._observedEvents.updateEvents(newAndUpdatedEntries);
|
||||
}
|
||||
if (removedPendingEvents) {
|
||||
this._sendQueue.emitRemovals(removedPendingEvents);
|
||||
|
@ -522,6 +546,10 @@ export class Room extends EventEmitter {
|
|||
return !!this._summary.data.encryption;
|
||||
}
|
||||
|
||||
get membership() {
|
||||
return this._summary.data.membership;
|
||||
}
|
||||
|
||||
enableSessionBackup(sessionBackup) {
|
||||
this._roomEncryption?.enableSessionBackup(sessionBackup);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,14 @@ export class Timeline {
|
|||
return this._allEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return {Array<EventEntry>} remote event entries, should not be modified
|
||||
*/
|
||||
get remoteEntries() {
|
||||
return this._remoteEntries.array;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
dispose() {
|
||||
if (this._closeCallback) {
|
||||
|
|
Loading…
Reference in a new issue