@abtnode/core 1.5.13 → 1.15.17

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.
@@ -28,11 +28,14 @@ const {
28
28
  CERTIFICATE_EXPIRES_WARNING_OFFSET,
29
29
  DEFAULT_DAEMON_PORT,
30
30
  DEFAULT_SERVICE_PATH,
31
+ SLOT_FOR_IP_DNS_SITE,
32
+ BLOCKLET_SITE_GROUP_SUFFIX,
31
33
  } = require('@abtnode/constant');
32
34
  const {
33
35
  BLOCKLET_DYNAMIC_PATH_PREFIX,
34
36
  BLOCKLET_INTERFACE_TYPE_WEB,
35
37
  BLOCKLET_INTERFACE_WELLKNOWN,
38
+ BLOCKLET_INTERFACE_TYPE_WELLKNOWN,
36
39
  } = require('@blocklet/meta/lib/constants');
37
40
 
38
41
  // eslint-disable-next-line global-require
@@ -48,15 +51,58 @@ const {
48
51
  } = require('../util');
49
52
  const { getServicesFromBlockletInterface } = require('../util/service');
50
53
  const getIpDnsDomainForBlocklet = require('../util/get-ip-dns-domain-for-blocklet');
54
+ const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-accessible-external-node-ip');
51
55
 
52
56
  const Router = require('./index');
53
57
  const states = require('../states');
54
58
 
