Skip to content

Commit 7c29f5d

Browse files
im-shivShivam Agarwal
andauthored
sanitized text should have target attribute in links (#1463)
* sanitized text should have target attribute in links * catering comments * correcting test case * catering comments --------- Co-authored-by: Shivam Agarwal <shivama@adobe.com>
1 parent 58264b8 commit 7c29f5d

File tree

3 files changed

+57
-2
lines changed
  • it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/text/basic
  • ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/text/v1/text/clientlibs/site/js
  • ui.tests/test-module/specs/text

3 files changed

+57
-2
lines changed

it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/text/basic/.content.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@
115115
jcr:primaryType="nt:unstructured"
116116
click="[testTextImportData()]"/>
117117
</button>
118+
<text_637944566
119+
jcr:created="{Date}2024-05-16T11:23:14.686+05:30"
120+
jcr:createdBy="admin"
121+
jcr:lastModified="{Date}2024-05-16T11:23:32.032+05:30"
122+
jcr:lastModifiedBy="admin"
123+
jcr:primaryType="nt:unstructured"
124+
jcr:title="Text"
125+
sling:resourceType="forms-components-examples/components/form/text"
126+
fieldType="plain-text"
127+
name="text_637944566"
128+
textIsRich="true"
129+
value="'&lt;p>&lt;b>&lt;i>&lt;u>Hello1,&lt;/u>&lt;/i>&lt;/b> &lt;sub>Hello2&lt;/sub>, &lt;sup>Hello3&lt;/sup>&lt;/p>&#xa;&lt;p>&lt;a target=&quot;_blank&quot; href=&quot;http://www.google.com&quot; title=&quot;sample link&quot;>Hello4&lt;/a>, &lt;a id=&quot;anchor&quot;>&lt;/a>Hello5, ©&lt;/p>&#xa;&lt;p style=&quot;text-align: left;&quot;>sample text&lt;/p>&#xa;&lt;p style=&quot;text-align: left;&quot;>&amp;nbsp;&lt;/p>&#xa;&lt;table height=&quot;89&quot; width=&quot;67&quot; border=&quot;2&quot; cellspacing=&quot;0&quot; cellpadding=&quot;1&quot;>&#xa;&lt;caption>sample table&lt;/caption>&#xa;&lt;tbody>&lt;tr>&lt;th scope=&quot;col&quot;>Header1&lt;/th>&#xa;&lt;th scope=&quot;col&quot;>Header2&lt;/th>&#xa;&lt;th scope=&quot;col&quot;>Header3&lt;/th>&#xa;&lt;/tr>&lt;tr>&lt;td>Cell1&lt;/td>&#xa;&lt;td>Cell2&lt;/td>&#xa;&lt;td>Cell3&lt;/td>&#xa;&lt;/tr>&lt;/tbody>&lt;/table>&#xa;&lt;h2>&lt;span class=&quot;bold&quot;>Section Title&lt;/span>&lt;/h2>&#xa;&lt;p style=&quot;text-align: right;&quot;>right-aligned text&lt;/p>&#xa;&lt;ul>&#xa;&lt;li>item one&lt;/li>&#xa;&lt;/ul>&#xa;&lt;ol>&#xa;&lt;li>ordered item one&lt;/li>&#xa;&lt;/ol>&#xa;&lt;p>Paragraph start&lt;/p>&#xa;&lt;p style=&quot;margin-left: 40px;&quot;>Span Test&lt;/p>&#xa;&lt;p style=&quot;margin-left: 40px;&quot;>&amp;nbsp;&lt;/p>&#xa;'"/>
118130
</guideContainer>
119131
</jcr:content>
120132
</jcr:root>

ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/text/v1/text/clientlibs/site/js/textview.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,36 @@
7070
updateValue(value) {
7171
// html sets undefined value as undefined string in input value, hence this check is added
7272
let actualValue = typeof value === "undefined" ? "" : value;
73-
const sanitizedValue = window.DOMPurify ? window.DOMPurify.sanitize(actualValue) : actualValue;
73+
74+
// Custom configuration for DOMPurify for RTE content
75+
const cleanHTML = (dirtyHTML) => {
76+
// Specify the allowed tags and attributes
77+
const allowedTags = [
78+
'b', 'strong', 'caption', 'i', 'em', 'u',
79+
'sub', 'sup', 'small', 'blockquote',
80+
'ul', 'ol', 'li', 'a', 'img',
81+
'table', 'tbody', 'tr', 'td', 'th',
82+
'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
83+
'br', 'p', 'span'
84+
];
85+
const allowedAttributes = [
86+
'href', 'target', 'rel', '_rte_href',
87+
'src', 'alt' , 'style', '_rte_a_id_repl',
88+
'class', 'id', 'title', 'colspan', 'rowspan',
89+
'cellPadding', 'cellSpacing', 'border', 'width', 'height', 'scope'
90+
];
91+
92+
// Sanitize the HTML
93+
const sanitizedHTML = window.DOMPurify ? window.DOMPurify.sanitize(dirtyHTML, {
94+
ALLOWED_TAGS: allowedTags,
95+
ALLOWED_ATTR: allowedAttributes,
96+
}) : dirtyHTML;
97+
98+
return sanitizedHTML;
99+
};
100+
101+
const sanitizedValue = cleanHTML(actualValue);
102+
74103
// since there is no widget for textview, the innerHTML is being changed
75104
if (this.element.children[0]) {
76105
this.element.children[0].innerHTML = sanitizedValue;

ui.tests/test-module/specs/text/text.runtime.cy.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,26 @@
107107

108108
it(" prefill of static text using explicit dataRef, name bindings is not supported", () => {
109109
const [id, fieldView] = Object.entries(formContainer._fields)[3];
110-
const [buttonId, buttonFieldView] = Object.entries(formContainer._fields)[5];
110+
const [buttonId, buttonFieldView] = Object.entries(formContainer._fields)[6];
111111
const model = formContainer._model.getElement(id);
112112
cy.get(`#${buttonId} button`).should("be.visible").click().then(() => {
113113
expect(model.value, " Text model should import data").contains("prefilled");
114114
cy.get(`#${id}`).contains("prefilled");
115115
});
116116
});
117117

118+
it("text hyperlink should have target attribute in runtime", () => {
119+
const [id] = Object.entries(formContainer._fields)[4];
120+
cy.get(`#${id}`).find('a').should('have.attr', 'href', 'http://www.google.com') // Ensure the link has the correct href
121+
.should('have.attr', 'target', '_blank') // Ensure the link opens in a new tab
122+
.should('have.attr', 'title', 'sample link');
123+
cy.get(`#${id}`).find('p').eq(2).should('have.attr', 'style');
124+
cy.get(`#${id}`).find('table').should('have.attr', 'cellpadding', '1')
125+
.should('have.attr', 'cellspacing', '0')
126+
.should('have.attr', 'border', '2')
127+
.should('have.attr', 'width', '67')
128+
.should('have.attr', 'height', '89');
129+
cy.get(`#${id}`).find('caption');
130+
});
131+
118132
})

0 commit comments

Comments
 (0)