forked from mystiq/hydrogen-web
add missing room ids to identities for tracked rooms & clear outbound session
This commit is contained in:
parent
fa555bedf0
commit
8e6bd6a7a1
2 changed files with 63 additions and 0 deletions
|
@ -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"];
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue