url-sanitizer 0.2.2 → 0.3.0
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/README.md +28 -29
- package/dist/url-sanitizer.js +282 -55
- package/dist/url-sanitizer.js.map +3 -3
- package/dist/url-sanitizer.min.js +1 -1
- package/dist/url-sanitizer.min.js.map +4 -4
- package/package.json +3 -5
- package/src/lib/file/text-chars.json +233 -0
- package/src/mjs/uri-util.js +54 -62
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ For browsers and web sites, standalone ESM builds are available in `dist/` direc
|
|
|
17
17
|
* node_modules/url-sanitizer/dist/url-sanitizer.js
|
|
18
18
|
* node_modules/url-sanitizer/dist/url-sanitizer.min.js
|
|
19
19
|
|
|
20
|
-
Or, download
|
|
20
|
+
Or, download them from [Releases](https://github.com/asamuzaK/urlSanitizer/releases).
|
|
21
21
|
|
|
22
22
|
## Usage
|
|
23
23
|
|
|
@@ -30,13 +30,15 @@ import urlSanitizer, {
|
|
|
30
30
|
## sanitizeURL(url, opt)
|
|
31
31
|
|
|
32
32
|
Sanitize the given URL.
|
|
33
|
-
* `data` and
|
|
34
|
-
* `javascript` and
|
|
33
|
+
* `data` and `file` schemes must be explicitly allowed.
|
|
34
|
+
* `javascript` and `vbscript` schemes can not be allowed.
|
|
35
35
|
|
|
36
36
|
### Parameters
|
|
37
37
|
|
|
38
38
|
* `url` **[string][1]** URL input
|
|
39
|
-
* `opt` **[object][
|
|
39
|
+
* `opt` **[object][3]** options
|
|
40
|
+
* `opt.allow` **[Array][4]<[string][1]>** array of allowed schemes
|
|
41
|
+
* `opt.deny` **[Array][4]<[string][1]>** array of denied schemes
|
|
40
42
|
|
|
41
43
|
Returns **[Promise][5]<[string][1]?>** sanitized URL, `null`able
|
|
42
44
|
|
|
@@ -56,21 +58,6 @@ const res3 = await sanitizeURL(`data:text/html;base64,${base64data3}`, {
|
|
|
56
58
|
allow: ['data']
|
|
57
59
|
}).then(res => decodeURIComponent(res));
|
|
58
60
|
// -> 'data:text/html,<script>alert(1);</script>'
|
|
59
|
-
|
|
60
|
-
// Also an option if you don't want to escape tags and quotes in data URL
|
|
61
|
-
// But use it with care
|
|
62
|
-
const res4 = await sanitizeURL('data:image/svg+xml,%3Csvg%3E%3C/svg%3E', {
|
|
63
|
-
allow: ['data'],
|
|
64
|
-
escapeTags: false
|
|
65
|
-
}).then(res => decodeURIComponent(res));
|
|
66
|
-
// -> 'data:image/svg+xml,<svg></svg>'
|
|
67
|
-
|
|
68
|
-
const res5 = await sanitizeURL('data:text/html,%3Cscript%3Ealert(1);%3C/script%3E', {
|
|
69
|
-
allow: ['data'],
|
|
70
|
-
escapeTags: false
|
|
71
|
-
}).then(res => decodeURIComponent(res));
|
|
72
|
-
// WATCH OUT!!!
|
|
73
|
-
// -> 'data:text/html,<script>alert(1);</script>'
|
|
74
61
|
```
|
|
75
62
|
|
|
76
63
|
## sanitizeURLSync
|
|
@@ -85,8 +72,8 @@ Determines whether the given URI is valid.
|
|
|
85
72
|
|
|
86
73
|
* `uri` **[string][1]** URI input
|
|
87
74
|
|
|
88
|
-
Returns **[Promise][5]<[boolean][
|
|
89
|
-
* Always `true` for `web+*` and
|
|
75
|
+
Returns **[Promise][5]<[boolean][2]>** result
|
|
76
|
+
* Always `true` for `web+*` and `ext+*` schemes
|
|
90
77
|
|
|
91
78
|
```javascript
|
|
92
79
|
const res1 = await isURI('https://example.com/foo');
|
|
@@ -114,7 +101,7 @@ Get an array of URI schemes registered at [iana.org](https://www.iana.org/assign
|
|
|
114
101
|
* Historical schemes omitted.
|
|
115
102
|
* `moz-extension` scheme added.
|
|
116
103
|
|
|
117
|
-
Returns **[Array][
|
|
104
|
+
Returns **[Array][4]<[string][1]>** array of registered URI schemes
|
|
118
105
|
|
|
119
106
|
```javascript
|
|
120
107
|
const schemes = urlSanitizer.get();
|
|
@@ -129,7 +116,7 @@ Check if the given scheme is registered.
|
|
|
129
116
|
|
|
130
117
|
* `scheme` **[string][1]** scheme
|
|
131
118
|
|
|
132
|
-
Returns **[boolean][
|
|
119
|
+
Returns **[boolean][2]** result
|
|
133
120
|
|
|
134
121
|
```javascript
|
|
135
122
|
const res1 = urlSanitizer.has('https');
|
|
@@ -142,17 +129,23 @@ const res2 = urlSanitizer.has('foo');
|
|
|
142
129
|
### urlSanitizer.add(scheme)
|
|
143
130
|
|
|
144
131
|
Add a scheme to the list of URI schemes.
|
|
145
|
-
* `javascript` and
|
|
132
|
+
* `javascript` and `vbscript` schemes can not be registered. It throws.
|
|
146
133
|
|
|
147
134
|
#### Parameters
|
|
148
135
|
|
|
149
136
|
* `scheme` **[string][1]** scheme
|
|
150
137
|
|
|
151
|
-
Returns **[Array][
|
|
138
|
+
Returns **[Array][4]<[string][1]>** array of registered URI schemes
|
|
152
139
|
|
|
153
140
|
```javascript
|
|
141
|
+
console.log(isURISync('foo'));
|
|
142
|
+
// -> false;
|
|
143
|
+
|
|
154
144
|
const res = urlSanitizer.add('foo');
|
|
155
145
|
// -> ['aaa', 'aaas', 'about', 'acap', 'acct', 'acd', ... 'foo', ...];
|
|
146
|
+
|
|
147
|
+
console.log(isURISync('foo'));
|
|
148
|
+
// -> true;
|
|
156
149
|
```
|
|
157
150
|
|
|
158
151
|
### urlSanitizer.remove(scheme)
|
|
@@ -163,23 +156,29 @@ Remove a scheme from the list of URI schemes.
|
|
|
163
156
|
|
|
164
157
|
* `scheme` **[string][1]** scheme
|
|
165
158
|
|
|
166
|
-
Returns **[boolean][
|
|
159
|
+
Returns **[boolean][2]** result
|
|
167
160
|
* `true` if the scheme is successfully removed, `false` otherwise.
|
|
168
161
|
|
|
169
162
|
```javascript
|
|
163
|
+
console.log(isURISync('aaa'));
|
|
164
|
+
// -> true;
|
|
165
|
+
|
|
170
166
|
const res1 = urlSanitizer.remove('aaa');
|
|
171
167
|
// -> true
|
|
172
168
|
|
|
169
|
+
console.log(isURISync('aaa'));
|
|
170
|
+
// -> false;
|
|
171
|
+
|
|
173
172
|
const res2 = urlSanitizer.remove('foo');
|
|
174
173
|
// -> false
|
|
175
174
|
```
|
|
176
175
|
|
|
177
176
|
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
|
178
177
|
|
|
179
|
-
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/
|
|
178
|
+
[2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
180
179
|
|
|
181
|
-
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/
|
|
180
|
+
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
|
182
181
|
|
|
183
|
-
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/
|
|
182
|
+
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
184
183
|
|
|
185
184
|
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
package/dist/url-sanitizer.js
CHANGED
|
@@ -4,6 +4,241 @@ var TYPE_TO = -1;
|
|
|
4
4
|
var getType = (o) => Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);
|
|
5
5
|
var isString = (o) => typeof o === "string" || o instanceof String;
|
|
6
6
|
|
|
7
|
+
// src/lib/file/text-chars.json
|
|
8
|
+
var text_chars_default = [
|
|
9
|
+
7,
|
|
10
|
+
8,
|
|
11
|
+
9,
|
|
12
|
+
10,
|
|
13
|
+
11,
|
|
14
|
+
12,
|
|
15
|
+
13,
|
|
16
|
+
27,
|
|
17
|
+
32,
|
|
18
|
+
33,
|
|
19
|
+
34,
|
|
20
|
+
35,
|
|
21
|
+
36,
|
|
22
|
+
37,
|
|
23
|
+
38,
|
|
24
|
+
39,
|
|
25
|
+
40,
|
|
26
|
+
41,
|
|
27
|
+
42,
|
|
28
|
+
43,
|
|
29
|
+
44,
|
|
30
|
+
45,
|
|
31
|
+
46,
|
|
32
|
+
47,
|
|
33
|
+
48,
|
|
34
|
+
49,
|
|
35
|
+
50,
|
|
36
|
+
51,
|
|
37
|
+
52,
|
|
38
|
+
53,
|
|
39
|
+
54,
|
|
40
|
+
55,
|
|
41
|
+
56,
|
|
42
|
+
57,
|
|
43
|
+
58,
|
|
44
|
+
59,
|
|
45
|
+
60,
|
|
46
|
+
61,
|
|
47
|
+
62,
|
|
48
|
+
63,
|
|
49
|
+
64,
|
|
50
|
+
65,
|
|
51
|
+
66,
|
|
52
|
+
67,
|
|
53
|
+
68,
|
|
54
|
+
69,
|
|
55
|
+
70,
|
|
56
|
+
71,
|
|
57
|
+
72,
|
|
58
|
+
73,
|
|
59
|
+
74,
|
|
60
|
+
75,
|
|
61
|
+
76,
|
|
62
|
+
77,
|
|
63
|
+
78,
|
|
64
|
+
79,
|
|
65
|
+
80,
|
|
66
|
+
81,
|
|
67
|
+
82,
|
|
68
|
+
83,
|
|
69
|
+
84,
|
|
70
|
+
85,
|
|
71
|
+
86,
|
|
72
|
+
87,
|
|
73
|
+
88,
|
|
74
|
+
89,
|
|
75
|
+
90,
|
|
76
|
+
91,
|
|
77
|
+
92,
|
|
78
|
+
93,
|
|
79
|
+
94,
|
|
80
|
+
95,
|
|
81
|
+
96,
|
|
82
|
+
97,
|
|
83
|
+
98,
|
|
84
|
+
99,
|
|
85
|
+
100,
|
|
86
|
+
101,
|
|
87
|
+
102,
|
|
88
|
+
103,
|
|
89
|
+
104,
|
|
90
|
+
105,
|
|
91
|
+
106,
|
|
92
|
+
107,
|
|
93
|
+
108,
|
|
94
|
+
109,
|
|
95
|
+
110,
|
|
96
|
+
111,
|
|
97
|
+
112,
|
|
98
|
+
113,
|
|
99
|
+
114,
|
|
100
|
+
115,
|
|
101
|
+
116,
|
|
102
|
+
117,
|
|
103
|
+
118,
|
|
104
|
+
119,
|
|
105
|
+
120,
|
|
106
|
+
121,
|
|
107
|
+
122,
|
|
108
|
+
123,
|
|
109
|
+
124,
|
|
110
|
+
125,
|
|
111
|
+
126,
|
|
112
|
+
128,
|
|
113
|
+
129,
|
|
114
|
+
130,
|
|
115
|
+
131,
|
|
116
|
+
132,
|
|
117
|
+
133,
|
|
118
|
+
134,
|
|
119
|
+
135,
|
|
120
|
+
136,
|
|
121
|
+
137,
|
|
122
|
+
138,
|
|
123
|
+
139,
|
|
124
|
+
140,
|
|
125
|
+
141,
|
|
126
|
+
142,
|
|
127
|
+
143,
|
|
128
|
+
144,
|
|
129
|
+
145,
|
|
130
|
+
146,
|
|
131
|
+
147,
|
|
132
|
+
148,
|
|
133
|
+
149,
|
|
134
|
+
150,
|
|
135
|
+
151,
|
|
136
|
+
152,
|
|
137
|
+
153,
|
|
138
|
+
154,
|
|
139
|
+
155,
|
|
140
|
+
156,
|
|
141
|
+
157,
|
|
142
|
+
158,
|
|
143
|
+
159,
|
|
144
|
+
160,
|
|
145
|
+
161,
|
|
146
|
+
162,
|
|
147
|
+
163,
|
|
148
|
+
164,
|
|
149
|
+
165,
|
|
150
|
+
166,
|
|
151
|
+
167,
|
|
152
|
+
168,
|
|
153
|
+
169,
|
|
154
|
+
170,
|
|
155
|
+
171,
|
|
156
|
+
172,
|
|
157
|
+
173,
|
|
158
|
+
174,
|
|
159
|
+
175,
|
|
160
|
+
176,
|
|
161
|
+
177,
|
|
162
|
+
178,
|
|
163
|
+
179,
|
|
164
|
+
180,
|
|
165
|
+
181,
|
|
166
|
+
182,
|
|
167
|
+
183,
|
|
168
|
+
184,
|
|
169
|
+
185,
|
|
170
|
+
186,
|
|
171
|
+
187,
|
|
172
|
+
188,
|
|
173
|
+
189,
|
|
174
|
+
190,
|
|
175
|
+
191,
|
|
176
|
+
192,
|
|
177
|
+
193,
|
|
178
|
+
194,
|
|
179
|
+
195,
|
|
180
|
+
196,
|
|
181
|
+
197,
|
|
182
|
+
198,
|
|
183
|
+
199,
|
|
184
|
+
200,
|
|
185
|
+
201,
|
|
186
|
+
202,
|
|
187
|
+
203,
|
|
188
|
+
204,
|
|
189
|
+
205,
|
|
190
|
+
206,
|
|
191
|
+
207,
|
|
192
|
+
208,
|
|
193
|
+
209,
|
|
194
|
+
210,
|
|
195
|
+
211,
|
|
196
|
+
212,
|
|
197
|
+
213,
|
|
198
|
+
214,
|
|
199
|
+
215,
|
|
200
|
+
216,
|
|
201
|
+
217,
|
|
202
|
+
218,
|
|
203
|
+
219,
|
|
204
|
+
220,
|
|
205
|
+
221,
|
|
206
|
+
222,
|
|
207
|
+
223,
|
|
208
|
+
224,
|
|
209
|
+
225,
|
|
210
|
+
226,
|
|
211
|
+
227,
|
|
212
|
+
228,
|
|
213
|
+
229,
|
|
214
|
+
230,
|
|
215
|
+
231,
|
|
216
|
+
232,
|
|
217
|
+
233,
|
|
218
|
+
234,
|
|
219
|
+
235,
|
|
220
|
+
236,
|
|
221
|
+
237,
|
|
222
|
+
238,
|
|
223
|
+
239,
|
|
224
|
+
240,
|
|
225
|
+
241,
|
|
226
|
+
242,
|
|
227
|
+
243,
|
|
228
|
+
244,
|
|
229
|
+
245,
|
|
230
|
+
246,
|
|
231
|
+
247,
|
|
232
|
+
248,
|
|
233
|
+
249,
|
|
234
|
+
250,
|
|
235
|
+
251,
|
|
236
|
+
252,
|
|
237
|
+
253,
|
|
238
|
+
254,
|
|
239
|
+
255
|
|
240
|
+
];
|
|
241
|
+
|
|
7
242
|
// src/lib/iana/uri-schemes.json
|
|
8
243
|
var uri_schemes_default = [
|
|
9
244
|
"aaa",
|
|
@@ -399,13 +634,7 @@ var parseBase64 = (data) => {
|
|
|
399
634
|
}
|
|
400
635
|
const bin = atob(data);
|
|
401
636
|
const uint8arr = Uint8Array.from([...bin].map((c) => c.charCodeAt(0)));
|
|
402
|
-
const textChars =
|
|
403
|
-
for (let i = 32; i < 127; i++) {
|
|
404
|
-
textChars.add(i);
|
|
405
|
-
}
|
|
406
|
-
for (let i = 128; i <= 255; i++) {
|
|
407
|
-
textChars.add(i);
|
|
408
|
-
}
|
|
637
|
+
const textChars = new Set(text_chars_default);
|
|
409
638
|
let parsedData;
|
|
410
639
|
if (uint8arr.every((c) => textChars.has(c))) {
|
|
411
640
|
parsedData = bin.replace(/\s/g, getUrlEncodedString);
|
|
@@ -490,6 +719,15 @@ var URISchemes = class {
|
|
|
490
719
|
}
|
|
491
720
|
};
|
|
492
721
|
var URLSanitizer = class extends URISchemes {
|
|
722
|
+
/* private fields */
|
|
723
|
+
#recurse;
|
|
724
|
+
/**
|
|
725
|
+
* construct
|
|
726
|
+
*/
|
|
727
|
+
constructor() {
|
|
728
|
+
super();
|
|
729
|
+
this.#recurse = /* @__PURE__ */ new Map();
|
|
730
|
+
}
|
|
493
731
|
/**
|
|
494
732
|
* sanitize URL
|
|
495
733
|
* NOTE: `data` and/or `file` schemes must be explicitly allowed
|
|
@@ -499,13 +737,12 @@ var URLSanitizer = class extends URISchemes {
|
|
|
499
737
|
* @param {object} opt - options
|
|
500
738
|
* @param {Array.<string>} opt.allow - array of allowed schemes
|
|
501
739
|
* @param {Array.<string>} opt.deny - array of denied schemes
|
|
502
|
-
* @param {boolean} opt.escapeTags - escape tags and quotes in data URL
|
|
503
740
|
* @returns {?string} - sanitized URL
|
|
504
741
|
*/
|
|
505
|
-
sanitize(url, opt = { allow: [], deny: []
|
|
742
|
+
sanitize(url, opt = { allow: [], deny: [] }) {
|
|
506
743
|
let sanitizedUrl;
|
|
507
744
|
if (super.isURI(url)) {
|
|
508
|
-
const { allow, deny
|
|
745
|
+
const { allow, deny } = opt ?? {};
|
|
509
746
|
const { href, pathname, protocol } = new URL(url);
|
|
510
747
|
const scheme = protocol.replace(/:$/, "");
|
|
511
748
|
const schemeParts = scheme.split("+");
|
|
@@ -555,66 +792,57 @@ var URLSanitizer = class extends URISchemes {
|
|
|
555
792
|
if (isBase64) {
|
|
556
793
|
let parsedData = parseBase64(data);
|
|
557
794
|
if (parsedData !== data) {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
795
|
+
if (/data:[^,]*,/.test(parsedData)) {
|
|
796
|
+
const regDataUrl = /data:[^,]*,[^"]+/g;
|
|
797
|
+
const regBase64DataUrl = /data:[^,]*;?base64,[\dA-Za-z+/\-_=]+/;
|
|
798
|
+
const matchedDataUrls = parsedData.matchAll(regDataUrl);
|
|
799
|
+
const items = [...matchedDataUrls].reverse();
|
|
800
|
+
if (items.length) {
|
|
801
|
+
for (const item of items) {
|
|
802
|
+
const { index } = item;
|
|
803
|
+
let [dataUrl] = item;
|
|
804
|
+
if (regBase64DataUrl.test(dataUrl)) {
|
|
805
|
+
[dataUrl] = regBase64DataUrl.exec(dataUrl);
|
|
806
|
+
}
|
|
807
|
+
const [beforeDataUrl, afterDataUrl] = [
|
|
808
|
+
parsedData.substring(0, index),
|
|
809
|
+
parsedData.substring(index + dataUrl.length)
|
|
810
|
+
];
|
|
811
|
+
this.#recurse.set(dataUrl, dataUrl);
|
|
570
812
|
const parsedDataUrl = this.sanitize(dataUrl, {
|
|
571
813
|
allow: ["data"]
|
|
572
814
|
});
|
|
573
815
|
if (parsedDataUrl) {
|
|
574
|
-
parsedData =
|
|
816
|
+
parsedData = [
|
|
817
|
+
beforeDataUrl,
|
|
818
|
+
parsedDataUrl,
|
|
819
|
+
afterDataUrl
|
|
820
|
+
].join("");
|
|
575
821
|
}
|
|
576
|
-
type = 0;
|
|
577
822
|
}
|
|
578
823
|
}
|
|
579
|
-
} else if (/data:[^,]*,/.test(parsedData) && !(escapeTags ?? true)) {
|
|
580
|
-
const dataArr = parsedData.split(/data:[^,]*,/);
|
|
581
|
-
const l = dataArr.length;
|
|
582
|
-
let i = 1;
|
|
583
|
-
while (i < l) {
|
|
584
|
-
const dataItem = dataArr[i].replace(regEncodedChars, escapeUrlEncodedHtmlChars);
|
|
585
|
-
parsedData = parsedData.replace(dataArr[i], dataItem);
|
|
586
|
-
i++;
|
|
587
|
-
}
|
|
588
|
-
type = 0;
|
|
589
824
|
}
|
|
590
|
-
|
|
591
|
-
|
|
825
|
+
if (this.#recurse.has(url)) {
|
|
826
|
+
this.#recurse.delete(url);
|
|
827
|
+
} else {
|
|
592
828
|
type = 1;
|
|
593
|
-
} else if (!Number.isInteger(type)) {
|
|
594
|
-
type = 2;
|
|
595
829
|
}
|
|
596
|
-
|
|
597
|
-
type = 1;
|
|
830
|
+
urlToSanitize = `${scheme}:${mediaType.join(";")},${parsedData}`;
|
|
598
831
|
} else {
|
|
599
|
-
type =
|
|
832
|
+
type = 1;
|
|
600
833
|
}
|
|
601
|
-
} else if (
|
|
602
|
-
|
|
834
|
+
} else if (this.#recurse.has(url)) {
|
|
835
|
+
this.#recurse.delete(url);
|
|
603
836
|
} else {
|
|
604
|
-
type =
|
|
837
|
+
type = 1;
|
|
605
838
|
}
|
|
606
839
|
} else {
|
|
607
840
|
type = 1;
|
|
608
841
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
case 2:
|
|
614
|
-
sanitizedUrl = urlToSanitize.replace(regChars, getUrlEncodedString).replace(regAmp, escapeUrlEncodedHtmlChars);
|
|
615
|
-
break;
|
|
616
|
-
default:
|
|
617
|
-
sanitizedUrl = urlToSanitize.replace(regChars, getUrlEncodedString);
|
|
842
|
+
if (type === 1) {
|
|
843
|
+
sanitizedUrl = urlToSanitize.replace(regChars, getUrlEncodedString).replace(regAmp, escapeUrlEncodedHtmlChars).replace(regEncodedChars, escapeUrlEncodedHtmlChars);
|
|
844
|
+
} else {
|
|
845
|
+
sanitizedUrl = urlToSanitize.replace(regChars, getUrlEncodedString).replace(regAmp, escapeUrlEncodedHtmlChars);
|
|
618
846
|
}
|
|
619
847
|
}
|
|
620
848
|
}
|
|
@@ -629,8 +857,7 @@ var isURI = async (uri) => {
|
|
|
629
857
|
};
|
|
630
858
|
var sanitizeUrl = (url, opt) => urlSanitizer.sanitize(url, opt ?? {
|
|
631
859
|
allow: [],
|
|
632
|
-
deny: []
|
|
633
|
-
escapeTags: true
|
|
860
|
+
deny: []
|
|
634
861
|
});
|
|
635
862
|
var sanitizeURL = async (url, opt) => {
|
|
636
863
|
const res = await sanitizeUrl(url, opt);
|