Skip to content

Commit 50dff96

Browse files
committed
fix: ecode social-embeds and embeds src urls
1 parent 10c3a0f commit 50dff96

File tree

6 files changed

+59
-73
lines changed

6 files changed

+59
-73
lines changed

README.md

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -231,60 +231,6 @@ The resulting HTML data will look as follows:
231231
```HTML
232232
<p><social-embed url="https://twitter.com/Contentstack/status/1508911909038436365?cxt=HHwWmsC9-d_Y3fApAAAA"></social-embed></p><p>This <color data-color="red">is</color> text.</p>
233233
```
234-
<br>
235-
<br>
236-
237-
##### <p>You can pass the option `skipURLSanitization` as true to bypass the validation checks and sanitization for the src URLs of JSON element types - social embed and embed.</p>
238-
<div>By default, this option is set to false.</div>
239-
240-
#### Examples:
241-
242-
1. For the following JSON, with src url containing script tags
243-
```JSON
244-
{
245-
"type": "doc",
246-
"attrs": {},
247-
"children": [
248-
{
249-
"type": "social-embeds",
250-
"attrs": {
251-
"src": "https://www.youtube.com/watch?v=Gw7EqoOYC9A\"></iframe><script>alert(document.cookie)</script><iframe ",
252-
"width": 560,
253-
"height": 320
254-
},
255-
}
256-
]
257-
}
258-
```
259-
The resulting HTML:
260-
```HTML
261-
<iframe src="https://www.youtube.com/watch?v=Gw7EqoOYC9A" width="560" height="320" data-type="social-embeds" ></iframe>
262-
```
263-
264-
2. For any JSON containing src urls violating expected protocols, the src attribute will be removed when converted to HTML
265-
266-
```JSON
267-
{
268-
"type": "doc",
269-
"attrs": {},
270-
"children": [
271-
{
272-
"type": "social-embeds",
273-
"attrs": {
274-
"src": "www.youtube.com/watch?v=Gw7EqoOYC9A\">",
275-
"width": 560,
276-
"height": 320
277-
},
278-
}
279-
]
280-
}
281-
```
282-
The resulting HTML:
283-
```HTML
284-
<iframe width="560" height="320" data-type="social-embeds" ></iframe>
285-
```
286-
287-
<br>
288234

289235
### Convert HTML to JSON
290236

@@ -411,6 +357,8 @@ The resulting JSON-formatted data will look as follows:
411357

412358
## Automatic Conversion
413359

360+
> **_Note_**: `src` url's provided for social-embeds and embed items will by default be encoded.
361+
414362
By default, the JSON Rich Text Editor field supports limited HTML tags within the editor. Due to this, the JSON RTE Serializer tool is not able to recognize each and every standard HTML tag.
415363

416364
To help the JSON RTE Serializer recognize and process additional tags that are commonly used across HTML, you can use the automatic conversion option. When using this option, you need to pass the `allowNonStandardTags: true` parameter within the `jsonToHtml` or `htmlToJson` method to manipulate the working of the JSON RTE Serializer package as per your requirements. When you pass this parameter, it customizes your JSON RTE Serializer code to allow the support for all standard HTML-recognized tags or element types in the JSON Rich Text Editor field.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/json-rte-serializer",
3-
"version": "2.1.0",
3+
"version": "2.0.13",
44
"description": "This Package converts Html Document to Json and vice-versa.",
55
"main": "lib/index.js",
66
"module": "lib/index.mjs",

src/toRedactor.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -498,17 +498,9 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string
498498
figureStyles.fieldsEdited.push(figureStyles.caption)
499499
}
500500

