remove needsRoomKey flag on member

This commit is contained in:
Bruno Windels 2020-09-11 14:38:36 +02:00
parent bba53b3477
commit 9f6822f362
4 changed files with 22 additions and 61 deletions

View file

@ -158,7 +158,7 @@ export class Room extends EventEmitter {
decryption = await decryptChanges.write(txn); decryption = await decryptChanges.write(txn);
} }
const {entries, newLiveKey, memberChanges} = const {entries, newLiveKey, memberChanges} =
await this._syncWriter.writeSync(roomResponse, this.isTrackingMembers, txn); await this._syncWriter.writeSync(roomResponse, txn);
if (decryption) { if (decryption) {
decryption.applyToEntries(entries); decryption.applyToEntries(entries);
} }

View file

@ -67,14 +67,6 @@ export class RoomMember {
}); });
} }
get needsRoomKey() {
return this._data.needsRoomKey;
}
set needsRoomKey(value) {
this._data.needsRoomKey = !!value;
}
get membership() { get membership() {
return this._data.membership; return this._data.membership;
} }

View file

@ -98,48 +98,40 @@ export class SyncWriter {
return {oldFragment, newFragment}; return {oldFragment, newFragment};
} }
async _writeMember(event, trackNewlyJoined, txn) { _writeMember(event, txn) {
const userId = event.state_key; const userId = event.state_key;
if (userId) { if (userId) {
const memberChange = new MemberChange(this._roomId, event); const memberChange = new MemberChange(this._roomId, event);
const {member} = memberChange; const {member} = memberChange;
if (member) { if (member) {
if (trackNewlyJoined) {
const existingMemberData = await txn.roomMembers.get(this._roomId, userId);
// mark new members so we know who needs our the room key for our outbound megolm session
member.needsRoomKey = existingMemberData?.needsRoomKey || memberChange.hasJoined;
}
txn.roomMembers.set(member.serialize()); txn.roomMembers.set(member.serialize());
return memberChange; return memberChange;
} }
} }
} }
async _writeStateEvent(event, trackNewlyJoined, txn) { _writeStateEvent(event, txn) {
if (event.type === MEMBER_EVENT_TYPE) { if (event.type === MEMBER_EVENT_TYPE) {
return await this._writeMember(event, trackNewlyJoined, txn); return this._writeMember(event, txn);
} else { } else {
txn.roomState.set(this._roomId, event); txn.roomState.set(this._roomId, event);
} }
} }
async _writeStateEvents(roomResponse, trackNewlyJoined, txn) { _writeStateEvents(roomResponse, memberChanges, txn) {
const memberChanges = new Map();
// persist state // persist state
const {state} = roomResponse; const {state} = roomResponse;
if (Array.isArray(state?.events)) { if (Array.isArray(state?.events)) {
await Promise.all(state.events.map(async event => { for (const event of state.events) {
const memberChange = await this._writeStateEvent(event, trackNewlyJoined, txn); const memberChange = this._writeStateEvent(event, txn);
if (memberChange) { if (memberChange) {
memberChanges.set(memberChange.userId, memberChange); memberChanges.set(memberChange.userId, memberChange);
} }
})); }
} }
return memberChanges;
} }
async _writeTimeline(entries, timeline, currentKey, trackNewlyJoined, txn) { async _writeTimeline(entries, timeline, currentKey, memberChanges, txn) {
const memberChanges = new Map();
if (Array.isArray(timeline.events)) { if (Array.isArray(timeline.events)) {
const events = deduplicateEvents(timeline.events); const events = deduplicateEvents(timeline.events);
for(const event of events) { for(const event of events) {
@ -153,19 +145,17 @@ export class SyncWriter {
} }
txn.timelineEvents.insert(entry); txn.timelineEvents.insert(entry);
entries.push(new EventEntry(entry, this._fragmentIdComparer)); entries.push(new EventEntry(entry, this._fragmentIdComparer));
}
// process live state events first, so new member info is available // process live state events first, so new member info is available
// also run async state event writing in parallel if (typeof event.state_key === "string") {
await Promise.all(events.filter(event => { const memberChange = this._writeStateEvent(event, txn);
return typeof event.state_key === "string"; if (memberChange) {
}).map(async stateEvent => { memberChanges.set(memberChange.userId, memberChange);
const memberChange = await this._writeStateEvent(stateEvent, trackNewlyJoined, txn); }
if (memberChange) {
memberChanges.set(memberChange.userId, memberChange);
} }
})); }
} }
return {currentKey, memberChanges}; return currentKey;
} }
async _findMemberData(userId, events, txn) { async _findMemberData(userId, events, txn) {
@ -193,11 +183,10 @@ export class SyncWriter {
* @property {Map<string, MemberChange>} memberChanges member changes in the processed sync ny user id * @property {Map<string, MemberChange>} memberChanges member changes in the processed sync ny user id
* *
* @param {Object} roomResponse [description] * @param {Object} roomResponse [description]
* @param {Boolean} trackNewlyJoined needed to know if we need to keep track whether a user needs keys when they join an encrypted room
* @param {Transaction} txn * @param {Transaction} txn
* @return {SyncWriterResult} * @return {SyncWriterResult}
*/ */
async writeSync(roomResponse, trackNewlyJoined, txn) { async writeSync(roomResponse, txn) {
const entries = []; const entries = [];
const {timeline} = roomResponse; const {timeline} = roomResponse;
let currentKey = this._lastLiveKey; let currentKey = this._lastLiveKey;
@ -217,16 +206,11 @@ export class SyncWriter {
entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer)); entries.push(FragmentBoundaryEntry.end(oldFragment, this._fragmentIdComparer));
entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer)); entries.push(FragmentBoundaryEntry.start(newFragment, this._fragmentIdComparer));
} }
const memberChanges = new Map();
// important this happens before _writeTimeline so // important this happens before _writeTimeline so
// members are available in the transaction // members are available in the transaction
const memberChanges = await this._writeStateEvents(roomResponse, trackNewlyJoined, txn); this._writeStateEvents(roomResponse, memberChanges, txn);
// TODO: remove trackNewlyJoined and pass in memberChanges currentKey = await this._writeTimeline(entries, timeline, currentKey, memberChanges, txn);
const timelineResult = await this._writeTimeline(entries, timeline, currentKey, trackNewlyJoined, txn);
currentKey = timelineResult.currentKey;
// merge member changes from state and timeline, giving precedence to the latter
for (const [userId, memberChange] of timelineResult.memberChanges.entries()) {
memberChanges.set(userId, memberChange);
}
return {entries, newLiveKey: currentKey, memberChanges}; return {entries, newLiveKey: currentKey, memberChanges};
} }

View file

@ -60,19 +60,4 @@ export class RoomMemberStore {
}); });
return userIds; return userIds;
} }
async getUserIdsNeedingRoomKey(roomId) {
const userIds = [];
const range = IDBKeyRange.lowerBound(encodeKey(roomId, ""));
await this._roomMembersStore.iterateWhile(range, member => {
if (member.roomId !== roomId) {
return false;
}
if (member.needsRoomKey) {
userIds.push(member.userId);
}
return true;
});
return userIds;
}
} }