import type { IOmnichannelRoom, IRoom, RoomType } from '@rocket.chat/core-typings'; import type { ServerMethods } from '@rocket.chat/ddp-client'; import { Rooms } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; import { roomFields } from '../../../lib/publishFields'; import { canAccessRoomAsync } from '../../lib/authorization'; import { hasPermissionAsync } from '../../lib/authorization/hasPermission'; import { roomCoordinator } from '../../lib/rooms/roomCoordinator'; import { settings } from '../../settings'; type PublicRoomField = keyof typeof roomFields; type PublicRoom = Pick & Pick; declare module '@rocket.chat/ddp-client' { // eslint-disable-next-line @typescript-eslint/naming-convention interface ServerMethods { 'rooms/get'(updatedAt?: Date): IRoom[] | { update: IRoom[]; remove: IRoom[] }; 'getRoomByTypeAndName': (type: RoomType, name: string) => PublicRoom; } } const roomMap = (record: IRoom | IOmnichannelRoom) => { return _.pick(record, ...Object.keys(roomFields)) as PublicRoom; }; export const roomsGetMethod = async (userId?: string | null, updatedAt?: Date): Promise => { const options = { projection: roomFields }; if (!userId) { if (settings.get('Accounts_AllowAnonymousRead')) { return Rooms.findByDefaultAndTypes(true, ['c'], options).toArray(); } return []; } if (updatedAt instanceof Date) { return { update: await (await Rooms.findBySubscriptionUserIdUpdatedAfter(userId, updatedAt, options)).toArray(), remove: await Rooms.trashFindDeletedAfter(updatedAt, {}, { projection: { _id: 1, _deletedAt: 1 } }).toArray(), }; } return (await Rooms.findBySubscriptionUserId(userId, options)).toArray(); }; Meteor.methods({ async 'rooms/get'(updatedAt) { return roomsGetMethod(Meteor.userId(), updatedAt); }, async 'getRoomByTypeAndName'(type, name) { if (!type || !name) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getRoomByTypeAndName', }); } const user = await Meteor.userAsync(); const isAnonymous = !user?._id; if (isAnonymous) { const allowAnon = settings.get('Accounts_AllowAnonymousRead'); if (!allowAnon || type !== 'c') { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getRoomByTypeAndName', }); } } const roomFind = roomCoordinator.getRoomFind(type); const room = roomFind ? await roomFind.call(this, name, user?._id) : await Rooms.findByTypeAndNameOrId(type, name); if (!room) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getRoomByTypeAndName', }); } if ( user && !(await canAccessRoomAsync(room, user, { includeInvitations: true, })) ) { throw new Meteor.Error('error-no-permission', 'No permission', { method: 'getRoomByTypeAndName', }); } if (settings.get('Store_Last_Message') && user && !(await hasPermissionAsync(user, 'preview-c-room'))) { delete room.lastMessage; } return roomMap(room); }, });