Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions apps/meteor/app/lib/server/functions/createRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AppEvents, Apps } from '@rocket.chat/apps';
import { AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions';
import { FederationMatrix, Message, Room, Team } from '@rocket.chat/core-services';
import type { ICreateRoomParams, ISubscriptionExtraData } from '@rocket.chat/core-services';
import type { ICreatedRoom, IUser, IRoom, RoomType } from '@rocket.chat/core-typings';
import { type ICreatedRoom, type IUser, type IRoom, type RoomType, isUserNativeFederated } from '@rocket.chat/core-typings';
import { Rooms, Subscriptions, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

Expand Down Expand Up @@ -184,7 +184,12 @@ export const createRoom = async <T extends RoomType>(

const shouldBeHandledByFederation = extraData.federated === true;

if (shouldBeHandledByFederation && owner && !(await hasPermissionAsync(owner._id, 'access-federation'))) {
if (
shouldBeHandledByFederation &&
owner &&
!isUserNativeFederated(owner) &&
!(await hasPermissionAsync(owner._id, 'access-federation'))
) {
throw new Meteor.Error('error-not-authorized-federation', 'Not authorized to access federation', {
method: 'createRoom',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const getRoomByNameOrIdWithOptionToJoin = async ({
joinChannel = true,
errorOnEmpty = true,
}: {
user: Pick<IUser, '_id' | 'username'>;
user: Pick<IUser, '_id' | 'username' | 'federated' | 'federation'>;
nameOrId: string;
type?: RoomType;
tryDirectByUserIdOnly?: boolean;
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/app/lib/server/methods/joinRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Meteor.methods<ServerMethods>({
async joinRoom(rid, code) {
check(rid, String);

const userId = await Meteor.userId();
if (!userId) {
const user = await Meteor.userAsync();
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'joinRoom' });
}

Expand All @@ -26,6 +26,6 @@ Meteor.methods<ServerMethods>({
throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'joinRoom' });
}

return Room.join({ room, user: { _id: userId }, ...(code ? { joinCode: code } : {}) });
return Room.join({ room, user, ...(code ? { joinCode: code } : {}) });
},
});
10 changes: 8 additions & 2 deletions apps/meteor/app/slashcommands-join/server/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { api, Room } from '@rocket.chat/core-services';
import type { SlashCommandCallbackParams } from '@rocket.chat/core-typings';
import { Rooms, Subscriptions } from '@rocket.chat/models';
import { Rooms, Subscriptions, Users } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { i18n } from '../../../server/lib/i18n';
Expand Down Expand Up @@ -43,7 +43,13 @@ slashCommands.add({
});
}

await Room.join({ room, user: { _id: userId } });
const user = await Users.findOneById(userId, { projection: { federated: 1, federation: 1 } });
if (!user) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'slashCommands',
});
}
await Room.join({ room, user });
},
options: {
description: 'Join_the_given_channel',
Expand Down
3 changes: 1 addition & 2 deletions apps/meteor/ee/server/hooks/federation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ beforeAddUserToRoom.add(
return;
}

// TODO should we really check for "user" here? it is potentially an external user
if (!(await Authorization.hasPermission(user._id, 'access-federation'))) {
if (!isUserNativeFederated(user) && !(await Authorization.hasPermission(user._id, 'access-federation'))) {
throw new MeteorError('error-not-authorized-federation', 'Not authorized to access federation');
}

Expand Down
9 changes: 7 additions & 2 deletions apps/meteor/server/services/room/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
isOmnichannelRoom,
isRoomWithJoinCode,
} from '@rocket.chat/core-typings';
import { isUserNativeFederated } from '@rocket.chat/core-typings';
import { Rooms, Subscriptions, Users } from '@rocket.chat/models';

import { getNameForDMs } from './getNameForDMs';
Expand Down Expand Up @@ -148,7 +149,7 @@ export class RoomService extends ServiceClassInternal implements IRoomService {
/**
* Method called by users to join a room.
*/
async join({ room, user, joinCode }: { room: IRoom; user: Pick<IUser, '_id'>; joinCode?: string }) {
async join({ room, user, joinCode }: { room: IRoom; user: Pick<IUser, '_id' | 'federated' | 'federation'>; joinCode?: string }) {
if (!(await roomCoordinator.getRoomDirectives(room.t)?.allowMemberAction(room, RoomMemberActions.JOIN, user._id))) {
throw new MeteorError('error-not-allowed', 'Not allowed', { method: 'joinRoom' });
}
Expand All @@ -161,7 +162,11 @@ export class RoomService extends ServiceClassInternal implements IRoomService {
throw new MeteorError('error-not-allowed', 'Not allowed', { method: 'joinRoom' });
}

if (FederationActions.shouldPerformFederationAction(room) && !(await Authorization.hasPermission(user._id, 'access-federation'))) {
if (
FederationActions.shouldPerformFederationAction(room) &&
!isUserNativeFederated(user) &&
!(await Authorization.hasPermission(user._id, 'access-federation'))
) {
throw new MeteorError('error-not-authorized-federation', 'Not authorized to access federation', { method: 'joinRoom' });
}

Expand Down
13 changes: 1 addition & 12 deletions ee/packages/federation-matrix/tests/end-to-end/dms.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,7 @@ import { IS_EE } from '../../../../../apps/meteor/tests/e2e/config/constants';
import { retry } from '../../../../../apps/meteor/tests/end-to-end/api/helpers/retry';
import { federationConfig } from '../helper/config';
import { SynapseClient } from '../helper/synapse-client';

function withTimeout<T>(fn: (signal: AbortSignal) => Promise<T>, ms: number): Promise<T> {
const controller = new AbortController();

const timeoutId = setTimeout(() => {
controller.abort();
}, ms);

return fn(controller.signal).finally(() => {
clearTimeout(timeoutId);
});
}
import { withTimeout } from '../helper/withTimeout';

const waitForRoomEvent = async (
room: Room,
Expand Down
Loading
Loading