@learncard/helpers 1.4.0 → 1.4.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.
- package/dist/helpers.cjs.development.cjs +40 -4
- package/dist/helpers.cjs.development.cjs.map +3 -3
- package/dist/helpers.cjs.production.min.cjs +10 -10
- package/dist/helpers.cjs.production.min.cjs.map +4 -4
- package/dist/helpers.esm.js +39 -4
- package/dist/helpers.esm.js.map +3 -3
- package/dist/images/images.helpers.d.ts.map +1 -1
- package/dist/images/index.d.ts +1 -0
- package/dist/images/index.d.ts.map +1 -1
- package/dist/images/sanitize.helpers.d.ts +28 -0
- package/dist/images/sanitize.helpers.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/images/images.helpers.ts +24 -7
- package/src/images/index.ts +1 -0
- package/src/images/sanitize.helpers.ts +59 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.helpers.d.ts","sourceRoot":"","sources":["../../src/images/images.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAE7C,QAAA,MAAM,SAAS;;;;CAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"images.helpers.d.ts","sourceRoot":"","sources":["../../src/images/images.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAE7C,QAAA,MAAM,SAAS;;;;CAAmC,CAAC;AASnD,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,MAAM,OAAO,SAAS,GAAG,IAkBnE,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,EAAE,SAAS,MAAM,KAAG,MAM5D,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,KAAK,MAAM,EAAE,WAAW,MAAM,EAAE,cAAY,KAAG,MAMrE,CAAC;AAEF,eAAO,MAAM,cAAc,GACvB,KAAK,MAAM,EACX,aAAa,MAAM,EAAE,EACrB,UAAS;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,KACnE,MAMF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAC/B,KAAK,MAAM,EACX,MAAM,MAAM,EACZ,SAAS,MAAM,EACf,UAAS;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,KACnE,MAMF,CAAC;AAEF,eAAO,MAAM,mBAAmB,UAAkB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,KAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAQlE,CAAC"}
|
package/dist/images/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/images/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/images/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for sanitizeImageUrl
|
|
3
|
+
*/
|
|
4
|
+
export type SanitizeImageUrlOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Allow blob: URLs (e.g., from URL.createObjectURL for local file previews).
|
|
7
|
+
* Default: false
|
|
8
|
+
*/
|
|
9
|
+
allowBlobUrls?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Allow data: URLs (e.g., data:image/png;base64,... for inline images).
|
|
12
|
+
* Only data:image/* URLs are allowed when enabled.
|
|
13
|
+
* Default: false
|
|
14
|
+
*/
|
|
15
|
+
allowDataUrls?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Sanitizes an image URL to prevent XSS via javascript: or other malicious URL schemes.
|
|
19
|
+
* Only allows http: and https: protocols by default.
|
|
20
|
+
* Optionally allows blob: URLs for local file preview scenarios.
|
|
21
|
+
* Optionally allows data:image/* URLs for inline base64 images.
|
|
22
|
+
*
|
|
23
|
+
* @param url - The URL to sanitize
|
|
24
|
+
* @param options - Optional configuration
|
|
25
|
+
* @returns The sanitized URL, or undefined if the URL is invalid or uses a disallowed protocol
|
|
26
|
+
*/
|
|
27
|
+
export declare const sanitizeImageUrl: (url: string | undefined, options?: SanitizeImageUrlOptions) => string | undefined;
|
|
28
|
+
//# sourceMappingURL=sanitize.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.helpers.d.ts","sourceRoot":"","sources":["../../src/images/sanitize.helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GACzB,KAAK,MAAM,GAAG,SAAS,EACvB,UAAS,uBAA4B,KACtC,MAAM,GAAG,SA4BX,CAAC"}
|
package/package.json
CHANGED
|
@@ -4,14 +4,31 @@ import * as discord from './discord.helpers';
|
|
|
4
4
|
|
|
5
5
|
const Providers = { filestack, unsplash, discord };
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Checks if the hostname matches exactly or is a subdomain of the target domain.
|
|
9
|
+
*/
|
|
10
|
+
const isHostnameMatch = (hostname: string, target: string): boolean => {
|
|
11
|
+
return hostname === target || hostname.endsWith(`.${target}`);
|
|
12
|
+
};
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export const getProvider = (url?: string): keyof typeof Providers | null => {
|
|
15
|
+
if (!url) return null;
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Handle protocol-relative URLs (e.g., //cdn.filestackcontent.com/...)
|
|
19
|
+
// by prepending https: so URL parsing succeeds
|
|
20
|
+
const normalizedUrl = url.startsWith('//') ? `https:${url}` : url;
|
|
21
|
+
const { hostname } = new URL(normalizedUrl);
|
|
22
|
+
|
|
23
|
+
// Check exact hostname or proper subdomain to prevent bypass via attacker-controlled domains
|
|
24
|
+
if (isHostnameMatch(hostname, 'cdn.filestackcontent.com')) return 'filestack';
|
|
25
|
+
if (isHostnameMatch(hostname, 'images.unsplash.com')) return 'unsplash';
|
|
26
|
+
if (isHostnameMatch(hostname, 'cdn.discordapp.com')) return 'discord';
|
|
27
|
+
|
|
28
|
+
return null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
15
32
|
};
|
|
16
33
|
|
|
17
34
|
export const changeQuality = (url: string, quality: number): string => {
|
package/src/images/index.ts
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for sanitizeImageUrl
|
|
3
|
+
*/
|
|
4
|
+
export type SanitizeImageUrlOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Allow blob: URLs (e.g., from URL.createObjectURL for local file previews).
|
|
7
|
+
* Default: false
|
|
8
|
+
*/
|
|
9
|
+
allowBlobUrls?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Allow data: URLs (e.g., data:image/png;base64,... for inline images).
|
|
12
|
+
* Only data:image/* URLs are allowed when enabled.
|
|
13
|
+
* Default: false
|
|
14
|
+
*/
|
|
15
|
+
allowDataUrls?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Sanitizes an image URL to prevent XSS via javascript: or other malicious URL schemes.
|
|
20
|
+
* Only allows http: and https: protocols by default.
|
|
21
|
+
* Optionally allows blob: URLs for local file preview scenarios.
|
|
22
|
+
* Optionally allows data:image/* URLs for inline base64 images.
|
|
23
|
+
*
|
|
24
|
+
* @param url - The URL to sanitize
|
|
25
|
+
* @param options - Optional configuration
|
|
26
|
+
* @returns The sanitized URL, or undefined if the URL is invalid or uses a disallowed protocol
|
|
27
|
+
*/
|
|
28
|
+
export const sanitizeImageUrl = (
|
|
29
|
+
url: string | undefined,
|
|
30
|
+
options: SanitizeImageUrlOptions = {}
|
|
31
|
+
): string | undefined => {
|
|
32
|
+
if (!url) return undefined;
|
|
33
|
+
|
|
34
|
+
const { allowBlobUrls = false, allowDataUrls = false } = options;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const parsed = new URL(url);
|
|
38
|
+
|
|
39
|
+
if (parsed.protocol === 'https:' || parsed.protocol === 'http:') {
|
|
40
|
+
return parsed.href;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (allowBlobUrls && parsed.protocol === 'blob:') {
|
|
44
|
+
return parsed.href;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (allowDataUrls && parsed.protocol === 'data:') {
|
|
48
|
+
// Only allow image/* MIME types for security
|
|
49
|
+
if (url.startsWith('data:image/')) {
|
|
50
|
+
return url;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return undefined;
|
|
56
|
+
} catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
};
|