-
Notifications
You must be signed in to change notification settings - Fork 13k
fix(federation): previous states on initial state and remove emitter #37677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| "@rocket.chat/meteor": patch | ||
| "@rocket.chat/federation-matrix": patch | ||
| --- | ||
|
|
||
| Fixes an issue where membership updates were not reflected when the user was the first member on their own server. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,15 @@ | ||
| import type { Emitter } from '@rocket.chat/emitter'; | ||
| import { type HomeserverEventSignatures } from '@rocket.chat/federation-sdk'; | ||
|
|
||
| import { edus } from './edu'; | ||
| import { member } from './member'; | ||
| import { message } from './message'; | ||
| import { ping } from './ping'; | ||
| import { reaction } from './reaction'; | ||
| import { room } from './room'; | ||
|
|
||
| export function registerEvents(emitter: Emitter<HomeserverEventSignatures>) { | ||
| ping(emitter); | ||
| message(emitter); | ||
| reaction(emitter); | ||
| member(emitter); | ||
| edus(emitter); | ||
| room(emitter); | ||
| export function registerEvents() { | ||
| ping(); | ||
| message(); | ||
| reaction(); | ||
| member(); | ||
| edus(); | ||
| room(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,7 @@ | ||
| import type { Emitter } from '@rocket.chat/emitter'; | ||
| import type { HomeserverEventSignatures } from '@rocket.chat/federation-sdk'; | ||
| import { federationSDK } from '@rocket.chat/federation-sdk'; | ||
|
|
||
| export const ping = async (emitter: Emitter<HomeserverEventSignatures>) => { | ||
| emitter.on('homeserver.ping', async (data) => { | ||
| export const ping = async () => { | ||
| federationSDK.eventEmitterService.on('homeserver.ping', async (data) => { | ||
| console.log('Message received from homeserver', data); | ||
| }); | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,8 @@ import { | |||||
| addUserToRoomSlashCommand, | ||||||
| acceptRoomInvite, | ||||||
| rejectRoomInvite, | ||||||
| getRoomMembers, | ||||||
| getSubscriptions, | ||||||
| } from '../../../../../apps/meteor/tests/data/rooms.helper'; | ||||||
| import { type IRequestConfig, getRequestConfig, createUser, deleteUser } from '../../../../../apps/meteor/tests/data/users.helper'; | ||||||
| import { IS_EE } from '../../../../../apps/meteor/tests/e2e/config/constants'; | ||||||
|
|
@@ -1563,14 +1565,58 @@ import { SynapseClient } from '../helper/synapse-client'; | |||||
| // RC view: Admin tries to accept rc1User1's invitation | ||||||
| const response = await acceptRoomInvite(federatedChannel._id, rc1AdminRequestConfig); | ||||||
| expect(response.success).toBe(false); | ||||||
| expect(response.error).toBe('Failed to handle invite: No subscription found or user does not have permission to accept or reject this invite'); | ||||||
| expect(response.error).toBe( | ||||||
| 'Failed to handle invite: No subscription found or user does not have permission to accept or reject this invite', | ||||||
| ); | ||||||
| }); | ||||||
|
|
||||||
| it('It should not allow admin to reject invitation on behalf of another user', async () => { | ||||||
| // RC view: Admin tries to reject rc1User1's invitation | ||||||
| const response = await rejectRoomInvite(federatedChannel._id, rc1AdminRequestConfig); | ||||||
| expect(response.success).toBe(false); | ||||||
| expect(response.error).toBe('Failed to handle invite: No subscription found or user does not have permission to accept or reject this invite'); | ||||||
| expect(response.error).toBe( | ||||||
| 'Failed to handle invite: No subscription found or user does not have permission to accept or reject this invite', | ||||||
| ); | ||||||
| }); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| describe('Inviting a RC user from Synapse', () => { | ||||||
| describe('Room that already contains previous events', () => { | ||||||
| let matrixRoomId: string; | ||||||
| let channelName: string; | ||||||
| let rid: string; | ||||||
| beforeAll(async () => { | ||||||
| channelName = `federated-channel-from-synapse-${Date.now()}`; | ||||||
| matrixRoomId = await hs1AdminApp.createRoom(channelName); | ||||||
|
|
||||||
| await hs1AdminApp.matrixClient.sendTextMessage(matrixRoomId, 'Message from admin'); | ||||||
| await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.hs1.additionalUser1.matrixUserId); | ||||||
| await hs1User1App.matrixClient.joinRoom(matrixRoomId); | ||||||
| await hs1User1App.matrixClient.sendTextMessage(matrixRoomId, 'Message from user1'); | ||||||
| await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); | ||||||
|
|
||||||
| const subscriptions = await getSubscriptions(rc1AdminRequestConfig); | ||||||
|
|
||||||
| const pendingInvitation = subscriptions.update.find((subscription) => subscription.status === 'INVITED'); | ||||||
|
|
||||||
| expect(pendingInvitation).not.toBeUndefined(); | ||||||
|
|
||||||
| rid = pendingInvitation?.rid!; | ||||||
|
|
||||||
| await acceptRoomInvite(rid, rc1AdminRequestConfig); | ||||||
| }, 15000); | ||||||
|
|
||||||
| describe('It should reflect all the members and messagens on the rocket.chat side', () => { | ||||||
|
||||||
| describe('It should reflect all the members and messagens on the rocket.chat side', () => { | |
| describe('It should reflect all the members and messages on the rocket.chat side', () => { |
Copilot
AI
Dec 8, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is checking for the wrong user. Line 1616 checks for federationConfig.rc1.additionalUser1.username, but this user was never invited to the room. Based on the setup in beforeAll, the three members should be:
- The Synapse admin who created the room
- The Synapse user1 (
federationConfig.hs1.additionalUser1.matrixUserId) who was invited on line 1594 - The RC admin (
federationConfig.rc1.adminUser) who was invited on line 1597
This assertion should check for federationConfig.hs1.additionalUser1.matrixUserId instead of federationConfig.rc1.additionalUser1.username.
| members.members.find((member: IUser) => member.username === federationConfig.rc1.additionalUser1.username), | |
| members.members.find((member: IUser) => member.username === federationConfig.hs1.additionalUser1.matrixUserId), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
senderfield in Matrix events contains the full Matrix user ID (format:@username:server.domain), butUsers.findOneByUsername()expects only the username part. This will cause the user lookup to fail. Use thegetUsernameServernameutility function to extract the username, similar to how it's done in theroom.roleevent handler (line 63).