@instructure/platform-sanitize 0.2.1

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitizeHtml.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeHtml.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sanitizeHtml.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitizeUrl.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeUrl.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sanitizeUrl.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { sanitizeHtml } from './sanitizeHtml';
2
+ export { sanitizeUrl } from './sanitizeUrl';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,194 @@
1
+ import n from "dompurify";
2
+ const d = /* @__PURE__ */ new Set([
3
+ // layout
4
+ "display",
5
+ "float",
6
+ "clear",
7
+ "overflow",
8
+ "overflow-x",
9
+ "overflow-y",
10
+ "visibility",
11
+ "cursor",
12
+ "direction",
13
+ "user-select",
14
+ "zoom",
15
+ // sizing
16
+ "width",
17
+ "height",
18
+ "min-width",
19
+ "min-height",
20
+ "max-width",
21
+ "max-height",
22
+ // spacing
23
+ "margin",
24
+ "margin-top",
25
+ "margin-right",
26
+ "margin-bottom",
27
+ "margin-left",
28
+ "margin-offset",
29
+ "padding",
30
+ "padding-top",
31
+ "padding-right",
32
+ "padding-bottom",
33
+ "padding-left",
34
+ // typography
35
+ "font",
36
+ "font-family",
37
+ "font-size",
38
+ "font-style",
39
+ "font-variant",
40
+ "font-weight",
41
+ "font-stretch",
42
+ "font-width",
43
+ "line-height",
44
+ "text-align",
45
+ "text-decoration",
46
+ "text-indent",
47
+ "white-space",
48
+ "vertical-align",
49
+ // color & background
50
+ "color",
51
+ "background",
52
+ "background-color",
53
+ "background-image",
54
+ "background-attachment",
55
+ "background-position",
56
+ "background-position-x",
57
+ "background-position-y",
58
+ "background-repeat",
59
+ // border
60
+ "border",
61
+ "border-color",
62
+ "border-style",
63
+ "border-width",
64
+ "border-radius",
65
+ "border-collapse",
66
+ "border-spacing",
67
+ "border-top",
68
+ "border-top-color",
69
+ "border-top-style",
70
+ "border-top-width",
71
+ "border-right",
72
+ "border-right-color",
73
+ "border-right-style",
74
+ "border-right-width",
75
+ "border-bottom",
76
+ "border-bottom-color",
77
+ "border-bottom-style",
78
+ "border-bottom-width",
79
+ "border-left",
80
+ "border-left-color",
81
+ "border-left-style",
82
+ "border-left-width",
83
+ // list
84
+ "list-style",
85
+ "list-style-image",
86
+ "list-style-position",
87
+ "list-style-type",
88
+ // table
89
+ "table-layout",
90
+ // flex
91
+ "flex",
92
+ "flex-basis",
93
+ "flex-direction",
94
+ "flex-flow",
95
+ "flex-grow",
96
+ "flex-shrink",
97
+ "flex-wrap",
98
+ "align-content",
99
+ "align-items",
100
+ "align-self",
101
+ "justify-content",
102
+ "justify-items",
103
+ "justify-self",
104
+ "order",
105
+ "gap",
106
+ "row-gap",
107
+ "column-gap",
108
+ "place-content",
109
+ "place-items",
110
+ "place-self",
111
+ // grid
112
+ "grid",
113
+ "grid-area",
114
+ "grid-auto-columns",
115
+ "grid-auto-flow",
116
+ "grid-auto-rows",
117
+ "grid-column",
118
+ "grid-column-end",
119
+ "grid-column-gap",
120
+ "grid-column-start",
121
+ "grid-gap",
122
+ "grid-row",
123
+ "grid-row-end",
124
+ "grid-row-gap",
125
+ "grid-row-start",
126
+ "grid-template",
127
+ "grid-template-areas",
128
+ "grid-template-columns",
129
+ "grid-template-rows"
130
+ ]), s = {
131
+ ADD_TAGS: ["iframe"],
132
+ ADD_ATTR: [
133
+ "allowfullscreen",
134
+ "allow",
135
+ "frameborder",
136
+ "sandbox",
137
+ "data-media-id",
138
+ "data-media-type",
139
+ // RCE produces target="_blank" for external links. Modern browsers treat
140
+ // target="_blank" as implicit rel="noopener", and the backend allowlist
141
+ // already includes target.
142
+ "target",
143
+ "webkitallowfullscreen",
144
+ "mozallowfullscreen",
145
+ "scrolling"
146
+ ],
147
+ // Rails UJS turns data-method/data-remote/etc. on clickable elements into
148
+ // state-changing requests carrying the victim's CSRF token. Strip them so
149
+ // user-authored HTML cannot become a CSRF gadget when UJS is on the page.
150
+ FORBID_ATTR: ["data-method", "data-remote", "data-url", "data-confirm", "data-disable-with"],
151
+ // In browsers that support the Trusted Types API (Chromium, Firefox),
152
+ // DOMPurify returns a TrustedHTML object rather than a plain string. The
153
+ // exported sanitizeHtml signature declares string — a deliberate lie that
154
+ // mirrors the same lie the browser DOM lib (Element.innerHTML: string),
155
+ // React (__html: string), and jQuery (html(string)) already tell. All those
156
+ // sinks runtime-accept TrustedHTML even though their TS signatures only
157
+ // declare string; lying here lets callers assign the result directly without
158
+ // a per-call cast. Do not perform string operations (.slice, .match, etc.)
159
+ // on the return value — those methods do not exist on TrustedHTML and will
160
+ // throw in modern browsers.
161
+ RETURN_TRUSTED_TYPE: !0
162
+ };
163
+ let o = null;
164
+ function f() {
165
+ return o || (o = typeof n == "function" ? n(window) : n, o.addHook("afterSanitizeAttributes", (t) => {
166
+ if (!(t instanceof Element) || !t.hasAttribute("style")) return;
167
+ const e = t.style, i = [];
168
+ for (let r = 0; r < e.length; r++) {
169
+ const a = e.item(r);
170
+ d.has(a) || i.push(a);
171
+ }
172
+ for (const r of i) e.removeProperty(r);
173
+ e.length === 0 && t.removeAttribute("style");
174
+ }), o);
175
+ }
176
+ function m(t) {
177
+ if (typeof window > "u")
178
+ throw new Error("sanitizeHtml requires a DOM environment (window is not defined)");
179
+ return f().sanitize(t ?? "", s);
180
+ }
181
+ const g = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]), l = "http://platform-sanitize.invalid/";
182
+ function b(t) {
183
+ if (!t || !t.trim()) return "about:blank";
184
+ try {
185
+ const e = new URL(t, l);
186
+ return g.has(e.protocol) ? e.href.startsWith(l) ? t : e.href : "about:blank";
187
+ } catch {
188
+ return "about:blank";
189
+ }
190
+ }
191
+ export {
192
+ m as sanitizeHtml,
193
+ b as sanitizeUrl
194
+ };
@@ -0,0 +1,2 @@
1
+ export declare function sanitizeHtml(html: string | null | undefined): string;
2
+ //# sourceMappingURL=sanitizeHtml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeHtml.d.ts","sourceRoot":"","sources":["../src/sanitizeHtml.ts"],"names":[],"mappings":"AAyMA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAKpE"}
@@ -0,0 +1,2 @@
1
+ export declare function sanitizeUrl(url: string | null | undefined): string;
2
+ //# sourceMappingURL=sanitizeUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizeUrl.d.ts","sourceRoot":"","sources":["../src/sanitizeUrl.ts"],"names":[],"mappings":"AAiBA,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAYlE"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@instructure/platform-sanitize",
3
+ "version": "0.2.1",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "peerDependencies": {
21
+ "dompurify": "^3.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "@vitest/coverage-v8": "^4.0.17",
25
+ "dompurify": "^3.0.0",
26
+ "jsdom": "^25.0.0",
27
+ "typescript": "^5.3.0",
28
+ "vite": "^6.0.0",
29
+ "vite-plugin-dts": "^4.0.0",
30
+ "vitest": "^4.0.0"
31
+ },
32
+ "scripts": {
33
+ "build": "vite build",
34
+ "dev": "vite build --watch",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "test:coverage": "vitest run --coverage",
38
+ "type-check": "tsc --noEmit"
39
+ }
40
+ }