Skip to content

Commit caa3005

Browse files
dhulkeggazzo
andauthored
fix: prioritizes federation not allowed error message over user not f… (#37364)
Co-authored-by: Guilherme Gazzo <guilherme@gazzo.xyz>
1 parent a05b8f7 commit caa3005

File tree

4 files changed

+52
-10
lines changed

4 files changed

+52
-10
lines changed

apps/meteor/app/lib/server/functions/createRoom.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ export const createRoom = async <T extends RoomType>(
143143
return member.username?.includes(':') && member.username?.includes('@');
144144
});
145145

146+
// Prevent adding federated users to rooms that are not marked as federated explicitly
147+
if (hasFederatedMembers && optionalExtraData.federated !== true) {
148+
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
149+
method: 'createRoom',
150+
});
151+
}
152+
146153
const extraData = {
147154
...optionalExtraData,
148155
...((hasFederatedMembers || optionalExtraData.federated) && {

apps/meteor/app/lib/server/methods/addUsersToRoom.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { api } from '@rocket.chat/core-services';
22
import type { IUser } from '@rocket.chat/core-typings';
3-
import { isRoomNativeFederated, isUserNativeFederated } from '@rocket.chat/core-typings';
3+
import { isRoomNativeFederated } from '@rocket.chat/core-typings';
44
import type { ServerMethods } from '@rocket.chat/ddp-client';
5+
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
56
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
67
import { Match } from 'meteor/check';
78
import { Meteor } from 'meteor/meteor';
@@ -88,15 +89,18 @@ export const addUsersToRoomMethod = async (userId: string, data: { rid: string;
8889

8990
await Promise.all(
9091
data.users.map(async (username) => {
91-
const newUser = await Users.findOneByUsernameIgnoringCase(sanitizeUsername(username));
92-
if (!newUser) {
93-
throw new Meteor.Error('error-user-not-found', 'User not found', {
92+
const sanitizedUsername = sanitizeUsername(username);
93+
94+
// If it's a federated username format and the room is not federated, throw error immediately
95+
if (validateFederatedUsername(sanitizedUsername) && !isRoomNativeFederated(room)) {
96+
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
9497
method: 'addUsersToRoom',
9598
});
9699
}
97100

98-
if (isUserNativeFederated(newUser) && !isRoomNativeFederated(room)) {
99-
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
101+
const newUser = await Users.findOneByUsernameIgnoringCase(sanitizedUsername);
102+
if (!newUser) {
103+
throw new Meteor.Error('error-user-not-found', 'User not found', {
100104
method: 'addUsersToRoom',
101105
});
102106
}

apps/meteor/app/slashcommands-invite/server/server.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { api } from '@rocket.chat/core-services';
1+
import { api, FederationMatrix } from '@rocket.chat/core-services';
22
import type { IUser, SlashCommandCallbackParams } from '@rocket.chat/core-typings';
3-
import { Subscriptions, Users } from '@rocket.chat/models';
3+
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
4+
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
45
import { Meteor } from 'meteor/meteor';
56

67
import { i18n } from '../../../server/lib/i18n';
8+
import { FederationActions } from '../../../server/services/room/hooks/BeforeFederationActions';
79
import { addUsersToRoomMethod, sanitizeUsername } from '../../lib/server/methods/addUsersToRoom';
810
import { settings } from '../../settings/server';
911
import { slashCommands } from '../../utils/server/slashCommand';
@@ -15,13 +17,42 @@ import { slashCommands } from '../../utils/server/slashCommand';
1517
slashCommands.add({
1618
command: 'invite',
1719
callback: async ({ params, message, userId }: SlashCommandCallbackParams<'invite'>): Promise<void> => {
18-
const usernames = params
20+
let usernames = params
1921
.split(/[\s,]/)
2022
.map((username) => sanitizeUsername(username))
2123
.filter((a) => a !== '');
2224
if (usernames.length === 0) {
2325
return;
2426
}
27+
28+
// Get room information for federation check
29+
const room = await Rooms.findOneById(message.rid);
30+
if (!room) {
31+
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
32+
msg: i18n.t('error-invalid-room', { lng: settings.get('Language') || 'en' }),
33+
});
34+
return;
35+
}
36+
37+
// Ensure federated users exist locally before looking them up
38+
const federatedUsernames = usernames.filter((u) => validateFederatedUsername(u)) as string[];
39+
if (federatedUsernames.length > 0) {
40+
if (FederationActions.shouldPerformFederationAction(room)) {
41+
await FederationMatrix.ensureFederatedUsersExistLocally(federatedUsernames);
42+
} else {
43+
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
44+
msg: i18n.t('You_cannot_add_external_users_to_non_federated_room', { lng: settings.get('Language') || 'en' }),
45+
});
46+
// These federated users shouldn't be invited and we already broadcasted the error message
47+
usernames = usernames.filter((username) => {
48+
return !federatedUsernames.includes(username);
49+
});
50+
if (usernames.length === 0) {
51+
return;
52+
}
53+
}
54+
}
55+
2556
const users = await Users.findByUsernames(usernames).toArray();
2657
if (users.length === 0) {
2758
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'reflect-metadata';
22

3-
export { FederationMatrix } from './FederationMatrix';
3+
export { FederationMatrix, validateFederatedUsername } from './FederationMatrix';
44

55
export { generateEd25519RandomSecretKey } from '@rocket.chat/federation-sdk';
66

0 commit comments

Comments
 (0)