diff --git a/.changeset/selfish-bulldogs-fold.md b/.changeset/selfish-bulldogs-fold.md
new file mode 100644
index 00000000000..1f2f0e5a11c
--- /dev/null
+++ b/.changeset/selfish-bulldogs-fold.md
@@ -0,0 +1,5 @@
+---
+'@rocket.chat/meteor': patch
+---
+
+Fixes incorrect character escaping in system messages by removing unnecessary escaping logic to ensure accurate rendering of special characters.
diff --git a/apps/meteor/app/livechat/lib/messageTypes.ts b/apps/meteor/app/livechat/lib/messageTypes.ts
index 8a1931a300d..a5e40ad51dd 100644
--- a/apps/meteor/app/livechat/lib/messageTypes.ts
+++ b/apps/meteor/app/livechat/lib/messageTypes.ts
@@ -1,5 +1,4 @@
import type { IOmnichannelSystemMessage } from '@rocket.chat/core-typings';
-import { escapeHTML } from '@rocket.chat/string-helpers';
import formatDistance from 'date-fns/formatDistance';
import moment from 'moment';
@@ -124,7 +123,7 @@ MessageTypes.registerType({
};
}
return {
- message: escapeHTML(message.msg),
+ message: message.msg,
};
},
});
diff --git a/apps/meteor/client/components/message/variants/SystemMessage.spec.tsx b/apps/meteor/client/components/message/variants/SystemMessage.spec.tsx
new file mode 100644
index 00000000000..c0482e831db
--- /dev/null
+++ b/apps/meteor/client/components/message/variants/SystemMessage.spec.tsx
@@ -0,0 +1,81 @@
+import { faker } from '@faker-js/faker';
+import type { IMessage } from '@rocket.chat/core-typings';
+import { mockAppRoot } from '@rocket.chat/mock-providers';
+import { Random } from '@rocket.chat/random';
+import { render, screen } from '@testing-library/react';
+
+import SystemMessage from './SystemMessage';
+import '../../../startup/messageTypes';
+
+jest.mock('../../../../app/ui-utils/client', () => {
+ const actual = jest.requireActual('../../../../app/ui-utils/lib/MessageTypes');
+ return {
+ MessageTypes: actual.MessageTypes,
+ };
+});
+
+jest.mock('../content/Attachments', () => ({
+ default: () =>
attachments
,
+}));
+
+jest.mock('../content/MessageActions', () => ({
+ default: () => message actions
,
+}));
+
+jest.mock('meteor/meteor', () => {
+ const actual = jest.requireActual('meteor/meteor');
+ return {
+ ...actual,
+ Meteor: {
+ ...actual.Meteor,
+ startup: (callback: () => void) => callback(),
+ },
+ };
+});
+
+const wrapper = mockAppRoot().withTranslations('en', 'core', {
+ changed_room_description_to__room_description_: 'changed room description to: {{room_description}}',
+});
+
+const createBaseMessage = (msg: string): IMessage => ({
+ _id: Random.id(),
+ t: 'room_changed_description',
+ rid: Random.id(),
+ ts: new Date(),
+ msg,
+ u: {
+ _id: Random.id(),
+ username: faker.person.firstName().toLocaleLowerCase(),
+ name: faker.person.fullName(),
+ },
+ groupable: false,
+ _updatedAt: new Date(),
+});
+
+describe('SystemMessage', () => {
+ it('should render system message', () => {
+ const message = createBaseMessage('& test &');
+
+ render(, { legacyRoot: true, wrapper: wrapper.build() });
+
+ expect(screen.getByText('changed room description to: & test &')).toBeInTheDocument();
+ });
+
+ it('should not show escaped html while rendering system message', () => {
+ const message = createBaseMessage('& test &');
+
+ render(, { legacyRoot: true, wrapper: wrapper.build() });
+
+ expect(screen.getByText('changed room description to: & test &')).toBeInTheDocument();
+ expect(screen.queryByText('changed room description to: & test &')).not.toBeInTheDocument();
+ });
+
+ it('should not inject html', () => {
+ const message = createBaseMessage('');
+
+ render(, { legacyRoot: true, wrapper: wrapper.build() });
+
+ expect(screen.queryByTitle('test-title')).not.toBeInTheDocument();
+ expect(screen.getByText('changed room description to: ')).toBeInTheDocument();
+ });
+});
diff --git a/apps/meteor/client/startup/messageTypes.ts b/apps/meteor/client/startup/messageTypes.ts
index 481ab49568a..467e7694bb9 100644
--- a/apps/meteor/client/startup/messageTypes.ts
+++ b/apps/meteor/client/startup/messageTypes.ts
@@ -1,5 +1,4 @@
import type { IMessage } from '@rocket.chat/core-typings';
-import { escapeHTML } from '@rocket.chat/string-helpers';
import { Meteor } from 'meteor/meteor';
import { MessageTypes } from '../../app/ui-utils/client';
@@ -23,7 +22,7 @@ Meteor.startup(() => {
message: 'room_changed_topic_to',
data(message: IMessage) {
return {
- room_topic: escapeHTML(message.msg || `(${t('None').toLowerCase()})`),
+ room_topic: message.msg || `(${t('None').toLowerCase()})`,
};
},
});
@@ -40,7 +39,7 @@ Meteor.startup(() => {
message: 'changed_room_announcement_to__room_announcement_',
data(message: IMessage) {
return {
- room_announcement: escapeHTML(message.msg || `(${t('None').toLowerCase()})`),
+ room_announcement: message.msg || `(${t('None').toLowerCase()})`,
};
},
});
@@ -51,7 +50,7 @@ Meteor.startup(() => {
message: 'changed_room_description_to__room_description_',
data(message: IMessage) {
return {
- room_description: escapeHTML(message.msg || `(${t('None').toLowerCase()})`),
+ room_description: message.msg || `(${t('None').toLowerCase()})`,
};
},
});
diff --git a/ee/packages/omnichannel-services/src/livechatSystemMessages.ts b/ee/packages/omnichannel-services/src/livechatSystemMessages.ts
index 48e313cfa4c..e6e42a02b65 100644
--- a/ee/packages/omnichannel-services/src/livechatSystemMessages.ts
+++ b/ee/packages/omnichannel-services/src/livechatSystemMessages.ts
@@ -1,5 +1,4 @@
import type { IOmnichannelSystemMessage, MessageTypesValues } from '@rocket.chat/core-typings';
-import { escapeHTML } from '@rocket.chat/string-helpers';
import formatDistance from 'date-fns/formatDistance';
import moment from 'moment';
@@ -152,7 +151,7 @@ addType('livechat_webrtc_video_call', {
};
}
return {
- message: escapeHTML(message.msg),
+ message: message.msg,
};
},
});