mirror of
https://github.com/penpot/penpot.git
synced 2026-09-18 18:06:14 +00:00
🐛 Escape markdown in Mattermost error notifications
Add escape-markdown to common/data.cljc that escapes Markdown special characters (*, _, ~, `, [, ], >, #, @, etc.) by prefixing them with backslash. Apply it to user-controlled fields (:hint, :href) in the Mattermost error reporter before constructing the notification message. This is an internal-only feature not accessible to end users. AI-assisted-by: mimo-v2.5-pro
This commit is contained in:
parent
3033da4409
commit
3021c2710a
@ -7,6 +7,7 @@
|
|||||||
(ns app.loggers.mattermost
|
(ns app.loggers.mattermost
|
||||||
"A mattermost integration for error reporting."
|
"A mattermost integration for error reporting."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
@ -25,7 +26,7 @@
|
|||||||
(defn- send-mattermost-notification!
|
(defn- send-mattermost-notification!
|
||||||
[cfg {:keys [id] :as report}]
|
[cfg {:keys [id] :as report}]
|
||||||
(let [type (get report :type)
|
(let [type (get report :type)
|
||||||
text (str "#" type " | " (get report :hint) "\n"
|
text (str "#" type " | " (d/escape-markdown (get report :hint)) "\n"
|
||||||
(when id
|
(when id
|
||||||
(str (u/join (cf/get :public-uri) "/dbg/error/" id) " "))
|
(str (u/join (cf/get :public-uri) "/dbg/error/" id) " "))
|
||||||
|
|
||||||
@ -38,7 +39,7 @@
|
|||||||
"- tenant: #" (:tenant report) "\n"
|
"- tenant: #" (:tenant report) "\n"
|
||||||
"- origin: #" (:origin report) "\n"
|
"- origin: #" (:origin report) "\n"
|
||||||
(when-let [href (get report :href)]
|
(when-let [href (get report :href)]
|
||||||
(str "- href: `" href "`\n"))
|
(str "- href: `" (d/escape-markdown href) "`\n"))
|
||||||
(when-let [version (get report :frontend-version)]
|
(when-let [version (get report :frontend-version)]
|
||||||
(str "- frontend-version: `" version "`\n"))
|
(str "- frontend-version: `" version "`\n"))
|
||||||
(when-let [version (get report :backend-version)]
|
(when-let [version (get report :backend-version)]
|
||||||
|
|||||||
@ -1192,6 +1192,15 @@
|
|||||||
str/trim)
|
str/trim)
|
||||||
""))
|
""))
|
||||||
|
|
||||||
|
(defn escape-markdown
|
||||||
|
"Escapes Markdown special characters by prefixing them with backslash.
|
||||||
|
Intended for user-controlled values embedded in Markdown messages
|
||||||
|
(e.g. Mattermost notifications)."
|
||||||
|
[s]
|
||||||
|
(if s
|
||||||
|
(str/replace (str s) #"([*_~`\[\]()>#+=\-|{}.!@\\])" (fn [[_ c]] (str "\\" c)))
|
||||||
|
""))
|
||||||
|
|
||||||
(defn get-initials
|
(defn get-initials
|
||||||
"Returns up to two uppercase initials extracted from a string.
|
"Returns up to two uppercase initials extracted from a string.
|
||||||
Non-letter prefixes in each token are ignored."
|
Non-letter prefixes in each token are ignored."
|
||||||
|
|||||||
@ -54,6 +54,25 @@
|
|||||||
(t/is (= :keyword (d/normalize-string :keyword)))
|
(t/is (= :keyword (d/normalize-string :keyword)))
|
||||||
(t/is (= true (d/normalize-string true))))
|
(t/is (= true (d/normalize-string true))))
|
||||||
|
|
||||||
|
(t/deftest escape-markdown-test
|
||||||
|
(t/is (= "hello" (d/escape-markdown "hello")))
|
||||||
|
(t/is (= "" (d/escape-markdown nil)))
|
||||||
|
(t/is (= "" (d/escape-markdown "")))
|
||||||
|
(t/is (= "\\*bold\\*" (d/escape-markdown "*bold*")))
|
||||||
|
(t/is (= "\\_italic\\_" (d/escape-markdown "_italic_")))
|
||||||
|
(t/is (= "\\~strikethrough\\~" (d/escape-markdown "~strikethrough~")))
|
||||||
|
(t/is (= "\\`code\\`" (d/escape-markdown "`code`")))
|
||||||
|
(t/is (= "\\[link\\]\\(http://evil\\.com\\)" (d/escape-markdown "[link](http://evil.com)")))
|
||||||
|
(t/is (= "\\> quote" (d/escape-markdown "> quote")))
|
||||||
|
(t/is (= "\\# heading" (d/escape-markdown "# heading")))
|
||||||
|
(t/is (= "\\@channel" (d/escape-markdown "@channel")))
|
||||||
|
(t/is (= "\\!bang" (d/escape-markdown "!bang")))
|
||||||
|
(t/is (= "normal\\-text" (d/escape-markdown "normal-text")))
|
||||||
|
(t/is (= "a\\+b\\=c" (d/escape-markdown "a+b=c")))
|
||||||
|
(t/is (= "pipe\\|separated" (d/escape-markdown "pipe|separated")))
|
||||||
|
(t/is (= "curly\\{\\}braces" (d/escape-markdown "curly{}braces")))
|
||||||
|
(t/is (= "backslash\\\\slash" (d/escape-markdown "backslash\\slash"))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Ordered Data Structures
|
;; Ordered Data Structures
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user