@arcblock/ux 2.10.82 → 2.10.84

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/lib/Util/index.js CHANGED
@@ -245,6 +245,7 @@ export function openWebWallet({
245
245
  mergedWindowFeatures.top = winTop;
246
246
  }
247
247
  const strWindowFeatures = Object.keys(mergedWindowFeatures).map(key => `${key}=${mergedWindowFeatures[key]}`).join(',');
248
+ // 这里打开的是钱包的 URL,是安全的
248
249
  window.open(windowUrl, 'targetWindow', strWindowFeatures);
249
250
  return {
250
251
  type: 'web'
@@ -0,0 +1,6 @@
1
+ export declare function getSafeUrl(url: string, { throwOnError, returnRaw, allowProtocol, allowHost, }?: {
2
+ throwOnError?: boolean | undefined;
3
+ returnRaw?: boolean | undefined;
4
+ allowProtocol?: string[] | undefined;
5
+ allowHost?: string[] | undefined;
6
+ }): string | null;
@@ -0,0 +1,43 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+
3
+ class CustomError extends Error {}
4
+ export function getSafeUrl(
5
+ // 只允许 / 开头, ./ 开头和带有 protocol 的 URL
6
+ url, {
7
+ throwOnError = true,
8
+ returnRaw = false,
9
+ // 根据 URL 的规范,protocol 以 : 结尾
10
+ allowProtocol = ['https:', 'http:'],
11
+ // host 中可能会携带端口号,需要使用 hostname 来获取干净的域名
12
+ allowHost = [window.location.href]
13
+ } = {}) {
14
+ try {
15
+ let base;
16
+ if (url.startsWith('/')) {
17
+ base = window.location.origin;
18
+ } else if (url.startsWith('./')) {
19
+ base = window.location.href;
20
+ }
21
+ const urlInstance = new URL(url, base);
22
+ const allowHostName = allowHost ? allowHost.map(host => new URL(host).hostname) : allowHost;
23
+ if (allowProtocol !== null && !allowProtocol.includes(urlInstance.protocol)) {
24
+ console.error(`Invalid protocol: ${urlInstance.protocol}`);
25
+ if (throwOnError) throw new CustomError(`Invalid protocol: ${urlInstance.protocol}`);
26
+ return null;
27
+ }
28
+ if (allowHostName !== null && !allowHostName.includes(urlInstance.hostname)) {
29
+ console.error(`Invalid host: ${urlInstance.hostname}`);
30
+ if (throwOnError) throw new CustomError(`Invalid host: ${urlInstance.hostname}`);
31
+ return null;
32
+ }
33
+ return returnRaw ? url : urlInstance.href;
34
+ } catch (error) {
35
+ if (error instanceof CustomError) {
36
+ if (throwOnError) throw error;
37
+ return null;
38
+ }
39
+ console.error(`Failed to convert url: ${url}`);
40
+ if (throwOnError) throw new Error(`Failed to convert url: ${url}`);
41
+ return null;
42
+ }
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.10.82",
3
+ "version": "2.10.84",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -68,12 +68,12 @@
68
68
  "react": ">=18.2.0",
69
69
  "react-router-dom": ">=6.22.3"
70
70
  },
71
- "gitHead": "25840ab8e0b037d16ef4fa8ead378ff81db95c46",
71
+ "gitHead": "1311dd7d9ce3a6b0164404de828e64dcd900ce6d",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.10.82",
75
- "@arcblock/nft-display": "^2.10.82",
76
- "@arcblock/react-hooks": "^2.10.82",
74
+ "@arcblock/icons": "^2.10.84",
75
+ "@arcblock/nft-display": "^2.10.84",
76
+ "@arcblock/react-hooks": "^2.10.84",
77
77
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
78
78
  "@fontsource/inter": "^5.0.16",
79
79
  "@fontsource/ubuntu-mono": "^5.0.18",
package/src/Util/index.ts CHANGED
@@ -306,6 +306,7 @@ export function openWebWallet({
306
306
  const strWindowFeatures = Object.keys(mergedWindowFeatures)
307
307
  .map((key) => `${key}=${mergedWindowFeatures[key]}`)
308
308
  .join(',');
309
+ // 这里打开的是钱包的 URL,是安全的
309
310
  window.open(windowUrl, 'targetWindow', strWindowFeatures);
310
311
  return { type: 'web' };
311
312
  }
@@ -0,0 +1,57 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+
3
+ type GetSafeUrlOptions = {
4
+ returnRaw?: boolean;
5
+ throwOnError?: Boolean;
6
+ // 为 null 时代表不检查 protocol
7
+ allowProtocol?: Array<string> | null;
8
+ // 为 null 时代表不检查 host
9
+ allowHost?: Array<string> | null;
10
+ };
11
+
12
+ class CustomError extends Error {}
13
+
14
+ export function getSafeUrl(
15
+ // 只允许 / 开头, ./ 开头和带有 protocol 的 URL
16
+ url: string,
17
+ {
18
+ throwOnError = true,
19
+ returnRaw = false,
20
+ // 根据 URL 的规范,protocol 以 : 结尾
21
+ allowProtocol = ['https:', 'http:'],
22
+ // host 中可能会携带端口号,需要使用 hostname 来获取干净的域名
23
+ allowHost = [window.location.href],
24
+ } = {}
25
+ ) {
26
+ try {
27
+ let base;
28
+ if (url.startsWith('/')) {
29
+ base = window.location.origin;
30
+ } else if (url.startsWith('./')) {
31
+ base = window.location.href;
32
+ }
33
+
34
+ const urlInstance = new URL(url, base);
35
+ const allowHostName = allowHost ? allowHost.map((host) => new URL(host).hostname) : allowHost;
36
+ if (allowProtocol !== null && !allowProtocol.includes(urlInstance.protocol)) {
37
+ console.error(`Invalid protocol: ${urlInstance.protocol}`);
38
+ if (throwOnError) throw new CustomError(`Invalid protocol: ${urlInstance.protocol}`);
39
+ return null;
40
+ }
41
+ if (allowHostName !== null && !allowHostName.includes(urlInstance.hostname)) {
42
+ console.error(`Invalid host: ${urlInstance.hostname}`);
43
+ if (throwOnError) throw new CustomError(`Invalid host: ${urlInstance.hostname}`);
44
+ return null;
45
+ }
46
+
47
+ return returnRaw ? url : urlInstance.href;
48
+ } catch (error) {
49
+ if (error instanceof CustomError) {
50
+ if (throwOnError) throw error;
51
+ return null;
52
+ }
53
+ console.error(`Failed to convert url: ${url}`);
54
+ if (throwOnError) throw new Error(`Failed to convert url: ${url}`);
55
+ return null;
56
+ }
57
+ }