[FIX] mail: replace <br/> by space in thread preview

task-2284905

closes odoo/odoo#53718

X-original-commit: 80504fabd43832c5495ded3afc4b364c71d3df70
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
Xavier Dubuc
2020-06-26 09:10:55 +00:00
committed by Alexandre Kühn
parent 03a0b2d22c
commit 343c1c05d3
4 changed files with 122 additions and 10 deletions
@@ -797,27 +797,26 @@ QUnit.test('no code injection in message body preview', async function (assert)
Object.assign(this.data.initMessaging, {
channel_slots: {
channel_channel: [{
channel_type: "channel",
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "General",
}],
},
});
this.data['mail.channel'].records = [{
id: 1,
name: "general",
channel_type: "channel",
channel_message_ids: [1],
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "General",
}];
this.data['mail.message'].records = [{
id: 1,
author_id: [1, 'Georges'],
author_id: [1, "Georges"],
body: "<p><em>&shoulnotberaised</em><script>throw new Error('CodeInjectionError');</script></p>",
channel_ids: [1],
id: 1,
}];
await this.start();
await afterNextRender(() => {
@@ -851,6 +850,118 @@ QUnit.test('no code injection in message body preview', async function (assert)
);
});
QUnit.test('no code injection in message body preview from sanitized message', async function (assert) {
assert.expect(5);
Object.assign(this.data.initMessaging, {
channel_slots: {
channel_channel: [{
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "General",
}],
},
});
this.data['mail.channel'].records = [{
channel_message_ids: [1],
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "General",
}];
this.data['mail.message'].records = [{
author_id: [1, "Georges"],
body: "<p>&lt;em&gt;&shoulnotberaised&lt;/em&gt;&lt;script&gt;throw new Error('CodeInjectionError');&lt;/script&gt;</p>",
channel_ids: [1],
id: 1,
}];
await this.start();
await afterNextRender(() => {
document.querySelector(`.o_MessagingMenu_toggler`).click();
});
assert.containsOnce(
document.body,
'.o_MessagingMenu_dropdownMenu .o_ThreadPreview',
"should display a preview",
);
assert.containsOnce(
document.body,
'.o_ThreadPreview_core',
"preview should have core in content",
);
assert.containsOnce(
document.body,
'.o_ThreadPreview_inlineText',
"preview should have inline text in core of content",
);
assert.strictEqual(
document.querySelector('.o_ThreadPreview_inlineText')
.textContent.replace(/\s/g, ""),
"Georges:<em>&shoulnotberaised</em><script>thrownewError('CodeInjectionError');</script>",
"should display correct uninjected last message inline content"
);
assert.containsNone(
document.querySelector('.o_ThreadPreview_inlineText'),
'script',
"last message inline content should not have any code injection"
);
});
QUnit.test('<br/> tags in message body preview are transformed in spaces', async function (assert) {
assert.expect(4);
Object.assign(this.data.initMessaging, {
channel_slots: {
channel_channel: [{
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "General",
}],
},
});
this.data['mail.channel'].records = [{
channel_message_ids: [1],
channel_type: 'channel',
id: 1,
is_pinned: true,
name: "general",
}];
this.data['mail.message'].records = [{
author_id: [1, "Georges"],
body: "<p>a<br/>b<br>c<br />d<br ></p>",
channel_ids: [1],
id: 1,
}];
await this.start();
await afterNextRender(() => {
document.querySelector(`.o_MessagingMenu_toggler`).click();
});
assert.containsOnce(
document.body,
'.o_MessagingMenu_dropdownMenu .o_ThreadPreview',
"should display a preview",
);
assert.containsOnce(
document.body,
'.o_ThreadPreview_core',
"preview should have core in content",
);
assert.containsOnce(
document.body,
'.o_ThreadPreview_inlineText',
"preview should have inline text in core of content",
);
assert.strictEqual(
document.querySelector('.o_ThreadPreview_inlineText').textContent,
"Georges: a b c d",
"should display correct last message inline content with brs replaced by spaces"
);
});
});
});
});
@@ -45,7 +45,7 @@
threadLocalId="thread.localId"
/>
</t>
<t t-raw="inlineLastNeedactionMessageBody"/>
<t t-esc="inlineLastNeedactionMessageBody"/>
</span>
<span class="o-autogrow"/>
<span class="o_ThreadNeedactionPreview_coreItem o_ThreadNeedactionPreview_markAsRead fa fa-check" title="Mark as Read" t-on-click="_onClickMarkAsRead" t-ref="markAsRead"/>
@@ -48,7 +48,7 @@
threadLocalId="thread.localId"
/>
</t>
<t t-raw="inlineLastMessageBody"/>
<t t-esc="inlineLastMessageBody"/>
</span>
<span class="o-autogrow"/>
<t t-if="thread.message_unread_counter > 0">
+1
View File
@@ -95,6 +95,7 @@ function htmlToTextContentInline(htmlString) {
const fragment = document.createDocumentFragment();
const div = document.createElement('div');
fragment.appendChild(div);
htmlString = htmlString.replace(/<br\s*\/?>/gi,' ');
try {
div.innerHTML = htmlString;
} catch (e) {