@beinformed/ui 1.33.0-beta.2 → 1.33.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/esm/utils/helpers/sanitizeHtml.js +8 -6
- package/esm/utils/helpers/sanitizeHtml.js.map +1 -1
- package/lib/utils/helpers/__tests__/sanitizeHTML.spec.js.flow +35 -1
- package/lib/utils/helpers/sanitizeHtml.js +8 -6
- package/lib/utils/helpers/sanitizeHtml.js.flow +7 -6
- package/lib/utils/helpers/sanitizeHtml.js.map +1 -1
- package/package.json +1 -1
- package/src/utils/helpers/__tests__/sanitizeHTML.spec.js +35 -1
- package/src/utils/helpers/sanitizeHtml.js +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.33.0-beta.3](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.33.0-beta.2...v1.33.0-beta.3) (2023-08-28)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **sanitize-html:** improve encoding of html entities to numerical entities ([45c3c56](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/commit/45c3c56c8e04ca36b898efb5651fd87cbc9eea9f))
|
|
11
|
+
|
|
5
12
|
## [1.33.0-beta.2](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.33.0-beta.1...v1.33.0-beta.2) (2023-08-24)
|
|
6
13
|
|
|
7
14
|
|
|
@@ -5,13 +5,15 @@ import { IllegalArgumentException } from "../../exceptions";
|
|
|
5
5
|
* When path is only one deep better use optional chaining
|
|
6
6
|
*/
|
|
7
7
|
const properEntityEncoding = html => {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
decimal: true
|
|
8
|
+
const htmlDecoded = he.decode(html, {
|
|
9
|
+
decimal: true,
|
|
10
|
+
allowUnsafeSymbols: true
|
|
12
11
|
});
|
|
13
|
-
const
|
|
14
|
-
|
|
12
|
+
const htmlEncoded = he.encode(htmlDecoded, {
|
|
13
|
+
decimal: true,
|
|
14
|
+
allowUnsafeSymbols: true
|
|
15
|
+
});
|
|
16
|
+
return htmlEncoded;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeHtml.js","names":["he","IllegalArgumentException","properEntityEncoding","html","
|
|
1
|
+
{"version":3,"file":"sanitizeHtml.js","names":["he","IllegalArgumentException","properEntityEncoding","html","htmlDecoded","decode","decimal","allowUnsafeSymbols","htmlEncoded","encode","removeUnwantedHtml","options","arguments","length","undefined","allowedTags","correctEntityHtml","htmlWithoutAttributes","replace","htmlWithCorrectBR","Array","isArray","join","pattern","regex","RegExp"],"sources":["../../../src/utils/helpers/sanitizeHtml.js"],"sourcesContent":["// @flow\nimport he from \"he\";\n\nimport { IllegalArgumentException } from \"../../exceptions\";\n\ntype removeUnwantedHtmlOptions = {\n allowedTags?: Array<string>,\n};\n\n/**\n * Translates html entities to their correct decimal equivalent\n * When path is only one deep better use optional chaining\n */\nconst properEntityEncoding = (html: string) => {\n const htmlDecoded = he.decode(html, {\n decimal: true,\n allowUnsafeSymbols: true,\n });\n\n const htmlEncoded = he.encode(htmlDecoded, {\n decimal: true,\n allowUnsafeSymbols: true,\n });\n\n return htmlEncoded;\n};\n\n/**\n * removes unwanted html, this might result in incorrect html, as it removes all html that we don't except,\n * like <b style=\"font-weight: 400\">bold</b> will result in bold</b>\n */\nconst removeUnwantedHtml = (\n html: string,\n options: removeUnwantedHtmlOptions = {\n allowedTags: [\"p\", \"br\", \"b\", \"i\", \"u\", \"strike\"],\n },\n): string => {\n if (typeof html !== \"string\") {\n throw new IllegalArgumentException(\"sanitizeHTML method expects a string\");\n }\n\n const correctEntityHtml = properEntityEncoding(html);\n\n // remove attributes from html elements\n const htmlWithoutAttributes = correctEntityHtml.replace(\n /<(\\w+)(.|[\\r\\n])*?>/gi,\n \"<$1>\",\n );\n\n const htmlWithCorrectBR = htmlWithoutAttributes.replace(\n /<br\\s*>/gi,\n \"<br />\",\n );\n\n // remove not allowed tags\n const allowedTags = Array.isArray(options.allowedTags)\n ? options.allowedTags.join(\"|\")\n : \"\";\n const pattern = `<(?!\\\\/?(${allowedTags})(>|\\\\s\\\\/))[^<]+?>`;\n const regex = new RegExp(pattern, \"gi\");\n\n return htmlWithCorrectBR.replace(regex, \"\");\n};\n\nexport { removeUnwantedHtml };\n"],"mappings":"AACA,OAAOA,EAAE,MAAM,IAAI;AAEnB,SAASC,wBAAwB,QAAQ,kBAAkB;AAM3D;AACA;AACA;AACA;AACA,MAAMC,oBAAoB,GAAIC,IAAY,IAAK;EAC7C,MAAMC,WAAW,GAAGJ,EAAE,CAACK,MAAM,CAACF,IAAI,EAAE;IAClCG,OAAO,EAAE,IAAI;IACbC,kBAAkB,EAAE;EACtB,CAAC,CAAC;EAEF,MAAMC,WAAW,GAAGR,EAAE,CAACS,MAAM,CAACL,WAAW,EAAE;IACzCE,OAAO,EAAE,IAAI;IACbC,kBAAkB,EAAE;EACtB,CAAC,CAAC;EAEF,OAAOC,WAAW;AACpB,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAME,kBAAkB,GAAG,SAAAA,CACzBP,IAAY,EAID;EAAA,IAHXQ,OAAkC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG;IACnCG,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ;EAClD,CAAC;EAED,IAAI,OAAOZ,IAAI,KAAK,QAAQ,EAAE;IAC5B,MAAM,IAAIF,wBAAwB,CAAC,sCAAsC,CAAC;EAC5E;EAEA,MAAMe,iBAAiB,GAAGd,oBAAoB,CAACC,IAAI,CAAC;;EAEpD;EACA,MAAMc,qBAAqB,GAAGD,iBAAiB,CAACE,OAAO,CACrD,uBAAuB,EACvB,MACF,CAAC;EAED,MAAMC,iBAAiB,GAAGF,qBAAqB,CAACC,OAAO,CACrD,WAAW,EACX,QACF,CAAC;;EAED;EACA,MAAMH,WAAW,GAAGK,KAAK,CAACC,OAAO,CAACV,OAAO,CAACI,WAAW,CAAC,GAClDJ,OAAO,CAACI,WAAW,CAACO,IAAI,CAAC,GAAG,CAAC,GAC7B,EAAE;EACN,MAAMC,OAAO,GAAI,YAAWR,WAAY,qBAAoB;EAC5D,MAAMS,KAAK,GAAG,IAAIC,MAAM,CAACF,OAAO,EAAE,IAAI,CAAC;EAEvC,OAAOJ,iBAAiB,CAACD,OAAO,CAACM,KAAK,EAAE,EAAE,CAAC;AAC7C,CAAC;AAED,SAASd,kBAAkB"}
|
|
@@ -12,7 +12,7 @@ describe("sanitizeHTML", () => {
|
|
|
12
12
|
|
|
13
13
|
expect(
|
|
14
14
|
removeUnwantedHtml(
|
|
15
|
-
"<p>String with <b>allowed <i>html</i></b><br /> and <
|
|
15
|
+
"<p>String with <b>allowed <i>html</i></b><br /> and <blink>NOT</blink> allowed html</p>",
|
|
16
16
|
),
|
|
17
17
|
).toBe(
|
|
18
18
|
"<p>String with <b>allowed <i>html</i></b><br /> and NOT allowed html</p>",
|
|
@@ -28,4 +28,38 @@ describe("sanitizeHTML", () => {
|
|
|
28
28
|
),
|
|
29
29
|
).toBe("<p>String <b>not allowed attribute</b> string</p>");
|
|
30
30
|
});
|
|
31
|
+
|
|
32
|
+
it("Can convert html entities to numerical entities", () => {
|
|
33
|
+
expect(
|
|
34
|
+
removeUnwantedHtml("föo ♥ bår 𝌆 baz"),
|
|
35
|
+
).toBe("föo ♥ bår 𝌆 baz");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("Can encode special charcaters to numerical characters", () => {
|
|
39
|
+
expect(removeUnwantedHtml("<p>foo © bar ≠ baz 𝌆 qux bla</p>")).toBe(
|
|
40
|
+
"<p>foo © bar ≠ baz 𝌆 qux bla</p>",
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(
|
|
44
|
+
removeUnwantedHtml(
|
|
45
|
+
"<p>foo © bar ≠ baz 𝌆 qux   bla</p>",
|
|
46
|
+
),
|
|
47
|
+
).toBe("<p>foo © bar ≠ baz 𝌆 qux   bla</p>");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("Keeps brackets", () => {
|
|
51
|
+
expect(
|
|
52
|
+
removeUnwantedHtml(
|
|
53
|
+
"The list of children [ Peter, Steven, Susan ] is up to date.",
|
|
54
|
+
),
|
|
55
|
+
).toBe("The list of children [ Peter, Steven, Susan ] is up to date.");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("Keeps curly brackets", () => {
|
|
59
|
+
expect(
|
|
60
|
+
removeUnwantedHtml(
|
|
61
|
+
"The list of children { Peter, Steven, Susan } is up to date.",
|
|
62
|
+
),
|
|
63
|
+
).toBe("The list of children { Peter, Steven, Susan } is up to date.");
|
|
64
|
+
});
|
|
31
65
|
});
|
|
@@ -12,13 +12,15 @@ var _exceptions = require("../../exceptions");
|
|
|
12
12
|
* When path is only one deep better use optional chaining
|
|
13
13
|
*/
|
|
14
14
|
const properEntityEncoding = html => {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
decimal: true
|
|
15
|
+
const htmlDecoded = _he.default.decode(html, {
|
|
16
|
+
decimal: true,
|
|
17
|
+
allowUnsafeSymbols: true
|
|
19
18
|
});
|
|
20
|
-
const
|
|
21
|
-
|
|
19
|
+
const htmlEncoded = _he.default.encode(htmlDecoded, {
|
|
20
|
+
decimal: true,
|
|
21
|
+
allowUnsafeSymbols: true
|
|
22
|
+
});
|
|
23
|
+
return htmlEncoded;
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -12,16 +12,17 @@ type removeUnwantedHtmlOptions = {
|
|
|
12
12
|
* When path is only one deep better use optional chaining
|
|
13
13
|
*/
|
|
14
14
|
const properEntityEncoding = (html: string) => {
|
|
15
|
-
const
|
|
16
|
-
const escapedLt = escapedGt.replace(/>/g, "]");
|
|
17
|
-
|
|
18
|
-
const properEntities = he.encode(he.decode(escapedLt), {
|
|
15
|
+
const htmlDecoded = he.decode(html, {
|
|
19
16
|
decimal: true,
|
|
17
|
+
allowUnsafeSymbols: true,
|
|
20
18
|
});
|
|
21
19
|
|
|
22
|
-
const
|
|
20
|
+
const htmlEncoded = he.encode(htmlDecoded, {
|
|
21
|
+
decimal: true,
|
|
22
|
+
allowUnsafeSymbols: true,
|
|
23
|
+
});
|
|
23
24
|
|
|
24
|
-
return
|
|
25
|
+
return htmlEncoded;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeHtml.js","names":["_he","_interopRequireDefault","require","_exceptions","properEntityEncoding","html","
|
|
1
|
+
{"version":3,"file":"sanitizeHtml.js","names":["_he","_interopRequireDefault","require","_exceptions","properEntityEncoding","html","htmlDecoded","he","decode","decimal","allowUnsafeSymbols","htmlEncoded","encode","removeUnwantedHtml","options","arguments","length","undefined","allowedTags","IllegalArgumentException","correctEntityHtml","htmlWithoutAttributes","replace","htmlWithCorrectBR","Array","isArray","join","pattern","regex","RegExp","exports"],"sources":["../../../src/utils/helpers/sanitizeHtml.js"],"sourcesContent":["// @flow\nimport he from \"he\";\n\nimport { IllegalArgumentException } from \"../../exceptions\";\n\ntype removeUnwantedHtmlOptions = {\n allowedTags?: Array<string>,\n};\n\n/**\n * Translates html entities to their correct decimal equivalent\n * When path is only one deep better use optional chaining\n */\nconst properEntityEncoding = (html: string) => {\n const htmlDecoded = he.decode(html, {\n decimal: true,\n allowUnsafeSymbols: true,\n });\n\n const htmlEncoded = he.encode(htmlDecoded, {\n decimal: true,\n allowUnsafeSymbols: true,\n });\n\n return htmlEncoded;\n};\n\n/**\n * removes unwanted html, this might result in incorrect html, as it removes all html that we don't except,\n * like <b style=\"font-weight: 400\">bold</b> will result in bold</b>\n */\nconst removeUnwantedHtml = (\n html: string,\n options: removeUnwantedHtmlOptions = {\n allowedTags: [\"p\", \"br\", \"b\", \"i\", \"u\", \"strike\"],\n },\n): string => {\n if (typeof html !== \"string\") {\n throw new IllegalArgumentException(\"sanitizeHTML method expects a string\");\n }\n\n const correctEntityHtml = properEntityEncoding(html);\n\n // remove attributes from html elements\n const htmlWithoutAttributes = correctEntityHtml.replace(\n /<(\\w+)(.|[\\r\\n])*?>/gi,\n \"<$1>\",\n );\n\n const htmlWithCorrectBR = htmlWithoutAttributes.replace(\n /<br\\s*>/gi,\n \"<br />\",\n );\n\n // remove not allowed tags\n const allowedTags = Array.isArray(options.allowedTags)\n ? options.allowedTags.join(\"|\")\n : \"\";\n const pattern = `<(?!\\\\/?(${allowedTags})(>|\\\\s\\\\/))[^<]+?>`;\n const regex = new RegExp(pattern, \"gi\");\n\n return htmlWithCorrectBR.replace(regex, \"\");\n};\n\nexport { removeUnwantedHtml };\n"],"mappings":";;;;;;;AACA,IAAAA,GAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,IAAAC,WAAA,GAAAD,OAAA;AAMA;AACA;AACA;AACA;AACA,MAAME,oBAAoB,GAAIC,IAAY,IAAK;EAC7C,MAAMC,WAAW,GAAGC,WAAE,CAACC,MAAM,CAACH,IAAI,EAAE;IAClCI,OAAO,EAAE,IAAI;IACbC,kBAAkB,EAAE;EACtB,CAAC,CAAC;EAEF,MAAMC,WAAW,GAAGJ,WAAE,CAACK,MAAM,CAACN,WAAW,EAAE;IACzCG,OAAO,EAAE,IAAI;IACbC,kBAAkB,EAAE;EACtB,CAAC,CAAC;EAEF,OAAOC,WAAW;AACpB,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAME,kBAAkB,GAAG,SAAAA,CACzBR,IAAY,EAID;EAAA,IAHXS,OAAkC,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG;IACnCG,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ;EAClD,CAAC;EAED,IAAI,OAAOb,IAAI,KAAK,QAAQ,EAAE;IAC5B,MAAM,IAAIc,oCAAwB,CAAC,sCAAsC,CAAC;EAC5E;EAEA,MAAMC,iBAAiB,GAAGhB,oBAAoB,CAACC,IAAI,CAAC;;EAEpD;EACA,MAAMgB,qBAAqB,GAAGD,iBAAiB,CAACE,OAAO,CACrD,uBAAuB,EACvB,MACF,CAAC;EAED,MAAMC,iBAAiB,GAAGF,qBAAqB,CAACC,OAAO,CACrD,WAAW,EACX,QACF,CAAC;;EAED;EACA,MAAMJ,WAAW,GAAGM,KAAK,CAACC,OAAO,CAACX,OAAO,CAACI,WAAW,CAAC,GAClDJ,OAAO,CAACI,WAAW,CAACQ,IAAI,CAAC,GAAG,CAAC,GAC7B,EAAE;EACN,MAAMC,OAAO,GAAI,YAAWT,WAAY,qBAAoB;EAC5D,MAAMU,KAAK,GAAG,IAAIC,MAAM,CAACF,OAAO,EAAE,IAAI,CAAC;EAEvC,OAAOJ,iBAAiB,CAACD,OAAO,CAACM,KAAK,EAAE,EAAE,CAAC;AAC7C,CAAC;AAACE,OAAA,CAAAjB,kBAAA,GAAAA,kBAAA"}
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@ describe("sanitizeHTML", () => {
|
|
|
12
12
|
|
|
13
13
|
expect(
|
|
14
14
|
removeUnwantedHtml(
|
|
15
|
-
"<p>String with <b>allowed <i>html</i></b><br /> and <
|
|
15
|
+
"<p>String with <b>allowed <i>html</i></b><br /> and <blink>NOT</blink> allowed html</p>",
|
|
16
16
|
),
|
|
17
17
|
).toBe(
|
|
18
18
|
"<p>String with <b>allowed <i>html</i></b><br /> and NOT allowed html</p>",
|
|
@@ -28,4 +28,38 @@ describe("sanitizeHTML", () => {
|
|
|
28
28
|
),
|
|
29
29
|
).toBe("<p>String <b>not allowed attribute</b> string</p>");
|
|
30
30
|
});
|
|
31
|
+
|
|
32
|
+
it("Can convert html entities to numerical entities", () => {
|
|
33
|
+
expect(
|
|
34
|
+
removeUnwantedHtml("föo ♥ bår 𝌆 baz"),
|
|
35
|
+
).toBe("föo ♥ bår 𝌆 baz");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("Can encode special charcaters to numerical characters", () => {
|
|
39
|
+
expect(removeUnwantedHtml("<p>foo © bar ≠ baz 𝌆 qux bla</p>")).toBe(
|
|
40
|
+
"<p>foo © bar ≠ baz 𝌆 qux bla</p>",
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(
|
|
44
|
+
removeUnwantedHtml(
|
|
45
|
+
"<p>foo © bar ≠ baz 𝌆 qux   bla</p>",
|
|
46
|
+
),
|
|
47
|
+
).toBe("<p>foo © bar ≠ baz 𝌆 qux   bla</p>");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("Keeps brackets", () => {
|
|
51
|
+
expect(
|
|
52
|
+
removeUnwantedHtml(
|
|
53
|
+
"The list of children [ Peter, Steven, Susan ] is up to date.",
|
|
54
|
+
),
|
|
55
|
+
).toBe("The list of children [ Peter, Steven, Susan ] is up to date.");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("Keeps curly brackets", () => {
|
|
59
|
+
expect(
|
|
60
|
+
removeUnwantedHtml(
|
|
61
|
+
"The list of children { Peter, Steven, Susan } is up to date.",
|
|
62
|
+
),
|
|
63
|
+
).toBe("The list of children { Peter, Steven, Susan } is up to date.");
|
|
64
|
+
});
|
|
31
65
|
});
|
|
@@ -12,16 +12,17 @@ type removeUnwantedHtmlOptions = {
|
|
|
12
12
|
* When path is only one deep better use optional chaining
|
|
13
13
|
*/
|
|
14
14
|
const properEntityEncoding = (html: string) => {
|
|
15
|
-
const
|
|
16
|
-
const escapedLt = escapedGt.replace(/>/g, "]");
|
|
17
|
-
|
|
18
|
-
const properEntities = he.encode(he.decode(escapedLt), {
|
|
15
|
+
const htmlDecoded = he.decode(html, {
|
|
19
16
|
decimal: true,
|
|
17
|
+
allowUnsafeSymbols: true,
|
|
20
18
|
});
|
|
21
19
|
|
|
22
|
-
const
|
|
20
|
+
const htmlEncoded = he.encode(htmlDecoded, {
|
|
21
|
+
decimal: true,
|
|
22
|
+
allowUnsafeSymbols: true,
|
|
23
|
+
});
|
|
23
24
|
|
|
24
|
-
return
|
|
25
|
+
return htmlEncoded;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
/**
|