fix: prioritizes federation not allowed error message over user not f… (#37364)

Co-authored-by: Guilherme Gazzo <guilherme@gazzo.xyz>
This commit is contained in:
Danilo Morães 2025-11-10 17:31:58 -03:00 committed by GitHub
parent a05b8f72ca
commit caa3005c79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 52 additions and 10 deletions

View File

@ -143,6 +143,13 @@ export const createRoom = async <T extends RoomType>(
return member.username?.includes(':') && member.username?.includes('@');
});
// Prevent adding federated users to rooms that are not marked as federated explicitly
if (hasFederatedMembers && optionalExtraData.federated !== true) {
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
method: 'createRoom',
});
}
const extraData = {
...optionalExtraData,
...((hasFederatedMembers || optionalExtraData.federated) && {

View File

@ -1,7 +1,8 @@
import { api } from '@rocket.chat/core-services';
import type { IUser } from '@rocket.chat/core-typings';
import { isRoomNativeFederated, isUserNativeFederated } from '@rocket.chat/core-typings';
import { isRoomNativeFederated } from '@rocket.chat/core-typings';
import type { ServerMethods } from '@rocket.chat/ddp-client';
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { Match } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
@ -88,15 +89,18 @@ export const addUsersToRoomMethod = async (userId: string, data: { rid: string;
await Promise.all(
data.users.map(async (username) => {
const newUser = await Users.findOneByUsernameIgnoringCase(sanitizeUsername(username));
if (!newUser) {
throw new Meteor.Error('error-user-not-found', 'User not found', {
const sanitizedUsername = sanitizeUsername(username);
// If it's a federated username format and the room is not federated, throw error immediately
if (validateFederatedUsername(sanitizedUsername) && !isRoomNativeFederated(room)) {
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
method: 'addUsersToRoom',
});
}
if (isUserNativeFederated(newUser) && !isRoomNativeFederated(room)) {
throw new Meteor.Error('error-federated-users-in-non-federated-rooms', 'Cannot add federated users to non-federated rooms', {
const newUser = await Users.findOneByUsernameIgnoringCase(sanitizedUsername);
if (!newUser) {
throw new Meteor.Error('error-user-not-found', 'User not found', {
method: 'addUsersToRoom',
});
}

View File

@ -1,9 +1,11 @@
import { api } from '@rocket.chat/core-services';
import { api, FederationMatrix } from '@rocket.chat/core-services';
import type { IUser, SlashCommandCallbackParams } from '@rocket.chat/core-typings';
import { Subscriptions, Users } from '@rocket.chat/models';
import { validateFederatedUsername } from '@rocket.chat/federation-matrix';
import { Subscriptions, Users, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';
import { i18n } from '../../../server/lib/i18n';
import { FederationActions } from '../../../server/services/room/hooks/BeforeFederationActions';
import { addUsersToRoomMethod, sanitizeUsername } from '../../lib/server/methods/addUsersToRoom';
import { settings } from '../../settings/server';
import { slashCommands } from '../../utils/server/slashCommand';
@ -15,13 +17,42 @@ import { slashCommands } from '../../utils/server/slashCommand';
slashCommands.add({
command: 'invite',
callback: async ({ params, message, userId }: SlashCommandCallbackParams<'invite'>): Promise<void> => {
const usernames = params
let usernames = params
.split(/[\s,]/)
.map((username) => sanitizeUsername(username))
.filter((a) => a !== '');
if (usernames.length === 0) {
return;
}
// Get room information for federation check
const room = await Rooms.findOneById(message.rid);
if (!room) {
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
msg: i18n.t('error-invalid-room', { lng: settings.get('Language') || 'en' }),
});
return;
}
// Ensure federated users exist locally before looking them up
const federatedUsernames = usernames.filter((u) => validateFederatedUsername(u)) as string[];
if (federatedUsernames.length > 0) {
if (FederationActions.shouldPerformFederationAction(room)) {
await FederationMatrix.ensureFederatedUsersExistLocally(federatedUsernames);
} else {
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {
msg: i18n.t('You_cannot_add_external_users_to_non_federated_room', { lng: settings.get('Language') || 'en' }),
});
// These federated users shouldn't be invited and we already broadcasted the error message
usernames = usernames.filter((username) => {
return !federatedUsernames.includes(username);
});
if (usernames.length === 0) {
return;
}
}
}
const users = await Users.findByUsernames(usernames).toArray();
if (users.length === 0) {
void api.broadcast('notify.ephemeralMessage', userId, message.rid, {

View File

@ -1,6 +1,6 @@
import 'reflect-metadata';
export { FederationMatrix } from './FederationMatrix';
export { FederationMatrix, validateFederatedUsername } from './FederationMatrix';
export { generateEd25519RandomSecretKey } from '@rocket.chat/federation-sdk';