Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/src/events/m.room.create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
finalEvent.content.room_version as RoomVersion,
);
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/events/m.room.member.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
expect(signedLeaveEvent.prev_events).toEqual([joinEventId]);
expect(signedLeaveEvent.auth_events).toContain(createEventId);
Expand Down Expand Up @@ -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);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
expect(signedKickEvent.prev_events).toEqual([userToKickJoinEventId]);

Expand Down Expand Up @@ -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);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
expect(signedBanEvent.prev_events).toEqual([userToBanJoinEventId]);

Expand Down
4 changes: 2 additions & 2 deletions packages/federation-sdk/src/services/federation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/federation-sdk/src/services/room.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
);

Expand Down
4 changes: 2 additions & 2 deletions packages/room/src/authorizartion-rules/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down
35 changes: 28 additions & 7 deletions packages/room/src/manager/event-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ export abstract class PersistentEventBase<
private authEventsIds: Set<EventID> = new Set();
private prevEventsIds: Set<EventID> = 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;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this new property needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch — you’re right, that extra property is not needed.

I removed eventOrigin and kept the refactor scoped strictly to naming semantics:

  • senderDomain is used only for sender-domain checks (authentication logic).
  • origin remains the federation/server-origin accessor for compatibility.

This keeps the behavior clear without introducing extra mutable state in PersistentEventBase.


constructor(
event: PduWithHashesAndSignaturesOptional,
public readonly version: Version,
Expand Down Expand Up @@ -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);
Expand All @@ -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<PduForType<Type>> {
Expand Down
2 changes: 1 addition & 1 deletion packages/room/src/manager/room-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down