The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/app/lib/server/methods/sendMessage.js

122 lines
3.5 KiB

import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import moment from 'moment';
import { hasPermission } from '../../../authorization';
import { metrics } from '../../../metrics';
import { settings } from '../../../settings';
import { messageProperties } from '../../../ui-utils';
import { Users, Messages } from '../../../models';
import { sendMessage } from '../functions';
import { RateLimiter } from '../lib';
import { canSendMessage } from '../../../authorization/server';
import { SystemLogger } from '../../../logger/server';
import { api } from '../../../../server/sdk/api';
export function executeSendMessage(uid, message) {
if (message.tshow && !message.tmid) {
throw new Meteor.Error('invalid-params', 'tshow provided but missing tmid', {
method: 'sendMessage',
});
}
if (message.tmid && !settings.get('Threads_enabled')) {
throw new Meteor.Error('error-not-allowed', 'not-allowed', {
method: 'sendMessage',
});
}
if (message.ts) {
const tsDiff = Math.abs(moment(message.ts).diff());
if (tsDiff > 60000) {
throw new Meteor.Error('error-message-ts-out-of-sync', 'Message timestamp is out of sync', {
method: 'sendMessage',
message_ts: message.ts,
server_ts: new Date().getTime(),
});
} else if (tsDiff > 10000) {
message.ts = new Date();
}
} else {
message.ts = new Date();
}
if (message.msg) {
const adjustedMessage = messageProperties.messageWithoutEmojiShortnames(message.msg);
if (messageProperties.length(adjustedMessage) > settings.get('Message_MaxAllowedSize')) {
throw new Meteor.Error('error-message-size-exceeded', 'Message size exceeds Message_MaxAllowedSize', {
method: 'sendMessage',
});
}
}
const user = Users.findOneById(uid, {
fields: {
username: 1,
type: 1,
},
});
let { rid } = message;
// do not allow nested threads
if (message.tmid) {
const parentMessage = Messages.findOneById(message.tmid);
message.tmid = parentMessage.tmid || message.tmid;
rid = parentMessage.rid;
}
if (!rid) {
throw new Error('The \'rid\' property on the message object is missing.');
}
try {
const room = canSendMessage(rid, { uid, username: user.username, type: user.type });
metrics.messagesSent.inc(); // TODO This line needs to be moved to it's proper place. See the comments on: https://github.com/RocketChat/Rocket.Chat/pull/5736
return sendMessage(user, message, room, false);
} catch (error) {
SystemLogger.error('Error sending message:', error);
const errorMessage = typeof error === 'string' ? error : error.error || error.message;
api.broadcast('notify.ephemeralMessage', uid, message.rid, {
msg: TAPi18n.__(errorMessage, {}, user.language),
});
if (typeof error === 'string') {
throw new Error(error);
}
throw error;
}
}
Meteor.methods({
sendMessage(message) {
check(message, Object);
const uid = Meteor.userId();
if (!uid) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'sendMessage',
});
}
try {
return executeSendMessage(uid, message);
} catch (error) {
if ((error.error || error.message) === 'error-not-allowed') {
throw new Meteor.Error(error.error || error.message, error.reason, {
method: 'sendMessage',
});
}
}
},
});
// Limit a user, who does not have the "bot" role, to sending 5 msgs/second
RateLimiter.limitMethod('sendMessage', 5, 1000, {
userId(userId) {
return !hasPermission(userId, 'send-many-messages');
},
});