import type { IEditedMessage } from '@rocket.chat/core-typings'; import type { ServerMethods } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; import moment from 'moment'; import { hasAtLeastOnePermission, hasPermission } from '../../app/authorization/client'; import { ChatMessage } from '../../app/models/client'; import { settings } from '../../app/settings/client'; import { t } from '../../app/utils/lib/i18n'; import { callbacks } from '../../lib/callbacks'; import { dispatchToastMessage } from '../lib/toast'; Meteor.methods({ updateMessage(message) { const uid = Meteor.userId(); if (!uid) { return; } const originalMessage = ChatMessage.findOne(message._id); if (!originalMessage) { return; } const canEditMessage = hasAtLeastOnePermission('edit-message', message.rid); const editAllowed = settings.get('Message_AllowEditing'); let editOwn = false; const msgText = originalMessage?.attachments?.[0]?.description ?? originalMessage.msg; if (msgText === message.msg) { return; } if (originalMessage?.u?._id) { editOwn = originalMessage.u._id === uid; } const me = Meteor.users.findOne(uid); if (!me) { return; } if (!(canEditMessage || (editAllowed && editOwn))) { dispatchToastMessage({ type: 'error', message: t('error-action-not-allowed', { action: t('Message_editing') }), }); return; } const blockEditInMinutes = Number(settings.get('Message_AllowEditing_BlockEditInMinutes') as number | undefined); const bypassBlockTimeLimit = hasPermission('bypass-time-limit-edit-and-delete'); if (!bypassBlockTimeLimit && blockEditInMinutes !== 0) { if (originalMessage.ts) { const msgTs = moment(originalMessage.ts); if (msgTs) { const currentTsDiff = moment().diff(msgTs, 'minutes'); if (currentTsDiff > blockEditInMinutes) { dispatchToastMessage({ type: 'error', message: t('error-message-editing-blocked') }); return; } } } } Tracker.nonreactive(async () => { message.editedAt = new Date(Date.now()); message.editedBy = { _id: uid, username: me.username, }; message = (await callbacks.run('beforeSaveMessage', message)) as IEditedMessage; const messageObject: Partial = { editedAt: message.editedAt, editedBy: message.editedBy, msg: message.msg, }; if (originalMessage.attachments?.length) { if (originalMessage.attachments[0].description !== undefined) { delete messageObject.msg; originalMessage.attachments[0].description = message.msg; } } ChatMessage.update( { '_id': message._id, 'u._id': uid, }, { $set: messageObject }, ); }); }, });