From 6bc0bd84afb9ca1e594c6632288bde3ddc30f4f9 Mon Sep 17 00:00:00 2001 From: Matthew Nickson Date: Sun, 8 Jan 2023 20:39:27 +0000 Subject: [PATCH] Allowed markdown in footer of status page Markdown support has been added using the marked module. To secure against XSS attacks, DOMPurify is used to sanitize the generated HTML before it is loaded on the page. Signed-off-by: Matthew Nickson --- package-lock.json | 28 ++++++++++++++++++++++++++++ package.json | 2 ++ src/languages/en.js | 1 + src/pages/StatusPage.vue | 12 +++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 7e88d126..3efce254 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "compare-versions": "~3.6.0", "compression": "~1.7.4", "dayjs": "~1.11.5", + "dompurify": "^2.4.3", "express": "~4.17.3", "express-basic-auth": "~1.2.1", "express-static-gzip": "~2.1.7", @@ -38,6 +39,7 @@ "jsonwebtoken": "~9.0.0", "jwt-decode": "~3.1.2", "limiter": "~2.1.0", + "marked": "^4.2.5", "mqtt": "~4.3.7", "mssql": "~8.1.4", "mysql2": "~2.3.3", @@ -6499,6 +6501,11 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", + "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" + }, "node_modules/domutils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", @@ -12185,6 +12192,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.5.tgz", + "integrity": "sha512-jPueVhumq7idETHkb203WDD4fMA3yV9emQ5vLwop58lu8bTclMghBWcYAavlDqIEMaisADinV1TooIFCfqOsYQ==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -22155,6 +22173,11 @@ "domelementtype": "^2.3.0" } }, + "dompurify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", + "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" + }, "domutils": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", @@ -26299,6 +26322,11 @@ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, + "marked": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.5.tgz", + "integrity": "sha512-jPueVhumq7idETHkb203WDD4fMA3yV9emQ5vLwop58lu8bTclMghBWcYAavlDqIEMaisADinV1TooIFCfqOsYQ==" + }, "mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", diff --git a/package.json b/package.json index ebe305f9..fcda3437 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "compare-versions": "~3.6.0", "compression": "~1.7.4", "dayjs": "~1.11.5", + "dompurify": "^2.4.3", "express": "~4.17.3", "express-basic-auth": "~1.2.1", "express-static-gzip": "~2.1.7", @@ -93,6 +94,7 @@ "jsonwebtoken": "~9.0.0", "jwt-decode": "~3.1.2", "limiter": "~2.1.0", + "marked": "^4.2.5", "mqtt": "~4.3.7", "mssql": "~8.1.4", "mysql2": "~2.3.3", diff --git a/src/languages/en.js b/src/languages/en.js index 8d07db6d..5824ea4a 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -675,4 +675,5 @@ export default { "General Monitor Type": "General Monitor Type", "Passive Monitor Type": "Passive Monitor Type", "Specific Monitor Type": "Specific Monitor Type", + markdownSupported: "Markdown syntax supported", }; diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index 6cecf668..6fbbe69a 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -26,6 +26,9 @@
+
+ {{ $t("markdownSupported") }} +
@@ -279,7 +282,9 @@ - + + +

{{ $t("Powered by") }} {{ $t("Uptime Kuma" ) }} @@ -310,6 +315,8 @@ import ImageCropUpload from "vue-image-crop-upload"; import { PrismEditor } from "vue-prism-editor"; import "vue-prism-editor/dist/prismeditor.min.css"; // import the styles somewhere import { useToast } from "vue-toastification"; +import { marked } from "marked"; +import DOMPurify from "dompurify"; import Confirm from "../components/Confirm.vue"; import PublicGroupList from "../components/PublicGroupList.vue"; import MaintenanceTime from "../components/MaintenanceTime.vue"; @@ -477,6 +484,9 @@ export default { return this.overallStatus === STATUS_PAGE_MAINTENANCE; }, + footerHTML() { + return DOMPurify.sanitize(marked(this.config.footerText)); + }, }, watch: {