diff --git a/frontend/src/components/ChatBubble/index.jsx b/frontend/src/components/ChatBubble/index.jsx index 4ffc3d085ea3c97d4efc9cb401b16f8b3a83e351..7b37cd5d17e540e43e65b134a7d3958fa2a8b95c 100644 --- a/frontend/src/components/ChatBubble/index.jsx +++ b/frontend/src/components/ChatBubble/index.jsx @@ -1,6 +1,8 @@ import React from "react"; import UserIcon from "../UserIcon"; import { userFromStorage } from "@/utils/request"; +import renderMarkdown from "@/utils/chat/markdown"; +import DOMPurify from "@/utils/chat/purify"; export default function ChatBubble({ message, type, popMsg }) { const isUser = type === "user"; @@ -16,11 +18,12 @@ export default function ChatBubble({ message, type, popMsg }) { role={type} /> - <span - className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`} - > - {message} - </span> + <div + className={`markdown whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`} + dangerouslySetInnerHTML={{ + __html: DOMPurify.sanitize(renderMarkdown(message)), + }} + /> </div> </div> </div> diff --git a/frontend/src/components/EditingChatBubble/index.jsx b/frontend/src/components/EditingChatBubble/index.jsx index feabd4c6ee174b7daa163a5c23ec86dfbcb2dba1..652297c7914f40582d377bd79f286620a6a0448c 100644 --- a/frontend/src/components/EditingChatBubble/index.jsx +++ b/frontend/src/components/EditingChatBubble/index.jsx @@ -1,6 +1,8 @@ import React, { useState } from "react"; import { X } from "@phosphor-icons/react"; import { useTranslation } from "react-i18next"; +import renderMarkdown from "@/utils/chat/markdown"; +import DOMPurify from "@/utils/chat/purify"; export default function EditingChatBubble({ message, @@ -57,9 +59,12 @@ export default function EditingChatBubble({ /> ) : ( tempMessage && ( - <p className=" font-[500] md:font-semibold text-sm md:text-base break-words light:invert"> - {tempMessage} - </p> + <div + className="markdown font-[500] md:font-semibold text-sm md:text-base break-words light:invert" + dangerouslySetInnerHTML={{ + __html: DOMPurify.sanitize(renderMarkdown(tempMessage)), + }} + /> ) )} </div> diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx index a5d60db4e077b3c2c13595d49be60522d1ee3933..5a5454bb283f153bb35d1cf5451a9d2afe8dd2e8 100644 --- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx +++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/HistoricalMessage/index.jsx @@ -6,7 +6,7 @@ import renderMarkdown from "@/utils/chat/markdown"; import { userFromStorage } from "@/utils/request"; import Citations from "../Citation"; import { v4 } from "uuid"; -import createDOMPurify from "dompurify"; +import DOMPurify from "@/utils/chat/purify"; import { EditMessageForm, useEditMessage } from "./Actions/EditMessage"; import { useWatchDeleteMessage } from "./Actions/DeleteMessage"; import TTSMessage from "./Actions/TTSButton"; @@ -17,11 +17,6 @@ import { ThoughtChainComponent, } from "../ThoughtContainer"; -const DOMPurify = createDOMPurify(window); -DOMPurify.setConfig({ - ADD_ATTR: ["target", "rel"], -}); - const HistoricalMessage = ({ uuid = v4(), message, diff --git a/frontend/src/utils/chat/purify.js b/frontend/src/utils/chat/purify.js new file mode 100644 index 0000000000000000000000000000000000000000..a6cf85206602c4153ff4c117c3177f4764ff8053 --- /dev/null +++ b/frontend/src/utils/chat/purify.js @@ -0,0 +1,8 @@ +import createDOMPurify from "dompurify"; + +const DOMPurify = createDOMPurify(window); +DOMPurify.setConfig({ + ADD_ATTR: ["target", "rel"], +}); + +export default DOMPurify;