From 0378546c7e9c3ddf7ad97857b309369b8e978703 Mon Sep 17 00:00:00 2001 From: prabhuignoto Date: Sat, 6 Jan 2024 20:23:15 +0530 Subject: [PATCH] replace sanitize-html with xss --- package.json | 3 +- pnpm-lock.yaml | 48 ++++++++++--------- rollup.config.mjs | 16 +++---- .../timeline-card-content/text-or-content.tsx | 16 ++----- src/demo/data.tsx | 34 ++++++------- src/utils/index.ts | 6 +-- 6 files changed, 58 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index e7a236ba..04eb3adb 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,8 @@ "classnames": "^2.5.1", "dayjs": "^1.11.10", "focus-visible": "^5.2.0", - "sanitize-html": "^2.11.0", "styled-components": "^6.1.6", - "stylis": "^4.3.1" + "xss": "^1.0.14" }, "peerDependencies": { "react": "^18.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cbf23234..7cd609a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,15 +19,12 @@ dependencies: focus-visible: specifier: ^5.2.0 version: 5.2.0 - sanitize-html: - specifier: ^2.11.0 - version: 2.11.0 styled-components: specifier: ^6.1.6 version: 6.1.6(react-dom@18.2.0)(react@18.2.0) - stylis: - specifier: ^4.3.1 - version: 4.3.1 + xss: + specifier: ^1.0.14 + version: 1.0.14 devDependencies: '@babel/core': @@ -4717,7 +4714,6 @@ packages: /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true /commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} @@ -4942,6 +4938,10 @@ packages: hasBin: true dev: true + /cssfilter@0.0.10: + resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==} + dev: false + /cssnano-preset-default@5.2.14(postcss@8.4.33): resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} engines: {node: ^10 || ^12 || >=14.0} @@ -5231,6 +5231,7 @@ packages: /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + dev: true /define-data-property@1.1.1: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} @@ -5339,9 +5340,11 @@ packages: domelementtype: 2.3.0 domhandler: 5.0.3 entities: 4.5.0 + dev: true /domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true /domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} @@ -5355,6 +5358,7 @@ packages: engines: {node: '>= 4'} dependencies: domelementtype: 2.3.0 + dev: true /domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} @@ -5370,6 +5374,7 @@ packages: dom-serializer: 2.0.0 domelementtype: 2.3.0 domhandler: 5.0.3 + dev: true /duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -5435,6 +5440,7 @@ packages: /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + dev: true /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} @@ -5685,6 +5691,7 @@ packages: /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + dev: true /escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} @@ -6774,6 +6781,7 @@ packages: domhandler: 5.0.3 domutils: 3.1.0 entities: 4.5.0 + dev: true /http-proxy-agent@7.0.0: resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} @@ -7134,6 +7142,7 @@ packages: /is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} + dev: true /is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -8295,10 +8304,6 @@ packages: lines-and-columns: 1.2.4 dev: true - /parse-srcset@1.0.2: - resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} - dev: false - /parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} dependencies: @@ -9475,6 +9480,7 @@ packages: nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 + dev: true /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -10115,17 +10121,6 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true - /sanitize-html@2.11.0: - resolution: {integrity: sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==} - dependencies: - deepmerge: 4.3.1 - escape-string-regexp: 4.0.0 - htmlparser2: 8.0.2 - is-plain-object: 5.0.0 - parse-srcset: 1.0.2 - postcss: 8.4.33 - dev: false - /sass@1.69.7: resolution: {integrity: sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==} engines: {node: '>=14.0.0'} @@ -11688,6 +11683,15 @@ packages: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} dev: true + /xss@1.0.14: + resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} + engines: {node: '>= 0.10.0'} + hasBin: true + dependencies: + commander: 2.20.3 + cssfilter: 0.0.10 + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} diff --git a/rollup.config.mjs b/rollup.config.mjs index 256069b9..88dff50c 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -12,6 +12,7 @@ import PeerDepsExternalPlugin from 'rollup-plugin-peer-deps-external'; import postcss from 'rollup-plugin-postcss'; import typescript from 'rollup-plugin-typescript2'; import pkg from './package.json' assert { type: 'json' }; +import buble from '@rollup/plugin-buble'; const banner = `/* * ${pkg.name} @@ -72,15 +73,12 @@ export default { ], ], }), - // buble({ - // objectAssign: true, - // transforms: { - // dangerousForOf: false, - // forOf: false, - // generator: false, - // templateString: false, - // }, - // }), + buble({ + objectAssign: true, + transforms: { + templateString: false, + }, + }), postcss({ plugins: [ postCSSPreset({ diff --git a/src/components/timeline-elements/timeline-card-content/text-or-content.tsx b/src/components/timeline-elements/timeline-card-content/text-or-content.tsx index 01de198f..f414ecbb 100644 --- a/src/components/timeline-elements/timeline-card-content/text-or-content.tsx +++ b/src/components/timeline-elements/timeline-card-content/text-or-content.tsx @@ -1,6 +1,6 @@ import { TimelineContentModel } from '@models/TimelineContentModel'; import { ForwardRefExoticComponent, forwardRef, useContext } from 'react'; -import sanitizeHtml from 'sanitize-html'; +import xss from 'xss'; import { GlobalContext } from '../../GlobalContext'; import { TimelineContentDetails, @@ -38,9 +38,7 @@ const getTextOrContent: ( const props = parseDetailsTextHTML ? { dangerouslySetInnerHTML: { - __html: sanitizeHtml(text, { - parseStyleAttributes: true, - }), + __html: xss(text), }, } : null; @@ -57,20 +55,14 @@ const getTextOrContent: ( ); }); } else { - textContent = parseDetailsTextHTML - ? sanitizeHtml(detailedText, { - parseStyleAttributes: true, - }) - : detailedText; + textContent = parseDetailsTextHTML ? xss(detailedText) : detailedText; } const textContentProps = parseDetailsTextHTML && !isTextArray ? { dangerouslySetInnerHTML: { - __html: sanitizeHtml(textContent, { - parseStyleAttributes: true, - }), + __html: xss(textContent), }, } : {}; diff --git a/src/demo/data.tsx b/src/demo/data.tsx index a0b25e17..b32146fb 100644 --- a/src/demo/data.tsx +++ b/src/demo/data.tsx @@ -16,25 +16,25 @@ const items: TimelineItemModel[] = [ // date: '1945-05-01', cardSubtitle: 'Men of the British Expeditionary Force (BEF) wade out to a destroyer during the evacuation from Dunkirk.', - cardDetailedText: [ - `On 10 May 1940, Hitler began his long-awaited offensive in the west by invading neutral Holland and Belgium and attacking northern France.`, - `Holland capitulated after only five days of fighting, and the Belgians surrendered on 28 May. With the success of the German ‘Blitzkrieg’, the British Expeditionary Force and French troops were in danger of being cut off and destroyed.`, - ], // cardDetailedText: [ - // `On 10 May 1940, Hitler began his long-awaited offensive in the west by invading neutral Holland and Belgium and attacking northern France. - //
`, - // ` - // `, + // `On 10 May 1940, Hitler began his long-awaited offensive in the west by invading neutral Holland and Belgium and attacking northern France.`, + // `Holland capitulated after only five days of fighting, and the Belgians surrendered on 28 May. With the success of the German ‘Blitzkrieg’, the British Expeditionary Force and French troops were in danger of being cut off and destroyed.`, // ], + cardDetailedText: [ + `On 10 May 1940, Hitler began his long-awaited offensive in the west by invading neutral Holland and Belgium and attacking northern France. +
`, + ` + `, + ], }, { title: '25 July 1941', diff --git a/src/utils/index.ts b/src/utils/index.ts index 5dcd96b0..b999b2b6 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,6 @@ import { SlideShowType, TimelineMode } from '@models/TimelineModel'; import { darkTheme, defaultTheme } from '../components/common/themes'; -import santizeHtml from 'sanitize-html'; +import xss from 'xss'; export const uniqueID = () => { const chars = @@ -73,7 +73,7 @@ export const isTextArray = (text: string | string[]): text is string[] => { export const sanitizeHtmlText = (text: string | string[]) => { if (isTextArray(text)) { - return text.map((t) => santizeHtml(t)); + return text.map((t) => xss(t)); } - return santizeHtml(text); + return xss(text); };