From 9e13cda50b4a91e9e27efde35d5e6dc0030e9227 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 10 Apr 2026 16:54:40 -0300 Subject: [PATCH 1/3] test(federation): refactor tests to create users on synapse --- .../federation-matrix/docker-compose.test.yml | 3 - .../tests/end-to-end/ban.spec.ts | 42 +- .../tests/end-to-end/dms.spec.ts | 258 +++++----- .../tests/end-to-end/messaging.spec.ts | 170 ++++--- .../tests/end-to-end/permissions.spec.ts | 40 +- .../tests/end-to-end/room.spec.ts | 440 ++++++++---------- .../federation-matrix/tests/helper/config.ts | 28 +- .../tests/helper/synapse-client.ts | 107 +++++ 8 files changed, 624 insertions(+), 464 deletions(-) diff --git a/ee/packages/federation-matrix/docker-compose.test.yml b/ee/packages/federation-matrix/docker-compose.test.yml index 40dbd4e224907..4677bf2e71130 100644 --- a/ee/packages/federation-matrix/docker-compose.test.yml +++ b/ee/packages/federation-matrix/docker-compose.test.yml @@ -58,9 +58,6 @@ services: echo ''; echo '=====> Running register_new_matrix_user...'; register_new_matrix_user -u admin -p admin --admin http://localhost:8008 -c /data/homeserver.yaml | sed 's/^/=======> /'; - register_new_matrix_user -u alice -p alice --admin http://localhost:8008 -c /data/homeserver.yaml | sed 's/^/=======> /'; - register_new_matrix_user -u bob -p bob --admin http://localhost:8008 -c /data/homeserver.yaml | sed 's/^/=======> /'; - register_new_matrix_user -u cleiton -p cleiton --admin http://localhost:8008 -c /data/homeserver.yaml | sed 's/^/=======> /'; echo '=====> Finished register_new_matrix_user.'; wait" volumes: diff --git a/ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts index c34dd0a891b77..83eb3c5c59e7d 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts @@ -14,6 +14,8 @@ import { SynapseClient } from '../helper/synapse-client'; let rc1AdminRequestConfig: IRequestConfig; let rc1User1RequestConfig: IRequestConfig; let hs1AdminApp: SynapseClient; + let hs1PrimaryApp: SynapseClient; + let hs1PrimaryMatrixUserId: string; beforeAll(async () => { rc1AdminRequestConfig = await getRequestConfig( @@ -40,9 +42,23 @@ import { SynapseClient } from '../helper/synapse-client'; hs1AdminApp = new SynapseClient(federationConfig.hs1.url, federationConfig.hs1.adminUser, federationConfig.hs1.adminPassword); await hs1AdminApp.initialize(); + + const primaryUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1PrimaryApp = primaryUser.client; + hs1PrimaryMatrixUserId = primaryUser.matrixUserId; }); afterAll(async () => { + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); + if (hs1PrimaryApp) { + await hs1PrimaryApp.close(); + } + if (hs1PrimaryMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1PrimaryMatrixUserId, adminAccessToken); + } if (hs1AdminApp) { await hs1AdminApp.close(); } @@ -58,7 +74,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId, federationConfig.rc1.additionalUser1.username], + members: [hs1PrimaryMatrixUserId, federationConfig.rc1.additionalUser1.username], extraData: { federated: true }, config: rc1AdminRequestConfig, }); @@ -66,7 +82,7 @@ import { SynapseClient } from '../helper/synapse-client'; federatedChannelId = createResponse.body.group._id; // Accept invitation on Synapse side - await hs1AdminApp.acceptInvitationForRoomName(channelName); + await hs1PrimaryApp.acceptInvitationForRoomName(channelName); // Accept invitation for the local RC user await acceptRoomInvite(federatedChannelId, rc1User1RequestConfig); @@ -75,7 +91,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'wait for RC user on Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); expect(member).not.toBeNull(); expect(member!.membership).toBe('join'); }, @@ -110,7 +126,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'wait for ban on Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); expect(member).not.toBeNull(); expect(member!.membership).toBe('ban'); }, @@ -149,7 +165,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'wait for unban on Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); expect(member).not.toBeNull(); expect(member!.membership).not.toBe('ban'); }, @@ -168,7 +184,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId, federationConfig.rc1.additionalUser1.username], + members: [hs1PrimaryMatrixUserId, federationConfig.rc1.additionalUser1.username], extraData: { federated: true }, config: rc1AdminRequestConfig, }); @@ -176,7 +192,7 @@ import { SynapseClient } from '../helper/synapse-client'; federatedChannelId = createResponse.body.group._id; // Accept invitation on Synapse side only — RC user stays as INVITED - await hs1AdminApp.acceptInvitationForRoomName(channelName); + await hs1PrimaryApp.acceptInvitationForRoomName(channelName); }, 30000); it('should ban the invited user before they accept', async () => { @@ -228,10 +244,10 @@ import { SynapseClient } from '../helper/synapse-client'; beforeAll(async () => { channelName = `fed-ban-synapse-${Date.now()}`; - synapseRoomId = await hs1AdminApp.createRoom(channelName, Visibility.Private); + synapseRoomId = await hs1PrimaryApp.createRoom(channelName, Visibility.Private); - await hs1AdminApp.inviteUserToRoom(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId); - await hs1AdminApp.inviteUserToRoom(synapseRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.inviteUserToRoom(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId); + await hs1PrimaryApp.inviteUserToRoom(synapseRoomId, federationConfig.rc1.adminMatrixUserId); const roomsResponse = await rc1AdminRequestConfig.request.get(api('rooms.get')).set(rc1AdminRequestConfig.credentials).expect(200); @@ -254,7 +270,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'wait for RC user on Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId); expect(member).not.toBeNull(); expect(member!.membership).toBe('join'); }, @@ -263,7 +279,7 @@ import { SynapseClient } from '../helper/synapse-client'; }, 30000); it('should ban the RC user from Synapse', async () => { - await hs1AdminApp.banUser(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId, 'federation ban test'); + await hs1PrimaryApp.banUser(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId, 'federation ban test'); }); it('should reflect ban on RC side', async () => { @@ -291,7 +307,7 @@ import { SynapseClient } from '../helper/synapse-client'; }); it('should unban the RC user from Synapse', async () => { - await hs1AdminApp.unbanUser(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId); + await hs1PrimaryApp.unbanUser(synapseRoomId, federationConfig.rc1.additionalUser1.matrixUserId); }); it('should reflect unban on RC side', async () => { diff --git a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts index 5aa85e92ce6a6..76a74d8cf2d63 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts @@ -35,9 +35,10 @@ const waitForRoomEvent = async ( (IS_EE ? describe : describe.skip)('Federation DMs', () => { let rc1AdminRequestConfig: IRequestConfig; - // let rc1User1RequestConfig: IRequestConfig; let hs1AdminApp: SynapseClient; - // let hs1User1App: SynapseClient; + let hs1PrimaryApp: SynapseClient; + let hs1PrimaryUsername: string; + let hs1PrimaryMatrixUserId: string; beforeAll(async () => { // Create admin request config for RC1 @@ -62,33 +63,27 @@ const waitForRoomEvent = async ( hs1AdminApp = new SynapseClient(federationConfig.hs1.url, federationConfig.hs1.adminUser, federationConfig.hs1.adminPassword); await hs1AdminApp.initialize(); - // Ensure the Synapse admin display name is reset to the expected value. - // A previous test run may have left it dirty if the "Display name changes" - // afterAll cleanup failed (federation propagation is inherently unreliable). - await hs1AdminApp.matrixClient.setDisplayName(federationConfig.hs1.adminUser); - - await retry( - 'waiting for Synapse admin displayname to be reset', - async () => { - const response = await rc1AdminRequestConfig.request - .get(api('users.info')) - .set(rc1AdminRequestConfig.credentials) - .query({ username: federationConfig.hs1.adminMatrixUserId }) - .expect(200); - - expect(response.body.user).toHaveProperty('name', federationConfig.hs1.adminUser); - }, - { retries: 5, delayMs: 1000 }, - ); + // Create dynamic primary Synapse user + const primaryUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1PrimaryApp = primaryUser.client; + hs1PrimaryUsername = primaryUser.username; + hs1PrimaryMatrixUserId = primaryUser.matrixUserId; }); afterAll(async () => { + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); + if (hs1PrimaryApp) { + await hs1PrimaryApp.close(); + } + if (hs1PrimaryMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1PrimaryMatrixUserId, adminAccessToken); + } if (hs1AdminApp) { await hs1AdminApp.close(); } - // if (hs1User1App) { - // await hs1User1App.close(); - // } }); describe('1:1 Direct Messages', () => { @@ -125,7 +120,7 @@ const waitForRoomEvent = async ( }); it('should create a DM and invite user from rc', async () => { - hs1Room = (await hs1AdminApp.createDM([userDmId])) as Room; + hs1Room = (await hs1PrimaryApp.createDM([userDmId])) as Room; expect(hs1Room).toHaveProperty('roomId'); @@ -147,7 +142,7 @@ const waitForRoomEvent = async ( subscriptionInvite = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); expect(subscriptionInvite).toHaveProperty('status', 'INVITED'); - expect(subscriptionInvite).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(subscriptionInvite).toHaveProperty('fname', hs1PrimaryUsername); }, { retries: 5, delayMs: 1000 }, ); @@ -176,11 +171,11 @@ const waitForRoomEvent = async ( it('should display the fname properly', async () => { const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); - expect(sub).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(sub).toHaveProperty('fname', hs1PrimaryUsername); }); it('should return own user name as the room name when user is alone in the DM', async () => { - await hs1AdminApp.matrixClient.leave(hs1Room.roomId); + await hs1PrimaryApp.matrixClient.leave(hs1Room.roomId); await retry( 'this is an async operation, so we need to wait for the event to be processed', @@ -240,7 +235,7 @@ const waitForRoomEvent = async ( }); it('should create a DM and invite user from rc', async () => { - hs1Room = (await hs1AdminApp.createDM([userDmId])) as Room; + hs1Room = (await hs1PrimaryApp.createDM([userDmId])) as Room; expect(hs1Room).toHaveProperty('roomId'); @@ -261,7 +256,7 @@ const waitForRoomEvent = async ( subscriptionInvite = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); expect(subscriptionInvite).toHaveProperty('status', 'INVITED'); - expect(subscriptionInvite).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(subscriptionInvite).toHaveProperty('fname', hs1PrimaryUsername); }, { retries: 5, delayMs: 1000 }, ); @@ -291,7 +286,7 @@ const waitForRoomEvent = async ( it('should display the fname properly', async () => { const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); - expect(sub).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(sub).toHaveProperty('fname', hs1PrimaryUsername); }); it('should be able to leave the DM from Rocket.Chat', async () => { @@ -317,6 +312,8 @@ const waitForRoomEvent = async ( describe('Rocket.Chat as the resident server', () => { let hs1User: SynapseClient; + let hs1UserUsername: string; + let hs1UserMatrixUserId: string; let rcUser: TestUser; let rcUserConfig: IRequestConfig; let hs1Room: Room; @@ -338,20 +335,25 @@ const waitForRoomEvent = async ( rcUserConfig = await getRequestConfig(federationConfig.rc1.url, rcUser.username, 'random'); - // Create Synapse user - hs1User = new SynapseClient( - federationConfig.hs1.url, - federationConfig.hs1.additionalUser1.username, - federationConfig.hs1.additionalUser1.password, - ); - await hs1User.initialize(); + // Create dynamic Synapse user + const dynamicUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1User = dynamicUser.client; + hs1UserUsername = dynamicUser.username; + hs1UserMatrixUserId = dynamicUser.matrixUserId; }); afterAll(async () => { + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); await deleteUser(rcUser, {}, rc1AdminRequestConfig); if (hs1User) { await hs1User.close(); } + if (hs1UserMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1UserMatrixUserId, adminAccessToken); + } }); describe('Reject invite flow', () => { @@ -363,7 +365,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUserConfig.credentials) .send({ - username: federationConfig.hs1.additionalUser1.matrixUserId, + username: hs1UserMatrixUserId, }) .expect(200); @@ -420,7 +422,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUserConfig.credentials) .send({ - username: federationConfig.hs1.additionalUser1.matrixUserId, + username: hs1UserMatrixUserId, }) .expect(200); @@ -453,7 +455,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', federationConfig.hs1.additionalUser1.username); + expect(sub).toHaveProperty('fname', hs1UserUsername); }, { retries: 5, delayMs: 1000 }, ); @@ -559,7 +561,7 @@ const waitForRoomEvent = async ( describe('Room list name validations', () => { it('should create a group DM with multiple RC users', async () => { - hs1Room = (await hs1AdminApp.createDM([userDmId1, userDmId2])) as Room; + hs1Room = (await hs1PrimaryApp.createDM([userDmId1, userDmId2])) as Room; expect(hs1Room).toHaveProperty('roomId'); @@ -594,7 +596,7 @@ const waitForRoomEvent = async ( pendingInvitation1 = await getSubscriptionByRoomId(rcRoom1._id, rcUserConfig1.credentials, rcUserConfig1.request); expect(pendingInvitation1).toHaveProperty('status', 'INVITED'); - expect(pendingInvitation1).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(pendingInvitation1).toHaveProperty('fname', hs1PrimaryUsername); }); it('should have user1 as regular user of the group DM on RC', async () => { @@ -606,7 +608,7 @@ const waitForRoomEvent = async ( pendingInvitation2 = await getSubscriptionByRoomId(rcRoom1._id, rcUserConfig2.credentials, rcUserConfig2.request); expect(pendingInvitation2).toHaveProperty('status', 'INVITED'); - expect(pendingInvitation2).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(pendingInvitation2).toHaveProperty('fname', hs1PrimaryUsername); }); it('should have user2 as regular user of the group DM on RC', async () => { @@ -630,8 +632,8 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom1._id, rcUserConfig1.credentials, rcUserConfig1.request); expect(sub).not.toHaveProperty('status'); - expect(sub).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${userDm2}`); - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${userDm2Name}`); + expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDm2}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDm2Name}`); }, { retries: 5, delayMs: 1000 }, ); @@ -645,7 +647,7 @@ const waitForRoomEvent = async ( }); it('should update the display name if the inviter from Synapse leaves the group DM', async () => { - await hs1AdminApp.matrixClient.leave(hs1Room.roomId); + await hs1PrimaryApp.matrixClient.leave(hs1Room.roomId); await retry( 'this is an async operation, so we need to wait for the event to be processed', @@ -789,7 +791,7 @@ const waitForRoomEvent = async ( rcUserConfigB = await getRequestConfig(federationConfig.rc1.url, rcUserB.username, 'random'); // Create 1:1 DM from Synapse with userA - hs1RoomConverted = (await hs1AdminApp.createDM([userDmIdA])) as Room; + hs1RoomConverted = (await hs1PrimaryApp.createDM([userDmIdA])) as Room; expect(hs1RoomConverted).toHaveProperty('roomId'); @@ -823,7 +825,7 @@ const waitForRoomEvent = async ( await waitForJoinEventPromise; // Now add userB to convert it to a group DM - await hs1AdminApp.matrixClient.invite(hs1RoomConverted.roomId, userDmIdB); + await hs1PrimaryApp.matrixClient.invite(hs1RoomConverted.roomId, userDmIdB); }); afterAll(async () => { @@ -841,7 +843,7 @@ const waitForRoomEvent = async ( ); expect(pendingInvitationB).toHaveProperty('status', 'INVITED'); - expect(pendingInvitationB).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(pendingInvitationB).toHaveProperty('fname', hs1PrimaryUsername); }, { retries: 5, delayMs: 1000 }, ); @@ -873,15 +875,15 @@ const waitForRoomEvent = async ( const subA = await getSubscriptionByRoomId(rcRoomConverted._id, rcUserConfigA.credentials, rcUserConfigA.request); expect(subA).not.toHaveProperty('status'); - expect(subA).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${userDmB}`); - expect(subA).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${userDmBName}`); + expect(subA).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDmB}`); + expect(subA).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDmBName}`); // Check userB's subscription const subB = await getSubscriptionByRoomId(rcRoomConverted._id, rcUserConfigB.credentials, rcUserConfigB.request); expect(subB).not.toHaveProperty('status'); - expect(subB).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${userDmA}`); - expect(subB).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${userDmAName}`); + expect(subB).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDmA}`); + expect(subB).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDmAName}`); }, { retries: 5, delayMs: 1000 }, ); @@ -897,18 +899,27 @@ const waitForRoomEvent = async ( describe('Rocket.Chat as the resident server', () => { let hs1User1: SynapseClient; + let hs1User1Username: string; + let hs1User1MatrixUserId: string; beforeAll(async () => { - hs1User1 = new SynapseClient( - federationConfig.hs1.url, - federationConfig.hs1.additionalUser1.username, - federationConfig.hs1.additionalUser1.password, - ); - await hs1User1.initialize(); + const dynamicUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1User1 = dynamicUser.client; + hs1User1Username = dynamicUser.username; + hs1User1MatrixUserId = dynamicUser.matrixUserId; }); afterAll(async () => { - await hs1User1.close(); + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); + if (hs1User1) { + await hs1User1.close(); + } + if (hs1User1MatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1User1MatrixUserId, adminAccessToken); + } }); describe('Room list name validations', () => { @@ -973,7 +984,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - usernames: [federationConfig.hs1.adminMatrixUserId, rcUser2.username].join(','), + usernames: [hs1PrimaryMatrixUserId, rcUser2.username].join(','), }) .expect(200); @@ -994,7 +1005,7 @@ const waitForRoomEvent = async ( await retry( 'waiting for room invitation', async () => { - hs1Room1 = (await hs1AdminApp.matrixClient.getRoom(rcRoom.federation.mrid)) as Room; + hs1Room1 = (await hs1PrimaryApp.matrixClient.getRoom(rcRoom.federation.mrid)) as Room; expect(hs1Room1).toBeDefined(); expect(hs1Room1.getMyMembership()).toBe('invite'); @@ -1012,20 +1023,20 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser1.config.credentials, rcUser1.config.request); // Should contain both invited users in the name - expect(sub).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${rcUser2.username}`); - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${rcUser2.fullName}`); + expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser2.username}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser2.fullName}`); }); it("should display only the inviter's username for the invited user on Rocket.Chat", async () => { const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); expect(sub).toHaveProperty('status', 'INVITED'); - expect(sub).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${rcUser1.username}`); - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser1.username}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); }); it('should accept the invitation on Synapse', async () => { - await hs1AdminApp.matrixClient.joinRoom(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.joinRoom(rcRoom.federation.mrid); await retry( 'wait for the join to be processed', @@ -1047,15 +1058,15 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); expect(sub).toHaveProperty('status', 'INVITED'); - expect(sub).toHaveProperty('name', `${federationConfig.hs1.adminMatrixUserId}, ${rcUser1.username}`); - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser1.username}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); }, { retries: 5, delayMs: 1000 }, ); }); it('should update the fname when a user leaves the DM', async () => { - await hs1AdminApp.matrixClient.leave(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.leave(rcRoom.federation.mrid); await retry( 'this is an async operation, so we need to wait for the event to be processed', @@ -1142,7 +1153,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUserConfig1.credentials) .send({ - usernames: [federationConfig.hs1.adminMatrixUserId, rcUser2.username].join(','), + usernames: [hs1PrimaryMatrixUserId, rcUser2.username].join(','), }) .expect(200); @@ -1163,7 +1174,7 @@ const waitForRoomEvent = async ( await retry( 'waiting for room invitation', async () => { - hs1Room1 = (await hs1AdminApp.matrixClient.getRoom(rcRoom.federation.mrid)) as Room; + hs1Room1 = (await hs1PrimaryApp.matrixClient.getRoom(rcRoom.federation.mrid)) as Room; expect(hs1Room1).toBeDefined(); expect(hs1Room1).toHaveProperty('roomId', rcRoom.federation.mrid); @@ -1196,7 +1207,7 @@ const waitForRoomEvent = async ( }); it('should add another user by another user than the initial inviter', async () => { - await hs1AdminApp.matrixClient.joinRoom(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.joinRoom(rcRoom.federation.mrid); await retry( 'waiting for join', @@ -1209,7 +1220,7 @@ const waitForRoomEvent = async ( { retries: 5, delayMs: 1000 }, ); - await hs1AdminApp.inviteUserToRoom(hs1Room1.roomId, userDmId3); + await hs1PrimaryApp.inviteUserToRoom(hs1Room1.roomId, userDmId3); await retry( 'waiting for user4 to receive invitation', @@ -1293,7 +1304,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - usernames: [rcUser2.username, federationConfig.hs1.adminMatrixUserId].join(','), + usernames: [rcUser2.username, hs1PrimaryMatrixUserId].join(','), }) .expect(200); @@ -1313,7 +1324,7 @@ const waitForRoomEvent = async ( await retry( 'waiting for room invitation', async () => { - hs1Room1 = hs1AdminApp.matrixClient.getRoom(rcRoom.federation.mrid) as Room; + hs1Room1 = hs1PrimaryApp.matrixClient.getRoom(rcRoom.federation.mrid) as Room; expect(hs1Room1).toBeDefined(); expect(hs1Room1).toHaveProperty('roomId', rcRoom.federation.mrid); @@ -1323,7 +1334,7 @@ const waitForRoomEvent = async ( ); // Accept the invitation - await hs1AdminApp.matrixClient.joinRoom(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.joinRoom(rcRoom.federation.mrid); await retry( 'wait for the join to be processed', @@ -1333,7 +1344,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1370,7 +1381,7 @@ const waitForRoomEvent = async ( expect(dmRooms.length).toBe(1); // now the synapse user leaves the federated DM - await hs1AdminApp.matrixClient.leave(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.leave(rcRoom.federation.mrid); await retry( 'wait for the leave to be processed', @@ -1485,7 +1496,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - username: federationConfig.hs1.adminMatrixUserId, + username: hs1PrimaryMatrixUserId, }) .expect(200); @@ -1506,7 +1517,7 @@ const waitForRoomEvent = async ( await retry( 'waiting for room invitation', async () => { - hs1Room1 = hs1AdminApp.matrixClient.getRoom(rcRoom1on1.federation.mrid) as Room; + hs1Room1 = hs1PrimaryApp.matrixClient.getRoom(rcRoom1on1.federation.mrid) as Room; expect(hs1Room1).toBeDefined(); expect(hs1Room1).toHaveProperty('roomId', rcRoom1on1.federation.mrid); @@ -1516,7 +1527,7 @@ const waitForRoomEvent = async ( ); // Accept the invitation - await hs1AdminApp.matrixClient.joinRoom(rcRoom1on1.federation.mrid); + await hs1PrimaryApp.matrixClient.joinRoom(rcRoom1on1.federation.mrid); await retry( 'wait for the join to be processed', @@ -1526,7 +1537,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom1on1._id, rcUser1.config.credentials, rcUser1.config.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(sub).toHaveProperty('fname', hs1PrimaryUsername); }, { retries: 5, delayMs: 1000 }, ); @@ -1537,7 +1548,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - usernames: [federationConfig.hs1.adminMatrixUserId, rcUser2.username].join(','), + usernames: [hs1PrimaryMatrixUserId, rcUser2.username].join(','), }) .expect(200); @@ -1558,7 +1569,7 @@ const waitForRoomEvent = async ( await retry( 'waiting for room invitation', async () => { - hs1Room1 = hs1AdminApp.matrixClient.getRoom(rcRoom.federation.mrid) as Room; + hs1Room1 = hs1PrimaryApp.matrixClient.getRoom(rcRoom.federation.mrid) as Room; expect(hs1Room1).toBeDefined(); expect(hs1Room1).toHaveProperty('roomId', rcRoom.federation.mrid); @@ -1568,7 +1579,7 @@ const waitForRoomEvent = async ( ); // Accept the invitation - await hs1AdminApp.matrixClient.joinRoom(rcRoom.federation.mrid); + await hs1PrimaryApp.matrixClient.joinRoom(rcRoom.federation.mrid); await retry( 'wait for the join to be processed', @@ -1578,7 +1589,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1606,7 +1617,7 @@ const waitForRoomEvent = async ( room.usernames && room.usernames.length === 2 && room.usernames.includes(rcUser1.username) && - room.usernames.includes(federationConfig.hs1.adminMatrixUserId), + room.usernames.includes(hs1PrimaryMatrixUserId), ); // at this time there should be only one DM with only two users (the non-federated one) @@ -1656,7 +1667,7 @@ const waitForRoomEvent = async ( room.usernames && room.usernames.length === 2 && room.usernames.includes(rcUser1.username) && - room.usernames.includes(federationConfig.hs1.adminMatrixUserId), + room.usernames.includes(hs1PrimaryMatrixUserId), ); expect(dmRoomsAfterLeave.length).toBe(2); @@ -1667,7 +1678,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - username: federationConfig.hs1.adminMatrixUserId, + username: hs1PrimaryMatrixUserId, }) .expect(200); @@ -1752,7 +1763,7 @@ const waitForRoomEvent = async ( expect(dmCreate.body).toHaveProperty('room'); const response = await addUserToRoom({ - usernames: [federationConfig.hs1.additionalUser1.matrixUserId], + usernames: [hs1User1MatrixUserId], rid: dmCreate.body.room._id, config: rcUser1.config, }); @@ -1772,7 +1783,7 @@ const waitForRoomEvent = async ( .post(api('dm.create')) .set(rcUser1.config.credentials) .send({ - username: federationConfig.hs1.adminMatrixUserId, + username: hs1PrimaryMatrixUserId, }) .expect(200); @@ -1796,14 +1807,14 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser1.config.credentials, rcUser1.config.request); // Should contain both invited users in the name - expect(sub).toHaveProperty('name', federationConfig.hs1.adminMatrixUserId); - expect(sub).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(sub).toHaveProperty('name', hs1PrimaryMatrixUserId); + expect(sub).toHaveProperty('fname', hs1PrimaryUsername); }); it('should send an invite to another Synapse user', async () => { // invite from rocket.chat const response = await addUserToRoom({ - usernames: [federationConfig.hs1.additionalUser1.matrixUserId], + usernames: [hs1User1MatrixUserId], rid: rcRoom._id, config: rcUser1.config, }); @@ -1829,11 +1840,8 @@ const waitForRoomEvent = async ( const subA = await getSubscriptionByRoomId(rcRoom._id, rcUser1.config.credentials, rcUser1.config.request); expect(subA).not.toHaveProperty('status'); - expect(subA).toHaveProperty( - 'name', - `${federationConfig.hs1.adminMatrixUserId}, ${federationConfig.hs1.additionalUser1.matrixUserId}`, - ); - expect(subA).toHaveProperty('fname', `${federationConfig.hs1.adminUser}, ${federationConfig.hs1.additionalUser1.username}`); + expect(subA).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${hs1User1MatrixUserId}`); + expect(subA).toHaveProperty('fname', `${hs1PrimaryUsername}, ${hs1User1Username}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1867,8 +1875,8 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); expect(sub).toHaveProperty('status', 'INVITED'); - expect(sub).toHaveProperty('name', federationConfig.hs1.additionalUser1.matrixUserId); - expect(sub).toHaveProperty('fname', federationConfig.hs1.additionalUser1.username); + expect(sub).toHaveProperty('name', hs1User1MatrixUserId); + expect(sub).toHaveProperty('fname', hs1User1Username); }, { retries: 5, delayMs: 1000 }, ); @@ -1901,7 +1909,7 @@ const waitForRoomEvent = async ( rcUserConfig = await getRequestConfig(federationConfig.rc1.url, rcUser.username, 'random'); - hs1Room = (await hs1AdminApp.createDM([userDmId])) as Room; + hs1Room = (await hs1PrimaryApp.createDM([userDmId])) as Room; await retry('waiting for the room to be created in RC', async () => { const roomsResponse = await rcUserConfig.request.get(api('rooms.get')).set(rcUserConfig.credentials).expect(200); @@ -1913,16 +1921,36 @@ const waitForRoomEvent = async ( }); afterAll(async () => { - await deleteUser(rcUser, {}, rc1AdminRequestConfig); + // Reset display name back to original before deleting the user + await hs1PrimaryApp.matrixClient.setDisplayName(hs1PrimaryUsername); - // Best-effort reset of the Synapse admin display name. - // The top-level beforeAll will also reset it on the next run, - // so this is not critical for test reliability. - try { - await hs1AdminApp.matrixClient.setDisplayName(federationConfig.hs1.adminUser); - } catch { - // ignore — the top-level beforeAll will handle it - } + // wait until the name change is reflected in RC before finishing the test + await retry( + 'waiting for Synapse user displayname to propagate to RC', + async () => { + const response = await rc1AdminRequestConfig.request + .get(api('users.info')) + .set(rc1AdminRequestConfig.credentials) + .query({ username: hs1PrimaryMatrixUserId }) + .expect(200); + + expect(response.body.user).toHaveProperty('name', hs1PrimaryUsername); + }, + { retries: 15, delayMs: 1000 }, + ); + + // Also wait for the DM subscription fname to be updated, since this propagates + // asynchronously after the user name change via debounced Room.updateDirectMessageRoomName + await retry( + 'waiting for subscription fname to reflect reset display name', + async () => { + const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); + expect(sub).toHaveProperty('fname', hs1PrimaryUsername); + }, + { retries: 10, delayMs: 1000 }, + ); + + await deleteUser(rcUser, {}, rc1AdminRequestConfig); }); it('should accept the DM invitation from RC', async () => { @@ -1933,10 +1961,10 @@ const waitForRoomEvent = async ( it('should update DM room name after Synapse user changes their display name', async () => { // Verify initial state: room name should be the Synapse admin initial display name const initialSub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); - expect(initialSub).toHaveProperty('fname', federationConfig.hs1.adminUser); + expect(initialSub).toHaveProperty('fname', hs1PrimaryUsername); // Action: update the Synapse user's displayname - await hs1AdminApp.matrixClient.setDisplayName(updatedDisplayName); + await hs1PrimaryApp.matrixClient.setDisplayName(updatedDisplayName); // Verify: the DM room name should be updated after the debounced name update completes await retry( @@ -1945,7 +1973,7 @@ const waitForRoomEvent = async ( const updatedSub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); expect(updatedSub).toHaveProperty('fname', updatedDisplayName); }, - { retries: 5, delayMs: 1000 }, + { delayMs: 1000 }, ); }); }); diff --git a/ee/packages/federation-matrix/tests/end-to-end/messaging.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/messaging.spec.ts index bf4ba49cf6bea..a65ac92289bf4 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/messaging.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/messaging.spec.ts @@ -17,7 +17,10 @@ import { SynapseClient } from '../helper/synapse-client'; (IS_EE ? describe : describe.skip)('Federation', () => { let rc1AdminRequestConfig: any; let hs1AdminApp: SynapseClient; + let hs1PrimaryApp: SynapseClient; + let hs1PrimaryMatrixUserId: string; let hs1User1App: SynapseClient; + let hs1User1MatrixUserId: string; beforeAll(async () => { // Create admin request config for RC1 @@ -42,22 +45,40 @@ import { SynapseClient } from '../helper/synapse-client'; hs1AdminApp = new SynapseClient(federationConfig.hs1.url, federationConfig.hs1.adminUser, federationConfig.hs1.adminPassword); await hs1AdminApp.initialize(); - // Create user1 Synapse client for HS1 - hs1User1App = new SynapseClient( - federationConfig.hs1.url, - federationConfig.hs1.additionalUser1.matrixUserId, - federationConfig.hs1.additionalUser1.password, - ); - await hs1User1App.initialize(); + // Create dynamic primary Synapse user + const primaryUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1PrimaryApp = primaryUser.client; + hs1PrimaryMatrixUserId = primaryUser.matrixUserId; + + // Create dynamic Synapse user for HS1 + const dynamicUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1User1App = dynamicUser.client; + hs1User1MatrixUserId = dynamicUser.matrixUserId; }); afterAll(async () => { - if (hs1AdminApp) { - await hs1AdminApp.close(); - } + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); if (hs1User1App) { await hs1User1App.close(); } + if (hs1User1MatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1User1MatrixUserId, adminAccessToken); + } + if (hs1PrimaryApp) { + await hs1PrimaryApp.close(); + } + if (hs1PrimaryMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1PrimaryMatrixUserId, adminAccessToken); + } + if (hs1AdminApp) { + await hs1AdminApp.close(); + } }); describe('Messaging', () => { @@ -73,7 +94,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -88,7 +109,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federated', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); @@ -111,7 +132,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.msg).toBe(messageText); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -152,7 +173,7 @@ import { SynapseClient } from '../helper/synapse-client'; // TODO: Verify emojis are correctly translated // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -191,7 +212,7 @@ import { SynapseClient } from '../helper/synapse-client'; // TODO: Verify emojis are correctly translated // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -222,7 +243,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.md).toEqual(expectedMd); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toContain(messageText); }); @@ -248,7 +269,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage).toBeDefined(); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -299,7 +320,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.md).toEqual(expectedMd); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -337,7 +358,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.md).toEqual(expectedMd); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -386,7 +407,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.md).toEqual(expectedMd); // Synapse view: Verify message appears correctly on remote Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); }); @@ -403,7 +424,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -418,7 +439,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federated', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); @@ -426,10 +447,10 @@ import { SynapseClient } from '../helper/synapse-client'; const messageText = 'Hello from Element'; // Synapse view: Send a text message from Element - await hs1AdminApp.sendTextMessage(channelName, messageText); + await hs1PrimaryApp.sendTextMessage(channelName, messageText); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); // RC view: Verify message appears correctly on remote RC1 @@ -443,10 +464,10 @@ import { SynapseClient } from '../helper/synapse-client'; const messageText = 'Hello :rocket: from Element 🚀'; // Synapse view: Send a text message with emoji shortcut and system emoji from Element - await hs1AdminApp.sendTextMessage(channelName, messageText); + await hs1PrimaryApp.sendTextMessage(channelName, messageText); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); @@ -478,10 +499,10 @@ import { SynapseClient } from '../helper/synapse-client'; const messageText = ':smirk:'; // Synapse view: Send a single emoji shortcut from Element - await hs1AdminApp.sendTextMessage(channelName, messageText); + await hs1PrimaryApp.sendTextMessage(channelName, messageText); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); // RC view: Verify message appears correctly on remote RC1 @@ -509,10 +530,10 @@ import { SynapseClient } from '../helper/synapse-client'; const messageText = '😀'; // Synapse view: Send a single system emoji from Element - await hs1AdminApp.sendTextMessage(channelName, messageText); + await hs1PrimaryApp.sendTextMessage(channelName, messageText); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toContain(messageText); @@ -536,10 +557,10 @@ import { SynapseClient } from '../helper/synapse-client'; const htmlFormattedBody = 'Plain text bold italic underline'; // Synapse view: Send a formatted text message from Element with HTML formatting - await hs1AdminApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); + await hs1PrimaryApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage?.content.body).toBe(messageText); // RC view: Verify message appears correctly on remote RC1 @@ -552,10 +573,10 @@ import { SynapseClient } from '../helper/synapse-client'; const messageText = 'Check this link: https://www.wikipedia.org'; // Synapse view: Send a message with plain link from Element - await hs1AdminApp.sendTextMessage(channelName, messageText); + await hs1PrimaryApp.sendTextMessage(channelName, messageText); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); @@ -599,10 +620,10 @@ import { SynapseClient } from '../helper/synapse-client'; const htmlFormattedBody = 'Check this google link'; // Synapse view: Send a message with markdown link from Element with HTML formatting - await hs1AdminApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); + await hs1PrimaryApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); @@ -632,10 +653,10 @@ import { SynapseClient } from '../helper/synapse-client'; const htmlFormattedBody = 'Here is some code:
const x = 1;
'; // Synapse view: Send a message with code block from Element with HTML formatting - await hs1AdminApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); + await hs1PrimaryApp.sendHtmlMessage(channelName, messageText, htmlFormattedBody); // Synapse view: Verify message appears in Element - const synapseMessage = await hs1AdminApp.findMessageInRoom(channelName, messageText); + const synapseMessage = await hs1PrimaryApp.findMessageInRoom(channelName, messageText); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(messageText); @@ -715,7 +736,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -730,7 +751,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federated', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); @@ -767,7 +788,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.federation?.eventId).not.toBe(''); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(fileInfo.fileName); expect(synapseMessage?.content.msgtype).toBe('m.image'); @@ -803,11 +824,14 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcFilesMatch).toBe(true); // Element view: Download and verify binary match from Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.url).toBeDefined(); - const synapseFilesMatch = await hs1AdminApp.downloadFileAndCompareBinary(synapseMessage?.content.url as string, fileInfo.path); + const synapseFilesMatch = await hs1PrimaryApp.downloadFileAndCompareBinary( + synapseMessage?.content.url as string, + fileInfo.path, + ); expect(synapseFilesMatch).toBe(true); }); }); @@ -843,7 +867,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.federation?.eventId).not.toBe(''); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(fileInfo.fileName); expect(synapseMessage?.content.msgtype).toBe('m.file'); @@ -879,11 +903,14 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcFilesMatch).toBe(true); // Element view: Download and verify binary match from Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.url).toBeDefined(); - const synapseFilesMatch = await hs1AdminApp.downloadFileAndCompareBinary(synapseMessage?.content.url as string, fileInfo.path); + const synapseFilesMatch = await hs1PrimaryApp.downloadFileAndCompareBinary( + synapseMessage?.content.url as string, + fileInfo.path, + ); expect(synapseFilesMatch).toBe(true); }); }); @@ -921,7 +948,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.federation?.eventId).not.toBe(''); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(fileInfo.fileName); expect(synapseMessage?.content.msgtype).toBe('m.video'); @@ -957,11 +984,14 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcFilesMatch).toBe(true); // Element view: Download and verify binary match from Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.url).toBeDefined(); - const synapseFilesMatch = await hs1AdminApp.downloadFileAndCompareBinary(synapseMessage?.content.url as string, fileInfo.path); + const synapseFilesMatch = await hs1PrimaryApp.downloadFileAndCompareBinary( + synapseMessage?.content.url as string, + fileInfo.path, + ); expect(synapseFilesMatch).toBe(true); }); }); @@ -999,7 +1029,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.federation?.eventId).not.toBe(''); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(fileInfo.fileName); expect(synapseMessage?.content.msgtype).toBe('m.audio'); @@ -1035,11 +1065,14 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcFilesMatch).toBe(true); // Element view: Download and verify binary match from Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.url).toBeDefined(); - const synapseFilesMatch = await hs1AdminApp.downloadFileAndCompareBinary(synapseMessage?.content.url as string, fileInfo.path); + const synapseFilesMatch = await hs1PrimaryApp.downloadFileAndCompareBinary( + synapseMessage?.content.url as string, + fileInfo.path, + ); expect(synapseFilesMatch).toBe(true); }); }); @@ -1074,7 +1107,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcMessage?.federation?.eventId).not.toBe(''); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.body).toBe(fileInfo.fileName); expect(synapseMessage?.content.msgtype).toBe('m.file'); @@ -1110,11 +1143,14 @@ import { SynapseClient } from '../helper/synapse-client'; expect(rcFilesMatch).toBe(true); // Element view: Download and verify binary match from Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.url).toBeDefined(); - const synapseFilesMatch = await hs1AdminApp.downloadFileAndCompareBinary(synapseMessage?.content.url as string, fileInfo.path); + const synapseFilesMatch = await hs1PrimaryApp.downloadFileAndCompareBinary( + synapseMessage?.content.url as string, + fileInfo.path, + ); expect(synapseFilesMatch).toBe(true); }); }); @@ -1131,7 +1167,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -1146,17 +1182,17 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federated', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); describe('Upload one image', () => { it('should appear correctly on the remote RC as messages', async () => { const fileInfo = testFiles.image; - await hs1AdminApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); + await hs1PrimaryApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.msgtype).toBe('m.image'); @@ -1201,10 +1237,10 @@ import { SynapseClient } from '../helper/synapse-client'; describe('Upload one PDF', () => { it('should appear correctly on the remote RC as messages', async () => { const fileInfo = testFiles.pdf; - await hs1AdminApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); + await hs1PrimaryApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.msgtype).toBe('m.file'); @@ -1247,10 +1283,10 @@ import { SynapseClient } from '../helper/synapse-client'; describe('Upload one Video', () => { it('should appear correctly on the remote RC as messages', async () => { const fileInfo = testFiles.video; - await hs1AdminApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); + await hs1PrimaryApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.msgtype).toBe('m.video'); @@ -1293,10 +1329,10 @@ import { SynapseClient } from '../helper/synapse-client'; describe('Upload one Audio', () => { it('should appear correctly on the remote RC as messages', async () => { const fileInfo = testFiles.audio; - await hs1AdminApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); + await hs1PrimaryApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.msgtype).toBe('m.audio'); @@ -1339,10 +1375,10 @@ import { SynapseClient } from '../helper/synapse-client'; describe('Upload one Text File', () => { it('should appear correctly on the remote RC as messages', async () => { const fileInfo = testFiles.text; - await hs1AdminApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); + await hs1PrimaryApp.uploadFile(channelName, fileInfo.path, fileInfo.fileName); // Element view: Verify in Element - const synapseMessage = await hs1AdminApp.findFileMessageInRoom(channelName, fileInfo.fileName); + const synapseMessage = await hs1PrimaryApp.findFileMessageInRoom(channelName, fileInfo.fileName); expect(synapseMessage).not.toBeNull(); expect(synapseMessage?.content.msgtype).toBe('m.file'); diff --git a/ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts index 92d44c95f309c..0a0706e4a3df9 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts @@ -14,6 +14,8 @@ import { SynapseClient } from '../helper/synapse-client'; let rc1AdminRequestConfig: IRequestConfig; let rc1User1RequestConfig: IRequestConfig; let hs1AdminApp: SynapseClient; + let hs1PrimaryApp: SynapseClient; + let hs1PrimaryMatrixUserId: string; beforeAll(async () => { // Create admin request config for RC1 @@ -33,6 +35,15 @@ import { SynapseClient } from '../helper/synapse-client'; // Create admin Synapse client for HS1 hs1AdminApp = new SynapseClient(federationConfig.hs1.url, federationConfig.hs1.adminUser, federationConfig.hs1.adminPassword); await hs1AdminApp.initialize(); + + // Create dynamic primary Synapse user for test participant operations + const primaryUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1PrimaryApp = primaryUser.client; + hs1PrimaryMatrixUserId = primaryUser.matrixUserId; + await rc1AdminRequestConfig.request .post(api('permissions.update')) .set(rc1AdminRequestConfig.credentials) @@ -51,7 +62,18 @@ import { SynapseClient } from '../helper/synapse-client'; .expect(200), ); - afterAll(async () => hs1AdminApp.close()); + afterAll(async () => { + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); + if (hs1PrimaryApp) { + await hs1PrimaryApp.close(); + } + if (hs1PrimaryMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1PrimaryMatrixUserId, adminAccessToken); + } + if (hs1AdminApp) { + await hs1AdminApp.close(); + } + }); describe('Access Federation Permission', () => { describe('Users without access-federation permission', () => { @@ -98,18 +120,20 @@ import { SynapseClient } from '../helper/synapse-client'; beforeAll(async () => { channelName = `federated-room-${Date.now()}`; - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); }); it('should throw an error if a remote user tries to invite a user without access-federation permission to a room', async () => { - await expect(hs1AdminApp.matrixClient.invite(matrixRoomId, `@${user.username}:${federationConfig.rc1.domain}`)).rejects.toThrow(); + await expect( + hs1PrimaryApp.matrixClient.invite(matrixRoomId, `@${user.username}:${federationConfig.rc1.domain}`), + ).rejects.toThrow(); const subscriptions = await getSubscriptions(rc1AdminRequestConfig); const invitedSub = subscriptions.update.find((sub) => sub.fname?.includes(channelName)); expect(invitedSub).toBeUndefined(); }); it('should be able to invite a user to a room if the user has access-federation permission', async () => { - await expect(hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId)).resolves.not.toThrow(); + await expect(hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId)).resolves.not.toThrow(); await retry('waiting for invitation to be processed', async () => { const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -193,7 +217,7 @@ import { SynapseClient } from '../helper/synapse-client'; it("should be able to add a remote user to a room regardless of the user's access-federation permission defined locally", async () => { addUserResponse = await addUserToRoom({ - usernames: [federationConfig.hs1.adminMatrixUserId], + usernames: [hs1PrimaryMatrixUserId], rid: createResponse.body.group._id, config: rc1AdminRequestConfig, }); @@ -742,7 +766,7 @@ import { SynapseClient } from '../helper/synapse-client'; .expect('Content-Type', 'application/json') .expect(200); - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); }); afterAll(async () => { @@ -752,7 +776,7 @@ import { SynapseClient } from '../helper/synapse-client'; it('should accept invitation for user with verified email matching federation domain', async () => { await expect( - hs1AdminApp.matrixClient.invite(matrixRoomId, `@${userWithMatchingEmail.username}:${federationConfig.rc1.domain}`), + hs1PrimaryApp.matrixClient.invite(matrixRoomId, `@${userWithMatchingEmail.username}:${federationConfig.rc1.domain}`), ).resolves.not.toThrow(); await retry('this is an async operation, so we need to wait for the room to be created in RC', async () => { @@ -782,7 +806,7 @@ import { SynapseClient } from '../helper/synapse-client'; it('should reject invitation for user with verified email NOT matching federation domain', async () => { await expect( - hs1AdminApp.matrixClient.invite(matrixRoomId, `@${userWithNonMatchingEmail.username}:${federationConfig.rc1.domain}`), + hs1PrimaryApp.matrixClient.invite(matrixRoomId, `@${userWithNonMatchingEmail.username}:${federationConfig.rc1.domain}`), ).rejects.toThrow(); const subscriptions = await getSubscriptions(userWithNonMatchingEmailRequestConfig); diff --git a/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts index 347f7bd4b8ebe..d97967d1931e4 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts @@ -22,14 +22,15 @@ import { federationConfig } from '../helper/config'; import { createDDPListener } from '../helper/ddp-listener'; import { SynapseClient } from '../helper/synapse-client'; -// import { KnownMembership } from 'matrix-js-sdk'; -// import { t } from 'i18next'; - (IS_EE ? describe : describe.skip)('Federation', () => { let rc1AdminRequestConfig: IRequestConfig; let rc1User1RequestConfig: IRequestConfig; let hs1AdminApp: SynapseClient; + let hs1PrimaryApp: SynapseClient; + let hs1PrimaryUsername: string; + let hs1PrimaryMatrixUserId: string; let hs1User1App: SynapseClient; + let hs1User1MatrixUserId: string; beforeAll(async () => { // Create admin request config for RC1 @@ -61,22 +62,41 @@ import { SynapseClient } from '../helper/synapse-client'; hs1AdminApp = new SynapseClient(federationConfig.hs1.url, federationConfig.hs1.adminUser, federationConfig.hs1.adminPassword); await hs1AdminApp.initialize(); - // Create user1 Synapse client for HS1 - hs1User1App = new SynapseClient( - federationConfig.hs1.url, - federationConfig.hs1.additionalUser1.matrixUserId, - federationConfig.hs1.additionalUser1.password, - ); - await hs1User1App.initialize(); + // Create dynamic primary Synapse user + const primaryUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1PrimaryApp = primaryUser.client; + hs1PrimaryUsername = primaryUser.username; + hs1PrimaryMatrixUserId = primaryUser.matrixUserId; + + // Create dynamic Synapse user for HS1 + const dynamicUser = await SynapseClient.createAndInitializeUser(federationConfig.hs1.url, federationConfig.hs1.domain, { + sharedSecret: federationConfig.hs1.registrationSharedSecret, + admin: true, + }); + hs1User1App = dynamicUser.client; + hs1User1MatrixUserId = dynamicUser.matrixUserId; }); afterAll(async () => { - if (hs1AdminApp) { - await hs1AdminApp.close(); - } + const adminAccessToken = hs1AdminApp?.matrixClient?.getAccessToken(); if (hs1User1App) { await hs1User1App.close(); } + if (hs1User1MatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1User1MatrixUserId, adminAccessToken); + } + if (hs1PrimaryApp) { + await hs1PrimaryApp.close(); + } + if (hs1PrimaryMatrixUserId && adminAccessToken) { + await SynapseClient.deactivateUser(federationConfig.hs1.url, hs1PrimaryMatrixUserId, adminAccessToken); + } + if (hs1AdminApp) { + await hs1AdminApp.close(); + } }); describe('Rooms', () => { @@ -98,7 +118,7 @@ import { SynapseClient } from '../helper/synapse-client'; it('should create a federated room when federated members are added', async () => { const response = await createRoom({ type: 'd', - username: federationConfig.hs1.adminMatrixUserId, + username: hs1PrimaryMatrixUserId, config: userRequestConfig, }); @@ -139,7 +159,7 @@ import { SynapseClient } from '../helper/synapse-client'; const response = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: false, }, @@ -161,7 +181,7 @@ import { SynapseClient } from '../helper/synapse-client'; const response = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId, federationConfig.hs1.additionalUser1.matrixUserId], + members: [hs1PrimaryMatrixUserId, hs1User1MatrixUserId], extraData: { federated: false, }, @@ -183,7 +203,7 @@ import { SynapseClient } from '../helper/synapse-client'; const response = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId, federationConfig.rc1.additionalUser1.username], + members: [hs1PrimaryMatrixUserId, federationConfig.rc1.additionalUser1.username], extraData: { federated: false, }, @@ -229,7 +249,7 @@ import { SynapseClient } from '../helper/synapse-client'; it('should not allow and show an error message', async () => { // RC view: Attempt to add a federated user to the non-federated room const response = await addUserToRoom({ - usernames: [federationConfig.hs1.adminMatrixUserId], + usernames: [hs1PrimaryMatrixUserId], rid: nonFederatedChannel._id, config: rc1AdminRequestConfig, }); @@ -245,7 +265,7 @@ import { SynapseClient } from '../helper/synapse-client'; // RC view: Verify the federated user was NOT added to the room's member list const federatedUserInRoom = await findRoomMember( nonFederatedChannel._id, - federationConfig.hs1.adminMatrixUserId, + hs1PrimaryMatrixUserId, { initialDelay: 0 }, rc1AdminRequestConfig, ); @@ -267,7 +287,7 @@ import { SynapseClient } from '../helper/synapse-client'; // RC view: Execute the /invite slash command to add a federated user const response = await addUserToRoomSlashCommand({ - usernames: [federationConfig.hs1.adminMatrixUserId], + usernames: [hs1PrimaryMatrixUserId], rid: nonFederatedChannel._id, config: rc1AdminRequestConfig, }); @@ -293,12 +313,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(ephemeralMessage.rid).toBe(nonFederatedChannel._id); // Verify it's for the correct room // RC view: Verify the federated user was NOT added to the room's member list - const federatedUserInRoom = await findRoomMember( - nonFederatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); + const federatedUserInRoom = await findRoomMember(nonFederatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); expect(federatedUserInRoom).toBeNull(); // RC view: Verify room remains non-federated @@ -321,7 +336,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -338,7 +353,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federation'); expect((federatedChannel as any).federation).toHaveProperty('version', 1); - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); // TODO: Figure out why syncing events are not working and uncomment this when we get the state change from @@ -354,7 +369,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element - const elementRoom = hs1AdminApp.getRoom(channelName); + const elementRoom = hs1PrimaryApp.getRoom(channelName); expect(elementRoom).toHaveProperty('name', channelName); }); @@ -368,7 +383,7 @@ import { SynapseClient } from '../helper/synapse-client'; ); const hs1AdminUserInRC = await findRoomMember( federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, + hs1PrimaryMatrixUserId, { initialDelay: 0 }, rc1AdminRequestConfig, ); @@ -378,10 +393,10 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRC?.federated).toBe(true); // Synapse view: Check in Element (Matrix) that the federated user is in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { delay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { delay: 2000, }); expect(rc1AdminUserInSynapse).not.toBeNull(); @@ -397,11 +412,11 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for a system message about the user being invited // Members added during room creation are invited (status: 'INVITED'), not auto-joined const inviteMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'ui' && message.msg && message.msg === federationConfig.hs1.adminMatrixUserId, + (message: IMessage) => message.t === 'ui' && message.msg && message.msg === hs1PrimaryMatrixUserId, ); expect(inviteMessage).toBeDefined(); - expect(inviteMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(inviteMessage?.msg).toContain(hs1PrimaryMatrixUserId); expect(inviteMessage?.u?.username).toBe(federationConfig.rc1.adminUser); }); }); @@ -417,7 +432,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId, federationConfig.hs1.additionalUser1.matrixUserId], + members: [hs1PrimaryMatrixUserId, hs1User1MatrixUserId], extraData: { federated: true, }, @@ -435,7 +450,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect((federatedChannel as any).federation).toHaveProperty('version', 1); // Accept invitations for both users - const acceptedRoomId1 = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId1 = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId1).not.toBe(''); const acceptedRoomId2 = await hs1User1App.acceptInvitationForRoomName(channelName); @@ -454,7 +469,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element for admin user - const elementRoom1 = hs1AdminApp.getRoom(channelName); + const elementRoom1 = hs1PrimaryApp.getRoom(channelName); expect(elementRoom1).toHaveProperty('name', channelName); // Synapse view: Check in Element for user1 @@ -465,18 +480,8 @@ import { SynapseClient } from '../helper/synapse-client'; it('should show the new users in the members list of all RCs involved', async () => { // RC view: Check in RC that both federated users are in the members list const rc1AdminUserInRC = await findRoomMember(federatedChannel._id, federationConfig.rc1.adminUser, {}, rc1AdminRequestConfig); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); - const hs1User1InRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.additionalUser1.matrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); + const hs1User1InRC = await findRoomMember(federatedChannel._id, hs1User1MatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(hs1AdminUserInRC).not.toBeNull(); @@ -485,9 +490,9 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1User1InRC?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) for admin user that all users are in the members list - const rc1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.additionalUser1.matrixUserId, { + const rc1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const hs1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1User1MatrixUserId, { initialDelay: 2000, }); @@ -497,8 +502,8 @@ import { SynapseClient } from '../helper/synapse-client'; // Synapse view: Check in Synapse (Matrix) for additional user that all users are in the members list const rc1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.additionalUser1.matrixUserId); + const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1User1MatrixUserId); expect(rc1AdminUserInSynapseUser1).not.toBeNull(); expect(hs1AdminUserInSynapseUser1).not.toBeNull(); @@ -514,19 +519,19 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about both users being invited // Members added during room creation are invited (status: 'INVITED'), not auto-joined const adminInviteMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'ui' && message.msg && message.msg === federationConfig.hs1.adminMatrixUserId, + (message: IMessage) => message.t === 'ui' && message.msg && message.msg === hs1PrimaryMatrixUserId, ); const hs1User1InviteMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'ui' && message.msg && message.msg === federationConfig.hs1.additionalUser1.matrixUserId, + (message: IMessage) => message.t === 'ui' && message.msg && message.msg === hs1User1MatrixUserId, ); expect(adminInviteMessage).toBeDefined(); - expect(adminInviteMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(adminInviteMessage?.msg).toContain(hs1PrimaryMatrixUserId); expect(adminInviteMessage?.u?.username).toBe(federationConfig.rc1.adminUser); expect(hs1User1InviteMessage).toBeDefined(); - expect(hs1User1InviteMessage?.msg).toContain(federationConfig.hs1.additionalUser1.matrixUserId); + expect(hs1User1InviteMessage?.msg).toContain(hs1User1MatrixUserId); expect(hs1User1InviteMessage?.u?.username).toBe(federationConfig.rc1.adminUser); }); @@ -539,21 +544,20 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about both users joining after accepting invites // 'uj' (user joined) message types const adminJoinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); const hs1User1JoinedMessage = historyResponse.messages.find( - (message: IMessage) => - message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.additionalUser1.matrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1User1MatrixUserId), ); expect(adminJoinedMessage).toBeDefined(); - expect(adminJoinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); - expect(adminJoinedMessage?.u?.username).toBe(federationConfig.hs1.adminMatrixUserId); + expect(adminJoinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); + expect(adminJoinedMessage?.u?.username).toBe(hs1PrimaryMatrixUserId); expect(hs1User1JoinedMessage).toBeDefined(); - expect(hs1User1JoinedMessage?.msg).toContain(federationConfig.hs1.additionalUser1.matrixUserId); - expect(hs1User1JoinedMessage?.u?.username).toBe(federationConfig.hs1.additionalUser1.matrixUserId); + expect(hs1User1JoinedMessage?.msg).toContain(hs1User1MatrixUserId); + expect(hs1User1JoinedMessage?.u?.username).toBe(hs1User1MatrixUserId); }); }); @@ -569,7 +573,7 @@ import { SynapseClient } from '../helper/synapse-client'; type: 'p', name: channelName, members: [ - federationConfig.hs1.adminMatrixUserId, // federated user + hs1PrimaryMatrixUserId, // federated user federationConfig.rc1.additionalUser1.username, // local user ], extraData: { @@ -589,7 +593,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect((federatedChannel as any).federation).toHaveProperty('version', 1); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); // Accept invitation for the local user (rc1User1) @@ -608,7 +612,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfoUser1.room).toHaveProperty('federated', true); // Synapse view: Check in Synapse (Matrix) for federated user - const room = hs1AdminApp.getRoom(channelName); + const room = hs1PrimaryApp.getRoom(channelName); expect(room).toHaveProperty('name', channelName); expect(room.getMyMembership()).toBe('join'); }); @@ -622,12 +626,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1AdminRequestConfig, ); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(rc1User1InRC).not.toBeNull(); @@ -647,12 +646,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1User1RequestConfig, ); - const hs1AdminUserInRCUser1 = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1User1RequestConfig, - ); + const hs1AdminUserInRCUser1 = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1User1RequestConfig); expect(rc1AdminUserInRCUser1).not.toBeNull(); expect(rc1User1InRCUser1).not.toBeNull(); @@ -660,13 +654,13 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRCUser1?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) that both users are in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { initialDelay: 2000, }); - const rc1User1InSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { + const rc1User1InSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { initialDelay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { initialDelay: 2000, }); @@ -687,7 +681,7 @@ import { SynapseClient } from '../helper/synapse-client'; ); const federatedUserInviteMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'ui' && message.msg && message.msg === federationConfig.hs1.adminMatrixUserId, + (message: IMessage) => message.t === 'ui' && message.msg && message.msg === hs1PrimaryMatrixUserId, ); expect(localUserInviteMessage).toBeDefined(); @@ -695,7 +689,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(localUserInviteMessage?.u?.username).toBe(federationConfig.rc1.adminUser); expect(federatedUserInviteMessage).toBeDefined(); - expect(federatedUserInviteMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(federatedUserInviteMessage?.msg).toContain(hs1PrimaryMatrixUserId); expect(federatedUserInviteMessage?.u?.username).toBe(federationConfig.rc1.adminUser); // RC view: Check in RC (user1 view) for system messages about both users being invited @@ -707,7 +701,7 @@ import { SynapseClient } from '../helper/synapse-client'; ); const federatedUserInviteMessageUser1 = historyResponseUser1.messages.find( - (message: IMessage) => message.t === 'ui' && message.msg && message.msg === federationConfig.hs1.adminMatrixUserId, + (message: IMessage) => message.t === 'ui' && message.msg && message.msg === hs1PrimaryMatrixUserId, ); expect(localUserInviteMessageUser1).toBeDefined(); @@ -729,7 +723,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, topic: channelTopic, @@ -744,7 +738,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('t', 'p'); expect(federatedChannel).toHaveProperty('federated', true); - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); @@ -755,7 +749,7 @@ import { SynapseClient } from '../helper/synapse-client'; }); it('should set the topic on the Matrix side', async () => { - const hs1Room1 = (await hs1AdminApp.matrixClient.getRoom(federatedChannel.federation.mrid)) as Room; + const hs1Room1 = (await hs1PrimaryApp.matrixClient.getRoom(federatedChannel.federation.mrid)) as Room; expect(hs1Room1).toBeDefined(); @@ -775,7 +769,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true, }, @@ -790,7 +784,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('federated', true); expect(federatedChannel).toHaveProperty('federation.mrid'); - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 10000); @@ -801,7 +795,7 @@ import { SynapseClient } from '../helper/synapse-client'; }); it('should not set a topic on the Matrix side', async () => { - const hs1Room1 = (await hs1AdminApp.matrixClient.getRoom(federatedChannel.federation.mrid)) as Room; + const hs1Room1 = (await hs1PrimaryApp.matrixClient.getRoom(federatedChannel.federation.mrid)) as Room; expect(hs1Room1).toBeDefined(); @@ -847,7 +841,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add federated user to the room const addUserResponse = await addUserToRoom({ - usernames: [federationConfig.hs1.adminMatrixUserId], + usernames: [hs1PrimaryMatrixUserId], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -855,7 +849,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 15000); @@ -866,7 +860,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element - const elementRoom = hs1AdminApp.getRoom(channelName); + const elementRoom = hs1PrimaryApp.getRoom(channelName); expect(elementRoom).toHaveProperty('name', channelName); }); @@ -880,7 +874,7 @@ import { SynapseClient } from '../helper/synapse-client'; ); const hs1AdminUserInRC = await findRoomMember( federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, + hs1PrimaryMatrixUserId, { initialDelay: 0 }, rc1AdminRequestConfig, ); @@ -890,10 +884,10 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRC?.federated).toBe(true); // Synapse view: Check in Element (Matrix) that both users are in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { delay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { delay: 2000, }); expect(rc1AdminUserInSynapse).not.toBeNull(); @@ -909,11 +903,11 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about the user joining after accepting invite // look for 'uj' (user joined) message types const joinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(joinedMessage).toBeDefined(); - expect(joinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(joinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); }); }); @@ -950,7 +944,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add both federated users to the room const addUserResponse = await addUserToRoom({ - usernames: [federationConfig.hs1.adminMatrixUserId, federationConfig.hs1.additionalUser1.matrixUserId], + usernames: [hs1PrimaryMatrixUserId, hs1User1MatrixUserId], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -958,7 +952,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitations for both users - const acceptedRoomId1 = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId1 = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId1).not.toBe(''); const acceptedRoomId2 = await hs1User1App.acceptInvitationForRoomName(channelName); @@ -972,7 +966,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element for admin user - const elementRoom1 = hs1AdminApp.getRoom(channelName); + const elementRoom1 = hs1PrimaryApp.getRoom(channelName); expect(elementRoom1).toHaveProperty('name', channelName); // Synapse view: Check in Element for user1 @@ -983,18 +977,8 @@ import { SynapseClient } from '../helper/synapse-client'; it('should show the new users in the members list of all RCs involved', async () => { // RC view: Check in RC that all users are in the members list const rc1AdminUserInRC = await findRoomMember(federatedChannel._id, federationConfig.rc1.adminUser, {}, rc1AdminRequestConfig); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); - const hs1User1InRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.additionalUser1.matrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); + const hs1User1InRC = await findRoomMember(federatedChannel._id, hs1User1MatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(hs1AdminUserInRC).not.toBeNull(); @@ -1003,15 +987,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1User1InRC?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) for admin user that all users are in the members list - const rc1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseAdmin = await hs1AdminApp.findRoomMember( - channelName, - federationConfig.hs1.additionalUser1.matrixUserId, - { - initialDelay: 2000, - }, - ); + const rc1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const hs1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1User1MatrixUserId, { + initialDelay: 2000, + }); expect(rc1AdminUserInSynapseAdmin).not.toBeNull(); expect(hs1AdminUserInSynapseAdmin).not.toBeNull(); @@ -1019,8 +999,8 @@ import { SynapseClient } from '../helper/synapse-client'; // Synapse view: Check in Synapse (Matrix) for additional user that all users are in the members list const rc1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.additionalUser1.matrixUserId); + const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1User1MatrixUserId); expect(rc1AdminUserInSynapseUser1).not.toBeNull(); expect(hs1AdminUserInSynapseUser1).not.toBeNull(); @@ -1036,20 +1016,19 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about both users joining after accepting invites // 'uj' (user joined) message types const adminJoinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(adminJoinedMessage).toBeDefined(); - expect(adminJoinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(adminJoinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); // Look for 'uj' (user joined) message types const hs1User1JoinedMessage = historyResponse.messages.find( - (message: IMessage) => - message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.additionalUser1.matrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1User1MatrixUserId), ); expect(hs1User1JoinedMessage).toBeDefined(); - expect(hs1User1JoinedMessage?.msg).toContain(federationConfig.hs1.additionalUser1.matrixUserId); + expect(hs1User1JoinedMessage?.msg).toContain(hs1User1MatrixUserId); }); }); @@ -1086,7 +1065,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add 1 federated user and 1 local user to the room const addUserResponse = await addUserToRoom({ - usernames: [federationConfig.hs1.adminMatrixUserId, federationConfig.rc1.additionalUser1.username], + usernames: [hs1PrimaryMatrixUserId, federationConfig.rc1.additionalUser1.username], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -1094,7 +1073,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); // Accept invitation for the local user (rc1User1) @@ -1113,7 +1092,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfoUser1.room).toHaveProperty('federated', true); // Synapse view: Check in Synapse (Matrix) for federated user - const room = hs1AdminApp.getRoom(channelName); + const room = hs1PrimaryApp.getRoom(channelName); expect(room).toHaveProperty('name', channelName); expect(room.getMyMembership()).toBe('join'); }); @@ -1127,12 +1106,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1AdminRequestConfig, ); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(rc1User1InRC).not.toBeNull(); @@ -1152,12 +1126,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1User1RequestConfig, ); - const hs1AdminUserInRCUser1 = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1User1RequestConfig, - ); + const hs1AdminUserInRCUser1 = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1User1RequestConfig); expect(rc1AdminUserInRCUser1).not.toBeNull(); expect(rc1User1InRCUser1).not.toBeNull(); @@ -1165,13 +1134,13 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRCUser1?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) that all users are in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { initialDelay: 2000, }); - const rc1User1InSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { + const rc1User1InSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { initialDelay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { initialDelay: 2000, }); @@ -1195,11 +1164,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(localUserJoinedMessage?.msg).toContain(federationConfig.rc1.additionalUser1.username); const federatedUserJoinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(federatedUserJoinedMessage).toBeDefined(); - expect(federatedUserJoinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(federatedUserJoinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); // RC view: Check in RC (user1 view) for system messages about both users joining const historyResponseUser1 = await getGroupHistory(federatedChannel._id, rc1User1RequestConfig); @@ -1215,11 +1184,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(localUserJoinedMessageUser1?.msg).toContain(federationConfig.rc1.additionalUser1.username); const federatedUserJoinedMessageUser1 = historyResponseUser1.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(federatedUserJoinedMessageUser1).toBeDefined(); - expect(federatedUserJoinedMessageUser1?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(federatedUserJoinedMessageUser1?.msg).toContain(hs1PrimaryMatrixUserId); }); }); }); @@ -1258,7 +1227,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add federated user to the room using slash command const addUserResponse = await addUserToRoomSlashCommand({ - usernames: [federationConfig.hs1.adminMatrixUserId], + usernames: [hs1PrimaryMatrixUserId], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -1266,7 +1235,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); }, 15000); @@ -1277,7 +1246,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element - const elementRoom = hs1AdminApp.getRoom(channelName); + const elementRoom = hs1PrimaryApp.getRoom(channelName); expect(elementRoom).toHaveProperty('name', channelName); }); @@ -1291,7 +1260,7 @@ import { SynapseClient } from '../helper/synapse-client'; ); const hs1AdminUserInRC = await findRoomMember( federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, + hs1PrimaryMatrixUserId, { initialDelay: 0 }, rc1AdminRequestConfig, ); @@ -1301,10 +1270,10 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRC?.federated).toBe(true); // Synapse view: Check in Element (Matrix) that both users are in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { delay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { delay: 2000, }); expect(rc1AdminUserInSynapse).not.toBeNull(); @@ -1320,11 +1289,11 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about the user joining after accepting invite // 'uj' (user joined) message types const joinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(joinedMessage).toBeDefined(); - expect(joinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(joinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); }); }); @@ -1361,7 +1330,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add both federated users to the room using slash command const addUserResponse = await addUserToRoomSlashCommand({ - usernames: [federationConfig.hs1.adminMatrixUserId, federationConfig.hs1.additionalUser1.matrixUserId], + usernames: [hs1PrimaryMatrixUserId, hs1User1MatrixUserId], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -1369,7 +1338,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitations for both users - const acceptedRoomId1 = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId1 = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId1).not.toBe(''); const acceptedRoomId2 = await hs1User1App.acceptInvitationForRoomName(channelName); @@ -1383,7 +1352,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfo.room).toHaveProperty('federated', true); // Synapse view: Check in Element for admin user - const elementRoom1 = hs1AdminApp.getRoom(channelName); + const elementRoom1 = hs1PrimaryApp.getRoom(channelName); expect(elementRoom1).toHaveProperty('name', channelName); // Synapse view: Check in Element for user1 @@ -1394,18 +1363,8 @@ import { SynapseClient } from '../helper/synapse-client'; it('should show the new users in the members list of all RCs involved', async () => { // RC view: Check in RC that all users are in the members list const rc1AdminUserInRC = await findRoomMember(federatedChannel._id, federationConfig.rc1.adminUser, {}, rc1AdminRequestConfig); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); - const hs1User1InRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.additionalUser1.matrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); + const hs1User1InRC = await findRoomMember(federatedChannel._id, hs1User1MatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(hs1AdminUserInRC).not.toBeNull(); @@ -1414,15 +1373,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1User1InRC?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) for admin user that all users are in the members list - const rc1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseAdmin = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseAdmin = await hs1AdminApp.findRoomMember( - channelName, - federationConfig.hs1.additionalUser1.matrixUserId, - { - initialDelay: 2000, - }, - ); + const rc1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const hs1AdminUserInSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseAdmin = await hs1PrimaryApp.findRoomMember(channelName, hs1User1MatrixUserId, { + initialDelay: 2000, + }); expect(rc1AdminUserInSynapseAdmin).not.toBeNull(); expect(hs1AdminUserInSynapseAdmin).not.toBeNull(); @@ -1430,8 +1385,8 @@ import { SynapseClient } from '../helper/synapse-client'; // Synapse view: Check in Synapse (Matrix) for additional user that all users are in the members list const rc1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); - const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId); - const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, federationConfig.hs1.additionalUser1.matrixUserId); + const hs1AdminUserInSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1PrimaryMatrixUserId); + const hs1User1InSynapseUser1 = await hs1User1App.findRoomMember(channelName, hs1User1MatrixUserId); expect(rc1AdminUserInSynapseUser1).not.toBeNull(); expect(hs1AdminUserInSynapseUser1).not.toBeNull(); @@ -1447,19 +1402,18 @@ import { SynapseClient } from '../helper/synapse-client'; // Look for system messages about both users joining after accepting invites // 'uj' (user joined) message types const adminJoinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(adminJoinedMessage).toBeDefined(); - expect(adminJoinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(adminJoinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); const hs1User1JoinedMessage = historyResponse.messages.find( - (message: IMessage) => - message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.additionalUser1.matrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1User1MatrixUserId), ); expect(hs1User1JoinedMessage).toBeDefined(); - expect(hs1User1JoinedMessage?.msg).toContain(federationConfig.hs1.additionalUser1.matrixUserId); + expect(hs1User1JoinedMessage?.msg).toContain(hs1User1MatrixUserId); }); }); @@ -1496,7 +1450,7 @@ import { SynapseClient } from '../helper/synapse-client'; // Add 1 federated user and 1 local user to the room using slash command const addUserResponse = await addUserToRoomSlashCommand({ - usernames: [federationConfig.hs1.adminMatrixUserId, federationConfig.rc1.additionalUser1.username], + usernames: [hs1PrimaryMatrixUserId, federationConfig.rc1.additionalUser1.username], rid: federatedChannel._id, config: rc1AdminRequestConfig, }); @@ -1504,7 +1458,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(addUserResponse.body).toHaveProperty('success', true); // Accept invitation for the federated user - const acceptedRoomId = await hs1AdminApp.acceptInvitationForRoomName(channelName); + const acceptedRoomId = await hs1PrimaryApp.acceptInvitationForRoomName(channelName); expect(acceptedRoomId).not.toBe(''); // Accept invitation for the local user (rc1User1) @@ -1523,7 +1477,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(roomInfoUser1.room).toHaveProperty('federated', true); // Synapse view: Check in Synapse (Matrix) for federated user - const room = hs1AdminApp.getRoom(channelName); + const room = hs1PrimaryApp.getRoom(channelName); expect(room).toHaveProperty('name', channelName); expect(room.getMyMembership()).toBe('join'); }); @@ -1537,12 +1491,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1AdminRequestConfig, ); - const hs1AdminUserInRC = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1AdminRequestConfig, - ); + const hs1AdminUserInRC = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1AdminRequestConfig); expect(rc1AdminUserInRC).not.toBeNull(); expect(rc1User1InRC).not.toBeNull(); @@ -1562,12 +1511,7 @@ import { SynapseClient } from '../helper/synapse-client'; {}, rc1User1RequestConfig, ); - const hs1AdminUserInRCUser1 = await findRoomMember( - federatedChannel._id, - federationConfig.hs1.adminMatrixUserId, - {}, - rc1User1RequestConfig, - ); + const hs1AdminUserInRCUser1 = await findRoomMember(federatedChannel._id, hs1PrimaryMatrixUserId, {}, rc1User1RequestConfig); expect(rc1AdminUserInRCUser1).not.toBeNull(); expect(rc1User1InRCUser1).not.toBeNull(); @@ -1575,13 +1519,13 @@ import { SynapseClient } from '../helper/synapse-client'; expect(hs1AdminUserInRCUser1?.federated).toBe(true); // Synapse view: Check in Synapse (Matrix) that all users are in the members list - const rc1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { + const rc1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId, { initialDelay: 2000, }); - const rc1User1InSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { + const rc1User1InSynapse = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.additionalUser1.matrixUserId, { initialDelay: 2000, }); - const hs1AdminUserInSynapse = await hs1AdminApp.findRoomMember(channelName, federationConfig.hs1.adminMatrixUserId, { + const hs1AdminUserInSynapse = await hs1PrimaryApp.findRoomMember(channelName, hs1PrimaryMatrixUserId, { initialDelay: 2000, }); @@ -1606,11 +1550,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(localUserJoinedMessage?.msg).toContain(federationConfig.rc1.additionalUser1.username); const federatedUserJoinedMessage = historyResponse.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(federatedUserJoinedMessage).toBeDefined(); - expect(federatedUserJoinedMessage?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(federatedUserJoinedMessage?.msg).toContain(hs1PrimaryMatrixUserId); // RC view: Check in RC (user1 view) for system messages about both users joining const historyResponseUser1 = await getGroupHistory(federatedChannel._id, rc1User1RequestConfig); @@ -1623,14 +1567,14 @@ import { SynapseClient } from '../helper/synapse-client'; ); const federatedUserJoinedMessageUser1 = historyResponseUser1.messages.find( - (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(federationConfig.hs1.adminMatrixUserId), + (message: IMessage) => message.t === 'uj' && message.msg && message.msg.includes(hs1PrimaryMatrixUserId), ); expect(localUserJoinedMessageUser1).toBeDefined(); expect(localUserJoinedMessageUser1?.msg).toContain(federationConfig.rc1.additionalUser1.username); expect(federatedUserJoinedMessageUser1).toBeDefined(); - expect(federatedUserJoinedMessageUser1?.msg).toContain(federationConfig.hs1.adminMatrixUserId); + expect(federatedUserJoinedMessageUser1?.msg).toContain(hs1PrimaryMatrixUserId); }); }); }); @@ -1688,13 +1632,13 @@ import { SynapseClient } from '../helper/synapse-client'; let rid: string; beforeAll(async () => { channelName = `federated-channel-from-synapse-${Date.now()}`; - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); - await hs1AdminApp.matrixClient.sendTextMessage(matrixRoomId, 'Message from admin'); - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.hs1.additionalUser1.matrixUserId); + await hs1PrimaryApp.matrixClient.sendTextMessage(matrixRoomId, 'Message from admin'); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, hs1User1MatrixUserId); await hs1User1App.matrixClient.joinRoom(matrixRoomId); await hs1User1App.matrixClient.sendTextMessage(matrixRoomId, 'Message from user1'); - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1722,7 +1666,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect( members.members.find((member: IUser) => member.username === federationConfig.rc1.additionalUser1.username), ).not.toBeNull(); - expect(members.members.find((member: IUser) => member.username === federationConfig.hs1.adminMatrixUserId)).not.toBeNull(); + expect(members.members.find((member: IUser) => member.username === hs1PrimaryMatrixUserId)).not.toBeNull(); }, { delayMs: 200 }, ); @@ -1738,9 +1682,9 @@ import { SynapseClient } from '../helper/synapse-client'; beforeAll(async () => { channelName = `federated-channel-reject-from-synapse-${Date.now()}`; - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1772,10 +1716,10 @@ import { SynapseClient } from '../helper/synapse-client'; beforeAll(async () => { channelName = `federated-channel-revoked-${Date.now()}`; - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); // hs1 invites RC user - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); const subscriptions = await getSubscriptions(rc1AdminRequestConfig); const pendingInvitation = subscriptions.update.find( @@ -1788,7 +1732,7 @@ import { SynapseClient } from '../helper/synapse-client'; rid = pendingInvitation!.rid!; // hs1 revokes the invitation by kicking the invited user - await hs1AdminApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Invitation revoked'); + await hs1PrimaryApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Invitation revoked'); }, 15000); it('should fail when RC user tries to accept the revoked invitation', async () => { @@ -1803,7 +1747,7 @@ import { SynapseClient } from '../helper/synapse-client'; }); it('should have the RC user with leave membership on Synapse side after revoked invitation', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); expect(member?.membership).toBe('leave'); }); }); @@ -1818,10 +1762,10 @@ import { SynapseClient } from '../helper/synapse-client'; channelName = `federated-channel-reinvite-kicked-${Date.now()}`; // Step 1: Create a room on Synapse - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); // Step 2: Invite RC user from Synapse - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); // Step 3: RC user accepts the invite const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1837,32 +1781,32 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'waiting for RC user join to propagate to Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); expect(member?.membership).toBe('join'); }, { delayMs: 500 }, ); // Step 4: Kick RC user from Synapse - await hs1AdminApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Kicked for re-invite test'); + await hs1PrimaryApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Kicked for re-invite test'); // Wait for kick to propagate to Synapse await retry( 'waiting for RC user kick to propagate to Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); expect(member?.membership).toBe('leave'); }, { delayMs: 500 }, ); // Step 5: Send a message from Synapse (while RC user is kicked) - await hs1AdminApp.matrixClient.sendTextMessage(matrixRoomId, 'Message sent after kicking RC user'); + await hs1PrimaryApp.matrixClient.sendTextMessage(matrixRoomId, 'Message sent after kicking RC user'); }, 30000); it('should allow re-inviting the same RC user after being kicked', async () => { // Step 6: Re-invite the same RC user from Synapse - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); // Step 7: Validate the invite was created successfully on the RC side const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1885,10 +1829,10 @@ import { SynapseClient } from '../helper/synapse-client'; channelName = `federated-channel-reinvite-left-${Date.now()}`; // Step 1: Create a room on Synapse - matrixRoomId = await hs1AdminApp.createRoom(channelName); + matrixRoomId = await hs1PrimaryApp.createRoom(channelName); // Step 2: Invite RC user from Synapse - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); // Step 3: RC user accepts the invite const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1904,7 +1848,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'waiting for RC user join to propagate to Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); expect(member?.membership).toBe('join'); }, { delayMs: 500 }, @@ -1921,19 +1865,19 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'waiting for RC user leave to propagate to Synapse', async () => { - const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + const member = await hs1PrimaryApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); expect(member?.membership).toBe('leave'); }, { delayMs: 500 }, ); // Step 5: Send a message from Synapse (while RC user has left) - await hs1AdminApp.matrixClient.sendTextMessage(matrixRoomId, 'Message sent after RC user left'); + await hs1PrimaryApp.matrixClient.sendTextMessage(matrixRoomId, 'Message sent after RC user left'); }, 30000); it('should allow re-inviting the same RC user after they left', async () => { // Step 6: Re-invite the same RC user from Synapse - await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + await hs1PrimaryApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); // Step 7: Validate the invite was created successfully on the RC side const subscriptions = await getSubscriptions(rc1AdminRequestConfig); @@ -1987,7 +1931,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: channelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true }, config: rcUser1.config, }); @@ -1997,7 +1941,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(federatedChannel).toHaveProperty('_id'); expect(federatedChannel).toHaveProperty('federation'); - await hs1AdminApp.acceptInvitationForRoomName(channelName); + await hs1PrimaryApp.acceptInvitationForRoomName(channelName); }, 20000); afterAll(async () => { @@ -2017,7 +1961,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'waiting for RC user displayname to propagate to Synapse', async () => { - const members = await hs1AdminApp.getRoomMembers(channelName); + const members = await hs1PrimaryApp.getRoomMembers(channelName); const member = members.find((m) => m.userId === rcUser1.matrixId); expect(member).toBeDefined(); expect(member?.name).toBe(rcUser1.newFullName); @@ -2040,7 +1984,7 @@ import { SynapseClient } from '../helper/synapse-client'; await retry( 'waiting for admin-updated displayname to propagate to Synapse', async () => { - const members = await hs1AdminApp.getRoomMembers(channelName); + const members = await hs1PrimaryApp.getRoomMembers(channelName); const member = members.find((m) => m.userId === rcUser1.matrixId); expect(member).toBeDefined(); expect(member?.name).toBe(rcUser1.adminUpdatedName); @@ -2058,7 +2002,7 @@ import { SynapseClient } from '../helper/synapse-client'; const createResponse = await createRoom({ type: 'p', name: newChannelName, - members: [federationConfig.hs1.adminMatrixUserId], + members: [hs1PrimaryMatrixUserId], extraData: { federated: true }, config: rcUser1.config, }); @@ -2067,13 +2011,13 @@ import { SynapseClient } from '../helper/synapse-client'; expect(newChannel).toHaveProperty('_id'); expect(newChannel).toHaveProperty('federation'); - await hs1AdminApp.acceptInvitationForRoomName(newChannelName); + await hs1PrimaryApp.acceptInvitationForRoomName(newChannelName); // Synapse view: the RC user should appear with their current name in the new room await retry( 'waiting for RC user to appear with correct displayname in new Synapse room', async () => { - const members = await hs1AdminApp.getRoomMembers(newChannelName); + const members = await hs1PrimaryApp.getRoomMembers(newChannelName); const member = members.find((m) => m.userId === rcUser1.matrixId); expect(member).toBeDefined(); expect(member?.name).toBe(rcUser1.adminUpdatedName); @@ -2085,13 +2029,13 @@ import { SynapseClient } from '../helper/synapse-client'; describe('When a Synapse user changes their displayname', () => { afterAll(async () => { - await hs1AdminApp.matrixClient.setDisplayName(federationConfig.hs1.adminMatrixUserId); // reset Synapse admin name + await hs1PrimaryApp.matrixClient.setDisplayName(hs1PrimaryUsername); // reset Synapse user name }); it('should propagate the updated name to the RC side', async () => { // Action: update the Synapse user's displayname — Synapse broadcasts new m.room.member // events to all joined rooms, which RC federation receives and debounces the name update - await hs1AdminApp.matrixClient.setDisplayName(newSynapseDisplayName); + await hs1PrimaryApp.matrixClient.setDisplayName(newSynapseDisplayName); // RC view: verify the federated user's name was updated — wait for debounce (> 2s) + propagation await retry( @@ -2100,7 +2044,7 @@ import { SynapseClient } from '../helper/synapse-client'; const response = await rc1AdminRequestConfig.request .get(api('users.info')) .set(rc1AdminRequestConfig.credentials) - .query({ username: federationConfig.hs1.adminMatrixUserId }) + .query({ username: hs1PrimaryMatrixUserId }) .expect(200); expect(response.body.user).toHaveProperty('name', newSynapseDisplayName); diff --git a/ee/packages/federation-matrix/tests/helper/config.ts b/ee/packages/federation-matrix/tests/helper/config.ts index b61b63bd5661b..335432eadb314 100644 --- a/ee/packages/federation-matrix/tests/helper/config.ts +++ b/ee/packages/federation-matrix/tests/helper/config.ts @@ -6,7 +6,7 @@ * for end-to-end federation testing. */ -type FederationServerConfig = { +type FederationRCServerConfig = { url: string; domain: string; adminUser: string; @@ -18,9 +18,19 @@ type FederationServerConfig = { matrixUserId: string; }; }; + +type FederationSynapseServerConfig = { + url: string; + domain: string; + adminUser: string; + adminPassword: string; + adminMatrixUserId: string; + registrationSharedSecret: string; +}; + export interface IFederationConfig { - rc1: FederationServerConfig; - hs1: FederationServerConfig; + rc1: FederationRCServerConfig; + hs1: FederationSynapseServerConfig; } /** @@ -64,8 +74,10 @@ function getFederationConfig(): IFederationConfig { const hs1Domain = validateEnvVar('FEDERATION_SYNAPSE_DOMAIN', 'hs1'); const hs1AdminUser = validateEnvVar('FEDERATION_SYNAPSE_ADMIN_USER', 'admin'); const hs1AdminPassword = validateEnvVar('FEDERATION_SYNAPSE_ADMIN_PASSWORD', 'admin'); - const hs1AdditionalUser1 = validateEnvVar('FEDERATION_SYNAPSE_ADDITIONAL_USER1', 'alice'); - const hs1AdditionalUser1Password = validateEnvVar('FEDERATION_SYNAPSE_ADDITIONAL_USER1_PASSWORD', 'alice'); + const hs1RegistrationSharedSecret = validateEnvVar( + 'FEDERATION_SYNAPSE_REGISTRATION_SHARED_SECRET', + '3l5H.Y5urc5@gKwYMe2^abk@nf.U_M6iyMgP,j&OL6pcSGrUQE', + ); return { rc1: { @@ -86,11 +98,7 @@ function getFederationConfig(): IFederationConfig { adminUser: hs1AdminUser, adminMatrixUserId: `@${hs1AdminUser}:${hs1Domain}`, adminPassword: hs1AdminPassword, - additionalUser1: { - username: hs1AdditionalUser1, - password: hs1AdditionalUser1Password, - matrixUserId: `@${hs1AdditionalUser1}:${hs1Domain}`, - }, + registrationSharedSecret: hs1RegistrationSharedSecret, }, }; } diff --git a/ee/packages/federation-matrix/tests/helper/synapse-client.ts b/ee/packages/federation-matrix/tests/helper/synapse-client.ts index 31be8d92cb78e..f71d83d87029c 100644 --- a/ee/packages/federation-matrix/tests/helper/synapse-client.ts +++ b/ee/packages/federation-matrix/tests/helper/synapse-client.ts @@ -3,6 +3,7 @@ * This file provides validated federation configuration for federation tests. */ +import { createHmac } from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; @@ -739,4 +740,110 @@ export class SynapseClient { this._matrixClient = null; } } + + /** + * Registers a new user on Synapse using the shared-secret registration Admin API. + * + * @param baseUrl - The Synapse homeserver URL + * @param options - Registration options + * @returns The registered user's access token and user ID + */ + static async registerUser( + baseUrl: string, + options: { username: string; password: string; displayname?: string; admin?: boolean; sharedSecret: string }, + ): Promise<{ accessToken: string; userId: string }> { + const nonceResponse = await fetch(`${baseUrl}/_synapse/admin/v1/register`, { method: 'GET' }); + if (!nonceResponse.ok) { + throw new Error(`Failed to get registration nonce: ${nonceResponse.status} ${nonceResponse.statusText}`); + } + const { nonce } = (await nonceResponse.json()) as { nonce: string }; + + const adminFlag = options.admin ? 'admin' : 'notadmin'; + const mac = createHmac('sha1', options.sharedSecret) + .update(`${nonce}\0${options.username}\0${options.password}\0${adminFlag}`) + .digest('hex'); + + const registerResponse = await fetch(`${baseUrl}/_synapse/admin/v1/register`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + nonce, + username: options.username, + password: options.password, + mac, + admin: options.admin ?? false, + displayname: options.displayname ?? options.username, + }), + }); + + if (!registerResponse.ok) { + const errorBody = await registerResponse.text(); + throw new Error(`Failed to register user ${options.username}: ${registerResponse.status} ${errorBody}`); + } + + const result = (await registerResponse.json()) as { access_token: string; user_id: string }; + return { accessToken: result.access_token, userId: result.user_id }; + } + + /** + * Deactivates and erases a user on Synapse via the Admin API. + * Failures are logged but do not throw so that test cleanup is not interrupted. + * + * @param baseUrl - The Synapse homeserver URL + * @param userId - The full Matrix user ID (e.g. @user:hs1) + * @param adminAccessToken - An access token from a Synapse admin user + */ + static async deactivateUser(baseUrl: string, userId: string, adminAccessToken: string): Promise { + try { + const response = await fetch(`${baseUrl}/_synapse/admin/v1/deactivate/${encodeURIComponent(userId)}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${adminAccessToken}`, + }, + body: JSON.stringify({ erase: true }), + }); + + if (!response.ok) { + console.warn(`Warning: Failed to deactivate user ${userId}: ${response.status} ${response.statusText}`); + } + } catch (error) { + console.warn(`Warning: Error deactivating user ${userId}:`, error); + } + } + + /** + * Creates a new Synapse user with a unique username, registers it on the homeserver, + * and returns an initialized SynapseClient along with the user's credentials. + * + * @param baseUrl - The Synapse homeserver URL + * @param domain - The Synapse homeserver domain (e.g. 'hs1') + * @param options - Options including optional prefix and the shared secret + * @returns An object with the initialized client, username, password, and matrixUserId + */ + static async createAndInitializeUser( + baseUrl: string, + domain: string, + options: { prefix?: string; sharedSecret: string; admin?: boolean }, + ): Promise<{ client: SynapseClient; username: string; password: string; matrixUserId: string }> { + const username = `${options.prefix || 'synapse-user'}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`; + const password = 'testpass123'; + const matrixUserId = `@${username}:${domain}`; + + await SynapseClient.registerUser(baseUrl, { + username, + password, + admin: options.admin, + sharedSecret: options.sharedSecret, + }); + + const client = new SynapseClient(baseUrl, username, password); + await client.initialize(); + + // Explicitly set the Matrix profile display name so that federated servers + // see a human-friendly name rather than the full matrix user ID. + await client.matrixClient.setDisplayName(username); + + return { client, username, password, matrixUserId }; + } } From 15d2bc94a71d6e4f051bd340803d9b3b7a508391 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 10 Apr 2026 18:59:38 -0300 Subject: [PATCH 2/3] reverse dm join names --- .../tests/end-to-end/dms.spec.ts | 57 +++++-------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts index 76a74d8cf2d63..917694d26c87c 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts @@ -142,7 +142,7 @@ const waitForRoomEvent = async ( subscriptionInvite = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); expect(subscriptionInvite).toHaveProperty('status', 'INVITED'); - expect(subscriptionInvite).toHaveProperty('fname', hs1PrimaryUsername); + expect(subscriptionInvite).toHaveProperty('fname', hs1PrimaryMatrixUserId); }, { retries: 5, delayMs: 1000 }, ); @@ -171,7 +171,7 @@ const waitForRoomEvent = async ( it('should display the fname properly', async () => { const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); - expect(sub).toHaveProperty('fname', hs1PrimaryUsername); + expect(sub).toHaveProperty('fname', hs1PrimaryMatrixUserId); }); it('should return own user name as the room name when user is alone in the DM', async () => { @@ -632,8 +632,8 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom1._id, rcUserConfig1.credentials, rcUserConfig1.request); expect(sub).not.toHaveProperty('status'); - expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDm2}`); - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDm2Name}`); + expect(sub).toHaveProperty('name', `${userDm2}, ${hs1PrimaryMatrixUserId}`); + expect(sub).toHaveProperty('fname', `${userDm2Name}, ${hs1PrimaryUsername}`); }, { retries: 5, delayMs: 1000 }, ); @@ -875,8 +875,8 @@ const waitForRoomEvent = async ( const subA = await getSubscriptionByRoomId(rcRoomConverted._id, rcUserConfigA.credentials, rcUserConfigA.request); expect(subA).not.toHaveProperty('status'); - expect(subA).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDmB}`); - expect(subA).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDmBName}`); + expect(subA).toHaveProperty('name', `${userDmB}, ${hs1PrimaryMatrixUserId}`); + expect(subA).toHaveProperty('fname', `${userDmBName}, ${hs1PrimaryUsername}`); // Check userB's subscription const subB = await getSubscriptionByRoomId(rcRoomConverted._id, rcUserConfigB.credentials, rcUserConfigB.request); @@ -1023,16 +1023,16 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser1.config.credentials, rcUser1.config.request); // Should contain both invited users in the name - expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser2.username}`); - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser2.fullName}`); + expect(sub).toHaveProperty('name', `${rcUser2.username}, ${hs1PrimaryMatrixUserId}`); + expect(sub).toHaveProperty('fname', `${rcUser2.fullName}, ${hs1PrimaryUsername}`); }); it("should display only the inviter's username for the invited user on Rocket.Chat", async () => { const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); expect(sub).toHaveProperty('status', 'INVITED'); - expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser1.username}`); - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('name', `${rcUser1.username}, ${hs1PrimaryMatrixUserId}`); + expect(sub).toHaveProperty('fname', `${rcUser1.fullName}, ${hs1PrimaryUsername}`); }); it('should accept the invitation on Synapse', async () => { @@ -1058,8 +1058,8 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); expect(sub).toHaveProperty('status', 'INVITED'); - expect(sub).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${rcUser1.username}`); - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('name', `${rcUser1.username}, ${hs1PrimaryMatrixUserId}`); + expect(sub).toHaveProperty('fname', `${rcUser1.fullName}, ${hs1PrimaryUsername}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1344,7 +1344,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('fname', `${rcUser1.fullName}, ${hs1PrimaryUsername}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1589,7 +1589,7 @@ const waitForRoomEvent = async ( const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request); // After acceptance, should display the Synapse user's ID - expect(sub).toHaveProperty('fname', `${hs1PrimaryUsername}, ${rcUser1.fullName}`); + expect(sub).toHaveProperty('fname', `${rcUser1.fullName}, ${hs1PrimaryUsername}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1921,35 +1921,6 @@ const waitForRoomEvent = async ( }); afterAll(async () => { - // Reset display name back to original before deleting the user - await hs1PrimaryApp.matrixClient.setDisplayName(hs1PrimaryUsername); - - // wait until the name change is reflected in RC before finishing the test - await retry( - 'waiting for Synapse user displayname to propagate to RC', - async () => { - const response = await rc1AdminRequestConfig.request - .get(api('users.info')) - .set(rc1AdminRequestConfig.credentials) - .query({ username: hs1PrimaryMatrixUserId }) - .expect(200); - - expect(response.body.user).toHaveProperty('name', hs1PrimaryUsername); - }, - { retries: 15, delayMs: 1000 }, - ); - - // Also wait for the DM subscription fname to be updated, since this propagates - // asynchronously after the user name change via debounced Room.updateDirectMessageRoomName - await retry( - 'waiting for subscription fname to reflect reset display name', - async () => { - const sub = await getSubscriptionByRoomId(rcRoom._id, rcUserConfig.credentials, rcUserConfig.request); - expect(sub).toHaveProperty('fname', hs1PrimaryUsername); - }, - { retries: 10, delayMs: 1000 }, - ); - await deleteUser(rcUser, {}, rc1AdminRequestConfig); }); From 203ee0509615526eb31e47a6968c4049bd29e53c Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 10 Apr 2026 20:15:28 -0300 Subject: [PATCH 3/3] fix tests --- .../federation-matrix/tests/end-to-end/dms.spec.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts index 917694d26c87c..6aa371e32570c 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts @@ -882,8 +882,8 @@ const waitForRoomEvent = async ( const subB = await getSubscriptionByRoomId(rcRoomConverted._id, rcUserConfigB.credentials, rcUserConfigB.request); expect(subB).not.toHaveProperty('status'); - expect(subB).toHaveProperty('name', `${hs1PrimaryMatrixUserId}, ${userDmA}`); - expect(subB).toHaveProperty('fname', `${hs1PrimaryUsername}, ${userDmAName}`); + expect(subB).toHaveProperty('name', `${userDmA}, ${hs1PrimaryMatrixUserId}`); + expect(subB).toHaveProperty('fname', `${userDmAName}, ${hs1PrimaryUsername}`); }, { retries: 5, delayMs: 1000 }, ); @@ -1014,8 +1014,9 @@ const waitForRoomEvent = async ( ); }); - it('should show the room name as the inviter name on Synapse before join', async () => { - expect(hs1Room1.name).toBe(rcUser1.fullName); + it('should show the room name with all members on Synapse before join', async () => { + // TODO it should also be rcUser2.fullName + expect(hs1Room1.name).toBe(`${rcUser1.fullName} and ${rcUser2.username}`); }); it('should display the fname containing the two invited users for the inviter', async () => {