Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/orange-mugs-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue where incoming webhook messages did not respect the maximum allowed characters per message.
7 changes: 7 additions & 0 deletions apps/meteor/app/lib/server/functions/processWebhookMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ensureArray } from '../../../../lib/utils/arrayUtils';
import { trim } from '../../../../lib/utils/stringUtils';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { validateRoomMessagePermissionsAsync } from '../../../authorization/server/functions/canSendMessage';
import { settings } from '../../../settings/server';

type Payload = {
channel?: string | string[];
Expand Down Expand Up @@ -114,6 +115,12 @@ export const processWebhookMessage = async function (
customFields: messageObj.customFields,
};

if (message.msg) {
if (message.msg.length > (settings.get<number>('Message_MaxAllowedSize') ?? 0)) {
throw Error('error-message-size-exceeded');
}
}

if (!_.isEmpty(messageObj.icon_url) || !_.isEmpty(messageObj.avatar)) {
message.avatar = messageObj.icon_url || messageObj.avatar;
} else if (!_.isEmpty(messageObj.icon_emoji) || !_.isEmpty(messageObj.emoji)) {
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/app/lib/server/functions/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ export function prepareMessageObject(
}

/**
* Validates and sends the message object.
* Validates and sends the message object. This function does not verify the Message_MaxAllowedSize settings.
* Caller of the function should verify the Message_MaxAllowedSize if needed.
* There might be same use cases which needs to override this setting. Example - sending error logs.
*/
export const sendMessage = async function (user: any, message: any, room: any, upsert = false, previewUrls?: string[]) {
if (!user || !message || !room._id) {
Expand Down
64 changes: 63 additions & 1 deletion apps/meteor/tests/end-to-end/api/incoming-integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { after, before, describe, it } from 'mocha';

import { getCredentials, api, request, credentials } from '../../data/api-data';
import { createIntegration, removeIntegration } from '../../data/integration.helper';
import { updatePermission } from '../../data/permissions.helper';
import { updatePermission, updateSetting } from '../../data/permissions.helper';
import { createRoom, deleteRoom } from '../../data/rooms.helper';
import { createTeam, deleteTeam } from '../../data/teams.helper';
import { password } from '../../data/user';
Expand Down Expand Up @@ -1202,5 +1202,67 @@ describe('[Incoming Integrations]', () => {
expect((res.body.members as AtLeast<IUser, '_id'>[]).find((m) => m._id === nonMemberUser._id)).not.to.be.undefined;
});
});

describe('Message Settings', async () => {
const maxSize = 5000;
before(() => updateSetting('Message_MaxAllowedSize', maxSize));
after(() => updateSetting('Message_MaxAllowedSize', maxSize));

it('should not send a message if message size is greater than the Message_MaxAllowedSize', async () => {
const largeMesssage = Array.from({ length: maxSize + 1 })
.map(() => 'A')
.join('');
await request
.post(`/hooks/${integration4._id}/${integration4.token}`)
.send({
text: largeMesssage,
})
.expect(400)
.expect((res) => {
expect(res.body.error).to.be.equal('error-message-size-exceeded');
});
await request
.get(api('channels.messages'))
.set(credentials)
.query({
roomId: publicRoom._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('messages').and.to.be.an('array');
expect((res.body.messages as IMessage[]).find((m) => m.msg === largeMesssage)).to.be.undefined;
});
});

it('should send a message if message size is less than the Message_MaxAllowedSize', async () => {
const smallerMessage = Array.from({ length: maxSize - 1 })
.map(() => 'A')
.join('');
await request
.post(`/hooks/${integration4._id}/${integration4.token}`)
.send({
text: smallerMessage,
})
.expect(200)
.expect((res) => {
expect(res.body.success).to.be.equal(true);
});
await request
.get(api('channels.messages'))
.set(credentials)
.query({
roomId: publicRoom._id,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('messages').and.to.be.an('array');
expect((res.body.messages as IMessage[]).find((m) => m.msg === smallerMessage)).to.not.be.undefined;
});
});
});
});
});
Loading