Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix handling incoming redactions in EventIndex #7443

Merged
merged 2 commits into from
Jan 4, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions src/indexing/EventIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import { TimelineIndex, TimelineWindow } from 'matrix-js-sdk/src/timeline-window
import { sleep } from "matrix-js-sdk/src/utils";
import { IResultRoomEvents } from "matrix-js-sdk/src/@types/search";
import { logger } from "matrix-js-sdk/src/logger";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClient } from "matrix-js-sdk/src/client";

import PlatformPeg from "../PlatformPeg";
import { MatrixClientPeg } from "../MatrixClientPeg";
Expand Down Expand Up @@ -69,7 +71,6 @@ export default class EventIndex extends EventEmitter {
client.on('sync', this.onSync);
client.on('Room.timeline', this.onRoomTimeline);
client.on('Room.timelineReset', this.onTimelineReset);
client.on('Room.redaction', this.onRedaction);
client.on('RoomState.events', this.onRoomStateEvent);
}

Expand All @@ -83,7 +84,6 @@ export default class EventIndex extends EventEmitter {
client.removeListener('sync', this.onSync);
client.removeListener('Room.timeline', this.onRoomTimeline);
client.removeListener('Room.timelineReset', this.onTimelineReset);
client.removeListener('Room.redaction', this.onRedaction);
client.removeListener('RoomState.events', this.onRoomStateEvent);
}

Expand Down Expand Up @@ -199,10 +199,12 @@ export default class EventIndex extends EventEmitter {
// We only index encrypted rooms locally.
if (!client.isRoomEncrypted(room.roomId)) return;

// If it isn't a live event or if it's redacted there's nothing to
// do.
if (toStartOfTimeline || !data || !data.liveEvent
|| ev.isRedacted()) {
if (ev.isRedaction()) {
return this.redactEvent(ev);
}

// If it isn't a live event or if it's redacted there's nothing to do.
if (toStartOfTimeline || !data || !data.liveEvent || ev.isRedacted()) {
return;
}

Expand All @@ -214,20 +216,17 @@ export default class EventIndex extends EventEmitter {
private onRoomStateEvent = async (ev: MatrixEvent, state: RoomState) => {
if (!MatrixClientPeg.get().isRoomEncrypted(state.roomId)) return;

if (ev.getType() === "m.room.encryption" && !(await this.isRoomIndexed(state.roomId))) {
if (ev.getType() === EventType.RoomEncryption && !(await this.isRoomIndexed(state.roomId))) {
logger.log("EventIndex: Adding a checkpoint for a newly encrypted room", state.roomId);
this.addRoomCheckpoint(state.roomId, true);
}
};

/*
* The Room.redaction listener.
*
* Removes a redacted event from our event index.
* We cannot rely on Room.redaction as this only fires if the redaction applied to an event the js-sdk has loaded.
*/
private onRedaction = async (ev: MatrixEvent, room: Room) => {
// We only index encrypted rooms locally.
if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) return;
private redactEvent = async (ev: MatrixEvent) => {
const indexManager = PlatformPeg.get().getEventIndexingManager();

try {
Expand Down Expand Up @@ -259,28 +258,32 @@ export default class EventIndex extends EventEmitter {
* Most notably we filter events for which decryption failed, are redacted
* or aren't of a type that we know how to index.
*
* @param {MatrixEvent} ev The event that should checked.
* @param {MatrixEvent} ev The event that should be checked.
* @returns {bool} Returns true if the event can be indexed, false
* otherwise.
*/
private isValidEvent(ev: MatrixEvent) {
const isUsefulType = ["m.room.message", "m.room.name", "m.room.topic"].includes(ev.getType());
private isValidEvent(ev: MatrixEvent): boolean {
const isUsefulType = [
EventType.RoomMessage,
EventType.RoomName,
EventType.RoomTopic,
].includes(ev.getType() as EventType);
const validEventType = isUsefulType && !ev.isRedacted() && !ev.isDecryptionFailure();

let validMsgType = true;
let hasContentValue = true;

if (ev.getType() === "m.room.message" && !ev.isRedacted()) {
if (ev.getType() === EventType.RoomMessage && !ev.isRedacted()) {
// Expand this if there are more invalid msgtypes.
const msgtype = ev.getContent().msgtype;

if (!msgtype) validMsgType = false;
else validMsgType = !msgtype.startsWith("m.key.verification");

if (!ev.getContent().body) hasContentValue = false;
} else if (ev.getType() === "m.room.topic" && !ev.isRedacted()) {
} else if (ev.getType() === EventType.RoomTopic && !ev.isRedacted()) {
if (!ev.getContent().topic) hasContentValue = false;
} else if (ev.getType() === "m.room.name" && !ev.isRedacted()) {
} else if (ev.getType() === EventType.RoomName && !ev.isRedacted()) {
if (!ev.getContent().name) hasContentValue = false;
}

Expand Down Expand Up @@ -399,7 +402,7 @@ export default class EventIndex extends EventEmitter {
*
* If a /room/{roomId}/messages request doesn't contain any events, stop the
* crawl, otherwise create a new checkpoint and push it to the
* crawlerCheckpoints queue so we go through them in a round-robin way.
* crawlerCheckpoints queue, so we go through them in a round-robin way.
*/
private async crawlerFunc() {
let cancelled = false;
Expand Down Expand Up @@ -455,7 +458,7 @@ export default class EventIndex extends EventEmitter {
const eventMapper = client.getEventMapper({ preventReEmit: true });
// TODO we need to ensure to use member lazy loading with this
// request so we get the correct profiles.
let res;
let res: Awaited<ReturnType<MatrixClient["createMessagesRequest"]>>;

try {
res = await client.createMessagesRequest(
Expand Down Expand Up @@ -539,11 +542,8 @@ export default class EventIndex extends EventEmitter {
// stage?
const filteredEvents = matrixEvents.filter(this.isValidEvent);

// Collect the redaction events so we can delete the redacted events
// from the index.
const redactionEvents = matrixEvents.filter((ev) => {
return ev.getType() === "m.room.redaction";
});
// Collect the redaction events, so we can delete the redacted events from the index.
const redactionEvents = matrixEvents.filter(ev => ev.isRedaction());

// Let us convert the events back into a format that EventIndex can
// consume.
Expand Down Expand Up @@ -738,7 +738,7 @@ export default class EventIndex extends EventEmitter {
avatar_url: e.profile.avatar_url,
displayname: e.profile.displayname,
},
type: "m.room.member",
type: EventType.RoomMember,
event_id: matrixEvent.getId() + ":eventIndex",
room_id: matrixEvent.getRoomId(),
sender: matrixEvent.getSender(),
Expand Down