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

View File

@ -147,13 +147,13 @@ export class Room extends EventEmitter {
const events = entries.filter(entry => { const events = entries.filter(entry => {
return entry.eventType === EVENT_ENCRYPTED_TYPE; return entry.eventType === EVENT_ENCRYPTED_TYPE;
}).map(entry => entry.event); }).map(entry => entry.event);
const isTimelineOpen = this._isTimelineOpen; r.preparation = await this._roomEncryption.prepareDecryptAll(events, null, source, inboundSessionTxn);
r.preparation = await this._roomEncryption.prepareDecryptAll(events, null, source, isTimelineOpen, inboundSessionTxn);
if (r.cancelled) return; if (r.cancelled) return;
const changes = await r.preparation.decrypt(); const changes = await r.preparation.decrypt();
r.preparation = null; r.preparation = null;
if (r.cancelled) return; if (r.cancelled) return;
const stores = [this._storage.storeNames.groupSessionDecryptions]; const stores = [this._storage.storeNames.groupSessionDecryptions];
const isTimelineOpen = this._isTimelineOpen;
if (isTimelineOpen) { if (isTimelineOpen) {
// read to fetch devices if timeline is open // read to fetch devices if timeline is open
stores.push(this._storage.storeNames.deviceIdentities); stores.push(this._storage.storeNames.deviceIdentities);
@ -162,6 +162,9 @@ export class Room extends EventEmitter {
let decryption; let decryption;
try { try {
decryption = await changes.write(writeTxn); decryption = await changes.write(writeTxn);
if (isTimelineOpen) {
await decryption.verifySenders(writeTxn);
}
} catch (err) { } catch (err) {
writeTxn.abort(); writeTxn.abort();
throw err; throw err;
@ -210,7 +213,7 @@ export class Room extends EventEmitter {
return event?.type === EVENT_ENCRYPTED_TYPE; return event?.type === EVENT_ENCRYPTED_TYPE;
}); });
decryptPreparation = await roomEncryption.prepareDecryptAll( 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); await log.wrap("syncWriter", log => this._syncWriter.writeSync(roomResponse, txn, log), log.level.Detail);
if (decryptChanges) { if (decryptChanges) {
const decryption = await decryptChanges.write(txn); const decryption = await decryptChanges.write(txn);
if (this._isTimelineOpen) {
await decryption.verifySenders(txn);
}
if (retryEntries?.length) { if (retryEntries?.length) {
// TODO: this will modify existing timeline entries (which we should not do in writeSync), // 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 // but it is a temporary way of reattempting decryption while timeline is open