Skip to content
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
5 changes: 3 additions & 2 deletions packages/federation-sdk/src/services/send-join.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,14 @@ export class SendJoinService {

const signedJoinEvent = await stateService.signEvent(joinEvent);

this.emitterService.emit('homeserver.matrix.accept-invite', {
this.emitterService.emit('homeserver.matrix.membership', {
event_id: eventId,
room_id: roomId,
sender: signedJoinEvent.sender,
state_key: signedJoinEvent.sender,
origin_server_ts: signedJoinEvent.originServerTs,
Comment on lines +74 to 79

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Restore state_key to target user instead of sender

For m.room.member events the state_key must always be the user whose membership state is changing. Invites, kicks, bans, and third‑party invites all have sender !== state_key. By copying the sender here we’ll publish the wrong membership target, so downstream consumers will update the inviter rather than the invitee—precisely what this PR is trying to fix. Please pull the actual state key from the event payload instead.

-			state_key: signedJoinEvent.sender,
+			state_key: signedJoinEvent.event.state_key,
🤖 Prompt for AI Agents
packages/federation-sdk/src/services/send-join.service.ts around lines 74 to 79:
the emitted m.room.member payload sets state_key to the sender, which is
incorrect for membership events; change the code to read the actual state key
from the signed event payload (use the event's state_key property — e.g.
signedJoinEvent.state_key or signedJoinEvent.stateKey depending on naming) and
emit that as state_key so the membership target (invitee/kicked/banned user) is
published correctly.

content: {
avatar_url: signedJoinEvent.getContent().avatar_url || null,
avatar_url: signedJoinEvent.getContent().avatar_url,
displayname: signedJoinEvent.getContent().displayname || '',
membership: signedJoinEvent.getContent().membership,
},
Expand Down