@abtnode/util 1.16.29-beta-bb5685f8 → 1.16.29-beta-44e63d18
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/cloud.js +12 -0
- package/lib/gcp.js +88 -0
- package/lib/get-ip.js +22 -1
- package/lib/security.js +18 -4
- package/package.json +6 -6
package/lib/cloud.js
ADDED
package/lib/gcp.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Google Cloud Platform(GCP) util
|
|
3
|
+
*/
|
|
4
|
+
const debug = require('debug')('core:util:gcp');
|
|
5
|
+
const { joinURL } = require('ufo');
|
|
6
|
+
|
|
7
|
+
const axios = require('./axios');
|
|
8
|
+
|
|
9
|
+
const HOST = 'http://169.254.169.254/computeMetadata/v1';
|
|
10
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get meta data from GCP
|
|
14
|
+
* Docs, View project metadata: https://cloud.google.com/compute/docs/metadata/querying-metadata#rest_2
|
|
15
|
+
* Docs, Predefined metadata keys: https://cloud.google.com/compute/docs/metadata/predefined-metadata-keys
|
|
16
|
+
* @param {string} key
|
|
17
|
+
* @param {number} timeout default 5000
|
|
18
|
+
* @returns {string} meta data
|
|
19
|
+
*/
|
|
20
|
+
const getMeta = async (key, timeout = 5000) => {
|
|
21
|
+
try {
|
|
22
|
+
if (!key) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const url = joinURL(HOST, key);
|
|
27
|
+
debug('getMeta', { url });
|
|
28
|
+
const result = await axios.get(url, {
|
|
29
|
+
timeout,
|
|
30
|
+
headers: {
|
|
31
|
+
'Metadata-Flavor': 'Google',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
debug('get meta', { key, status: result.status, data: result.data });
|
|
36
|
+
|
|
37
|
+
return result.status === 200 ? result.data : '';
|
|
38
|
+
} catch (error) {
|
|
39
|
+
debug('failed to fetch meta', { key, error });
|
|
40
|
+
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const isInGCP = async () => {
|
|
46
|
+
const instanceId = await getMeta('instance/id');
|
|
47
|
+
debug('isInGCP:instanceId:', instanceId);
|
|
48
|
+
return !!instanceId;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getInternalIpv4 = async () => {
|
|
52
|
+
const internalIp = await getMeta('instance/network-interfaces/0/ip');
|
|
53
|
+
debug('getLocalIpv4', { internalIp });
|
|
54
|
+
return internalIp;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const getExternalIpv4 = async () => {
|
|
58
|
+
const externalIp = await getMeta('instance/network-interfaces/0/access-configs/0/external-ip');
|
|
59
|
+
debug('getPublicIpv4', { externalIp });
|
|
60
|
+
return externalIp;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getInternalIpv6 = async () => {
|
|
64
|
+
// TODO: 没有支持 ipv6 的机器,这个接口没有在实际的机器上测试
|
|
65
|
+
const internalIp = await getMeta('instance/network-interfaces/0/ipv6s');
|
|
66
|
+
|
|
67
|
+
debug('getLocalIpv6', { internalIp });
|
|
68
|
+
return internalIp;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const getExternalIpv6 = async () => {
|
|
72
|
+
// TODO: 没有支持 ipv6 的机器,这个接口没有在实际的机器上测试
|
|
73
|
+
const externalIp = await getMeta('instance/network-interfaces/0/access-configs/0/external-ipv6');
|
|
74
|
+
debug('getPublicIpv6', { externalIp });
|
|
75
|
+
|
|
76
|
+
return externalIp;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
module.exports = {
|
|
80
|
+
HOST,
|
|
81
|
+
DEFAULT_TIMEOUT,
|
|
82
|
+
getMeta,
|
|
83
|
+
isInGCP,
|
|
84
|
+
getInternalIpv4,
|
|
85
|
+
getExternalIpv4,
|
|
86
|
+
getInternalIpv6,
|
|
87
|
+
getExternalIpv6,
|
|
88
|
+
};
|
package/lib/get-ip.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const internalIp = require('internal-ip');
|
|
2
2
|
const externalIp = require('public-ip');
|
|
3
|
+
const debug = require('debug')('core:util:get-ip');
|
|
3
4
|
|
|
5
|
+
const gcp = require('./gcp');
|
|
4
6
|
const isEC2 = require('./is-ec2');
|
|
5
7
|
const getEc2Meta = require('./get-ec2-meta');
|
|
6
8
|
const tryWithTimeout = require('./try-with-timeout');
|
|
@@ -30,13 +32,32 @@ const getExternalIp = async ({ v6 = false, timeout = 5000 } = {}) => {
|
|
|
30
32
|
*/
|
|
31
33
|
const getIP = async ({ includeV6 = false, timeout = 5000, includeExternal = true } = {}) => {
|
|
32
34
|
try {
|
|
33
|
-
|
|
35
|
+
const [inEc2, inGCP] = await Promise.all([isEC2(), gcp.isInGCP()]);
|
|
36
|
+
debug('check env', { inEc2, inGCP });
|
|
37
|
+
|
|
38
|
+
if (inEc2) {
|
|
39
|
+
debug('in ec2');
|
|
34
40
|
const [internal, external, internalV6, externalV6] = await Promise.all([
|
|
35
41
|
getEc2Meta('local-ipv4', timeout),
|
|
36
42
|
includeExternal ? getEc2Meta('public-ipv4', timeout) : '',
|
|
37
43
|
includeV6 ? getEc2Meta('local-ipv6', timeout) : '',
|
|
38
44
|
includeV6 && includeExternal ? getEc2Meta('public-ipv6', timeout) : '',
|
|
39
45
|
]);
|
|
46
|
+
|
|
47
|
+
debug('got ips in ec2', { internal, external, internalV6, externalV6 });
|
|
48
|
+
return { internal, external, internalV6, externalV6 };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (inGCP) {
|
|
52
|
+
debug('in gcp');
|
|
53
|
+
const [internal, external, internalV6, externalV6] = await Promise.all([
|
|
54
|
+
gcp.getInternalIpv4(),
|
|
55
|
+
includeExternal ? gcp.getExternalIpv4() : '',
|
|
56
|
+
includeV6 ? gcp.getInternalIpv6() : '',
|
|
57
|
+
includeV6 && includeExternal ? gcp.getExternalIpv6() : '',
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
debug('got ips in gcp', { internal, external, internalV6, externalV6 });
|
|
40
61
|
return { internal, external, internalV6, externalV6 };
|
|
41
62
|
}
|
|
42
63
|
|
package/lib/security.js
CHANGED
|
@@ -70,12 +70,26 @@ function findExecutable(executable) {
|
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* @description
|
|
73
|
+
* @see https://github.com/nodejs/node/issues/53621#issuecomment-2196879752
|
|
73
74
|
* @param {import('@abtnode/client').BlockletState & { environmentObj: [key: string]: string } } blocklet
|
|
74
75
|
* @param {true | false} enableFileSystemIsolation
|
|
75
76
|
* @return {string}
|
|
76
77
|
*/
|
|
77
78
|
const getSecurityNodeOptions = (blocklet, enableFileSystemIsolation = true) => {
|
|
78
|
-
const
|
|
79
|
+
const nodeOptions = process.env.NODE_OPTIONS ?? '';
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
nodeOptions.includes('--experimental-permission') ||
|
|
83
|
+
nodeOptions.includes('--allow-fs-read') ||
|
|
84
|
+
nodeOptions.includes('--allow-fs-write')
|
|
85
|
+
) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
'process.env.NODE_OPTIONS should not include --experimental-permission or --allow-fs-read or --allow-fs-write'
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// @note: vscode 开启调试模式的时候,需要携带某些权限
|
|
92
|
+
const options = [nodeOptions].filter((x) => Boolean(x) && x !== 'undefined');
|
|
79
93
|
|
|
80
94
|
if (!canUseFileSystemIsolateApi() || !enableFileSystemIsolation) {
|
|
81
95
|
return options.join(' ').trim();
|
|
@@ -98,7 +112,7 @@ const getSecurityNodeOptions = (blocklet, enableFileSystemIsolation = true) => {
|
|
|
98
112
|
blocklet.environmentObj.BLOCKLET_CACHE_DIR,
|
|
99
113
|
join(blocklet.environmentObj.BLOCKLET_APP_DATA_DIR, '.projects'), // allow all components to access blocklet studio
|
|
100
114
|
tmpdir(),
|
|
101
|
-
].map((dir) => `--allow-fs-write=${dir}`),
|
|
115
|
+
].map((dir) => `--allow-fs-write=${join(dir, '/*')}`),
|
|
102
116
|
// @note: sqlite3 需要这个
|
|
103
117
|
'--allow-addons',
|
|
104
118
|
// FIXME: 目前我们非常多的应用都依赖使用 child_process 安装 sqlite,所以暂时放行。等 @blocklet/db ready 了,我们把限制再加上,@jianchao
|
|
@@ -111,7 +125,7 @@ const getSecurityNodeOptions = (blocklet, enableFileSystemIsolation = true) => {
|
|
|
111
125
|
blocklet.environmentObj.BLOCKLET_MODE === BLOCKLET_MODES.DEVELOPMENT
|
|
112
126
|
) {
|
|
113
127
|
options.push('--allow-worker', '--allow-fs-read=*');
|
|
114
|
-
options.push(`--allow-fs-write=${join(homedir(), '.npm', '_logs')}`);
|
|
128
|
+
options.push(`--allow-fs-write=${join(homedir(), '.npm', '_logs', '/*')}`);
|
|
115
129
|
} else {
|
|
116
130
|
options.push(
|
|
117
131
|
...[
|
|
@@ -128,7 +142,7 @@ const getSecurityNodeOptions = (blocklet, enableFileSystemIsolation = true) => {
|
|
|
128
142
|
]
|
|
129
143
|
.filter(Boolean)
|
|
130
144
|
.filter((x) => x !== sep)
|
|
131
|
-
.map((dir) => `--allow-fs-read=${dir}`)
|
|
145
|
+
.map((dir) => `--allow-fs-read=${join(dir, '/*')}`)
|
|
132
146
|
);
|
|
133
147
|
}
|
|
134
148
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.29-beta-
|
|
6
|
+
"version": "1.16.29-beta-44e63d18",
|
|
7
7
|
"description": "ArcBlock's JavaScript utility",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"author": "polunzh <polunzh@gmail.com> (http://github.com/polunzh)",
|
|
19
19
|
"license": "Apache-2.0",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@abtnode/constant": "1.16.29-beta-
|
|
22
|
-
"@abtnode/logger": "1.16.29-beta-
|
|
21
|
+
"@abtnode/constant": "1.16.29-beta-44e63d18",
|
|
22
|
+
"@abtnode/logger": "1.16.29-beta-44e63d18",
|
|
23
23
|
"@arcblock/pm2": "^5.4.0",
|
|
24
|
-
"@blocklet/constant": "1.16.29-beta-
|
|
25
|
-
"@blocklet/meta": "1.16.29-beta-
|
|
24
|
+
"@blocklet/constant": "1.16.29-beta-44e63d18",
|
|
25
|
+
"@blocklet/meta": "1.16.29-beta-44e63d18",
|
|
26
26
|
"@ocap/client": "1.18.124",
|
|
27
27
|
"@ocap/mcrypto": "1.18.124",
|
|
28
28
|
"@ocap/util": "1.18.124",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"fs-extra": "^11.2.0",
|
|
80
80
|
"jest": "^29.7.0"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "0a389ad71f5a189041c4896b029f05f73c8ce8d6"
|
|
83
83
|
}
|