Skip to content

Commit d85b39a

Browse files
sampaiodiegocubic-dev-ai[bot]
authored andcommitted
regression(federation): fix mixed DM invite not working (RocketChat#37924)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent 44351f5 commit d85b39a

File tree

7 files changed

+70
-56
lines changed

7 files changed

+70
-56
lines changed

apps/meteor/server/services/room/service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { removeRoomOwner } from '../../methods/removeRoomOwner';
3636
export class RoomService extends ServiceClassInternal implements IRoomService {
3737
protected name = 'room';
3838

39-
async updateDirectMessageRoomName(room: IRoom): Promise<boolean> {
39+
async updateDirectMessageRoomName(room: IRoom, ignoreStatusFromSubs?: string[]): Promise<boolean> {
4040
const subs = await Subscriptions.findByRoomId(room._id, { projection: { u: 1, status: 1 } }).toArray();
4141

4242
const uids = subs.map((sub) => sub.u._id);
@@ -47,7 +47,7 @@ export class RoomService extends ServiceClassInternal implements IRoomService {
4747

4848
for await (const sub of subs) {
4949
// don't update the name if the user is invited but hasn't accepted yet
50-
if (sub.status === 'INVITED') {
50+
if (!ignoreStatusFromSubs?.includes(sub._id) && sub.status === 'INVITED') {
5151
continue;
5252
}
5353
await Subscriptions.updateOne({ _id: sub._id }, { $set: roomNames[sub.u._id] });

ee/packages/federation-matrix/src/FederationMatrix.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,9 @@ export class FederationMatrix extends ServiceClass implements IFederationMatrixS
291291
continue;
292292
}
293293

294-
if (!isUserNativeFederated(member)) {
295-
continue;
296-
}
297-
298294
try {
299295
await federationSDK.inviteUserToRoom(
300-
userIdSchema.parse(member.username),
296+
isUserNativeFederated(member) ? userIdSchema.parse(member.username) : `@${member.username}:${this.serverName}`,
301297
roomIdSchema.parse(matrixRoomResult.room_id),
302298
userIdSchema.parse(actualMatrixUserId),
303299
);
@@ -919,8 +915,6 @@ export class FederationMatrix extends ServiceClass implements IFederationMatrixS
919915

920916
if (action === 'accept') {
921917
await federationSDK.acceptInvite(room.federation.mrid, matrixUserId);
922-
923-
await Room.performAcceptRoomInvite(room, subscription, user);
924918
}
925919

926920
if (action === 'reject') {

ee/packages/federation-matrix/src/events/member.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ async function handleJoin({
215215

216216
// update room name for DMs
217217
if (room.t === 'd') {
218-
await Room.updateDirectMessageRoomName(room);
218+
await Room.updateDirectMessageRoomName(room, [subscription._id]);
219219
}
220220

221221
if (!subscription.status) {

ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,7 +1097,7 @@ const waitForRoomEvent = async (
10971097
});
10981098
});
10991099

1100-
it.failing('should accept the invitation by the Rocket.Chat user', async () => {
1100+
it('should accept the invitation by the Rocket.Chat user', async () => {
11011101
const response = await acceptRoomInvite(rcRoom._id, rcUserConfig2);
11021102
expect(response.success).toBe(true);
11031103
});
@@ -1204,22 +1204,7 @@ const waitForRoomEvent = async (
12041204
});
12051205

12061206
beforeAll(async () => {
1207-
// Create non-federated DM between rcUser1 and rcUser2
1208-
const nonFedDmResponse = await rcUser1.config.request
1209-
.post(api('dm.create'))
1210-
.set(rcUser1.config.credentials)
1211-
.send({
1212-
username: rcUser2.username,
1213-
})
1214-
.expect(200);
1215-
1216-
expect(nonFedDmResponse.body).toHaveProperty('success', true);
1217-
1218-
const roomInfoNonFed = await getRoomInfo(nonFedDmResponse.body.room._id, rcUser1.config);
1219-
1220-
rcRoomNonFed = roomInfoNonFed.room as IRoomNativeFederated;
1221-
1222-
// Create federated DM between rcUser1 and rcUser2 and the Synapse user
1207+
// First create a federated DM between rcUser1 and rcUser2 and the Synapse user, so this is the oldest room
12231208
const fedDmResponse = await rcUser1.config.request
12241209
.post(api('dm.create'))
12251210
.set(rcUser1.config.credentials)
@@ -1260,6 +1245,21 @@ const waitForRoomEvent = async (
12601245
// After acceptance, should display the Synapse user's ID
12611246
expect(sub).toHaveProperty('fname', `${federationConfig.hs1.adminMatrixUserId}, ${rcUser1.fullName}`);
12621247
});
1248+
1249+
// Then create non-federated DM between rcUser1 and rcUser2 which should be returned on duplication
1250+
const nonFedDmResponse = await rcUser1.config.request
1251+
.post(api('dm.create'))
1252+
.set(rcUser1.config.credentials)
1253+
.send({
1254+
username: rcUser2.username,
1255+
})
1256+
.expect(200);
1257+
1258+
expect(nonFedDmResponse.body).toHaveProperty('success', true);
1259+
1260+
const roomInfoNonFed = await getRoomInfo(nonFedDmResponse.body.room._id, rcUser1.config);
1261+
1262+
rcRoomNonFed = roomInfoNonFed.room as IRoomNativeFederated;
12631263
});
12641264

12651265
it('should have two DMs with same users', async () => {
@@ -1322,9 +1322,6 @@ const waitForRoomEvent = async (
13221322

13231323
expect(response.body).toHaveProperty('success', true);
13241324

1325-
// expect(response.body).toHaveProperty('room._id', rcRoom._id);
1326-
1327-
// TODO this is currently wrong, the correct value should be rcRoom._id
13281325
expect(response.body).toHaveProperty('room._id', rcRoomNonFed._id);
13291326
});
13301327
});
@@ -1435,7 +1432,7 @@ const waitForRoomEvent = async (
14351432
});
14361433
});
14371434

1438-
it.failing('should create a federated DM between rcUser1 and rcUser2 and the Synapse user', async () => {
1435+
it('should create a federated DM between rcUser1 and rcUser2 and the Synapse user', async () => {
14391436
const fedDmResponse = await rcUser1.config.request
14401437
.post(api('dm.create'))
14411438
.set(rcUser1.config.credentials)
@@ -1486,13 +1483,21 @@ const waitForRoomEvent = async (
14861483
{ delayMs: 100 },
14871484
);
14881485

1489-
// TODO accept not working
14901486
const response = await acceptRoomInvite(rcRoom._id, rcUser2.config);
14911487
expect(response.success).toBe(true);
1488+
1489+
await retry(
1490+
'wait for the join to be processed',
1491+
async () => {
1492+
const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser2.config.credentials, rcUser2.config.request);
1493+
1494+
expect(sub).not.toHaveProperty('status');
1495+
},
1496+
{ delayMs: 100 },
1497+
);
14921498
});
14931499

1494-
// TODO this is failing because we cannot accept the invite properly on the line above
1495-
it.failing('should have two DMs with same users', async () => {
1500+
it('should have a single DM with same users before one leaves', async () => {
14961501
const roomsResponse = await rcUser1.config.request.get(api('rooms.get')).set(rcUser1.config.credentials).expect(200);
14971502

14981503
const dmRooms = roomsResponse.body.update.filter(
@@ -1506,7 +1511,9 @@ const waitForRoomEvent = async (
15061511

15071512
// at this time there should be only one DM with only two users (the non-federated one)
15081513
expect(dmRooms.length).toBe(1);
1514+
});
15091515

1516+
it('should leave the federated DM with three users', async () => {
15101517
// now the rc user leaves the federated DM
15111518
const response = await rcUser2.config.request
15121519
.post(api('rooms.leave'))
@@ -1518,19 +1525,21 @@ const waitForRoomEvent = async (
15181525

15191526
expect(response.body).toHaveProperty('success', true);
15201527

1521-
await retry(
1522-
'wait for the leave to be processed',
1523-
async () => {
1524-
expect(hs1Room1.getMyMembership()).toBe('leave');
1528+
// Verify room is no longer accessible to RC users
1529+
await retry('waiting for room cleanup', async () => {
1530+
const roomsResponse = await rcUser2.config.request.get(api('rooms.get')).set(rcUser2.config.credentials).expect(200);
15251531

1526-
const sub = await getSubscriptionByRoomId(rcRoom._id, rcUser1.config.credentials, rcUser1.config.request);
1532+
expect(roomsResponse.body).toHaveProperty('update');
1533+
expect(roomsResponse.body.update).toBeInstanceOf(Array);
15271534

1528-
// After leave, should display only the RC user's full name
1529-
expect(sub).toHaveProperty('fname', rcUser2.fullName);
1530-
},
1531-
{ delayMs: 100 },
1532-
);
1535+
const room = roomsResponse.body.update?.find((r: IRoom) => r._id === rcRoom._id);
1536+
1537+
// Room should not be in active rooms list
1538+
expect(room).toBeUndefined();
1539+
});
1540+
});
15331541

1542+
it('should have two DMs with same users', async () => {
15341543
// now there should be two DMs with the same users
15351544
const roomsResponseAfterLeave = await rcUser1.config.request
15361545
.get(api('rooms.get'))
@@ -1560,9 +1569,6 @@ const waitForRoomEvent = async (
15601569

15611570
expect(response.body).toHaveProperty('success', true);
15621571

1563-
// expect(response.body).toHaveProperty('room._id', rcRoom._id);
1564-
1565-
// TODO this is currently wrong, the correct value should be rcRoom._id
15661572
expect(response.body).toHaveProperty('room._id', rcRoom1on1._id);
15671573
});
15681574
});

ee/packages/federation-matrix/tests/end-to-end/room.spec.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '../../../../../apps/meteor/tests/data/rooms.helper';
1515
import { type IRequestConfig, getRequestConfig, createUser, deleteUser } from '../../../../../apps/meteor/tests/data/users.helper';
1616
import { IS_EE } from '../../../../../apps/meteor/tests/e2e/config/constants';
17+
import { retry } from '../../../../../apps/meteor/tests/end-to-end/api/helpers/retry';
1718
import { federationConfig } from '../helper/config';
1819
import { createDDPListener } from '../helper/ddp-listener';
1920
import { SynapseClient } from '../helper/synapse-client';
@@ -1612,13 +1613,20 @@ import { SynapseClient } from '../helper/synapse-client';
16121613

16131614
describe('It should reflect all the members and messagens on the rocket.chat side', () => {
16141615
it('It should show all the three users in the members list', async () => {
1615-
const members = await getRoomMembers(rid, rc1AdminRequestConfig);
1616-
expect(members.members.length).toBe(3);
1617-
expect(members.members.find((member: IUser) => member.username === federationConfig.rc1.adminUser)).not.toBeNull();
1618-
expect(
1619-
members.members.find((member: IUser) => member.username === federationConfig.rc1.additionalUser1.username),
1620-
).not.toBeNull();
1621-
expect(members.members.find((member: IUser) => member.username === federationConfig.hs1.adminMatrixUserId)).not.toBeNull();
1616+
await retry(
1617+
'Getting room members until all are present',
1618+
async () => {
1619+
const members = await getRoomMembers(rid, rc1AdminRequestConfig);
1620+
1621+
expect(members.members.length).toBe(3);
1622+
expect(members.members.find((member: IUser) => member.username === federationConfig.rc1.adminUser)).not.toBeNull();
1623+
expect(
1624+
members.members.find((member: IUser) => member.username === federationConfig.rc1.additionalUser1.username),
1625+
).not.toBeNull();
1626+
expect(members.members.find((member: IUser) => member.username === federationConfig.hs1.adminMatrixUserId)).not.toBeNull();
1627+
},
1628+
{ delayMs: 200 },
1629+
);
16221630
});
16231631
});
16241632
});

packages/core-services/src/types/IRoomService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,5 @@ export interface IRoomService {
6969
status?: 'INVITED';
7070
roles?: ISubscription['roles'];
7171
}): Promise<string | undefined>;
72-
updateDirectMessageRoomName(room: IRoom): Promise<boolean>;
72+
updateDirectMessageRoomName(room: IRoom, ignoreStatusFromSubs?: string[]): Promise<boolean>;
7373
}

packages/models/src/models/Rooms.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,13 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
897897
uids: { $size: uid.length, $all: uid },
898898
};
899899

900-
return this.findOne<IRoom>(query, options);
900+
return this.findOne<IRoom>(query, {
901+
...options,
902+
sort: {
903+
federated: 1,
904+
ts: 1,
905+
},
906+
});
901907
}
902908

903909
findFederatedRooms(options: FindOptions<IRoom> = {}): FindCursor<IRoomFederated> {

0 commit comments

Comments
 (0)