send room keys to newly joined members in afterSyncCompleted stage
This commit is contained in:
parent
c158e3da77
commit
31d4b6f75d
5 changed files with 53 additions and 1 deletions
|
@ -125,6 +125,7 @@ export class Session {
|
|||
olmEncryption: this._olmEncryption,
|
||||
megolmEncryption: this._megolmEncryption,
|
||||
megolmDecryption: this._megolmDecryption,
|
||||
storage: this._storage,
|
||||
encryptionParams
|
||||
});
|
||||
}
|
||||
|
|
|
@ -128,6 +128,22 @@ export class RoomEncryption {
|
|||
};
|
||||
}
|
||||
|
||||
needsToShareKeys(memberChanges) {
|
||||
for (const m of memberChanges.values()) {
|
||||
if (m.member.needsRoomKey) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async shareRoomKeyToPendingMembers(hsApi) {
|
||||
// sucks to call this for all encrypted rooms on startup?
|
||||
const txn = await this._storage.readTxn([this._storage.storeNames.roomMembers]);
|
||||
const pendingUserIds = await txn.roomMembers.getUserIdsNeedingRoomKey(this._room.id);
|
||||
return await this._shareRoomKey(pendingUserIds, hsApi);
|
||||
}
|
||||
|
||||
async shareRoomKeyForMemberChanges(memberChanges, hsApi) {
|
||||
const pendingUserIds = [];
|
||||
for (const m of memberChanges.values()) {
|
||||
|
|
|
@ -157,7 +157,8 @@ export class Room extends EventEmitter {
|
|||
newLiveKey,
|
||||
removedPendingEvents,
|
||||
memberChanges,
|
||||
heroChanges
|
||||
heroChanges,
|
||||
needsAfterSyncCompleted: this._roomEncryption?.needsToShareKeys(memberChanges)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -204,6 +205,17 @@ export class Room extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called if the result of writeSync had `needsAfterSyncCompleted` set.
|
||||
* Can be used to do longer running operations that resulted from the last sync,
|
||||
* like network operations.
|
||||
*/
|
||||
async afterSyncCompleted({memberChanges}) {
|
||||
if (this._roomEncryption) {
|
||||
await this._roomEncryption.shareRoomKeyForMemberChanges(memberChanges, this._hsApi);
|
||||
}
|
||||
}
|
||||
|
||||
/** @package */
|
||||
resumeSending() {
|
||||
this._sendQueue.resumeSending();
|
||||
|
|
|
@ -187,6 +187,14 @@ export class QueryTarget {
|
|||
return results;
|
||||
}
|
||||
|
||||
async iterateWhile(range, predicate) {
|
||||
const cursor = this._openCursor(range, "next");
|
||||
await iterateCursor(cursor, (value) => {
|
||||
const passesPredicate = predicate(value);
|
||||
return {done: !passesPredicate};
|
||||
});
|
||||
}
|
||||
|
||||
async _find(range, predicate, direction) {
|
||||
const cursor = this._openCursor(range, direction);
|
||||
let result;
|
||||
|
|
|
@ -60,4 +60,19 @@ export class RoomMemberStore {
|
|||
});
|
||||
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