From 157a321322d03d1ea4464a93dfbe152626bd56fc Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 16 Oct 2023 10:51:26 -0400 Subject: [PATCH] SECURITY: Correctly escape 'text' email preview (stable) --- .../addon/templates/email-preview-digest.hbs | 12 +++--- .../acceptance/admin-email-preview-test.js | 39 +++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 app/assets/javascripts/discourse/tests/acceptance/admin-email-preview-test.js diff --git a/app/assets/javascripts/admin/addon/templates/email-preview-digest.hbs b/app/assets/javascripts/admin/addon/templates/email-preview-digest.hbs index 4e14d37d007..214b3112dfa 100644 --- a/app/assets/javascripts/admin/addon/templates/email-preview-digest.hbs +++ b/app/assets/javascripts/admin/addon/templates/email-preview-digest.hbs @@ -21,13 +21,15 @@ {{#if this.showHtml}} {{i18n "admin.email.html"}} | - + {{i18n "admin.email.text"}} {{else}} - {{i18n - "admin.email.html" - }} + {{i18n "admin.email.html"}} | {{i18n "admin.email.text"}} {{/if}} @@ -77,7 +79,7 @@ > {{/if}} {{else}} -
{{html-safe this.model.text_content}}
+
{{this.model.text_content}}
{{/if}} diff --git a/app/assets/javascripts/discourse/tests/acceptance/admin-email-preview-test.js b/app/assets/javascripts/discourse/tests/acceptance/admin-email-preview-test.js new file mode 100644 index 00000000000..1f5d5aa291c --- /dev/null +++ b/app/assets/javascripts/discourse/tests/acceptance/admin-email-preview-test.js @@ -0,0 +1,39 @@ +import { acceptance, query } from "discourse/tests/helpers/qunit-helpers"; +import { click, visit, waitUntil } from "@ember/test-helpers"; +import { test } from "qunit"; + +acceptance("Admin - email-preview", function (needs) { + needs.user(); + needs.pretender((server, helper) => { + server.get("/admin/email/preview-digest.json", () => + helper.response(200, { + html_content: "Hello world", + text_content: "Not actually html", + }) + ); + }); + + test("preview rendering", async function (assert) { + await visit("/admin/email/preview-digest"); + const iframe = query(".preview-output iframe"); + + // Rendered as a separate document, so Ember's built-in waiters don't work properly + await waitUntil(() => iframe.contentWindow.document.body); + + const iframeBody = iframe.contentWindow.document.body; + + assert.strictEqual( + iframeBody.querySelector("span").innerText, + "Hello world", + "html content is rendered inside iframe" + ); + + await click("a.show-text-link"); + assert + .dom(".preview-output pre") + .hasText( + "Not actually html", + "text content is escaped correctly" + ); + }); +});