take history visibility into account in device tracker
and return added and removed userids to their userIdentity for the given room, so room encryption can share and discard the keys for them
This commit is contained in:
parent
86c0e9e669
commit
f6011f3f34
1 changed files with 42 additions and 29 deletions
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {verifyEd25519Signature, SIGNATURE_ALGORITHM} from "./common.js";
|
import {verifyEd25519Signature, SIGNATURE_ALGORITHM} from "./common.js";
|
||||||
|
import {shouldShareKey} from "./common.js";
|
||||||
|
|
||||||
const TRACKING_STATUS_OUTDATED = 0;
|
const TRACKING_STATUS_OUTDATED = 0;
|
||||||
const TRACKING_STATUS_UPTODATE = 1;
|
const TRACKING_STATUS_UPTODATE = 1;
|
||||||
|
@ -79,13 +80,38 @@ export class DeviceTracker {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeMemberChanges(room, memberChanges, txn) {
|
/** @return Promise<{added: string[], removed: string[]}> the user ids for who the room was added or removed to the userIdentity,
|
||||||
return Promise.all(Array.from(memberChanges.values()).map(async memberChange => {
|
* and with who a key should be now be shared
|
||||||
return this._applyMemberChange(memberChange, txn);
|
**/
|
||||||
|
async writeMemberChanges(room, memberChanges, historyVisibility, txn) {
|
||||||
|
const added = [];
|
||||||
|
const removed = [];
|
||||||
|
await Promise.all(Array.from(memberChanges.values()).map(async memberChange => {
|
||||||
|
// keys should now be shared with this member?
|
||||||
|
// add the room to the userIdentity if so
|
||||||
|
if (shouldShareKey(memberChange.membership, historyVisibility)) {
|
||||||
|
if (await this._addRoomToUserIdentity(memberChange.roomId, memberChange.userId, txn)) {
|
||||||
|
added.push(memberChange.userId);
|
||||||
|
}
|
||||||
|
} else if (memberChange.hasLeft) {
|
||||||
|
// remove room
|
||||||
|
const {roomId} = memberChange;
|
||||||
|
// if we left the room, remove room from all user identities in the room
|
||||||
|
if (memberChange.userId === this._ownUserId) {
|
||||||
|
const userIds = await txn.roomMembers.getAllUserIds(roomId);
|
||||||
|
await Promise.all(userIds.map(userId => {
|
||||||
|
return this._removeRoomFromUserIdentity(roomId, userId, txn);
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
await this._removeRoomFromUserIdentity(roomId, memberChange.userId, txn);
|
||||||
|
}
|
||||||
|
removed.push(memberChange.userId);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
return {added, removed};
|
||||||
}
|
}
|
||||||
|
|
||||||
async trackRoom(room, log) {
|
async trackRoom(room, historyVisibility, log) {
|
||||||
if (room.isTrackingMembers || !room.isEncrypted) {
|
if (room.isTrackingMembers || !room.isEncrypted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +126,11 @@ export class DeviceTracker {
|
||||||
isTrackingChanges = room.writeIsTrackingMembers(true, txn);
|
isTrackingChanges = room.writeIsTrackingMembers(true, txn);
|
||||||
const members = Array.from(memberList.members.values());
|
const members = Array.from(memberList.members.values());
|
||||||
log.set("members", members.length);
|
log.set("members", members.length);
|
||||||
await this._writeJoinedMembers(members, txn);
|
await Promise.all(members.map(async member => {
|
||||||
|
if (shouldShareKey(member.membership, historyVisibility)) {
|
||||||
|
await this._addRoomToUserIdentity(member.roomId, member.userId, txn);
|
||||||
|
}
|
||||||
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
txn.abort();
|
txn.abort();
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -120,13 +150,15 @@ export class DeviceTracker {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _writeMember(member, txn) {
|
async _addRoomToUserIdentity(roomId, userId, txn) {
|
||||||
const {userIdentities} = txn;
|
const {userIdentities} = txn;
|
||||||
const identity = await userIdentities.get(member.userId);
|
const identity = await userIdentities.get(userId);
|
||||||
const updatedIdentity = addRoomToIdentity(identity, member.userId, member.roomId);
|
const updatedIdentity = addRoomToIdentity(identity, userId, roomId);
|
||||||
if (updatedIdentity) {
|
if (updatedIdentity) {
|
||||||
userIdentities.set(updatedIdentity);
|
userIdentities.set(updatedIdentity);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _removeRoomFromUserIdentity(roomId, userId, txn) {
|
async _removeRoomFromUserIdentity(roomId, userId, txn) {
|
||||||
|
@ -141,28 +173,9 @@ export class DeviceTracker {
|
||||||
} else {
|
} else {
|
||||||
userIdentities.set(identity);
|
userIdentities.set(identity);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
|
|
||||||
async _applyMemberChange(memberChange, txn) {
|
|
||||||
// TODO: depends whether we encrypt for invited users??
|
|
||||||
// add room
|
|
||||||
if (memberChange.hasJoined) {
|
|
||||||
await this._writeMember(memberChange.member, txn);
|
|
||||||
}
|
|
||||||
// remove room
|
|
||||||
else if (memberChange.hasLeft) {
|
|
||||||
const {roomId} = memberChange;
|
|
||||||
// if we left the room, remove room from all user identities in the room
|
|
||||||
if (memberChange.userId === this._ownUserId) {
|
|
||||||
const userIds = await txn.roomMembers.getAllUserIds(roomId);
|
|
||||||
await Promise.all(userIds.map(userId => {
|
|
||||||
return this._removeRoomFromUserIdentity(roomId, userId, txn);
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
await this._removeRoomFromUserIdentity(roomId, memberChange.userId, txn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async _queryKeys(userIds, hsApi, log) {
|
async _queryKeys(userIds, hsApi, log) {
|
||||||
|
|
Reference in a new issue