remove needsRoomKey flag on member
This commit is contained in:
parent
bba53b3477
commit
9f6822f362
4 changed files with 22 additions and 61 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
|
||||||
}).map(async stateEvent => {
|
|
||||||
const memberChange = await this._writeStateEvent(stateEvent, trackNewlyJoined, txn);
|
|
||||||
if (memberChange) {
|
if (memberChange) {
|
||||||
memberChanges.set(memberChange.userId, 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};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue