From 6c265ff5d4bc4b13004b048cb387d28e89f836eb Mon Sep 17 00:00:00 2001 From: Muawiya-contact Date: Mon, 19 Jan 2026 21:55:49 +0500 Subject: [PATCH 1/2] refactor: rename confusing origin getter to senderDomain in EventWrapper --- bun.lock | 1 + .../core/src/events/m.room.create.spec.ts | 2 +- .../core/src/events/m.room.member.spec.ts | 6 ++-- .../src/services/federation.service.ts | 4 +-- .../src/services/room.service.ts | 2 +- .../room/src/authorizartion-rules/rules.ts | 4 +-- packages/room/src/manager/event-wrapper.ts | 35 +++++++++++++++---- packages/room/src/manager/room-state.ts | 2 +- 8 files changed, 39 insertions(+), 17 deletions(-) diff --git a/bun.lock b/bun.lock index 0a6f88c81..bcaabd7de 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "homeserver", diff --git a/packages/core/src/events/m.room.create.spec.ts b/packages/core/src/events/m.room.create.spec.ts index 38658e284..9e00ed08a 100644 --- a/packages/core/src/events/m.room.create.spec.ts +++ b/packages/core/src/events/m.room.create.spec.ts @@ -109,7 +109,7 @@ test('roomCreateEvent with factory', async () => { origin_server_ts: timestamp, unsigned: { age_ts: timestamp }, depth: finalEvent.depth, - origin: finalEvent.origin, + origin: finalEvent.senderDomain, }, finalEvent.content.room_version as RoomVersion, ); diff --git a/packages/core/src/events/m.room.member.spec.ts b/packages/core/src/events/m.room.member.spec.ts index f4cfbaf12..91e6aae84 100644 --- a/packages/core/src/events/m.room.member.spec.ts +++ b/packages/core/src/events/m.room.member.spec.ts @@ -142,7 +142,7 @@ test('roomMemberEvent - leave', async () => { expect(signedLeaveEvent.sender).toBe(userId); expect(signedLeaveEvent.state_key).toBe(userId); expect(signedLeaveEvent.content.membership).toBe('leave'); - expect(signedLeaveEvent.origin).toBe(serverName); + expect(signedLeaveEvent.senderDomain).toBe(serverName); expect(signedLeaveEvent.origin_server_ts).toBe(ts); expect(signedLeaveEvent.prev_events).toEqual([joinEventId]); expect(signedLeaveEvent.auth_events).toContain(createEventId); @@ -306,7 +306,7 @@ test('roomMemberEvent - kick', async () => { expect(signedKickEvent.state_key).toBe(userToKickId); expect(signedKickEvent.content.membership).toBe('leave'); expect(signedKickEvent.content.reason).toBe(kickReason); - expect(signedKickEvent.origin).toBe(serverName); + expect(signedKickEvent.senderDomain).toBe(serverName); expect(signedKickEvent.origin_server_ts).toBe(ts); expect(signedKickEvent.prev_events).toEqual([userToKickJoinEventId]); @@ -474,7 +474,7 @@ test('roomMemberEvent - ban', async () => { expect(signedBanEvent.state_key).toBe(userToBanId); expect(signedBanEvent.content.membership).toBe('ban'); expect(signedBanEvent.content.reason).toBe(banReason); - expect(signedBanEvent.origin).toBe(serverName); + expect(signedBanEvent.senderDomain).toBe(serverName); expect(signedBanEvent.origin_server_ts).toBe(ts); expect(signedBanEvent.prev_events).toEqual([userToBanJoinEventId]); diff --git a/packages/federation-sdk/src/services/federation.service.ts b/packages/federation-sdk/src/services/federation.service.ts index fc7e7f860..b1d141918 100644 --- a/packages/federation-sdk/src/services/federation.service.ts +++ b/packages/federation-sdk/src/services/federation.service.ts @@ -313,9 +313,9 @@ export class FederationService { } for (const server of servers) { - if (server === event.origin) { + if (server === event.senderDomain) { this.logger.info( - `Skipping transaction to event origin: ${event.origin}`, + `Skipping transaction to event origin: ${event.senderDomain}`, ); continue; } diff --git a/packages/federation-sdk/src/services/room.service.ts b/packages/federation-sdk/src/services/room.service.ts index cdc320669..debcd2c56 100644 --- a/packages/federation-sdk/src/services/room.service.ts +++ b/packages/federation-sdk/src/services/room.service.ts @@ -1112,7 +1112,7 @@ export class RoomService { // try to persist the join event now, should succeed with state in place void this.eventService.processIncomingPDUs( - residentServer || joinEventFinal.origin, + residentServer, [...state, joinEventFinal.event], ); diff --git a/packages/room/src/authorizartion-rules/rules.ts b/packages/room/src/authorizartion-rules/rules.ts index 16d84f3bd..5a94d45e3 100644 --- a/packages/room/src/authorizartion-rules/rules.ts +++ b/packages/room/src/authorizartion-rules/rules.ts @@ -83,7 +83,7 @@ function isRoomAliasAllowed( } // If sender’s domain doesn’t matches state_key, reject. - if (roomAliasEvent.origin !== roomAliasEvent.stateKey) { + if (roomAliasEvent.senderDomain !== roomAliasEvent.stateKey) { throw new StateResolverAuthorizationError(RejectCodes.AuthError, { rejectedEvent: roomAliasEvent, reason: @@ -799,7 +799,7 @@ export async function checkEventAuthWithState( // If the content of the m.room.create event in the room state has the property m.federate set to false, and the sender domain of the event does not match the sender domain of the create event, reject. if ( roomCreateEvent.getContent()['m.federate'] === false && - event.origin !== roomCreateEvent.origin + event.senderDomain !== roomCreateEvent.senderDomain ) { throw new StateResolverAuthorizationError(RejectCodes.AuthError, { rejectedEvent: event, diff --git a/packages/room/src/manager/event-wrapper.ts b/packages/room/src/manager/event-wrapper.ts index d24c76542..c80c2a723 100644 --- a/packages/room/src/manager/event-wrapper.ts +++ b/packages/room/src/manager/event-wrapper.ts @@ -72,6 +72,13 @@ export abstract class PersistentEventBase< private authEventsIds: Set = new Set(); private prevEventsIds: Set = new Set(); + /** + * The origin server that created this event. + * This is metadata stored separately from the PDU and is used to track + * which server the event came from in federation scenarios. + */ + public eventOrigin?: string; + constructor( event: PduWithHashesAndSignaturesOptional, public readonly version: Version, @@ -118,13 +125,18 @@ export abstract class PersistentEventBase< // TODO: This should be removed or different name used instead? - get origin() { - const domain = extractDomainFromId(this.rawEvent.sender); - if (!domain) { - throw new Error('Invalid sender, no domain found'); - } - return domain; - } + /** + * Gets the domain of the sender from their ID. + * @returns {string} The sender's domain. + * @throws {Error} If the sender ID is invalid or has no domain. + */ + get senderDomain() { + const domain = extractDomainFromId(this.rawEvent.sender); + if (!domain) { + throw new Error('Invalid sender, no domain found'); + } + return domain; + } get residentServer() { const residentServer = extractDomainFromId(this.rawEvent.room_id); @@ -142,6 +154,15 @@ export abstract class PersistentEventBase< return this.rawEvent.origin_server_ts; } + /** + * Gets the origin server that created this event. + * This is the server identity where the event originated (from federation). + * @returns {string | undefined} The origin server name, or undefined if not set. + */ + get origin() { + return this.eventOrigin; + } + // if we are accessing the inner event, the event itself should be frozen immediately to not change the reference hash any longer, affecting the id // if anywhere the code still tries to, we will throw an error, which is why "lock" isn't just a flag in the class. get event(): Readonly> { diff --git a/packages/room/src/manager/room-state.ts b/packages/room/src/manager/room-state.ts index e7107ef85..cd2960df2 100644 --- a/packages/room/src/manager/room-state.ts +++ b/packages/room/src/manager/room-state.ts @@ -119,7 +119,7 @@ export class RoomState { throw new Error('Room create event not found'); } - const origin = createEvent.origin; + const origin = createEvent.senderDomain; if (!origin) { throw new Error('Room create event has no origin'); } From 61e51f5b007763a5a7ca6a50b908671ab853beb3 Mon Sep 17 00:00:00 2001 From: Muawiya-contact Date: Mon, 19 Jan 2026 22:22:53 +0500 Subject: [PATCH 2/2] refactor: address reviewer feedback on test assertions and unreachable code --- packages/core/src/events/m.room.create.spec.ts | 2 +- packages/core/src/events/m.room.member.spec.ts | 6 +++--- packages/room/src/manager/event-wrapper.ts | 3 --- packages/room/src/manager/room-state.ts | 10 ++-------- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/core/src/events/m.room.create.spec.ts b/packages/core/src/events/m.room.create.spec.ts index 9e00ed08a..38658e284 100644 --- a/packages/core/src/events/m.room.create.spec.ts +++ b/packages/core/src/events/m.room.create.spec.ts @@ -109,7 +109,7 @@ test('roomCreateEvent with factory', async () => { origin_server_ts: timestamp, unsigned: { age_ts: timestamp }, depth: finalEvent.depth, - origin: finalEvent.senderDomain, + origin: finalEvent.origin, }, finalEvent.content.room_version as RoomVersion, ); diff --git a/packages/core/src/events/m.room.member.spec.ts b/packages/core/src/events/m.room.member.spec.ts index 91e6aae84..f4cfbaf12 100644 --- a/packages/core/src/events/m.room.member.spec.ts +++ b/packages/core/src/events/m.room.member.spec.ts @@ -142,7 +142,7 @@ test('roomMemberEvent - leave', async () => { expect(signedLeaveEvent.sender).toBe(userId); expect(signedLeaveEvent.state_key).toBe(userId); expect(signedLeaveEvent.content.membership).toBe('leave'); - expect(signedLeaveEvent.senderDomain).toBe(serverName); + expect(signedLeaveEvent.origin).toBe(serverName); expect(signedLeaveEvent.origin_server_ts).toBe(ts); expect(signedLeaveEvent.prev_events).toEqual([joinEventId]); expect(signedLeaveEvent.auth_events).toContain(createEventId); @@ -306,7 +306,7 @@ test('roomMemberEvent - kick', async () => { expect(signedKickEvent.state_key).toBe(userToKickId); expect(signedKickEvent.content.membership).toBe('leave'); expect(signedKickEvent.content.reason).toBe(kickReason); - expect(signedKickEvent.senderDomain).toBe(serverName); + expect(signedKickEvent.origin).toBe(serverName); expect(signedKickEvent.origin_server_ts).toBe(ts); expect(signedKickEvent.prev_events).toEqual([userToKickJoinEventId]); @@ -474,7 +474,7 @@ test('roomMemberEvent - ban', async () => { expect(signedBanEvent.state_key).toBe(userToBanId); expect(signedBanEvent.content.membership).toBe('ban'); expect(signedBanEvent.content.reason).toBe(banReason); - expect(signedBanEvent.senderDomain).toBe(serverName); + expect(signedBanEvent.origin).toBe(serverName); expect(signedBanEvent.origin_server_ts).toBe(ts); expect(signedBanEvent.prev_events).toEqual([userToBanJoinEventId]); diff --git a/packages/room/src/manager/event-wrapper.ts b/packages/room/src/manager/event-wrapper.ts index c80c2a723..3190ef9b6 100644 --- a/packages/room/src/manager/event-wrapper.ts +++ b/packages/room/src/manager/event-wrapper.ts @@ -132,9 +132,6 @@ export abstract class PersistentEventBase< */ get senderDomain() { const domain = extractDomainFromId(this.rawEvent.sender); - if (!domain) { - throw new Error('Invalid sender, no domain found'); - } return domain; } diff --git a/packages/room/src/manager/room-state.ts b/packages/room/src/manager/room-state.ts index cd2960df2..31283e3a6 100644 --- a/packages/room/src/manager/room-state.ts +++ b/packages/room/src/manager/room-state.ts @@ -108,8 +108,7 @@ export class RoomState { return topicEvent.getContent().topic; } - - // origin is the origin of the room gotten from the room id + // origin is the domain of the room creator (sender of m.room.create event) get origin() { const createEvent = getStateByMapKey(this.stateMap, { type: 'm.room.create', @@ -119,12 +118,7 @@ export class RoomState { throw new Error('Room create event not found'); } - const origin = createEvent.senderDomain; - if (!origin) { - throw new Error('Room create event has no origin'); - } - - return origin; + return createEvent.senderDomain; } get powerLevels() {