@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 ADDED
@@ -0,0 +1,12 @@
1
+ const isEC2 = require('./is-ec2');
2
+ const gcp = require('./gcp');
3
+
4
+ const isInCloud = () => {
5
+ return Promise.all([isEC2(), gcp.isInGCP()]).then(([inEC2, inGCP]) => {
6
+ return inEC2 || inGCP;
7
+ });
8
+ };
9
+
10
+ module.exports = {
11
+ isInCloud,
12
+ };
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
- if (await isEC2()) {
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 options = [];
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-bb5685f8",
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-bb5685f8",
22
- "@abtnode/logger": "1.16.29-beta-bb5685f8",
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-bb5685f8",
25
- "@blocklet/meta": "1.16.29-beta-bb5685f8",
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": "e1180f28ed9ce6a5a93141352ca5fbabd2b64cbc"
82
+ "gitHead": "0a389ad71f5a189041c4896b029f05f73c8ce8d6"
83
83
  }