You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-30 04:23:07 +03:00
Fix issue with sentinels being incorrect on m.room.member events (#4609)
* Fix issue with sentinels being incorrect on m.room.member events Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Simplify change Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
5b85ae491e
commit
1da26b5cd1
@ -23,6 +23,7 @@ import {
|
||||
EventTimelineSet,
|
||||
EventType,
|
||||
Filter,
|
||||
KnownMembership,
|
||||
MatrixClient,
|
||||
MatrixEvent,
|
||||
MatrixEventEvent,
|
||||
@ -138,6 +139,31 @@ describe("EventTimelineSet", () => {
|
||||
expect(eventsInLiveTimeline.length).toStrictEqual(1);
|
||||
expect(eventsInLiveTimeline[0]).toStrictEqual(duplicateMessageEvent);
|
||||
});
|
||||
|
||||
it("should set event.target after applying the membership state update", () => {
|
||||
const eventTimelineSet = room.getUnfilteredTimelineSet();
|
||||
|
||||
const ev1 = utils.mkMembership({
|
||||
room: roomId,
|
||||
mship: KnownMembership.Invite,
|
||||
user: "@sender:server",
|
||||
skey: userA,
|
||||
event: true,
|
||||
});
|
||||
const ev2 = utils.mkMembership({
|
||||
room: roomId,
|
||||
mship: KnownMembership.Join,
|
||||
user: userA,
|
||||
skey: userA,
|
||||
name: "This is my displayname",
|
||||
event: true,
|
||||
});
|
||||
|
||||
eventTimelineSet.addLiveEvent(ev1, { addToState: true });
|
||||
expect(ev1.target?.name).toBe(userA);
|
||||
eventTimelineSet.addLiveEvent(ev2, { addToState: true });
|
||||
expect(ev2.target?.name).toBe("This is my displayname");
|
||||
});
|
||||
});
|
||||
|
||||
describe("addEventToTimeline", () => {
|
||||
|
@ -7348,10 +7348,8 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
const sr = SearchResult.fromJson(roomEvents.results![i], mapper);
|
||||
const room = this.getRoom(sr.context.getEvent().getRoomId());
|
||||
if (room) {
|
||||
// Copy over a known event sender if we can
|
||||
for (const ev of sr.context.getTimeline()) {
|
||||
const sender = room.getMember(ev.getSender()!);
|
||||
if (!ev.sender && sender) ev.sender = sender;
|
||||
ev.setMetadata(room.currentState, false);
|
||||
}
|
||||
}
|
||||
searchResults.results.push(sr);
|
||||
|
@ -68,27 +68,7 @@ export class EventTimeline {
|
||||
* @param toStartOfTimeline - if true the event's forwardLooking flag is set false
|
||||
*/
|
||||
public static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void {
|
||||
// When we try to generate a sentinel member before we have that member
|
||||
// in the members object, we still generate a sentinel but it doesn't
|
||||
// have a membership event, so test to see if events.member is set. We
|
||||
// check this to avoid overriding non-sentinel members by sentinel ones
|
||||
// when adding the event to a filtered timeline
|
||||
if (!event.sender?.events?.member) {
|
||||
event.sender = stateContext.getSentinelMember(event.getSender()!);
|
||||
}
|
||||
if (!event.target?.events?.member && event.getType() === EventType.RoomMember) {
|
||||
event.target = stateContext.getSentinelMember(event.getStateKey()!);
|
||||
}
|
||||
|
||||
if (event.isState()) {
|
||||
// room state has no concept of 'old' or 'current', but we want the
|
||||
// room state to regress back to previous values if toStartOfTimeline
|
||||
// is set, which means inspecting prev_content if it exists. This
|
||||
// is done by toggling the forwardLooking flag.
|
||||
if (toStartOfTimeline) {
|
||||
event.forwardLooking = false;
|
||||
}
|
||||
}
|
||||
event.setMetadata(stateContext, toStartOfTimeline);
|
||||
}
|
||||
|
||||
private readonly roomId: string | null;
|
||||
|
@ -48,6 +48,7 @@ import { Room } from "./room.ts";
|
||||
import { EventTimeline } from "./event-timeline.ts";
|
||||
import { Membership } from "../@types/membership.ts";
|
||||
import { DecryptionFailureCode } from "../crypto-api/index.ts";
|
||||
import { RoomState } from "./room-state.ts";
|
||||
|
||||
export { EventStatus } from "./event-status.ts";
|
||||
|
||||
@ -232,6 +233,7 @@ export enum MatrixEventEvent {
|
||||
Status = "Event.status",
|
||||
Replaced = "Event.replaced",
|
||||
RelationsCreated = "Event.relationsCreated",
|
||||
SentinelUpdated = "Event.sentinelUpdated",
|
||||
}
|
||||
|
||||
export type MatrixEventEmittedEvents = MatrixEventEvent | ThreadEvent.Update;
|
||||
@ -244,6 +246,7 @@ export type MatrixEventHandlerMap = {
|
||||
[MatrixEventEvent.Status]: (event: MatrixEvent, status: EventStatus | null) => void;
|
||||
[MatrixEventEvent.Replaced]: (event: MatrixEvent) => void;
|
||||
[MatrixEventEvent.RelationsCreated]: (relationType: string, eventType: string) => void;
|
||||
[MatrixEventEvent.SentinelUpdated]: () => void;
|
||||
} & Pick<ThreadEventHandlerMap, ThreadEvent.Update>;
|
||||
|
||||
export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, MatrixEventHandlerMap> {
|
||||
@ -328,6 +331,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Should be read-only
|
||||
*/
|
||||
public sender: RoomMember | null = null;
|
||||
|
||||
/**
|
||||
* The room member who is the target of this event, e.g.
|
||||
* the invitee, the person being banned, etc.
|
||||
@ -335,6 +339,51 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* Should be read-only
|
||||
*/
|
||||
public target: RoomMember | null = null;
|
||||
|
||||
/**
|
||||
* Update the sentinels and forwardLooking flag for this event.
|
||||
* @param stateContext - the room state to be queried
|
||||
* @param toStartOfTimeline - if true the event's forwardLooking flag is set false
|
||||
* @internal
|
||||
*/
|
||||
public setMetadata(stateContext: RoomState, toStartOfTimeline: boolean): void {
|
||||
// If an event is an m.room.member state event then we should set the sentinels again in case setEventMetadata
|
||||
// was already called before the state was applied and thus the sentinel points at the member from before this event.
|
||||
const affectsSelf =
|
||||
this.isState() && this.getType() === EventType.RoomMember && this.getSender() === this.getStateKey();
|
||||
|
||||
let changed = false;
|
||||
// When we try to generate a sentinel member before we have that member
|
||||
// in the members object, we still generate a sentinel but it doesn't
|
||||
// have a membership event, so test to see if events.member is set. We
|
||||
// check this to avoid overriding non-sentinel members by sentinel ones
|
||||
// when adding the event to a filtered timeline
|
||||
if (affectsSelf || !this.sender?.events?.member) {
|
||||
const newSender = stateContext.getSentinelMember(this.getSender()!);
|
||||
if (newSender !== this.sender) changed = true;
|
||||
this.sender = newSender;
|
||||
}
|
||||
if (affectsSelf || (!this.target?.events?.member && this.getType() === EventType.RoomMember)) {
|
||||
const newTarget = stateContext.getSentinelMember(this.getStateKey()!);
|
||||
if (newTarget !== this.target) changed = true;
|
||||
this.target = newTarget;
|
||||
}
|
||||
|
||||
if (this.isState()) {
|
||||
// room state has no concept of 'old' or 'current', but we want the
|
||||
// room state to regress back to previous values if toStartOfTimeline
|
||||
// is set, which means inspecting prev_content if it exists. This
|
||||
// is done by toggling the forwardLooking flag.
|
||||
if (toStartOfTimeline) {
|
||||
this.forwardLooking = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
this.emit(MatrixEventEvent.SentinelUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sending status of the event.
|
||||
* @privateRemarks
|
||||
|
Reference in New Issue
Block a user