From 6f545a905bcdf5a152cdb5da19dbb370e33dbfb3 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Fri, 12 Mar 2021 00:43:10 -0800 Subject: [PATCH] Support full html in system messages. Closes #747 (#814) --- controllers/admin/chat.go | 6 +++--- core/chat/client.go | 2 ++ core/chat/messageRendering_test.go | 11 +++++++++++ core/chat/server.go | 7 ------- models/chatMessage.go | 10 ++++++++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/controllers/admin/chat.go b/controllers/admin/chat.go index 656481b92..f9166ac0e 100644 --- a/controllers/admin/chat.go +++ b/controllers/admin/chat.go @@ -58,8 +58,7 @@ func GetChatMessages(w http.ResponseWriter, r *http.Request) { } } -// SendSystemMessage will send an official "SYSTEM" message -// to chat on behalf of your server. +// SendSystemMessage will send an official "SYSTEM" message to chat on behalf of your server. func SendSystemMessage(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") @@ -76,7 +75,7 @@ func SendSystemMessage(w http.ResponseWriter, r *http.Request) { message.Visible = true message.SetDefaults() - message.RenderAndSanitizeMessageBody() + message.RenderBody() if err := core.SendMessageToChat(message); err != nil { controllers.BadRequestHandler(w, err) @@ -137,6 +136,7 @@ func SendChatAction(w http.ResponseWriter, r *http.Request) { } message.SetDefaults() + message.RenderAndSanitizeMessageBody() if err := core.SendMessageToChat(message); err != nil { controllers.BadRequestHandler(w, err) diff --git a/core/chat/client.go b/core/chat/client.go index 5ecb5f8fc..2cb950339 100644 --- a/core/chat/client.go +++ b/core/chat/client.go @@ -222,6 +222,8 @@ func (c *Client) chatMessageReceived(data []byte) { c.Username = &msg.Author msg.ClientID = c.ClientID + msg.RenderAndSanitizeMessageBody() + _server.SendToAll(msg) } diff --git a/core/chat/messageRendering_test.go b/core/chat/messageRendering_test.go index b0d320244..e5cf552f0 100644 --- a/core/chat/messageRendering_test.go +++ b/core/chat/messageRendering_test.go @@ -52,3 +52,14 @@ func TestAllowEmojiImages(t *testing.T) { t.Errorf("message rendering/sanitation does not match expected. Got\n%s, \n\n want:\n%s", result, expected) } } + +// Test to verify we can pass raw html and render markdown. +func TestAllowHTML(t *testing.T) { + messageContent := `` + expected := "

\n" + result := models.RenderMarkdown(messageContent) + + if result != expected { + t.Errorf("message rendering does not match expected. Got\n%s, \n\n want:\n%s", result, expected) + } +} diff --git a/core/chat/server.go b/core/chat/server.go index 0e8352d34..3c2add7b0 100644 --- a/core/chat/server.go +++ b/core/chat/server.go @@ -135,13 +135,6 @@ func (s *server) Listen() { case c := <-s.delCh: s.removeClient(c) case msg := <-s.sendAllCh: - // message was received from a client and should be sanitized, validated - // and distributed to other clients. - // - // Will turn markdown into html, sanitize user-supplied raw html - // and standardize this message into something safe we can send everyone else. - msg.RenderAndSanitizeMessageBody() - if !msg.Empty() { // set defaults before sending msg to anywhere msg.SetDefaults() diff --git a/models/chatMessage.go b/models/chatMessage.go index 2b17cd20e..d0e65b317 100644 --- a/models/chatMessage.go +++ b/models/chatMessage.go @@ -55,17 +55,23 @@ func (m *ChatEvent) Empty() bool { return m.Body == "" } +// RenderBody will render markdown to html without any sanitization +func (m *ChatEvent) RenderBody() { + m.RawBody = m.Body + m.Body = RenderMarkdown(m.RawBody) +} + // RenderAndSanitize will turn markdown into HTML, sanitize raw user-supplied HTML and standardize // the message into something safe and renderable for clients. func RenderAndSanitize(raw string) string { - rendered := renderMarkdown(raw) + rendered := RenderMarkdown(raw) safe := sanitize(rendered) // Set the new, sanitized and rendered message body return strings.TrimSpace(safe) } -func renderMarkdown(raw string) string { +func RenderMarkdown(raw string) string { markdown := goldmark.New( goldmark.WithRendererOptions( html.WithUnsafe(),