Skip to content

Commit 218cca8

Browse files
authored
Merge pull request #1287 from Piumal1999/htmlrender
Improve document view component
2 parents 90a8ef5 + e68bbe0 commit 218cca8

File tree

9 files changed

+72
-65
lines changed

9 files changed

+72
-65
lines changed

portals/devportal/src/main/webapp/package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portals/devportal/src/main/webapp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"cleanup-dependencies": "0.0.6",
5454
"dataloader": "^2.1.0",
5555
"dayjs": "^1.11.13",
56+
"dompurify": "3.3.3",
5657
"fetch-to-curl": "^0.6.0",
5758
"fs-react": "0.0.4",
5859
"graphiql": "^3.1.1",

portals/devportal/src/main/webapp/site/public/theme/settings.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,10 @@
2424
},
2525
"syntaxHighlighterDarkTheme": false
2626
},
27-
"sanitizeHtml": {
28-
"allowedTags": false,
29-
"allowedAttributes": false
30-
},
31-
"reactHTMLParser": {
32-
"decodeEntries": true,
33-
"tagsNotAllowed": []
27+
"sanitizeHtmlDocs": {
28+
"enabled": true,
29+
"additionalAllowedTags": [],
30+
"additionalAllowedAttributes": []
3431
}
3532
},
3633
"grantTypes": {

portals/devportal/src/main/webapp/source/src/app/components/LandingPage/Carousel.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ function Carousel() {
147147
>
148148
<HTMLRender html={slide.title} />
149149
</div>
150-
<div className={classes.slideContentContent}><HTMLRender html={slide.content} /></div>
150+
<div className={classes.slideContentContent}>
151+
<HTMLRender html={slide.content} />
152+
</div>
151153
</div>
152154
<img
153155
alt='slider'

portals/devportal/src/main/webapp/source/src/app/components/Shared/HTMLRender.jsx

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,38 @@
2020
*/
2121
import React from 'react'
2222
import parse from 'html-react-parser';
23+
import DOMPurify from 'dompurify';
2324
import Settings from 'Settings';
2425

2526
/**
26-
* Render html content.
27-
* @param {int} props Props passing down from parent components.
27+
* Render html content with optional sanitization.
28+
* @param {object} props Props passing down from parent components.
29+
* @param {string} props.html The HTML content to render.
30+
* @param {boolean} [props.sanitize=true] Whether to sanitize the HTML content.
2831
* @returns {JSX} React render output.
2932
*/
3033
export default function HTMLRender(props) {
31-
const {html} = props;
32-
// Extract html parser props from settings.json
33-
const { tagsNotAllowed } = (Settings.app &&
34-
Settings.app.reactHTMLParser) ? Settings.app.reactHTMLParser : {
35-
tagsNotAllowed: [],
36-
};
37-
// Define a custom replace function to filter out script tags
38-
const customReplace = (node) => {
39-
if (node.type === 'tag' && tagsNotAllowed.find( t => t === node.name)) {
40-
// You can handle script tags in any way you want here.
41-
// For example, you can replace them with a harmless element like a <div>.
42-
return <div>{node.name} tags are not allowed</div>;
43-
}
44-
// Return the node as is for other tags
45-
return node;
46-
};
47-
48-
// Use html-react-parser with the custom replace function
49-
const parsedHtml = parse(html, {
50-
replace: customReplace,
51-
});
52-
// Remove tags from html
34+
const { html, sanitize = true } = props;
35+
36+
// Extract sanitization config from settings.json
37+
const sanitizeConfig = Settings.app?.sanitizeHtmlDocs || {};
38+
const isSanitizationEnabled = sanitize === true && sanitizeConfig.enabled !== false;
39+
40+
let parsedHtml;
41+
42+
if (isSanitizationEnabled) {
43+
// Use DOMPurify for sanitization when enabled
44+
const sanitizationOptions = {
45+
ADD_TAGS: sanitizeConfig.additionalAllowedTags || [],
46+
ADD_ATTR: sanitizeConfig.additionalAllowedAttributes || [],
47+
};
48+
const sanitizedHtml = DOMPurify.sanitize(html, sanitizationOptions);
49+
parsedHtml = parse(sanitizedHtml);
50+
} else {
51+
// Render without sanitization
52+
parsedHtml = html ? parse(html) : null;
53+
}
54+
5355
return (
5456
<>{parsedHtml}</>
5557
)

portals/publisher/src/main/webapp/package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portals/publisher/src/main/webapp/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"btoa": "^1.2.1",
5656
"caniuse-api": "^3.0.0",
5757
"dayjs": "^1.11.13",
58+
"dompurify": "3.3.3",
5859
"downshift": "^6.1.12",
5960
"draft-js": "^0.11.7",
6061
"draftjs-to-html": "^0.9.1",

portals/publisher/src/main/webapp/site/public/conf/settings.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@
3333
"other": ""
3434
}
3535
},
36-
"reactHTMLParser": {
37-
"decodeEntries": true,
38-
"tagsNotAllowed": []
36+
"sanitizeHtmlDocs": {
37+
"enabled": true,
38+
"additionalAllowedTags": [],
39+
"additionalAllowedAttributes": []
3940
},
4041
"workflows": {
4142
"limit": 30

portals/publisher/src/main/webapp/source/src/app/components/Shared/HTMLRender.jsx

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,38 @@
2020
*/
2121
import React from 'react'
2222
import parse from 'html-react-parser';
23+
import DOMPurify from 'dompurify';
2324
import Configuration from 'Config';
2425

2526
/**
26-
* Render html content.
27-
* @param {int} props Props passing down from parent components.
27+
* Render html content with optional sanitization.
28+
* @param {object} props Props passing down from parent components.
29+
* @param {string} props.html The HTML content to render.
30+
* @param {boolean} [props.sanitize=true] Whether to sanitize the HTML content.
2831
* @returns {JSX} React render output.
2932
*/
3033
export default function HTMLRender(props) {
31-
const {html} = props;
32-
// Extract html parser props from settings.json
33-
const { tagsNotAllowed } = (Configuration.app &&
34-
Configuration.app.reactHTMLParser) ? Configuration.app.reactHTMLParser : {
35-
tagsNotAllowed: [],
34+
const { html, sanitize = true } = props;
35+
36+
// Extract sanitization config from Configuration
37+
const sanitizeConfig = Configuration.app?.sanitizeHtmlDocs || {};
38+
const isSanitizationEnabled = sanitize === true && sanitizeConfig.enabled !== false;
39+
40+
let parsedHtml;
41+
42+
if (isSanitizationEnabled) {
43+
// Use DOMPurify for sanitization when enabled
44+
const sanitizationOptions = {
45+
ADD_TAGS: sanitizeConfig.additionalAllowedTags || [],
46+
ADD_ATTR: sanitizeConfig.additionalAllowedAttributes || [],
3647
};
37-
// Define a custom replace function to filter out script tags
38-
const customReplace = (node) => {
39-
if (node.type === 'tag' && tagsNotAllowed.find( t => t === node.name)) {
40-
// You can handle script tags in any way you want here.
41-
// For example, you can replace them with a harmless element like a <div>.
42-
return <div>{node.name} tags are not allowed</div>;
43-
}
44-
// Return the node as is for other tags
45-
return node;
46-
};
47-
48-
// Use html-react-parser with the custom replace function
49-
const parsedHtml = parse(html, {
50-
replace: customReplace,
51-
});
52-
// Remove tags from html
53-
48+
const sanitizedHtml = DOMPurify.sanitize(html, sanitizationOptions);
49+
parsedHtml = parse(sanitizedHtml);
50+
} else {
51+
// Render without sanitization
52+
parsedHtml = html ? parse(html) : null;
53+
}
54+
5455
return (
5556
<>{parsedHtml}</>
5657
)

0 commit comments

Comments
 (0)