remove isTimelineOpen flag and rather do the check to verify in Room

flags are ugly, let's avoid them where we can
This commit is contained in:
Bruno Windels 2021-03-01 23:14:14 +01:00
parent e191880379
commit 3fa2d22015
2 changed files with 26 additions and 18 deletions

View file

@ -93,7 +93,7 @@ export class RoomEncryption {
// this happens before entries exists, as they are created by the syncwriter
// but we want to be able to map it back to something in the timeline easily
// when retrying decryption.
async prepareDecryptAll(events, newKeys, source, isTimelineOpen, txn) {
async prepareDecryptAll(events, newKeys, source, txn) {
const errors = new Map();
const validEvents = [];
for (const event of events) {
@ -126,7 +126,7 @@ export class RoomEncryption {
if (customCache) {
customCache.dispose();
}
return new DecryptionPreparation(preparation, errors, {isTimelineOpen, source}, this, events);
return new DecryptionPreparation(preparation, errors, source, this, events);
}
async _processDecryptionResults(events, results, errors, flags, txn) {
@ -139,11 +139,6 @@ export class RoomEncryption {
this._missingSessionCandidates.removeEvent(event);
}
}
if (flags.isTimelineOpen) {
for (const result of results.values()) {
await this._verifyDecryptionResult(result, txn);
}
}
}
async _verifyDecryptionResult(result, txn) {
@ -424,10 +419,10 @@ export class RoomEncryption {
* the decryption results before turning them
*/
class DecryptionPreparation {
constructor(megolmDecryptionPreparation, extraErrors, flags, roomEncryption, events) {
constructor(megolmDecryptionPreparation, extraErrors, source, roomEncryption, events) {
this._megolmDecryptionPreparation = megolmDecryptionPreparation;
this._extraErrors = extraErrors;
this._flags = flags;
this._source = source;
this._roomEncryption = roomEncryption;
this._events = events;
}
@ -436,7 +431,7 @@ class DecryptionPreparation {
return new DecryptionChanges(
await this._megolmDecryptionPreparation.decrypt(),
this._extraErrors,
this._flags,
this._source,
this._roomEncryption,
this._events);
}
@ -447,10 +442,10 @@ class DecryptionPreparation {
}
class DecryptionChanges {
constructor(megolmDecryptionChanges, extraErrors, flags, roomEncryption, events) {
constructor(megolmDecryptionChanges, extraErrors, source, roomEncryption, events) {
this._megolmDecryptionChanges = megolmDecryptionChanges;
this._extraErrors = extraErrors;
this._flags = flags;
this._source = source;
this._roomEncryption = roomEncryption;
this._events = events;
}
@ -458,15 +453,16 @@ class DecryptionChanges {
async write(txn) {
const {results, errors} = await this._megolmDecryptionChanges.write(txn);
mergeMap(this._extraErrors, errors);
await this._roomEncryption._processDecryptionResults(this._events, results, errors, this._flags, txn);
return new BatchDecryptionResult(results, errors);
await this._roomEncryption._processDecryptionResults(this._events, results, errors, this._source, txn);
return new BatchDecryptionResult(results, errors, this._roomEncryption);
}
}
class BatchDecryptionResult {
constructor(results, errors) {
constructor(results, errors, roomEncryption) {
this.results = results;
this.errors = errors;
this._roomEncryption = roomEncryption;
}
applyToEntries(entries) {
@ -482,6 +478,12 @@ class BatchDecryptionResult {
}
}
}
verifySenders(txn) {
return Promise.all(Array.from(this.results.values()).map(result => {
return this._roomEncryption._verifyDecryptionResult(result, txn);
}));
}
}
class SessionToEventIdsMap {

View file

@ -147,13 +147,13 @@ export class Room extends EventEmitter {
const events = entries.filter(entry => {
return entry.eventType === EVENT_ENCRYPTED_TYPE;
}).map(entry => entry.event);
const isTimelineOpen = this._isTimelineOpen;
r.preparation = await this._roomEncryption.prepareDecryptAll(events, null, source, isTimelineOpen, inboundSessionTxn);
r.preparation = await this._roomEncryption.prepareDecryptAll(events, null, source, inboundSessionTxn);
if (r.cancelled) return;
const changes = await r.preparation.decrypt();
r.preparation = null;
if (r.cancelled) return;
const stores = [this._storage.storeNames.groupSessionDecryptions];
const isTimelineOpen = this._isTimelineOpen;
if (isTimelineOpen) {
// read to fetch devices if timeline is open
stores.push(this._storage.storeNames.deviceIdentities);
@ -162,6 +162,9 @@ export class Room extends EventEmitter {
let decryption;
try {
decryption = await changes.write(writeTxn);
if (isTimelineOpen) {
await decryption.verifySenders(writeTxn);
}
} catch (err) {
writeTxn.abort();
throw err;
@ -210,7 +213,7 @@ export class Room extends EventEmitter {
return event?.type === EVENT_ENCRYPTED_TYPE;
});
decryptPreparation = await roomEncryption.prepareDecryptAll(
eventsToDecrypt, newKeys, DecryptionSource.Sync, this._isTimelineOpen, txn);
eventsToDecrypt, newKeys, DecryptionSource.Sync, txn);
}
}
@ -240,6 +243,9 @@ export class Room extends EventEmitter {
await log.wrap("syncWriter", log => this._syncWriter.writeSync(roomResponse, txn, log), log.level.Detail);
if (decryptChanges) {
const decryption = await decryptChanges.write(txn);
if (this._isTimelineOpen) {
await decryption.verifySenders(txn);
}
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