mirror of https://github.com/vector-im/riot-web
Fix handling incoming redactions in EventIndex (#7443)
parent
74ea2adfc2
commit
b6c2b5c995
|
@ -25,6 +25,8 @@ import { TimelineIndex, TimelineWindow } from 'matrix-js-sdk/src/timeline-window
|
||||||
import { sleep } from "matrix-js-sdk/src/utils";
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
import { IResultRoomEvents } from "matrix-js-sdk/src/@types/search";
|
import { IResultRoomEvents } from "matrix-js-sdk/src/@types/search";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
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 PlatformPeg from "../PlatformPeg";
|
||||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||||
|
@ -69,7 +71,6 @@ export default class EventIndex extends EventEmitter {
|
||||||
client.on('sync', this.onSync);
|
client.on('sync', this.onSync);
|
||||||
client.on('Room.timeline', this.onRoomTimeline);
|
client.on('Room.timeline', this.onRoomTimeline);
|
||||||
client.on('Room.timelineReset', this.onTimelineReset);
|
client.on('Room.timelineReset', this.onTimelineReset);
|
||||||
client.on('Room.redaction', this.onRedaction);
|
|
||||||
client.on('RoomState.events', this.onRoomStateEvent);
|
client.on('RoomState.events', this.onRoomStateEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +84,6 @@ export default class EventIndex extends EventEmitter {
|
||||||
client.removeListener('sync', this.onSync);
|
client.removeListener('sync', this.onSync);
|
||||||
client.removeListener('Room.timeline', this.onRoomTimeline);
|
client.removeListener('Room.timeline', this.onRoomTimeline);
|
||||||
client.removeListener('Room.timelineReset', this.onTimelineReset);
|
client.removeListener('Room.timelineReset', this.onTimelineReset);
|
||||||
client.removeListener('Room.redaction', this.onRedaction);
|
|
||||||
client.removeListener('RoomState.events', this.onRoomStateEvent);
|
client.removeListener('RoomState.events', this.onRoomStateEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,10 +199,12 @@ export default class EventIndex extends EventEmitter {
|
||||||
// We only index encrypted rooms locally.
|
// We only index encrypted rooms locally.
|
||||||
if (!client.isRoomEncrypted(room.roomId)) return;
|
if (!client.isRoomEncrypted(room.roomId)) return;
|
||||||
|
|
||||||
// If it isn't a live event or if it's redacted there's nothing to
|
if (ev.isRedaction()) {
|
||||||
// do.
|
return this.redactEvent(ev);
|
||||||
if (toStartOfTimeline || !data || !data.liveEvent
|
}
|
||||||
|| ev.isRedacted()) {
|
|
||||||
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,20 +216,17 @@ export default class EventIndex extends EventEmitter {
|
||||||
private onRoomStateEvent = async (ev: MatrixEvent, state: RoomState) => {
|
private onRoomStateEvent = async (ev: MatrixEvent, state: RoomState) => {
|
||||||
if (!MatrixClientPeg.get().isRoomEncrypted(state.roomId)) return;
|
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);
|
logger.log("EventIndex: Adding a checkpoint for a newly encrypted room", state.roomId);
|
||||||
this.addRoomCheckpoint(state.roomId, true);
|
this.addRoomCheckpoint(state.roomId, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Room.redaction listener.
|
|
||||||
*
|
|
||||||
* Removes a redacted event from our event index.
|
* 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) => {
|
private redactEvent = async (ev: MatrixEvent) => {
|
||||||
// We only index encrypted rooms locally.
|
|
||||||
if (!MatrixClientPeg.get().isRoomEncrypted(room.roomId)) return;
|
|
||||||
const indexManager = PlatformPeg.get().getEventIndexingManager();
|
const indexManager = PlatformPeg.get().getEventIndexingManager();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -259,18 +258,22 @@ export default class EventIndex extends EventEmitter {
|
||||||
* Most notably we filter events for which decryption failed, are redacted
|
* Most notably we filter events for which decryption failed, are redacted
|
||||||
* or aren't of a type that we know how to index.
|
* 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
|
* @returns {bool} Returns true if the event can be indexed, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
private isValidEvent(ev: MatrixEvent) {
|
private isValidEvent(ev: MatrixEvent): boolean {
|
||||||
const isUsefulType = ["m.room.message", "m.room.name", "m.room.topic"].includes(ev.getType());
|
const isUsefulType = [
|
||||||
|
EventType.RoomMessage,
|
||||||
|
EventType.RoomName,
|
||||||
|
EventType.RoomTopic,
|
||||||
|
].includes(ev.getType() as EventType);
|
||||||
const validEventType = isUsefulType && !ev.isRedacted() && !ev.isDecryptionFailure();
|
const validEventType = isUsefulType && !ev.isRedacted() && !ev.isDecryptionFailure();
|
||||||
|
|
||||||
let validMsgType = true;
|
let validMsgType = true;
|
||||||
let hasContentValue = 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.
|
// Expand this if there are more invalid msgtypes.
|
||||||
const msgtype = ev.getContent().msgtype;
|
const msgtype = ev.getContent().msgtype;
|
||||||
|
|
||||||
|
@ -278,9 +281,9 @@ export default class EventIndex extends EventEmitter {
|
||||||
else validMsgType = !msgtype.startsWith("m.key.verification");
|
else validMsgType = !msgtype.startsWith("m.key.verification");
|
||||||
|
|
||||||
if (!ev.getContent().body) hasContentValue = false;
|
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;
|
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;
|
if (!ev.getContent().name) hasContentValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +402,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
*
|
*
|
||||||
* If a /room/{roomId}/messages request doesn't contain any events, stop the
|
* If a /room/{roomId}/messages request doesn't contain any events, stop the
|
||||||
* crawl, otherwise create a new checkpoint and push it to 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() {
|
private async crawlerFunc() {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
@ -455,7 +458,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
const eventMapper = client.getEventMapper({ preventReEmit: true });
|
const eventMapper = client.getEventMapper({ preventReEmit: true });
|
||||||
// TODO we need to ensure to use member lazy loading with this
|
// TODO we need to ensure to use member lazy loading with this
|
||||||
// request so we get the correct profiles.
|
// request so we get the correct profiles.
|
||||||
let res;
|
let res: Awaited<ReturnType<MatrixClient["createMessagesRequest"]>>;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
res = await client.createMessagesRequest(
|
res = await client.createMessagesRequest(
|
||||||
|
@ -539,11 +542,8 @@ export default class EventIndex extends EventEmitter {
|
||||||
// stage?
|
// stage?
|
||||||
const filteredEvents = matrixEvents.filter(this.isValidEvent);
|
const filteredEvents = matrixEvents.filter(this.isValidEvent);
|
||||||
|
|
||||||
// Collect the redaction events so we can delete the redacted events
|
// Collect the redaction events, so we can delete the redacted events from the index.
|
||||||
// from the index.
|
const redactionEvents = matrixEvents.filter(ev => ev.isRedaction());
|
||||||
const redactionEvents = matrixEvents.filter((ev) => {
|
|
||||||
return ev.getType() === "m.room.redaction";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Let us convert the events back into a format that EventIndex can
|
// Let us convert the events back into a format that EventIndex can
|
||||||
// consume.
|
// consume.
|
||||||
|
@ -738,7 +738,7 @@ export default class EventIndex extends EventEmitter {
|
||||||
avatar_url: e.profile.avatar_url,
|
avatar_url: e.profile.avatar_url,
|
||||||
displayname: e.profile.displayname,
|
displayname: e.profile.displayname,
|
||||||
},
|
},
|
||||||
type: "m.room.member",
|
type: EventType.RoomMember,
|
||||||
event_id: matrixEvent.getId() + ":eventIndex",
|
event_id: matrixEvent.getId() + ":eventIndex",
|
||||||
room_id: matrixEvent.getRoomId(),
|
room_id: matrixEvent.getRoomId(),
|
||||||
sender: matrixEvent.getSender(),
|
sender: matrixEvent.getSender(),
|
||||||
|
|
Loading…
Reference in New Issue