From e7029e29dde95d56aaa38c33768b3f3d02ebd203 Mon Sep 17 00:00:00 2001 From: Marcos Defendi Date: Thu, 30 Jan 2025 10:34:32 -0300 Subject: [PATCH 1/3] refactor: remove method calls from chat endpoints (server) --- apps/meteor/app/api/server/v1/chat.ts | 21 ++- .../lib/server/methods/getSingleMessage.ts | 30 ++-- .../app/message-pin/server/pinMessage.ts | 168 +++++++++--------- .../app/message-star/server/starMessage.ts | 86 ++++----- .../threads/server/methods/followMessage.ts | 58 +++--- .../threads/server/methods/unfollowMessage.ts | 58 +++--- apps/meteor/server/methods/ignoreUser.ts | 63 ++++--- 7 files changed, 258 insertions(+), 226 deletions(-) diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index cef220b050bce..d69117c4dd25a 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -13,19 +13,24 @@ import { escapeRegExp } from '@rocket.chat/string-helpers'; import { Meteor } from 'meteor/meteor'; import { reportMessage } from '../../../../server/lib/moderation/reportMessage'; +import { ignoreUser } from '../../../../server/methods/ignoreUser'; import { roomAccessAttributes } from '../../../authorization/server'; import { canAccessRoomAsync, canAccessRoomIdAsync } from '../../../authorization/server/functions/canAccessRoom'; import { canSendMessageAsync } from '../../../authorization/server/functions/canSendMessage'; import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission'; import { deleteMessageValidatingPermission } from '../../../lib/server/functions/deleteMessage'; import { processWebhookMessage } from '../../../lib/server/functions/processWebhookMessage'; +import { getSingleMessage } from '../../../lib/server/methods/getSingleMessage'; import { executeSendMessage } from '../../../lib/server/methods/sendMessage'; import { executeUpdateMessage } from '../../../lib/server/methods/updateMessage'; import { applyAirGappedRestrictionsValidation } from '../../../license/server/airGappedRestrictionsWrapper'; -import { pinMessage } from '../../../message-pin/server/pinMessage'; +import { pinMessage, unpinMessage } from '../../../message-pin/server/pinMessage'; +import { starMessage } from '../../../message-star/server/starMessage'; import { OEmbed } from '../../../oembed/server/server'; import { executeSetReaction } from '../../../reactions/server/setReaction'; import { settings } from '../../../settings/server'; +import { followMessage } from '../../../threads/server/methods/followMessage'; +import { unfollowMessage } from '../../../threads/server/methods/unfollowMessage'; import { MessageTypes } from '../../../ui-utils/server'; import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; import { API } from '../api'; @@ -128,7 +133,7 @@ API.v1.addRoute( return API.v1.failure('The "msgId" query parameter must be provided.'); } - const msg = await Meteor.callAsync('getSingleMessage', this.queryParams.msgId); + const msg = await getSingleMessage(this.userId, this.queryParams.msgId); if (!msg) { return API.v1.failure(); @@ -274,7 +279,7 @@ API.v1.addRoute( throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); } - await Meteor.callAsync('starMessage', { + await starMessage(this.userId, { _id: msg._id, rid: msg.rid, starred: true, @@ -300,7 +305,7 @@ API.v1.addRoute( throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); } - await Meteor.callAsync('unpinMessage', msg); + await unpinMessage(this.userId, msg); return API.v1.success(); }, @@ -322,7 +327,7 @@ API.v1.addRoute( throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); } - await Meteor.callAsync('starMessage', { + await starMessage(this.userId, { _id: msg._id, rid: msg.rid, starred: false, @@ -442,7 +447,7 @@ API.v1.addRoute( throw new Meteor.Error('error-user-id-param-not-provided', 'The required "userId" param is missing.'); } - await Meteor.callAsync('ignoreUser', { rid, userId, ignore }); + await ignoreUser(this.userId, { rid, userId, ignore }); return API.v1.success(); }, @@ -719,7 +724,7 @@ API.v1.addRoute( throw new Meteor.Error('The required "mid" body param is missing.'); } - await Meteor.callAsync('followMessage', { mid }); + await followMessage(this.userId, { mid }); return API.v1.success(); }, @@ -737,7 +742,7 @@ API.v1.addRoute( throw new Meteor.Error('The required "mid" body param is missing.'); } - await Meteor.callAsync('unfollowMessage', { mid }); + await unfollowMessage(this.userId, { mid }); return API.v1.success(); }, diff --git a/apps/meteor/app/lib/server/methods/getSingleMessage.ts b/apps/meteor/app/lib/server/methods/getSingleMessage.ts index c4b6f065296b7..52801d47bc61a 100644 --- a/apps/meteor/app/lib/server/methods/getSingleMessage.ts +++ b/apps/meteor/app/lib/server/methods/getSingleMessage.ts @@ -13,26 +13,30 @@ declare module '@rocket.chat/ddp-client' { } } +export const getSingleMessage = async (userId: string, mid: IMessage['_id']): Promise => { + check(mid, String); + + const msg = await Messages.findOneById(mid); + + if (!msg?.rid) { + return null; + } + + if (!(await canAccessRoomIdAsync(msg.rid, userId))) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getSingleMessage' }); + } + + return msg; +}; + Meteor.methods({ async getSingleMessage(mid) { - check(mid, String); - const uid = Meteor.userId(); if (!uid) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getSingleMessage' }); } - const msg = await Messages.findOneById(mid); - - if (!msg?.rid) { - return null; - } - - if (!(await canAccessRoomIdAsync(msg.rid, uid))) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getSingleMessage' }); - } - - return msg; + return getSingleMessage(uid, mid); }, }); diff --git a/apps/meteor/app/message-pin/server/pinMessage.ts b/apps/meteor/app/message-pin/server/pinMessage.ts index f3622ff7bcadd..012c9bb2a23d8 100644 --- a/apps/meteor/app/message-pin/server/pinMessage.ts +++ b/apps/meteor/app/message-pin/server/pinMessage.ts @@ -43,7 +43,15 @@ declare module '@rocket.chat/ddp-client' { } } -export async function pinMessage(originalMessage: IMessage, userId: string, pinnedAt?: Date) { +export async function pinMessage(message: IMessage, userId: string, pinnedAt?: Date) { + let originalMessage = await Messages.findOneById(message._id); + if (!originalMessage?.rid) { + throw new Meteor.Error('error-invalid-message', 'Message you are pinning was not found', { + method: 'pinMessage', + action: 'Message_pinning', + }); + } + if (!settings.get('Message_AllowPinning')) { throw new Meteor.Error('error-action-not-allowed', 'Message pinning not allowed', { method: 'pinMessage', @@ -118,6 +126,81 @@ export async function pinMessage(originalMessage: IMessage, userId: string, pinn }); } +export const unpinMessage = async (userId: string, message: IMessage) => { + if (!settings.get('Message_AllowPinning')) { + throw new Meteor.Error('error-action-not-allowed', 'Message pinning not allowed', { + method: 'unpinMessage', + action: 'Message_pinning', + }); + } + + let originalMessage = await Messages.findOneById(message._id); + if (originalMessage == null || originalMessage._id == null) { + throw new Meteor.Error('error-invalid-message', 'Message you are unpinning was not found', { + method: 'unpinMessage', + action: 'Message_pinning', + }); + } + + const subscription = await Subscriptions.findOneByRoomIdAndUserId(originalMessage.rid, userId, { projection: { _id: 1 } }); + if (!subscription) { + // If it's a valid message but on a room that the user is not subscribed to, report that the message was not found. + throw new Meteor.Error('error-invalid-message', 'Message you are unpinning was not found', { + method: 'unpinMessage', + action: 'Message_pinning', + }); + } + + if (!(await hasPermissionAsync(userId, 'pin-message', originalMessage.rid))) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); + } + + const me = await Users.findOneById(userId); + if (!me) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unpinMessage' }); + } + + // If we keep history of edits, insert a new message to store history information + if (settings.get('Message_KeepHistory') && isRegisterUser(me)) { + await Messages.cloneAndSaveAsHistoryById(originalMessage._id, me); + } + + originalMessage.pinned = false; + originalMessage.pinnedBy = { + _id: userId, + username: me.username, + }; + + const room = await Rooms.findOneById(originalMessage.rid, { projection: { ...roomAccessAttributes, lastMessage: 1 } }); + if (!room) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); + } + + if (!(await canAccessRoomAsync(room, { _id: userId }))) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); + } + + originalMessage = await Message.beforeSave({ message: originalMessage, room, user: me }); + + if (isTheLastMessage(room, message)) { + await Rooms.setLastMessagePinned(room._id, originalMessage.pinnedBy, originalMessage.pinned); + void notifyOnRoomChangedById(room._id); + } + + // App IPostMessagePinned event hook + await Apps.self?.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); + + await Messages.setPinnedByIdAndUserId(originalMessage._id, originalMessage.pinnedBy, originalMessage.pinned); + if (settings.get('Message_Read_Receipt_Store_Users')) { + await ReadReceipts.setPinnedByMessageId(originalMessage._id, originalMessage.pinned); + } + void notifyOnMessageChange({ + id: message._id, + }); + + return true; +}; + Meteor.methods({ async pinMessage(message, pinnedAt) { check(message._id, String); @@ -129,15 +212,7 @@ Meteor.methods({ }); } - const originalMessage = await Messages.findOneById(message._id); - if (!originalMessage?.rid) { - throw new Meteor.Error('error-invalid-message', 'Message you are pinning was not found', { - method: 'pinMessage', - action: 'Message_pinning', - }); - } - - return pinMessage(originalMessage, userId, pinnedAt); + return pinMessage(message, userId, pinnedAt); }, async unpinMessage(message) { check(message._id, String); @@ -150,77 +225,6 @@ Meteor.methods({ }); } - if (!settings.get('Message_AllowPinning')) { - throw new Meteor.Error('error-action-not-allowed', 'Message pinning not allowed', { - method: 'unpinMessage', - action: 'Message_pinning', - }); - } - - let originalMessage = await Messages.findOneById(message._id); - if (originalMessage == null || originalMessage._id == null) { - throw new Meteor.Error('error-invalid-message', 'Message you are unpinning was not found', { - method: 'unpinMessage', - action: 'Message_pinning', - }); - } - - const subscription = await Subscriptions.findOneByRoomIdAndUserId(originalMessage.rid, userId, { projection: { _id: 1 } }); - if (!subscription) { - // If it's a valid message but on a room that the user is not subscribed to, report that the message was not found. - throw new Meteor.Error('error-invalid-message', 'Message you are unpinning was not found', { - method: 'unpinMessage', - action: 'Message_pinning', - }); - } - - if (!(await hasPermissionAsync(userId, 'pin-message', originalMessage.rid))) { - throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); - } - - const me = await Users.findOneById(userId); - if (!me) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unpinMessage' }); - } - - // If we keep history of edits, insert a new message to store history information - if (settings.get('Message_KeepHistory') && isRegisterUser(me)) { - await Messages.cloneAndSaveAsHistoryById(originalMessage._id, me); - } - - originalMessage.pinned = false; - originalMessage.pinnedBy = { - _id: userId, - username: me.username, - }; - - const room = await Rooms.findOneById(originalMessage.rid, { projection: { ...roomAccessAttributes, lastMessage: 1 } }); - if (!room) { - throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); - } - - if (!(await canAccessRoomAsync(room, { _id: userId }))) { - throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); - } - - originalMessage = await Message.beforeSave({ message: originalMessage, room, user: me }); - - if (isTheLastMessage(room, message)) { - await Rooms.setLastMessagePinned(room._id, originalMessage.pinnedBy, originalMessage.pinned); - void notifyOnRoomChangedById(room._id); - } - - // App IPostMessagePinned event hook - await Apps.self?.triggerEvent(AppEvents.IPostMessagePinned, originalMessage, await Meteor.userAsync(), originalMessage.pinned); - - await Messages.setPinnedByIdAndUserId(originalMessage._id, originalMessage.pinnedBy, originalMessage.pinned); - if (settings.get('Message_Read_Receipt_Store_Users')) { - await ReadReceipts.setPinnedByMessageId(originalMessage._id, originalMessage.pinned); - } - void notifyOnMessageChange({ - id: message._id, - }); - - return true; + return unpinMessage(userId, message); }, }); diff --git a/apps/meteor/app/message-star/server/starMessage.ts b/apps/meteor/app/message-star/server/starMessage.ts index 36c67c1f40206..96b342f8bfa69 100644 --- a/apps/meteor/app/message-star/server/starMessage.ts +++ b/apps/meteor/app/message-star/server/starMessage.ts @@ -12,60 +12,64 @@ import { settings } from '../../settings/server'; declare module '@rocket.chat/ddp-client' { // eslint-disable-next-line @typescript-eslint/naming-convention interface ServerMethods { - starMessage(message: Omit & { starred: boolean }): boolean; + starMessage(message: Pick & { starred: boolean }): boolean; } } -Meteor.methods({ - async starMessage(message) { - const uid = Meteor.userId(); +export const starMessage = async (userId: string, message: Pick & { starred: boolean }): Promise => { + if (!settings.get('Message_AllowStarring')) { + throw new Meteor.Error('error-action-not-allowed', 'Message starring not allowed', { + method: 'starMessage', + action: 'Message_starring', + }); + } - if (!uid) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'starMessage', - }); - } + const subscription = await Subscriptions.findOneByRoomIdAndUserId(message.rid, userId, { + projection: { _id: 1 }, + }); + if (!subscription) { + return false; + } + if (!(await Messages.findOneByRoomIdAndMessageId(message.rid, message._id))) { + return false; + } - if (!settings.get('Message_AllowStarring')) { - throw new Meteor.Error('error-action-not-allowed', 'Message starring not allowed', { - method: 'starMessage', - action: 'Message_starring', - }); - } + const room = await Rooms.findOneById(message.rid, { projection: { ...roomAccessAttributes, lastMessage: 1 } }); - const subscription = await Subscriptions.findOneByRoomIdAndUserId(message.rid, uid, { - projection: { _id: 1 }, - }); - if (!subscription) { - return false; - } - if (!(await Messages.findOneByRoomIdAndMessageId(message.rid, message._id))) { - return false; - } + if (!room) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'starMessage' }); + } - const room = await Rooms.findOneById(message.rid, { projection: { ...roomAccessAttributes, lastMessage: 1 } }); + if (!(await canAccessRoomAsync(room, { _id: userId }))) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'starMessage' }); + } - if (!room) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'starMessage' }); - } + if (isTheLastMessage(room, message)) { + await Rooms.updateLastMessageStar(room._id, userId, message.starred); + void notifyOnRoomChangedById(room._id); + } - if (!(await canAccessRoomAsync(room, { _id: uid }))) { - throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'starMessage' }); - } + await Apps.self?.triggerEvent(AppEvents.IPostMessageStarred, message, await Meteor.userAsync(), message.starred); - if (isTheLastMessage(room, message)) { - await Rooms.updateLastMessageStar(room._id, uid, message.starred); - void notifyOnRoomChangedById(room._id); - } + await Messages.updateUserStarById(message._id, userId, message.starred); - await Apps.self?.triggerEvent(AppEvents.IPostMessageStarred, message, await Meteor.userAsync(), message.starred); + void notifyOnMessageChange({ + id: message._id, + }); - await Messages.updateUserStarById(message._id, uid, message.starred); + return true; +}; - void notifyOnMessageChange({ - id: message._id, - }); +Meteor.methods({ + async starMessage(message) { + const uid = Meteor.userId(); + + if (!uid) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'starMessage', + }); + } - return true; + return starMessage(uid, message); }, }); diff --git a/apps/meteor/app/threads/server/methods/followMessage.ts b/apps/meteor/app/threads/server/methods/followMessage.ts index 8ed7093e00d4d..9fcee01fcbe48 100644 --- a/apps/meteor/app/threads/server/methods/followMessage.ts +++ b/apps/meteor/app/threads/server/methods/followMessage.ts @@ -18,42 +18,46 @@ declare module '@rocket.chat/ddp-client' { } } -Meteor.methods({ - async followMessage({ mid }) { - check(mid, String); +export const followMessage = async (userId: string, { mid }: { mid: IMessage['_id'] }): Promise => { + check(mid, String); - const uid = Meteor.userId(); - if (!uid) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'followMessage' }); - } + if (mid && !settings.get('Threads_enabled')) { + throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); + } - if (mid && !settings.get('Threads_enabled')) { - throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); - } + const message = await Messages.findOneById(mid); + if (!message) { + throw new Meteor.Error('error-invalid-message', 'Invalid message', { + method: 'followMessage', + }); + } - const message = await Messages.findOneById(mid); - if (!message) { - throw new Meteor.Error('error-invalid-message', 'Invalid message', { - method: 'followMessage', - }); - } + if (!(await canAccessRoomIdAsync(message.rid, userId))) { + throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); + } - if (!(await canAccessRoomIdAsync(message.rid, uid))) { - throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); - } + const id = message.tmid || message._id; - const id = message.tmid || message._id; + const followResult = await follow({ tmid: id, uid: userId }); - const followResult = await follow({ tmid: id, uid }); + void notifyOnMessageChange({ + id, + }); - void notifyOnMessageChange({ - id, - }); + const isFollowed = true; + await Apps.self?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); - const isFollowed = true; - await Apps.self?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); + return followResult; +}; + +Meteor.methods({ + async followMessage({ mid }) { + const uid = Meteor.userId(); + if (!uid) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'followMessage' }); + } - return followResult; + return followMessage(uid, { mid }); }, }); diff --git a/apps/meteor/app/threads/server/methods/unfollowMessage.ts b/apps/meteor/app/threads/server/methods/unfollowMessage.ts index de4f2683be41f..7d062991839c2 100644 --- a/apps/meteor/app/threads/server/methods/unfollowMessage.ts +++ b/apps/meteor/app/threads/server/methods/unfollowMessage.ts @@ -18,42 +18,46 @@ declare module '@rocket.chat/ddp-client' { } } -Meteor.methods({ - async unfollowMessage({ mid }) { - check(mid, String); +export const unfollowMessage = async (userId: string, { mid }: { mid: IMessage['_id'] }): Promise => { + check(mid, String); - const uid = Meteor.userId(); - if (!uid) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unfollowMessage' }); - } + if (mid && !settings.get('Threads_enabled')) { + throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); + } - if (mid && !settings.get('Threads_enabled')) { - throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); - } + const message = await Messages.findOneById(mid); + if (!message) { + throw new Meteor.Error('error-invalid-message', 'Invalid message', { + method: 'unfollowMessage', + }); + } - const message = await Messages.findOneById(mid); - if (!message) { - throw new Meteor.Error('error-invalid-message', 'Invalid message', { - method: 'unfollowMessage', - }); - } + if (!(await canAccessRoomIdAsync(message.rid, userId))) { + throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); + } - if (!(await canAccessRoomIdAsync(message.rid, uid))) { - throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); - } + const id = message.tmid || message._id; - const id = message.tmid || message._id; + const unfollowResult = await unfollow({ rid: message.rid, tmid: id, uid: userId }); - const unfollowResult = await unfollow({ rid: message.rid, tmid: id, uid }); + void notifyOnMessageChange({ + id, + }); - void notifyOnMessageChange({ - id, - }); + const isFollowed = false; + await Apps.self?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); - const isFollowed = false; - await Apps.self?.triggerEvent(AppEvents.IPostMessageFollowed, message, await Meteor.userAsync(), isFollowed); + return unfollowResult; +}; + +Meteor.methods({ + async unfollowMessage({ mid }) { + const uid = Meteor.userId(); + if (!uid) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unfollowMessage' }); + } - return unfollowResult; + return unfollowMessage(uid, { mid }); }, }); diff --git a/apps/meteor/server/methods/ignoreUser.ts b/apps/meteor/server/methods/ignoreUser.ts index a8739a910b37a..63708231ce0e5 100644 --- a/apps/meteor/server/methods/ignoreUser.ts +++ b/apps/meteor/server/methods/ignoreUser.ts @@ -12,12 +12,42 @@ declare module '@rocket.chat/ddp-client' { } } +export const ignoreUser = async ( + fromUserId: string, + { rid, userId: ignoredUser, ignore }: { rid: string; userId: string; ignore?: boolean }, +): Promise => { + check(ignoredUser, String); + check(rid, String); + check(ignore, Boolean); + + const [subscription, subscriptionIgnoredUser] = await Promise.all([ + Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId), + Subscriptions.findOneByRoomIdAndUserId(rid, ignoredUser), + ]); + + if (!subscription) { + throw new Meteor.Error('error-invalid-subscription', 'Invalid subscription', { + method: 'ignoreUser', + }); + } + + if (!subscriptionIgnoredUser) { + throw new Meteor.Error('error-invalid-subscription', 'Invalid subscription', { + method: 'ignoreUser', + }); + } + + const result = await Subscriptions.ignoreUser({ _id: subscription._id, ignoredUser, ignore }); + + if (result.modifiedCount) { + void notifyOnSubscriptionChangedById(subscription._id); + } + + return !!result; +}; + Meteor.methods({ async ignoreUser({ rid, userId: ignoredUser, ignore = true }) { - check(ignoredUser, String); - check(rid, String); - check(ignore, Boolean); - const userId = Meteor.userId(); if (!userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { @@ -25,29 +55,6 @@ Meteor.methods({ }); } - const [subscription, subscriptionIgnoredUser] = await Promise.all([ - Subscriptions.findOneByRoomIdAndUserId(rid, userId), - Subscriptions.findOneByRoomIdAndUserId(rid, ignoredUser), - ]); - - if (!subscription) { - throw new Meteor.Error('error-invalid-subscription', 'Invalid subscription', { - method: 'ignoreUser', - }); - } - - if (!subscriptionIgnoredUser) { - throw new Meteor.Error('error-invalid-subscription', 'Invalid subscription', { - method: 'ignoreUser', - }); - } - - const result = await Subscriptions.ignoreUser({ _id: subscription._id, ignoredUser, ignore }); - - if (result.modifiedCount) { - void notifyOnSubscriptionChangedById(subscription._id); - } - - return !!result; + return ignoreUser(userId, { rid, userId: ignoredUser, ignore }); }, }); From 7e9aa723ffef426386d5f58cfe73dab94053ea15 Mon Sep 17 00:00:00 2001 From: Marcos Defendi Date: Mon, 10 Feb 2025 10:21:11 -0300 Subject: [PATCH 2/3] fix: suggestions from review --- apps/meteor/app/lib/server/methods/getSingleMessage.ts | 4 ++-- apps/meteor/app/threads/server/methods/unfollowMessage.ts | 4 ++-- apps/meteor/server/methods/ignoreUser.ts | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/meteor/app/lib/server/methods/getSingleMessage.ts b/apps/meteor/app/lib/server/methods/getSingleMessage.ts index 52801d47bc61a..3408d1e6c5790 100644 --- a/apps/meteor/app/lib/server/methods/getSingleMessage.ts +++ b/apps/meteor/app/lib/server/methods/getSingleMessage.ts @@ -14,8 +14,6 @@ declare module '@rocket.chat/ddp-client' { } export const getSingleMessage = async (userId: string, mid: IMessage['_id']): Promise => { - check(mid, String); - const msg = await Messages.findOneById(mid); if (!msg?.rid) { @@ -31,6 +29,8 @@ export const getSingleMessage = async (userId: string, mid: IMessage['_id']): Pr Meteor.methods({ async getSingleMessage(mid) { + check(mid, String); + const uid = Meteor.userId(); if (!uid) { diff --git a/apps/meteor/app/threads/server/methods/unfollowMessage.ts b/apps/meteor/app/threads/server/methods/unfollowMessage.ts index 7d062991839c2..d19bdf6040051 100644 --- a/apps/meteor/app/threads/server/methods/unfollowMessage.ts +++ b/apps/meteor/app/threads/server/methods/unfollowMessage.ts @@ -19,8 +19,6 @@ declare module '@rocket.chat/ddp-client' { } export const unfollowMessage = async (userId: string, { mid }: { mid: IMessage['_id'] }): Promise => { - check(mid, String); - if (mid && !settings.get('Threads_enabled')) { throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); } @@ -52,6 +50,8 @@ export const unfollowMessage = async (userId: string, { mid }: { mid: IMessage[' Meteor.methods({ async unfollowMessage({ mid }) { + check(mid, String); + const uid = Meteor.userId(); if (!uid) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'unfollowMessage' }); diff --git a/apps/meteor/server/methods/ignoreUser.ts b/apps/meteor/server/methods/ignoreUser.ts index 63708231ce0e5..8e679221396a5 100644 --- a/apps/meteor/server/methods/ignoreUser.ts +++ b/apps/meteor/server/methods/ignoreUser.ts @@ -16,10 +16,6 @@ export const ignoreUser = async ( fromUserId: string, { rid, userId: ignoredUser, ignore }: { rid: string; userId: string; ignore?: boolean }, ): Promise => { - check(ignoredUser, String); - check(rid, String); - check(ignore, Boolean); - const [subscription, subscriptionIgnoredUser] = await Promise.all([ Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId), Subscriptions.findOneByRoomIdAndUserId(rid, ignoredUser), @@ -48,6 +44,10 @@ export const ignoreUser = async ( Meteor.methods({ async ignoreUser({ rid, userId: ignoredUser, ignore = true }) { + check(ignoredUser, String); + check(rid, String); + check(ignore, Boolean); + const userId = Meteor.userId(); if (!userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { From 980e3b6267c59ee4ac7bd5179ad761f8f83ca4c9 Mon Sep 17 00:00:00 2001 From: Marcos Defendi Date: Wed, 12 Feb 2025 07:04:24 -0300 Subject: [PATCH 3/3] fix: review --- apps/meteor/app/threads/server/methods/followMessage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/app/threads/server/methods/followMessage.ts b/apps/meteor/app/threads/server/methods/followMessage.ts index 9fcee01fcbe48..88d1b6274002a 100644 --- a/apps/meteor/app/threads/server/methods/followMessage.ts +++ b/apps/meteor/app/threads/server/methods/followMessage.ts @@ -19,8 +19,6 @@ declare module '@rocket.chat/ddp-client' { } export const followMessage = async (userId: string, { mid }: { mid: IMessage['_id'] }): Promise => { - check(mid, String); - if (mid && !settings.get('Threads_enabled')) { throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); } @@ -52,6 +50,8 @@ export const followMessage = async (userId: string, { mid }: { mid: IMessage['_i Meteor.methods({ async followMessage({ mid }) { + check(mid, String); + const uid = Meteor.userId(); if (!uid) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'followMessage' });