55
- const attachInterfaceUrls = async ({ sites = [], context }) => {
59
+ /**
60
+ * replace 888-888-888-888 with accessible ip for domain
61
+ */
62
+ const attachRuntimeDomainAliases = async ({ sites = [], context = {}, node }) => {
63
+ let ip;
64
+ const ipRegex = /\d+[-.]\d+[-.]\d+[-.]\d+/;
65
+ const match = ipRegex.exec(context.hostname);
66
+ if (match) {
67
+ ip = match[0];
68
+ } else if (node) {
69
+ const nodeInfo = await node.read();
70
+ const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
71
+ if (nodeIp) {
72
+ ip = nodeIp;
73
+ }
74
+ }
75
+
76
+ const getDomainAliases = (site) =>
77
+ (site.domainAliases || []).map((domain) => {
78
+ if (!domain.value) {
79
+ return domain;
80
+ }
81
+ if (domain.value.includes(SLOT_FOR_IP_DNS_SITE) && ip) {
82
+ domain.value = domain.value.replace(SLOT_FOR_IP_DNS_SITE, ip.replace(/\./g, '-'));
83
+ }
84
+ return domain;
85
+ });
86
+
87
+ if (!Array.isArray(sites)) {
88
+ sites.domainAliases = getDomainAliases(sites);
89
+ return sites;
90
+ }
91
+
92
+ return sites.map((site) => {
93
+ site.domainAliases = getDomainAliases(site);
94
+
95
+ return site;
96
+ });
97
+ };
98
+
99
+ const attachInterfaceUrls = async ({ sites = [], context, node }) => {
56
100
  if (!sites) {
57
101
  return [];
58
102
  }
59
103
 
104
+ attachRuntimeDomainAliases({ sites, context, node });
105
+
60
106
  const getUrl = (rule, domain = '') => {
61
107
  const host = getBlockletHost({ domain, context });
62
108
  const prefix = trimSlash(rule.from.pathPrefix);
@@ -340,7 +386,7 @@ const ensureAuthService = async (sites = [], blockletManager) => {
340
386
  // we should only use rule.to.realInterfaceName, rule.to.interfaceName is for backward compatible
341
387
  const interfaceName = rule.to.realInterfaceName || rule.to.interfaceName;
342
388
  const { interfaces } = blocklet.meta;
343
- const _interface = interfaces.find((x) => x.type === 'web' && x.name === interfaceName);
389
+ const _interface = interfaces.find((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB && x.name === interfaceName);
344
390
  if (_interface) {
345
391
  rule.services = rule.services || [];
346
392
  rule.services.unshift(...getServicesFromBlockletInterface(_interface, { logError: logger.error }));
@@ -596,10 +642,13 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
596
642
  /**
597
643
  * Add system sites for blocklet
598
644
  *
599
- * @returns {boolean} if routing changed
645
+ * @returns {boolean} if routing state db changed
600
646
  */
601
647
  const _ensureBlockletSites = async (blocklet, sites, nodeInfo, context = {}) => {
602
- const interfaces = (blocklet.meta.interfaces || []).filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
648
+ const webInterface = (blocklet.meta.interfaces || []).find((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
649
+ if (!webInterface) {
650
+ return false;
651
+ }
603
652
 
604
653
  const getPrefix = (str) => {
605
654
  if (!str || str === '*') {
@@ -608,68 +657,59 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
608
657
  return `/${str}`.replace(/^\/+/, '/');
609
658
  };
610
659
 
611
- const changes = await Promise.all(
612
- interfaces.map(async (x) => {
613
- const domain = getIpDnsDomainForBlocklet(blocklet, x);
614
- const pathPrefix = getPrefix(x.prefix);
615
- const rule = {
616
- from: { pathPrefix },
617
- to: {
618
- port: findInterfacePortByName(blocklet, x.name),
619
- did: blocklet.meta.did,
620
- type: ROUTING_RULE_TYPES.BLOCKLET,
621
- interfaceName: x.name, // root blocklet interface
622
- },
623
- isProtected: true,
624
- };
660
+ const domainGroup = `${blocklet.meta.did}${BLOCKLET_SITE_GROUP_SUFFIX}`;
661
+ const domain = getIpDnsDomainForBlocklet(blocklet, webInterface);
662
+ const pathPrefix = getPrefix(webInterface.prefix);
663
+ const rule = {
664
+ from: { pathPrefix },
665
+ to: {
666
+ port: findInterfacePortByName(blocklet, webInterface.name),
667
+ did: blocklet.meta.did,
668
+ type: ROUTING_RULE_TYPES.BLOCKLET,
669
+ interfaceName: webInterface.name, // root blocklet interface
670
+ },
671
+ isProtected: true,
672
+ };
625
673
 
626
- let changed = false; // if state db changed
627
-
628
- const exist = await states.site.findOne({ domain });
629
- if (!exist) {
630
- await routerManager.addRoutingSite(
631
- {
632
- site: {
633
- domain,
634
- isProtected: true,
635
- // FIXME: tmp fix for https://github.com/ArcBlock/abt-node/issues/3526
636
- corsAllowedOrigins: ['*'],
637
- rules: [rule],
638
- },
639
- skipCheckDynamicBlacklist: true,
640
- },
641
- context
642
- );
643
- logger.info('add routing site', { site: domain });
674
+ const existSite = await states.site.findOne({ domain: domainGroup });
675
+ if (!existSite) {
676
+ await routerManager.addRoutingSite(
677
+ {
678
+ site: {
679
+ domain: domainGroup,
680
+ domainAliases: [{ value: domain, isProtected: true }],
681
+ isProtected: true,
682
+ rules: [rule],
683
+ },
684
+ skipCheckDynamicBlacklist: true,
685
+ },
686
+ context
687
+ );
688
+ logger.info('add routing site', { site: domain });
644
689
 
645
- changed = true;
646
- } else {
647
- const existRule = (exist.rules || []).find((y) => get(y, 'from.pathPrefix') === pathPrefix);
648
- if (existRule) {
649
- await routerManager.updateRoutingRule({
650
- id: exist.id,
651
- rule: {
652
- ...rule,
653
- id: exist.id,
654
- },
655
- skipProtectedRuleChecking: true,
656
- });
657
- logger.info('update routing rule for site', { site: domain });
658
- } else {
659
- await routerManager.addRoutingRule({
660
- id: exist.id,
661
- rule,
662
- });
663
- logger.info('add routing rule for site', { site: domain });
664
- }
665
- changed = true;
666
- }
690
+ return true;
691
+ }
667
692
 
668
- return changed;
669
- })
670
- );
693
+ const existRule = (existSite.rules || []).find((y) => get(y, 'from.pathPrefix') === pathPrefix);
694
+ if (existRule) {
695
+ await routerManager.updateRoutingRule({
696
+ id: existSite.id,
697
+ rule: {
698
+ ...rule,
699
+ id: existRule.id,
700
+ },
701
+ skipProtectedRuleChecking: true,
702
+ });
703
+ logger.info('update routing rule for site', { site: domain });
704
+ } else {
705
+ await routerManager.addRoutingRule({
706
+ id: existSite.id,
707
+ rule,
708
+ });
709
+ logger.info('add routing rule for site', { site: domain });
710
+ }
671
711
 
672
- return changes.some(Boolean);
712
+ return true;
673
713
  };
674
714
 
675
715
  /**
@@ -684,7 +724,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
684
724
  }
685
725
 
686
726
  const tasks = (blocklet.meta.interfaces || [])
687
- .filter((x) => x.name === BLOCKLET_INTERFACE_WELLKNOWN)
727
+ .filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WELLKNOWN)
688
728
  .map(async (x) => {
689
729
  const pathPrefix = normalizePathPrefix(x.prefix);
690
730
  if (!pathPrefix.startsWith(WELLKNOWN_PATH_PREFIX)) {
@@ -811,30 +851,15 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
811
851
  };
812
852
 
813
853
  const _removeBlockletSites = async (blocklet, nodeInfo, context = {}) => {
814
- const interfaces = (blocklet.meta.interfaces || []).filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
815
-
816
- const changes = await Promise.all(
817
- interfaces.map(async (x) => {
818
- let changed = false;
819
-
820
- const domain = getIpDnsDomainForBlocklet(blocklet, x);
821
-
822
- const site = await states.site.findOne({ domain });
823
- if (
824
- site &&
825
- site.isProtected &&
826
- (!site.domainAliases || !site.domainAliases.length) &&
827
- (!site.rules || !site.rules.length)
828
- ) {
829
- await routerManager.deleteRoutingSite({ id: site.id }, context);
830
- changed = true;
831
- }
854
+ let changed = false;
832
855
 
833
- return changed;
834
- })
835
- );
856
+ const site = await states.site.findOne({ domain: `${blocklet.meta.did}${BLOCKLET_SITE_GROUP_SUFFIX}` });
857
+ if (site) {
858
+ await routerManager.deleteRoutingSite({ id: site.id }, context);
859
+ changed = true;
860
+ }
836
861
 
837
- return changes.some(Boolean);
862
+ return changed;
838
863
  };
839
864
 
840
865
  /**
@@ -854,8 +879,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
854
879
  return false;
855
880
  }
856
881
 
857
- const interfaces = (blocklet.meta.interfaces || []).filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
858
- if (interfaces.length === 0) {
882
+ const hasWebInterface = (blocklet.meta.interfaces || []).some((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
883
+ if (!hasWebInterface) {
859
884
  return false;
860
885
  }
861
886
 
@@ -886,9 +911,11 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
886
911
  * @returns {boolean} if routing changed
887
912
  */
888
913
  const ensureBlockletCustomRouting = async (blocklet) => {
914
+ // Only one blocklet web interface can be declared since router 2.0
889
915
  const interfaces = (blocklet.meta.interfaces || []).filter((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB);
890
916
  const hasInterface = (name) => interfaces.some((x) => x.name === name);
891
- const sites = await siteState.getRulesByDid(blocklet.meta.did);
917
+
918
+ const sites = await siteState.getSitesByBlocklet(blocklet.meta.did);
892
919
  let changed = false;
893
920
 
894
921
  for (const site of sites) {
@@ -1164,7 +1191,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1164
1191
  if (msg.length < 5) {
1165
1192
  throw new Error('Message cannot be less than 5 characters');
1166
1193
  }
1167
- if (msg.length > 100) {
1194
+ if (msg.length > 150) {
1168
1195
  throw new Error('Message cannot exceed 100 characters');
1169
1196
  }
1170
1197
  }
@@ -1216,12 +1243,17 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1216
1243
  return attachInterfaceUrls({
1217
1244
  sites: await ensureLatestInfo(sites, { withDefaultCors }),
1218
1245
  context,
1246
+ node: nodeState,
1219
1247
  });
1220
1248
  };
1221
1249
 
1222
1250
  const getSnapshotSites = async ({ hash }, context = {}, { withDefaultCors = true } = {}) => {
1223
1251
  const sites = await routingSnapshot.readSnapshotSites(hash);
1224
- return attachInterfaceUrls({ sites: await ensureLatestInfo(sites, { withDefaultCors }), context });
1252
+ return attachInterfaceUrls({
1253
+ sites: await ensureLatestInfo(sites, { withDefaultCors }),
1254
+ context,
1255
+ node: nodeState,
1256
+ });
1225
1257
  };
1226
1258
 
1227
1259
  const getCertificates = async () => {
@@ -1262,7 +1294,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1262
1294
  logger.info('send certificate expire notification', { domain: cert.domain });
1263
1295
  notification.create({
1264
1296
  title: 'SSL Certificate Expired',
1265
- description: `Your SSL certificate for domain ${cert.domain} has expired, please update it in ABT Node`,
1297
+ description: `Your SSL certificate for domain ${cert.domain} has expired, please update it in Blocklet Server`,
1266
1298
  severity: 'error',
1267
1299
  entityType: 'certificate',
1268
1300
  entityId: cert._id, // eslint-disable-line no-underscore-dangle
@@ -1276,7 +1308,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1276
1308
  cert.domain
1277
1309
  } will expire in ${expireInDays} days (on ${new Date(
1278
1310
  cert.validTo
1279
- ).toLocaleString()}), please remember to update it in ABT Node`,
1311
+ ).toLocaleString()}), please remember to update it in Blocklet Server`,
1280
1312
  severity: 'warning',
1281
1313
  entityType: 'certificate',
1282
1314
  entityId: cert._id, // eslint-disable-line no-underscore-dangle
@@ -6,6 +6,7 @@ const {
6
6
  ROUTING_RULE_TYPES,
7
7
  DEFAULT_DASHBOARD_DOMAIN,
8
8
  BLOCKLET_PROXY_PATH_PREFIX,
9
+ BLOCKLET_SITE_GROUP_SUFFIX,
9
10
  } = require('@abtnode/constant');
10
11
  const { BLOCKLET_UI_INTERFACES } = require('@blocklet/meta/lib/constants');
11
12
  const { pick } = require('lodash');
@@ -26,7 +27,11 @@ const expandSites = (sites = []) => {
26
27
  });
27
28
 
28
29
  delete site.domainAliases;
29
- result.push(site);
30
+
31
+ // skip site if domain is BLOCKLET_SITE_GROUP
32
+ if (!site.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX)) {
33
+ result.push(site);
34
+ }
30
35
  });
31
36
 
32
37
  const defaultSite = result.find((site) => site.domain === DOMAIN_FOR_DEFAULT_SITE);
@@ -45,7 +50,10 @@ const mergeAllowedOrigins = (domain, allowedOrigins) => {
45
50
  origins.push(domain);
46
51
  }
47
52
 
48
- return origins;
53
+ // skip site if domain is BLOCKLET_SITE_GROUP
54
+ const res = origins.filter((x) => !x.endsWith(BLOCKLET_SITE_GROUP_SUFFIX));
55
+
56
+ return res;
49
57
  };
50
58
 
51
59
  const getRoutingTable = ({ sites, nodeInfo }) => {
@@ -121,7 +121,7 @@ class RouterManager extends EventEmitter {
121
121
  await this.validateRouterConfig('addRoutingSite', { site: newSite });
122
122
 
123
123
  const result = await states.site.add(newSite);
124
- await attachInterfaceUrls({ sites: result, context });
124
+ await attachInterfaceUrls({ sites: result, context, node: states.node });
125
125
 
126
126
  this.emit('router.site.created', result);
127
127
  return result;
@@ -181,7 +181,7 @@ class RouterManager extends EventEmitter {
181
181
  this.emit('router.site.updated', params.id);
182
182
 
183
183
  const dbSite = await states.site.findOne({ _id: params.id });
184
- await attachInterfaceUrls({ sites: dbSite, context });
184
+ await attachInterfaceUrls({ sites: dbSite, context, node: states.node });
185
185
  return dbSite;
186
186
  }
187
187
 
@@ -207,7 +207,7 @@ class RouterManager extends EventEmitter {
207
207
  logger.debug('add domain alias update result', { id, updateResult, domainAlias });
208
208
 
209
209
  const newSite = await states.site.findOne({ _id: id });
210
- await attachInterfaceUrls({ sites: newSite, context });
210
+ await attachInterfaceUrls({ sites: newSite, context, node: states.node });
211
211
 
212
212
  return newSite;
213
213
  }
@@ -230,7 +230,7 @@ class RouterManager extends EventEmitter {
230
230
  const updateResult = await states.site.update({ _id: id }, { $set: { domainAliases: dbSite.domainAliases } });
231
231
  logger.debug('remove domain alias update result', { id, updateResult, domainAlias });
232
232
 
233
- await attachInterfaceUrls({ sites: dbSite, context });
233
+ await attachInterfaceUrls({ sites: dbSite, context, node: states.node });
234
234
 
235
235
  return dbSite;
236
236
  }
@@ -265,7 +265,7 @@ class RouterManager extends EventEmitter {
265
265
  }
266
266
 
267
267
  const newSite = await states.site.findOne({ _id: id });
268
- await attachInterfaceUrls({ sites: newSite, context });
268
+ await attachInterfaceUrls({ sites: newSite, context, node: states.node });
269
269
 
270
270
  this.emit('router.rule.created', newSite);
271
271
  return newSite;
@@ -306,7 +306,7 @@ class RouterManager extends EventEmitter {
306
306
  logger.info('update result', { updateResult });
307
307
  const newSite = await states.site.findOne({ _id: id });
308
308
 
309
- await attachInterfaceUrls({ sites: newSite, context });
309
+ await attachInterfaceUrls({ sites: newSite, context, node: states.node });
310
310
 
311
311
  this.emit('router.rule.updated', newSite);
312
312
 
@@ -335,7 +335,7 @@ class RouterManager extends EventEmitter {
335
335
  logger.info('router.rule.removed', { id, ruleId });
336
336
  const newSite = await states.site.findOne({ _id: id });
337
337
 
338
- await attachInterfaceUrls({ sites: newSite, context });
338
+ await attachInterfaceUrls({ sites: newSite, context, node: states.node });
339
339
 
340
340
  this.emit('router.rule.removed', newSite);
341
341
  return newSite;
@@ -33,7 +33,7 @@ class SiteState extends BaseState {
33
33
  return SiteState.renameIdFiledName(result);
34
34
  }
35
35
 
36
- async getRulesByDid(did) {
36
+ async getSitesByBlocklet(did) {
37
37
  const rules = await this.asyncDB.find({ 'rules.to.did': did });
38
38
  return SiteState.renameIdFiledName(rules);
39
39
  }
@@ -190,7 +190,7 @@ class TeamManager extends EventEmitter {
190
190
  // first getRBAC after blocklet added
191
191
  if (!this.cache[did].rbac) {
192
192
  if (this.isNodeTeam(did)) {
193
- throw new Error('ABT Node rbac instance has not been initialized');
193
+ throw new Error('Blocklet Server rbac instance has not been initialized');
194
194
  }
195
195
 
196
196
  // FIXME: cross process lock
@@ -1,7 +1,7 @@
1
1
  const {
2
2
  NODE_REGISTER_URL,
3
- BLOCKLET_REGISTRY_URL,
4
- BLOCKLET_REGISTRY_URL_DEV,
3
+ BLOCKLET_STORE_URL,
4
+ BLOCKLET_STORE_URL_DEV,
5
5
  WEB_WALLET_URL,
6
6
  NODE_PACKAGE_NAME,
7
7
  NODE_COMMAND_NAME,
@@ -23,18 +23,18 @@ const defaultNodeConfigs = {
23
23
  blockletRegistryList: {
24
24
  getDefaultValue: () => [
25
25
  {
26
- name: 'Official Registry',
26
+ name: 'Official Store',
27
27
  description: 'ArcBlock official blocklet registry',
28
- url: BLOCKLET_REGISTRY_URL,
28
+ url: BLOCKLET_STORE_URL,
29
29
  logoUrl: '/logo.png',
30
30
  maintainer: 'arcblock',
31
31
  selected: true,
32
32
  protected: true,
33
33
  },
34
34
  {
35
- name: 'Dev Registry',
35
+ name: 'Dev Store',
36
36
  description: 'ArcBlock dev registry that contains demo and example blocklets',
37
- url: BLOCKLET_REGISTRY_URL_DEV,
37
+ url: BLOCKLET_STORE_URL_DEV,
38
38
  maintainer: 'arcblock',
39
39
  logoUrl: '/logo.png',
40
40
  selected: false,
package/lib/util/index.js CHANGED
@@ -7,6 +7,7 @@ const crypto = require('crypto');
7
7
  const shell = require('shelljs');
8
8
  const get = require('lodash/get');
9
9
  const uniqBy = require('lodash/uniqBy');
10
+ const pickBy = require('lodash/pickBy');
10
11
  const { isFromPublicKey } = require('@arcblock/did');
11
12
  const joinUrl = require('url-join');
12
13
  const { Certificate } = require('@fidm/x509');
@@ -28,7 +29,9 @@ const {
28
29
  ROUTING_RULE_TYPES,
29
30
  SLOT_FOR_IP_DNS_SITE,
30
31
  DEFAULT_IP_DNS_DOMAIN_SUFFIX,
32
+ BLOCKLET_SITE_GROUP_SUFFIX,
31
33
  } = require('@abtnode/constant');
34
+ const { BLOCKLET_INTERFACE_TYPE_WEB } = require('@blocklet/meta/lib/constants');
32
35
 
33
36
  const DEFAULT_WELLKNOWN_PORT = 8088;
34
37
 
@@ -136,7 +139,7 @@ const getAuthConfig = (rule, blocklet) => {
136
139
  // find interface in meta
137
140
  const interfaceName = rule.to.realInterfaceName;
138
141
  const { interfaces } = _blocklet.meta;
139
- const _interface = interfaces.find((x) => x.type === 'web' && x.name === interfaceName);
142
+ const _interface = interfaces.find((x) => x.type === BLOCKLET_INTERFACE_TYPE_WEB && x.name === interfaceName);
140
143
 
141
144
  if (!_interface) {
142
145
  return null;
@@ -154,13 +157,14 @@ const getAuthConfig = (rule, blocklet) => {
154
157
  return auth.config;
155
158
  };
156
159
 
157
- const getBlockletBaseUrls = ({ routingEnabled = false, port, sites = [], context = {}, blocklet, nodeIp }) => {
160
+ const getBlockletBaseUrls = ({ routingEnabled = false, port, rules = [], context = {}, blocklet, nodeIp }) => {
158
161
  let baseUrls = [];
159
162
 
160
- if (routingEnabled && Array.isArray(sites) && sites.length > 0) {
161
- baseUrls = sites
162
- .map((site) => {
163
- const host = getBlockletHost({ domain: site.from.domain, context, nodeIp });
163
+ if (routingEnabled && Array.isArray(rules) && rules.length > 0) {
164
+ baseUrls = rules
165
+ .filter((rule) => !(rule.from.domain || '').endsWith(BLOCKLET_SITE_GROUP_SUFFIX))
166
+ .map((rule) => {
167
+ const host = getBlockletHost({ domain: rule.from.domain, context, nodeIp });
164
168
  if (host) {
165
169
  let protocol = 'http'; // TODO: 这里固定为 http, 因为判断 url 是不是 https 和证书相关,这里实现的话比较复杂
166
170
  if (host.includes(DEFAULT_IP_DNS_DOMAIN_SUFFIX)) {
@@ -168,10 +172,10 @@ const getBlockletBaseUrls = ({ routingEnabled = false, port, sites = [], context
168
172
  }
169
173
 
170
174
  return {
171
- ruleId: site.id,
172
- baseUrl: `${protocol}://${host}/${trimSlash(site.from.pathPrefix)}`,
173
- interfaceName: get(site, 'to.interfaceName', ''),
174
- authConfig: getAuthConfig(site, blocklet),
175
+ ruleId: rule.id,
176
+ baseUrl: `${protocol}://${host}/${trimSlash(rule.from.pathPrefix)}`,
177
+ interfaceName: get(rule, 'to.interfaceName', ''),
178
+ authConfig: getAuthConfig(rule, blocklet),
175
179
  };
176
180
  }
177
181
 
@@ -187,7 +191,7 @@ const getBlockletBaseUrls = ({ routingEnabled = false, port, sites = [], context
187
191
  return baseUrls;
188
192
  };
189
193
 
190
- const getBlockletInterfaces = ({ blocklet, context, nodeInfo, sites, nodeIp }) => {
194
+ const getBlockletInterfaces = ({ blocklet, context, nodeInfo, routingRules, nodeIp }) => {
191
195
  const interfaces = [];
192
196
  (blocklet.meta.interfaces || []).forEach((x) => {
193
197
  if (x.port && x.port.external) {
@@ -195,7 +199,7 @@ const getBlockletInterfaces = ({ blocklet, context, nodeInfo, sites, nodeIp }) =
195
199
  const baseUrls = getBlockletBaseUrls({
196
200
  routingEnabled: false,
197
201
  port: x.port.external,
198
- sites: [],
202
+ rules: [],
199
203
  context,
200
204
  });
201
205
  baseUrls.forEach(({ baseUrl }) => interfaces.push({ type: x.type, name: x.name, url: baseUrl }));
@@ -205,9 +209,11 @@ const getBlockletInterfaces = ({ blocklet, context, nodeInfo, sites, nodeIp }) =
205
209
  const baseUrls = getBlockletBaseUrls({
206
210
  routingEnabled: isRoutingEnabled(nodeInfo.routing),
207
211
  port,
208
- sites: (sites || []).filter((r) => {
212
+ rules: (routingRules || []).filter((r) => {
209
213
  return (
210
214
  // don't show wellknown interface
215
+ r.to.type !== ROUTING_RULE_TYPES.GENERAL_PROXY &&
216
+ // LEGACY don't show wellknown interface
211
217
  r.to.interfaceName !== BLOCKLET_INTERFACE_WELLKNOWN &&
212
218
  // don't show child blocklet interface
213
219
  (!r.from.groupPathPrefix || r.from.pathPrefix === r.from.groupPathPrefix)
@@ -328,7 +334,7 @@ const getDataDirs = (dataDir) => ({
328
334
  services: path.join(dataDir, 'services'),
329
335
  });
330
336
 
331
- // Ensure data dir for ABT Node exists
337
+ // Ensure data dir for Blocklet Server exists
332
338
  const ensureDataDirs = (dataDir) => {
333
339
  try {
334
340
  logger.info('ensure data dir', { dataDir });
@@ -519,6 +525,14 @@ const getQueueConcurrencyByMem = () => {
519
525
  return 1;
520
526
  };
521
527
 
528
+ const getSafeEnv = (inputEnv, processEnv = process.env) => {
529
+ const whiteList = ['ABT_NODE', 'ABT_NODE_DID', 'ABT_NODE_PK', 'ABT_NODE_PORT', 'ABT_NODE_SERVICE_PORT'];
530
+ // 此处需要保留 process.env 中的环境变量,只移除和 ABT_NODE 相关的环境变量(否则丢失了 process.env.SHELL 变量可能会造成无法使用 nodejs 的情况)
531
+ const filterProcessEnv = pickBy(processEnv, (value, key) => !key.startsWith('ABT_NODE') || whiteList.includes(key));
532
+ const mergedEnv = { ...filterProcessEnv, ...inputEnv };
533
+ return mergedEnv;
534
+ };
535
+
522
536
  const lib = {
523
537
  validateOwner,
524
538
  getProviderFromNodeInfo,
@@ -558,6 +572,7 @@ const lib = {
558
572
  shouldUpdateBlockletStatus,
559
573
  transformIPToDomain,
560
574
  getQueueConcurrencyByMem,
575
+ getSafeEnv,
561
576
  };
562
577
 
563
578
  module.exports = lib;
package/lib/util/ready.js CHANGED
@@ -29,19 +29,19 @@ const createStateReadyHandler =
29
29
  // eslint-disable-next-line no-underscore-dangle
30
30
  await states.node.remove({ _id: state._id });
31
31
  console.error('\n\x1b[31m======================================================');
32
- console.error(`Data dir: ${options.dataDir} is used by another ABT Node instance, abort!`);
33
- console.error('Sharing data dir between ABT Node instances may break things!');
32
+ console.error(`Data dir: ${options.dataDir} is used by another Blocklet Server instance, abort!`);
33
+ console.error('Sharing data dir between Blocklet Server instances may break things!');
34
34
  console.error('======================================================\x1b[0m');
35
35
  console.log('\nIf you intend to use this dir:');
36
- console.log(` 1. Stop ABT Node by ${chalk.cyan('abtnode stop --force')}`);
36
+ console.log(` 1. Stop Blocklet Server by ${chalk.cyan('abtnode stop --force')}`);
37
37
  console.log(` 2. Clear data dir by ${chalk.cyan(`rm -r ${options.dataDir}`)}`);
38
- console.log(` 3. Reinitialize and start ABT Node`);
38
+ console.log(' 3. Reinitialize and start Blocklet Server');
39
39
  process.exit(1);
40
40
  }
41
41
  }
42
42
  })
43
43
  .catch((err) => {
44
- console.error('Can not ready node state on ABT Node start:', err.message);
44
+ console.error('Can not ready node state on Blocklet Server start:', err.message);
45
45
  process.exit(1);
46
46
  });
47
47
  };
@@ -36,15 +36,15 @@ const checkNewVersion = async (params, context) => {
36
36
  const latestVersion = versions[0].version;
37
37
  if (semver.gt(latestVersion, info.version)) {
38
38
  // if (semver.gte(latestVersion, info.version)) {
39
- logger.info('New version found for abt node', {
39
+ logger.info('New version found for Blocklet Server', {
40
40
  latestVersion,
41
41
  currentVersion: info.version,
42
42
  nextVersion: info.nextVersion,
43
43
  });
44
44
  await states.node.updateNodeInfo({ nextVersion: latestVersion });
45
45
  await states.notification.create({
46
- title: 'ABT Node upgrade available',
47
- description: 'A new and improved version of ABT Node is now available',
46
+ title: 'Blocklet Server upgrade available',
47
+ description: 'A new and improved version of blocklet server is now available',
48
48
  entityType: 'node',
49
49
  severity: 'info',
50
50
  sticky: true,
@@ -57,7 +57,7 @@ const checkNewVersion = async (params, context) => {
57
57
 
58
58
  return '';
59
59
  } catch (err) {
60
- logger.error('Failed to check new version for abt node', { error: err });
60
+ logger.error('Failed to check new version for Blocklet Server', { error: err });
61
61
  }
62
62
 
63
63
  return '';