From 5bb8fdafe1eca64c11f195d1d867e16e42ca3fad Mon Sep 17 00:00:00 2001 From: Bryan de Jong Date: Thu, 16 May 2024 10:26:12 +0100 Subject: [PATCH 1/2] feat: add dom-purify to tiptap editor update --- .../admin/src/components/Wysiwyg/index.tsx | 4 +++- packages/strapi-tiptap-editor/package.json | 8 +++++--- yarn.lock | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx b/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx index 4836703cb..905f14713 100644 --- a/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx +++ b/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx @@ -33,6 +33,7 @@ import UnderlineExtension from '@tiptap/extension-underline'; import YouTubeExtension from '@tiptap/extension-youtube'; import { Extensions, useEditor } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; +import { sanitize } from 'dompurify'; import React, { useEffect, useState } from 'react'; import { useIntl } from 'react-intl'; import { useQuery } from 'react-query'; @@ -49,6 +50,7 @@ import { Price } from '../extensions/Price/index'; import '@utrecht/component-library-css'; import '@utrecht/component-library-css/dist/html.css'; import '@utrecht/design-tokens/dist/index.css'; + interface Target { name: string; value: string; @@ -230,7 +232,7 @@ const WysiwygContent = ({ if (settings.other.saveJson) { onChange({ target: { name, value: JSON.stringify(editor.getJSON()) } }); } else { - onChange({ target: { name, value: editor.getHTML() } }); + onChange({ target: { name, value: sanitize(editor.getHTML()) } }); } }, }); diff --git a/packages/strapi-tiptap-editor/package.json b/packages/strapi-tiptap-editor/package.json index 92587fa96..a75f8b1a2 100644 --- a/packages/strapi-tiptap-editor/package.json +++ b/packages/strapi-tiptap-editor/package.json @@ -64,6 +64,7 @@ "@utrecht/component-library-react": "3.0.1-alpha.31", "@utrecht/design-tokens": "1.0.0-alpha.644", "classnames": "2.3.3", + "dompurify": "3.1.3", "react-cool-inview": "3.0.1", "react-icons": "4.8.0", "util": "0.12.5", @@ -73,11 +74,12 @@ }, "devDependencies": { "@strapi/typescript-utils": "4.14.6", + "@types/dompurify": "3.0.5", + "@types/react-router-dom": "5.3.3", "@types/styled-components": "5.1.34", + "@types/uuid": "9.0.8", "react-router-dom": "5.3.4", - "@types/react-router-dom": "5.3.3", - "typescript": "5.0.4", - "@types/uuid": "9.0.8" + "typescript": "5.0.4" }, "peerDependencies": { "@strapi/strapi": ">=4.0.0" diff --git a/yarn.lock b/yarn.lock index a042e11b6..df4cf2ba7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5636,6 +5636,13 @@ dependencies: "@types/ms" "*" +"@types/dompurify@3.1.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.5.tgz#02069a2fcb89a163bacf1a788f73cb415dd75cb7" + integrity sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg== + dependencies: + "@types/trusted-types" "*" + "@types/eslint-scope@^3.7.3": version "3.7.7" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" @@ -6139,6 +6146,11 @@ resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== +"@types/trusted-types@*": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/unist@*", "@types/unist@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" @@ -9845,6 +9857,11 @@ domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" +dompurify@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.3.tgz#cfe3ce4232c216d923832f68f2aa18b2fb9bd223" + integrity sha512-5sOWYSNPaxz6o2MUPvtyxTTqR4D3L77pr5rUQoWgD5ROQtVIZQgJkXbo1DLlK3vj11YGw5+LnF4SYti4gZmwng== + dompurify@^2.3.3: version "2.4.7" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.7.tgz#277adeb40a2c84be2d42a8bcd45f582bfa4d0cfc" From 3884f02a253df3825aeb130e729be42bcbefabe8 Mon Sep 17 00:00:00 2001 From: Bryan de Jong Date: Thu, 16 May 2024 14:12:58 +0100 Subject: [PATCH 2/2] config: explicitly allow data attributes --- .../strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx b/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx index 905f14713..b9c446bd7 100644 --- a/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx +++ b/packages/strapi-tiptap-editor/admin/src/components/Wysiwyg/index.tsx @@ -232,7 +232,7 @@ const WysiwygContent = ({ if (settings.other.saveJson) { onChange({ target: { name, value: JSON.stringify(editor.getJSON()) } }); } else { - onChange({ target: { name, value: sanitize(editor.getHTML()) } }); + onChange({ target: { name, value: sanitize(editor.getHTML(), { ALLOW_DATA_ATTR: true }) } }); } }, });