@devvit/shared-types 0.11.0-next-2024-10-03-38b7c67ab.0 → 0.11.0-next-2024-10-03-ca1abc4bf.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +6 -6
- package/imageUtil.d.ts +0 -20
- package/imageUtil.d.ts.map +0 -1
- package/imageUtil.js +0 -89
- package/imageUtil.test.d.ts.map +0 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@devvit/shared-types",
|
3
|
-
"version": "0.11.0-next-2024-10-03-
|
3
|
+
"version": "0.11.0-next-2024-10-03-ca1abc4bf.0",
|
4
4
|
"license": "BSD-3-Clause",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -24,14 +24,14 @@
|
|
24
24
|
},
|
25
25
|
"types": "./index.d.ts",
|
26
26
|
"dependencies": {
|
27
|
-
"@devvit/protos": "0.11.0-next-2024-10-03-
|
27
|
+
"@devvit/protos": "0.11.0-next-2024-10-03-ca1abc4bf.0",
|
28
28
|
"jsonschema": "1.4.1",
|
29
29
|
"uuid": "9.0.0"
|
30
30
|
},
|
31
31
|
"devDependencies": {
|
32
|
-
"@devvit/eslint-config": "0.11.0-next-2024-10-03-
|
33
|
-
"@devvit/repo-tools": "0.11.0-next-2024-10-03-
|
34
|
-
"@devvit/tsconfig": "0.11.0-next-2024-10-03-
|
32
|
+
"@devvit/eslint-config": "0.11.0-next-2024-10-03-ca1abc4bf.0",
|
33
|
+
"@devvit/repo-tools": "0.11.0-next-2024-10-03-ca1abc4bf.0",
|
34
|
+
"@devvit/tsconfig": "0.11.0-next-2024-10-03-ca1abc4bf.0",
|
35
35
|
"@types/redis-mock": "0.17.1",
|
36
36
|
"@types/uuid": "9.0.0",
|
37
37
|
"eslint": "8.9.0",
|
@@ -45,5 +45,5 @@
|
|
45
45
|
"directory": "dist"
|
46
46
|
},
|
47
47
|
"source": "./src/index.ts",
|
48
|
-
"gitHead": "
|
48
|
+
"gitHead": "ce4d984e1fa96c9101f82748de3abe03002cda87"
|
49
49
|
}
|
package/imageUtil.d.ts
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
export declare const REDD_IT = "redd.it";
|
2
|
-
export declare const REDDIT_STATIC = "redditstatic.com";
|
3
|
-
export declare const REDDIT_MEDIA = "redditmedia.com";
|
4
|
-
export declare const SNOO_DEV = "snoo.dev";
|
5
|
-
export declare const VerifiedPublicImageHosts: readonly string[];
|
6
|
-
export declare const VerifiedImageHosts: readonly string[];
|
7
|
-
/**
|
8
|
-
* Validates whether an image URL is allowed to be displayed
|
9
|
-
* @param imageUrl
|
10
|
-
* @returns true if the URL is allowed
|
11
|
-
*/
|
12
|
-
export declare function isValidImageURL(imageUrl: string): boolean;
|
13
|
-
/**
|
14
|
-
* Performs any sanitization needed on a given image URL
|
15
|
-
* Currently only processes SVG data URIs
|
16
|
-
* @param imageUrl
|
17
|
-
* @returns the sanitized URL
|
18
|
-
*/
|
19
|
-
export declare function sanitizeImageURL(imageUrl: string): string | undefined;
|
20
|
-
//# sourceMappingURL=imageUtil.d.ts.map
|
package/imageUtil.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"imageUtil.d.ts","sourceRoot":"","sources":["../src/imageUtil.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,aAAa,qBAAqB,CAAC;AAChD,eAAO,MAAM,YAAY,oBAAoB,CAAC;AAC9C,eAAO,MAAM,QAAQ,aAAa,CAAC;AAEnC,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAClG,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAK/C,CAAC;AAoBF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAgBzD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAsCrE"}
|
package/imageUtil.js
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
// Only the following domains are approved: redd.it, redditstatic.com, redditmedia.com, or snoo.dev
|
2
|
-
import { sanitizeSvg } from './sanitizeSvg.js';
|
3
|
-
export const REDD_IT = 'redd.it';
|
4
|
-
export const REDDIT_STATIC = 'redditstatic.com';
|
5
|
-
export const REDDIT_MEDIA = 'redditmedia.com';
|
6
|
-
export const SNOO_DEV = 'snoo.dev';
|
7
|
-
export const VerifiedPublicImageHosts = [REDD_IT, REDDIT_STATIC, REDDIT_MEDIA];
|
8
|
-
export const VerifiedImageHosts = [
|
9
|
-
SNOO_DEV,
|
10
|
-
REDD_IT,
|
11
|
-
REDDIT_STATIC,
|
12
|
-
REDDIT_MEDIA,
|
13
|
-
];
|
14
|
-
const MIME_SVG_XML = 'image/svg+xml';
|
15
|
-
const ALLOWED_DATA_MIMETYPES = [MIME_SVG_XML];
|
16
|
-
function validateDataUrl(url) {
|
17
|
-
// mediaType is everything before the data section
|
18
|
-
const mediaType = url.pathname.split(',')[0];
|
19
|
-
// chunks are separated by semicolons, with the first being the mimetype
|
20
|
-
const mimetype = mediaType.split(';')[0];
|
21
|
-
return ALLOWED_DATA_MIMETYPES.includes(mimetype);
|
22
|
-
}
|
23
|
-
function validateHttpUrl(url) {
|
24
|
-
// Get just the domain name from the hostname
|
25
|
-
const domain = url.hostname.split('.').slice(-2).join('.');
|
26
|
-
return VerifiedImageHosts.includes(domain);
|
27
|
-
}
|
28
|
-
/**
|
29
|
-
* Validates whether an image URL is allowed to be displayed
|
30
|
-
* @param imageUrl
|
31
|
-
* @returns true if the URL is allowed
|
32
|
-
*/
|
33
|
-
export function isValidImageURL(imageUrl) {
|
34
|
-
try {
|
35
|
-
const url = new URL(imageUrl);
|
36
|
-
const protocol = url.protocol.substring(0, 4);
|
37
|
-
switch (protocol) {
|
38
|
-
case 'blob':
|
39
|
-
return true;
|
40
|
-
case 'data':
|
41
|
-
return validateDataUrl(url);
|
42
|
-
case 'http':
|
43
|
-
return validateHttpUrl(url);
|
44
|
-
}
|
45
|
-
}
|
46
|
-
catch (_) {
|
47
|
-
// invalid imageUrl
|
48
|
-
}
|
49
|
-
return false;
|
50
|
-
}
|
51
|
-
/**
|
52
|
-
* Performs any sanitization needed on a given image URL
|
53
|
-
* Currently only processes SVG data URIs
|
54
|
-
* @param imageUrl
|
55
|
-
* @returns the sanitized URL
|
56
|
-
*/
|
57
|
-
export function sanitizeImageURL(imageUrl) {
|
58
|
-
try {
|
59
|
-
// only parse up until the data segment so we don't waste time parsing it here
|
60
|
-
const dataSeparator = imageUrl.indexOf(',');
|
61
|
-
const url = new URL(dataSeparator > 0 ? imageUrl.slice(0, dataSeparator) : imageUrl);
|
62
|
-
// nothing to sanitize
|
63
|
-
if (url.protocol.startsWith('http') || url.protocol.startsWith('blob')) {
|
64
|
-
return encodeURI(imageUrl);
|
65
|
-
}
|
66
|
-
const mediaType = url.pathname;
|
67
|
-
const [mimetype] = mediaType.split(';');
|
68
|
-
// can't sanitize binary image data
|
69
|
-
if (mimetype !== MIME_SVG_XML) {
|
70
|
-
return imageUrl;
|
71
|
-
}
|
72
|
-
const base64 = mediaType.split(';').at(-1) === 'base64';
|
73
|
-
const data = imageUrl.slice(dataSeparator + 1);
|
74
|
-
const svgData = base64 ? atob(data) : data;
|
75
|
-
// extract SVG
|
76
|
-
const svg = decodeURIComponent(svgData);
|
77
|
-
// sanitize
|
78
|
-
const safeSvg = sanitizeSvg(svg);
|
79
|
-
if (safeSvg === undefined) {
|
80
|
-
return undefined;
|
81
|
-
}
|
82
|
-
// URI encode if we're not base64 encoding to ensure the img tag doesn't choke on `#` and `?` characters
|
83
|
-
const safeData = base64 ? btoa(safeSvg) : encodeURIComponent(safeSvg);
|
84
|
-
return `data:${mediaType},${safeData}`;
|
85
|
-
}
|
86
|
-
catch {
|
87
|
-
// failed to parse URL
|
88
|
-
}
|
89
|
-
}
|
package/imageUtil.test.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"imageUtil.test.d.ts","sourceRoot":"","sources":["../src/imageUtil.test.ts"],"names":[],"mappings":""}
|