add missing room ids to identities for tracked rooms & clear outbound session

This commit is contained in:
Bruno Windels 2021-08-27 19:39:24 +02:00
parent fa555bedf0
commit 8e6bd6a7a1
2 changed files with 63 additions and 0 deletions

View file

@ -19,6 +19,22 @@ import {verifyEd25519Signature, SIGNATURE_ALGORITHM} from "./common.js";
const TRACKING_STATUS_OUTDATED = 0; const TRACKING_STATUS_OUTDATED = 0;
const TRACKING_STATUS_UPTODATE = 1; const TRACKING_STATUS_UPTODATE = 1;
export function addRoomToIdentity(identity, userId, roomId) {
if (!identity) {
identity = {
userId: userId,
roomIds: [roomId],
deviceTrackingStatus: TRACKING_STATUS_OUTDATED,
};
return identity;
} else {
if (!identity.roomIds.includes(roomId)) {
identity.roomIds.push(roomId);
return identity;
}
}
}
// map 1 device from /keys/query response to DeviceIdentity // map 1 device from /keys/query response to DeviceIdentity
function deviceKeysAsDeviceIdentity(deviceSection) { function deviceKeysAsDeviceIdentity(deviceSection) {
const deviceId = deviceSection["device_id"]; const deviceId = deviceSection["device_id"];

View file

@ -1,8 +1,10 @@
import {iterateCursor, reqAsPromise} from "./utils.js"; import {iterateCursor, reqAsPromise} from "./utils.js";
import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js"; import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js";
import {addRoomToIdentity} from "../../e2ee/DeviceTracker.js";
import {RoomMemberStore} from "./stores/RoomMemberStore.js"; import {RoomMemberStore} from "./stores/RoomMemberStore.js";
import {SessionStore} from "./stores/SessionStore.js"; import {SessionStore} from "./stores/SessionStore.js";
import {encodeScopeTypeKey} from "./stores/OperationStore.js"; import {encodeScopeTypeKey} from "./stores/OperationStore.js";
import {MAX_UNICODE} from "./stores/common.js";
// FUNCTIONS SHOULD ONLY BE APPENDED!! // FUNCTIONS SHOULD ONLY BE APPENDED!!
// the index in the array is the database version // the index in the array is the database version
@ -17,6 +19,7 @@ export const schema = [
createArchivedRoomSummaryStore, createArchivedRoomSummaryStore,
migrateOperationScopeIndex, migrateOperationScopeIndex,
createTimelineRelationsStore, createTimelineRelationsStore,
fixMissingRoomsInUserIdentities
]; ];
// TODO: how to deal with git merge conflicts of this array? // TODO: how to deal with git merge conflicts of this array?
@ -142,3 +145,47 @@ async function migrateOperationScopeIndex(db, txn) {
function createTimelineRelationsStore(db) { function createTimelineRelationsStore(db) {
db.createObjectStore("timelineRelations", {keyPath: "key"}); db.createObjectStore("timelineRelations", {keyPath: "key"});
} }
//v11 doesn't change the schema, but ensures all userIdentities have all the roomIds they should (see #470)
async function fixMissingRoomsInUserIdentities(db, txn, log) {
const roomSummaryStore = txn.objectStore("roomSummary");
const trackedRoomIds = [];
await iterateCursor(roomSummaryStore.openCursor(), roomSummary => {
if (roomSummary.isTrackingMembers) {
trackedRoomIds.push(roomSummary.roomId);
}
});
const outboundGroupSessionsStore = txn.objectStore("outboundGroupSessions");
const userIdentitiesStore = txn.objectStore("userIdentities");
const roomMemberStore = txn.objectStore("roomMembers");
for (const roomId of trackedRoomIds) {
let foundMissing = false;
const joinedUserIds = [];
const memberRange = IDBKeyRange.bound(roomId, `${roomId}|${MAX_UNICODE}`, true, true);
await log.wrap({l: "room", id: roomId}, async log => {
await iterateCursor(roomMemberStore.openCursor(memberRange), member => {
if (member.membership === "join") {
joinedUserIds.push(member.userId);
}
});
log.set("joinedUserIds", joinedUserIds.length);
for (const userId of joinedUserIds) {
const identity = await reqAsPromise(userIdentitiesStore.get(userId));
const originalRoomCount = identity?.roomIds?.length;
const updatedIdentity = addRoomToIdentity(identity, userId, roomId);
if (updatedIdentity) {
log.log({l: `fixing up`, id: userId,
roomsBefore: originalRoomCount, roomsAfter: updatedIdentity.roomIds.length});
userIdentitiesStore.put(updatedIdentity);
foundMissing = true;
}
}
log.set("foundMissing", foundMissing);
if (foundMissing) {
// clear outbound megolm session,
// so we'll create a new one on the next message that will be properly shared
outboundGroupSessionsStore.delete(roomId);
}
});
}
}