diff --git a/freedata_gui/src/components/chat_messages_received.vue b/freedata_gui/src/components/chat_messages_received.vue index efc22a508..9e093531b 100644 --- a/freedata_gui/src/components/chat_messages_received.vue +++ b/freedata_gui/src/components/chat_messages_received.vue @@ -158,9 +158,25 @@ export default { }, parsedMessageBody() { - // Use marked to parse markdown and DOMPurify to sanitize - return DOMPurify.sanitize(marked.parse(this.message.body)); - }, + // Parse markdown to HTML + let parsedHTML = marked.parse(this.message.body); + + // Sanitize the HTML + let sanitizedHTML = DOMPurify.sanitize(parsedHTML); + + // Create a temporary DOM element to manipulate the sanitized output + let tempDiv = document.createElement("div"); + tempDiv.innerHTML = sanitizedHTML; + + // Modify all links to open in a new tab + tempDiv.querySelectorAll("a").forEach(link => { + link.setAttribute("target", "_blank"); + link.setAttribute("rel", "noopener noreferrer"); // Security best practice + }); + + // Return the updated HTML + return tempDiv.innerHTML; + }, }, }; diff --git a/freedata_gui/src/components/chat_messages_sent.vue b/freedata_gui/src/components/chat_messages_sent.vue index c0b545379..3d74e58e7 100644 --- a/freedata_gui/src/components/chat_messages_sent.vue +++ b/freedata_gui/src/components/chat_messages_sent.vue @@ -202,8 +202,26 @@ export default { }, parsedMessageBody() { - // Use marked to parse markdown and DOMPurify to sanitize - return DOMPurify.sanitize(marked.parse(this.message.body)); + // Parse markdown to HTML + let parsedHTML = marked.parse(this.message.body); + + // Sanitize the HTML + let sanitizedHTML = DOMPurify.sanitize(parsedHTML); + + // Create a temporary DOM element to manipulate the sanitized output + let tempDiv = document.createElement("div"); + tempDiv.innerHTML = sanitizedHTML; + + // Modify all links to open in a new tab + tempDiv.querySelectorAll("a").forEach(link => { + link.setAttribute("target", "_blank"); + link.setAttribute("rel", "noopener noreferrer"); // Security best practice + }); + + // Return the updated HTML + return tempDiv.innerHTML; + + }, }, };