import type { IRoom, IUser, ValueOf } from '@rocket.chat/core-typings'; import { isRoomFederated, isDirectMessageRoom } from '@rocket.chat/core-typings'; import { Subscriptions } from '@rocket.chat/models'; import { escapeExternalFederationEventId, unescapeExternalFederationEventId, } from './infrastructure/rocket-chat/adapters/federation-id-escape-helper'; import { RoomMemberActions, RoomSettingsEnum } from '../../../definition/IRoomTypeConfig'; const allowedActionsInFederatedRooms: ValueOf[] = [ RoomMemberActions.REMOVE_USER, RoomMemberActions.SET_AS_OWNER, RoomMemberActions.SET_AS_MODERATOR, RoomMemberActions.INVITE, RoomMemberActions.JOIN, RoomMemberActions.LEAVE, ]; const allowedActionsForModerators = allowedActionsInFederatedRooms.filter((action) => action !== RoomMemberActions.SET_AS_OWNER); const allowedRoomSettingsChangesInFederatedRooms: ValueOf[] = [RoomSettingsEnum.NAME, RoomSettingsEnum.TOPIC]; export class Federation { public static async actionAllowed(room: IRoom, action: ValueOf, userId?: IUser['_id']): Promise { if (!isRoomFederated(room)) { return false; } if (isDirectMessageRoom(room)) { return false; } if (!userId) { return true; } const userSubscription = await Subscriptions.findOneByRoomIdAndUserId(room._id, userId); if (!userSubscription) { return true; } if (action === RoomMemberActions.LEAVE) { return true; } if (userSubscription.roles?.includes('owner')) { return allowedActionsInFederatedRooms.includes(action); } if (userSubscription.roles?.includes('moderator')) { return allowedActionsForModerators.includes(action); } return false; } public static isAFederatedUsername(username: string): boolean { return username.includes('@') && username.includes(':'); } public static escapeExternalFederationEventId(externalEventId: string): string { return escapeExternalFederationEventId(externalEventId); } public static unescapeExternalFederationEventId(externalEventId: string): string { return unescapeExternalFederationEventId(externalEventId); } public static isRoomSettingAllowed(room: Partial, setting: ValueOf): boolean { if (!isRoomFederated(room)) { return false; } if (isDirectMessageRoom(room)) { return false; } return allowedRoomSettingsChangesInFederatedRooms.includes(setting); } }