501-
if (!options?.skipURLSanitization && (jsonValue['type'] === 'social-embeds' || jsonValue['type'] === 'embed')) {
502-
const sanitizedHTML = DOMPurify.sanitize(allattrs['src']);
503-
504-
const urlMatch = sanitizedHTML.match(/https?:\/\/[^\s"'<>()]+/);
505-
506-
if (urlMatch) {
507-
attrsJson['src'] = decodeURIComponent(urlMatch[0]);
508-
} else {
509-
delete attrsJson['src'];
510-
}
511-
}
501+
if (jsonValue['type'] === 'social-embeds' || jsonValue['type'] === 'embed') {
502+
attrsJson['src'] = encodeURI(allattrs['src']);
503+
}
512504

513505
if(!(options?.customElementTypes && !isEmpty(options.customElementTypes) && options.customElementTypes[jsonValue['type']])) {
514506
delete attrsJson['url']

src/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ export interface IJsonToHtmlOptions {
2020
customElementTypes?: IJsonToHtmlElementTags,
2121
customTextWrapper?: IJsonToHtmlTextTags,
2222
allowNonStandardTypes?: boolean,
23-
skipURLSanitization?:boolean
2423
}

test/expectedJson.ts

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,9 +2002,10 @@ export default {
20022002
},
20032003
"RT-360":{
20042004
"html": [
2005-
`<iframe src="https://www.youtube.com/watch?v=Gw7EqoOYC9A" width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A\"></iframe>`,
2005+
`<iframe src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A%22%3E%3C/iframe%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3Ciframe%20\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/watch?v=Gw7EqoOYC9A%22%3E%3C/iframe%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E%3Ciframe%20\"></iframe>`,
20062006
`<iframe width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\"></iframe>`,
2007-
'<iframe width="560" height="320" data-type="social-embeds" ></iframe><iframe allowfullscreen=\"true\"></iframe>',
2007+
'<iframe src=\"www.youtube.com/watch?v=Gw7EqoOYC9A\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"www.youtube.com/embed/VD6xJq8NguY\"></iframe>',
2008+
`<iframe src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\" width=\"560\" height=\"320\" data-type=\"social-embeds\" ></iframe><iframe allowfullscreen=\"true\" src=\"https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU\"></iframe>`
20082009
],
20092010
"json":
20102011
[
@@ -2057,7 +2058,7 @@ export default {
20572058
"uid": "45a850acbeb949db86afe415625ad1ce",
20582059
"type": "social-embeds",
20592060
"attrs": {
2060-
"src": null,
2061+
"src": "",
20612062
"width": 560,
20622063
"height": 320
20632064
},
@@ -2077,7 +2078,7 @@ export default {
20772078
"uid": "87fed1cc68ce435caa0f71d17788c618",
20782079
"type": "embed",
20792080
"attrs": {
2080-
"src": null,
2081+
"src": "",
20812082
"redactor-attributes": {
20822083
"allowfullscreen": true
20832084
}
@@ -2127,6 +2128,46 @@ export default {
21272128
}
21282129
],
21292130
"_version": 1
2131+
},
2132+
{
2133+
"type": "doc",
2134+
"attrs": {},
2135+
"uid": "18396bf67f1f4b0a9da57643ac0542ca",
2136+
"children": [
2137+
{
2138+
"uid": "45a850acbeb949db86afe415625ad1ce",
2139+
"type": "social-embeds",
2140+
"attrs": {
2141+
"src": "https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU",
2142+
"width": 560,
2143+
"height": 320
2144+
},
2145+
"children": [
2146+
{
2147+
"text": ""
2148+
}
2149+
]
2150+
},
2151+
{
2152+
"uid": "d3c2ab78a5e547b082f95dc01123b0c1",
2153+
"type": "doc",
2154+
"_version": 11,
2155+
"attrs": {},
2156+
"children": [
2157+
{
2158+
"uid": "87fed1cc68ce435caa0f71d17788c618",
2159+
"type": "embed",
2160+
"attrs": {
2161+
"src": "https://www.youtube.com/embed/Gw7EqoOYC9A?si=bWdnezma6qFAePQU",
2162+
"redactor-attributes": {
2163+
"allowfullscreen": true
2164+
}
2165+
}
2166+
}
2167+
]
2168+
}
2169+
],
2170+
"_version": 1
21302171
}
21312172
]
21322173

test/toRedactor.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ describe("Testing json to html conversion", () => {
250250
})
251251

252252
describe("RT-360", () =>{
253-
it("should remove script and/or other tags from src links in HTML for social-embeds", () => {
253+
it("should encode and not render invalid src urls", () => {
254254
const json = expectedValue["RT-360"].json[0]
255255
const html = toRedactor(json);
256256
expect(html).toBe(expectedValue["RT-360"].html[0]);
@@ -262,11 +262,17 @@ describe("Testing json to html conversion", () => {
262262
expect(html).toBe(expectedValue["RT-360"].html[1]);
263263
})
264264

265-
it("should handle src without protocol",()=>{
265+
it("should handle src urls without protocol",()=>{
266266
const json = expectedValue["RT-360"].json[2]
267267
const html = toRedactor(json);
268268
expect(html).toBe(expectedValue["RT-360"].html[2]);
269269
})
270+
271+
it("should work only for valid embed urls",()=>{
272+
const json = expectedValue["RT-360"].json[3]
273+
const html = toRedactor(json);
274+
expect(html).toBe(expectedValue["RT-360"].html[3]);
275+
})
270276
})
271277

272278
test('should convert numeric width to string', () => {

0 commit comments

Comments
 (0)