fill in the blanks

This commit is contained in:
Bruno Windels 2020-09-23 17:59:42 +02:00
parent 9d41e122a0
commit d53b5eefb3
4 changed files with 41 additions and 9 deletions

View file

@ -222,9 +222,26 @@ export class RoomEncryption {
return eventIds; return eventIds;
} }
/**
* caches mapping of session to event id of all encrypted candidates
* and filters to return only the candidates for the given room key
*/
findAndCacheEntriesForRoomKey(roomKey, candidateEntries) { findAndCacheEntriesForRoomKey(roomKey, candidateEntries) {
// add all to _missingSessionCandidates const matches = [];
// filter messages to roomKey
for (const entry of candidateEntries) {
if (entry.eventType === ENCRYPTED_TYPE) {
this._missingSessionCandidates.addEvent(entry.event);
const senderKey = entry.event?.content?.["sender_key"];
const sessionId = entry.event?.content?.["session_id"];
if (senderKey === roomKey.senderKey && sessionId === roomKey.sessionId) {
matches.push(entry);
}
}
}
return matches;
} }
async encrypt(type, content, hsApi) { async encrypt(type, content, hsApi) {

View file

@ -15,9 +15,10 @@ limitations under the License.
*/ */
import {EventEmitter} from "../../utils/EventEmitter.js"; import {EventEmitter} from "../../utils/EventEmitter.js";
import {RoomSummary, needsHeroes} from "./RoomSummary.js"; import {RoomSummary} from "./RoomSummary.js";
import {SyncWriter} from "./timeline/persistence/SyncWriter.js"; import {SyncWriter} from "./timeline/persistence/SyncWriter.js";
import {GapWriter} from "./timeline/persistence/GapWriter.js"; import {GapWriter} from "./timeline/persistence/GapWriter.js";
import {readRawTimelineEntriesWithTxn} from "./timeline/persistence/TimelineReader.js";
import {Timeline} from "./timeline/Timeline.js"; import {Timeline} from "./timeline/Timeline.js";
import {FragmentIdComparer} from "./timeline/FragmentIdComparer.js"; import {FragmentIdComparer} from "./timeline/FragmentIdComparer.js";
import {SendQueue} from "./sending/SendQueue.js"; import {SendQueue} from "./sending/SendQueue.js";
@ -26,6 +27,8 @@ import {fetchOrLoadMembers} from "./members/load.js";
import {MemberList} from "./members/MemberList.js"; import {MemberList} from "./members/MemberList.js";
import {Heroes} from "./members/Heroes.js"; import {Heroes} from "./members/Heroes.js";
import {EventEntry} from "./timeline/entries/EventEntry.js"; import {EventEntry} from "./timeline/entries/EventEntry.js";
import {EventKey} from "./timeline/EventKey.js";
import {Direction} from "./timeline/Direction.js";
import {DecryptionSource} from "../e2ee/common.js"; import {DecryptionSource} from "../e2ee/common.js";
const EVENT_ENCRYPTED_TYPE = "m.room.encrypted"; const EVENT_ENCRYPTED_TYPE = "m.room.encrypted";
@ -54,10 +57,13 @@ export class Room extends EventEmitter {
_readRetryDecryptCandidateEntries(sinceEventKey, txn) { _readRetryDecryptCandidateEntries(sinceEventKey, txn) {
if (sinceEventKey) { if (sinceEventKey) {
return readFromWithTxn(sinceEventKey, Direction.Forward, Number.MAX_SAFE_INTEGER, txn); return readRawTimelineEntriesWithTxn(sinceEventKey, Direction.Forward, Number.MAX_SAFE_INTEGER, txn);
} else { } else {
// all messages for room // all messages for room ...
return readFromWithTxn(this._syncWriter.lastMessageKey, Direction.Backward, Number.MAX_SAFE_INTEGER, txn); // if you haven't decrypted any message in a room yet,
// it's unlikely you will have tons of them.
// so this should be fine as a last resort
return readRawTimelineEntriesWithTxn(this._syncWriter.lastMessageKey, Direction.Backward, Number.MAX_SAFE_INTEGER, txn);
} }
} }

View file

@ -131,6 +131,12 @@ function processTimelineEvent(data, eventEntry, isInitialSync, isTimelineOpen, o
try { try {
hasLargerEventKey = eventEntry.compare(data.lastDecryptedEventKey) > 0; hasLargerEventKey = eventEntry.compare(data.lastDecryptedEventKey) > 0;
} catch (err) { } catch (err) {
// TODO: load the fragments in between here?
// this could happen if an earlier event gets decrypted that
// is in a fragment different from the live one and the timeline is not open.
// In this case, we will just read too many events once per app load
// and then keep the mapping in memory. When eventually an event is decrypted in
// the live fragment, this should stop failing and the event key will be written.
hasLargerEventKey = false; hasLargerEventKey = false;
} }
} }

View file

@ -37,8 +37,11 @@ class ReaderRequest {
} }
} }
/**
export async function readFromWithTxn(eventKey, direction, amount, r, txn) { * Raw because it doesn't do decryption and in the future it should not read relations either.
* It is just about reading entries and following fragment links
*/
export async function readRawTimelineEntriesWithTxn(eventKey, direction, amount, r, txn) {
let entries = []; let entries = [];
const timelineStore = txn.timelineEvents; const timelineStore = txn.timelineEvents;
const fragmentStore = txn.timelineFragments; const fragmentStore = txn.timelineFragments;
@ -130,7 +133,7 @@ export class TimelineReader {
} }
async _readFrom(eventKey, direction, amount, r, txn) { async _readFrom(eventKey, direction, amount, r, txn) {
const entries = readFromWithTxn(eventKey, direction, amount, r, txn); const entries = readRawTimelineEntriesWithTxn(eventKey, direction, amount, r, txn);
if (this._decryptEntries) { if (this._decryptEntries) {
r.decryptRequest = this._decryptEntries(entries, txn); r.decryptRequest = this._decryptEntries(entries, txn);
try { try {