From f52cde9e3dc4ed652bf0f81351cbd7efb23b8b75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 May 2026 17:29:15 +0000 Subject: [PATCH 1/2] Initial plan From 2c54b3ce0b1e95b3ecfa57a2b5805cc5842a5ba4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 May 2026 17:41:27 +0000 Subject: [PATCH 2/2] refactor: swap method.call/addUsersToRoom for per-type REST endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the DDP method.call/addUsersToRoom helper with per-type REST endpoints: - type 'c' → POST /v1/channels.invite - type 'p' → POST /v1/groups.invite - type 'd' → fallback to method.call (no REST equivalent for DM invites) Update federation test assertions from DDP error shape (JSON.parse(body.message).error.error) to REST envelope (body.errorType), and success assertions from DDP result string to REST response shape (body.group). --- apps/meteor/tests/end-to-end/api/chat.ts | 2 +- .../tests/end-to-end/permissions.spec.ts | 48 ++++++++++--------- .../tests/end-to-end/room.spec.ts | 4 ++ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/apps/meteor/tests/end-to-end/api/chat.ts b/apps/meteor/tests/end-to-end/api/chat.ts index 7fe0a6309e5db..5c9baba456a4e 100644 --- a/apps/meteor/tests/end-to-end/api/chat.ts +++ b/apps/meteor/tests/end-to-end/api/chat.ts @@ -2583,7 +2583,7 @@ describe('[Chat]', () => { otherUser = await createUser({ username }); otherUserCredentials = await login(otherUser.username, password); parentThreadId = (await sendSimpleMessage({ roomId: testChannel._id })).body.message._id; - await addUserToRoom({ rid: testChannel._id, usernames: [otherUser.username] }); + await addUserToRoom({ rid: testChannel._id, usernames: [otherUser.username], type: 'c' }); }); after(() => Promise.all([deleteUser(otherUser), deleteMessage({ msgId: parentThreadId, roomId: testChannel._id })])); 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 fa5d91469321b..1bc6bdbc5225b 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 @@ -2,12 +2,7 @@ import type { IRoomNativeFederated, IUser } from '@rocket.chat/core-typings'; import type {} from '../../../../../apps/meteor/app/api/server/v1/permissions.ts'; import { api } from '../../../../../apps/meteor/tests/data/api-data'; -import { - addUserToRoomViaMethod, - createRoom, - getSubscriptionByRoomId, - getSubscriptions, -} from '../../../../../apps/meteor/tests/data/rooms.helper'; +import { addUserToRoom, createRoom, getSubscriptionByRoomId, getSubscriptions } from '../../../../../apps/meteor/tests/data/rooms.helper'; import { createUser, deleteUser, getRequestConfig } from '../../../../../apps/meteor/tests/data/users.helper'; import type { IRequestConfig, TestUser } from '../../../../../apps/meteor/tests/data/users.helper'; import { IS_EE } from '../../../../../apps/meteor/tests/e2e/config/constants'; @@ -185,28 +180,29 @@ import { SynapseClient } from '../helper/synapse-client'; await deleteUser(user, {}, rc1AdminRequestConfig); }); it('should not be able to add a user without access-federation permission to a room', async () => { - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [user.username], rid: createResponse.body.group._id, config: rc1AdminRequestConfig, + type: 'p', }); expect(addUserResponse.status).toBe(400); expect(addUserResponse.body).toHaveProperty('success', false); - expect(addUserResponse.body.message).toMatch(/error-not-authorized-federation/); + expect(addUserResponse.body).toHaveProperty('errorType', 'error-not-authorized-federation'); }); 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 addUserToRoomViaMethod({ + [addUserResponse] = await addUserToRoom({ usernames: [federationConfig.hs1.adminMatrixUserId], rid: createResponse.body.group._id, config: rc1AdminRequestConfig, + type: 'p', }); expect(addUserResponse.status).toBe(200); expect(addUserResponse.body).toHaveProperty('success', true); - expect(addUserResponse.body).toHaveProperty('message'); - expect(addUserResponse.body.message).toMatch('{"msg":"result","id":"id","result":true}'); + expect(addUserResponse.body).toHaveProperty('group'); }); }); }); @@ -270,15 +266,16 @@ import { SynapseClient } from '../helper/synapse-client'; config: rc1AdminRequestConfig, }).expect(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [user.username], rid: createResponse.body.group._id, config: rc1AdminRequestConfig, - }).expect(200); + type: 'p', + }); + expect(addUserResponse.status).toBe(200); expect(addUserResponse.body).toHaveProperty('success', true); - expect(addUserResponse.body).toHaveProperty('message'); - expect(addUserResponse.body.message).toMatch('{"msg":"result","id":"id","result":true}'); + expect(addUserResponse.body).toHaveProperty('group'); }); }); }); @@ -425,10 +422,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(createResponse.status).toBe(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [rcValidUser2.username], rid: createResponse.body.group._id, config: rcValidUser1.config, + type: 'p', }); expect(addUserResponse.status).toBe(200); @@ -520,15 +518,16 @@ import { SynapseClient } from '../helper/synapse-client'; expect(createResponse.status).toBe(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [userWithNonMatchingEmail.username], rid: createResponse.body.group._id, config: rcValidUser1.config, + type: 'p', }); expect(addUserResponse.status).toBe(400); expect(addUserResponse.body).toHaveProperty('success', false); - expect(addUserResponse.body.message).toMatch(/error-not-authorized-federation/); + expect(addUserResponse.body).toHaveProperty('errorType', 'error-not-authorized-federation'); }); it('should NOT be able to be added to a federated room during creation', async () => { @@ -602,15 +601,16 @@ import { SynapseClient } from '../helper/synapse-client'; expect(createResponse.status).toBe(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [userWithUnverifiedEmail.username], rid: createResponse.body.group._id, config: rcValidUser1.config, + type: 'p', }); expect(addUserResponse.status).toBe(400); expect(addUserResponse.body).toHaveProperty('success', false); - expect(addUserResponse.body.message).toMatch(/error-not-authorized-federation/); + expect(addUserResponse.body).toHaveProperty('errorType', 'error-not-authorized-federation'); }); }); @@ -666,15 +666,16 @@ import { SynapseClient } from '../helper/synapse-client'; expect(createResponse.status).toBe(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [userWithoutEmail.username], rid: createResponse.body.group._id, config: rcValidUser1.config, + type: 'p', }); expect(addUserResponse.status).toBe(400); expect(addUserResponse.body).toHaveProperty('success', false); - expect(addUserResponse.body.message).toMatch(/error-not-authorized-federation/); + expect(addUserResponse.body).toHaveProperty('errorType', 'error-not-authorized-federation'); }); }); @@ -875,10 +876,11 @@ import { SynapseClient } from '../helper/synapse-client'; expect(createResponse.status).toBe(200); - const addUserResponse = await addUserToRoomViaMethod({ + const [addUserResponse] = await addUserToRoom({ usernames: [userWithNonMatchingEmail.username], rid: createResponse.body.group._id, config: rc1AdminRequestConfig, + type: 'p', }); expect(addUserResponse.status).toBe(200); 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 ce0a764d04df7..d8018d245170c 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 @@ -234,6 +234,7 @@ import { SynapseClient } from '../helper/synapse-client'; rid: nonFederatedChannel._id, type: 'p', config: rc1AdminRequestConfig, + type: 'p', }); // The REST endpoint rejects the invite with the federation-specific error: the federated @@ -852,6 +853,7 @@ import { SynapseClient } from '../helper/synapse-client'; rid: federatedChannel._id, type: 'p', config: rc1AdminRequestConfig, + type: 'p', }); expect(addUserResponse.body).toHaveProperty('success', true); @@ -956,6 +958,7 @@ import { SynapseClient } from '../helper/synapse-client'; rid: federatedChannel._id, type: 'p', config: rc1AdminRequestConfig, + type: 'p', }); addUserResponse.forEach((response) => expect(response.body).toHaveProperty('success', true)); @@ -1093,6 +1096,7 @@ import { SynapseClient } from '../helper/synapse-client'; rid: federatedChannel._id, type: 'p', config: rc1AdminRequestConfig, + type: 'p', }); addUserResponse.forEach((response) => expect(response.body).toHaveProperty('success', true));