From 78a314db58d5a90ca94ab0470991a1bfc62fd21f Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Fri, 12 Dec 2025 15:41:38 -0300 Subject: [PATCH 1/5] test: federation add test for revoked invitation flow --- .../tests/end-to-end/room.spec.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) 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 ecbd82b2bae4f..a415782bf6bdd 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 @@ -1660,5 +1660,54 @@ import { SynapseClient } from '../helper/synapse-client'; expect(invitedSub).toBeFalsy(); }); }); + + describe('Revoked invitation flow from Synapse', () => { + describe('Synapse revokes an invitation before the RC user responds', () => { + let matrixRoomId: string; + let channelName: string; + let rid: string; + + beforeAll(async () => { + channelName = `federated-channel-revoked-accept-${Date.now()}`; + matrixRoomId = await hs1AdminApp.createRoom(channelName); + + // hs1 invites RC user + await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + + // Wait for RC to receive the invitation + const subscriptions = await getSubscriptions(rc1AdminRequestConfig); + + const pendingInvitation = subscriptions.update.find( + (subscription) => subscription.status === 'INVITED' && subscription.fname?.includes(channelName), + ); + + expect(pendingInvitation).not.toBeUndefined(); + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + rid = pendingInvitation?.rid!; + + // hs1 revokes the invitation by kicking the invited user + await hs1AdminApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Invitation revoked'); + + // Wait for the revocation to propagate + await new Promise((resolve) => setTimeout(resolve, 2000)); + }, 20000); + + it('should no longer have the user status as INVITED after revocation', async () => { + const subscriptions = await getSubscriptions(rc1AdminRequestConfig); + + const invitedSubscription = subscriptions.update.find( + (subscription) => subscription.status === 'INVITED' && subscription.fname?.includes(channelName), + ); + + expect(invitedSubscription).toBeUndefined(); + }); + + it('should fail when RC user tries to accept the revoked invitation', async () => { + const acceptResponse = await acceptRoomInvite(rid, rc1AdminRequestConfig); + expect(acceptResponse.success).toBe(false); + }); + }); + }); }); }); From de49d11939a41266dc2cd5823dd743ac4ff2d3db Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Fri, 12 Dec 2025 17:50:13 -0300 Subject: [PATCH 2/5] fix: add reject logic --- .../tests/end-to-end/room.spec.ts | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) 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 a415782bf6bdd..5f1e5dcd2058e 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 @@ -1668,13 +1668,11 @@ import { SynapseClient } from '../helper/synapse-client'; let rid: string; beforeAll(async () => { - channelName = `federated-channel-revoked-accept-${Date.now()}`; + channelName = `federated-channel-revoked-${Date.now()}`; matrixRoomId = await hs1AdminApp.createRoom(channelName); // hs1 invites RC user await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); - - // Wait for RC to receive the invitation const subscriptions = await getSubscriptions(rc1AdminRequestConfig); const pendingInvitation = subscriptions.update.find( @@ -1693,20 +1691,20 @@ import { SynapseClient } from '../helper/synapse-client'; await new Promise((resolve) => setTimeout(resolve, 2000)); }, 20000); - it('should no longer have the user status as INVITED after revocation', async () => { - const subscriptions = await getSubscriptions(rc1AdminRequestConfig); - - const invitedSubscription = subscriptions.update.find( - (subscription) => subscription.status === 'INVITED' && subscription.fname?.includes(channelName), - ); - - expect(invitedSubscription).toBeUndefined(); - }); - it('should fail when RC user tries to accept the revoked invitation', async () => { const acceptResponse = await acceptRoomInvite(rid, rc1AdminRequestConfig); expect(acceptResponse.success).toBe(false); }); + + it('should allow RC user to reject the revoked invitation', async () => { + const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); + expect(rejectResponse.success).toBe(true); + }); + + 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); + expect(member?.membership).toBe('leave'); + }); }); }); }); From a755c2b506795960748edbf5daa36590f77ecabb Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Fri, 12 Dec 2025 17:55:24 -0300 Subject: [PATCH 3/5] add validation to sub --- ee/packages/federation-matrix/tests/end-to-end/room.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) 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 5f1e5dcd2058e..5d51def100848 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 @@ -1699,6 +1699,10 @@ import { SynapseClient } from '../helper/synapse-client'; it('should allow RC user to reject the revoked invitation', async () => { const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); expect(rejectResponse.success).toBe(true); + + const subscriptions = await getSubscriptions(rc1AdminRequestConfig); + const invitedSub = subscriptions.update.find((sub) => sub.fname?.includes(channelName)); + expect(invitedSub).toBeFalsy(); }); it('should have the RC user with leave membership on Synapse side after revoked invitation', async () => { From 24dcae96fa22fc2e8b9daec0a482255a32388a5e Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Fri, 12 Dec 2025 18:11:03 -0300 Subject: [PATCH 4/5] improve tests naming --- .../federation-matrix/tests/end-to-end/room.spec.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) 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 5d51def100848..0d42e8211bf5d 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 @@ -1647,16 +1647,12 @@ import { SynapseClient } from '../helper/synapse-client'; rid = pendingInvitation?.rid!; }, 15000); - it('It should allow RC user to reject the invite', async () => { + it('should allow RC user to reject the invite and remove the subscription', async () => { const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); expect(rejectResponse.success).toBe(true); - }); - it('It should remove the subscription after rejection', async () => { const subscriptions = await getSubscriptions(rc1AdminRequestConfig); - const invitedSub = subscriptions.update.find((sub) => sub.fname?.includes(channelName)); - expect(invitedSub).toBeFalsy(); }); }); @@ -1696,7 +1692,7 @@ import { SynapseClient } from '../helper/synapse-client'; expect(acceptResponse.success).toBe(false); }); - it('should allow RC user to reject the revoked invitation', async () => { + it('should allow RC user to reject the revoked invitation and remove the subscription', async () => { const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); expect(rejectResponse.success).toBe(true); From 290f388c36f2cfc05582dfa874df90e499196649 Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Fri, 12 Dec 2025 19:18:50 -0300 Subject: [PATCH 5/5] remove delay --- ee/packages/federation-matrix/tests/end-to-end/room.spec.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 0d42e8211bf5d..8a76d7ef1a4e4 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 @@ -1682,10 +1682,7 @@ import { SynapseClient } from '../helper/synapse-client'; // hs1 revokes the invitation by kicking the invited user await hs1AdminApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Invitation revoked'); - - // Wait for the revocation to propagate - await new Promise((resolve) => setTimeout(resolve, 2000)); - }, 20000); + }, 15000); it('should fail when RC user tries to accept the revoked invitation', async () => { const acceptResponse = await acceptRoomInvite(rid, rc1AdminRequestConfig);