@abtnode/core 1.6.8 → 1.6.12

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.
@@ -20,12 +20,13 @@ const hashFiles = require('@abtnode/util/lib/hash-files');
20
20
  const downloadFile = require('@abtnode/util/lib/download-file');
21
21
  const Lock = require('@abtnode/util/lib/lock');
22
22
  const { getVcFromPresentation } = require('@abtnode/util/lib/vc');
23
+ const { updateBlocklet: updateDidDocument } = require('@abtnode/util/lib/did-document');
23
24
  const { BLOCKLET_PURCHASE_NFT_TYPE } = require('@abtnode/constant');
24
25
 
25
26
  const getBlockletEngine = require('@blocklet/meta/lib/engine');
26
- const { isFreeBlocklet } = require('@blocklet/meta/lib/util');
27
+ const { isFreeBlocklet, isDeletableBlocklet, getRequiredMissingConfigs } = require('@blocklet/meta/lib/util');
27
28
  const validateBlockletEntry = require('@blocklet/meta/lib/entry');
28
- const { getRequiredMissingConfigs } = require('@blocklet/meta/lib/util');
29
+ const { getBlockletInfo } = require('@blocklet/meta/lib');
29
30
 
30
31
  const {
31
32
  BlockletStatus,
@@ -243,7 +244,7 @@ class BlockletManager extends BaseBlockletManager {
243
244
  hooks.preStart(b, {
244
245
  appDir: b.env.appDir,
245
246
  hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
246
- env: getRuntimeEnvironments(b, nodeEnvironments),
247
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
247
248
  did, // root blocklet did,
248
249
  progress: blocklet.mode === BLOCKLET_MODES.DEVELOPMENT,
249
250
  }),
@@ -315,7 +316,7 @@ class BlockletManager extends BaseBlockletManager {
315
316
  hooks.preStop({
316
317
  appDir: b.env.appDir,
317
318
  hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
318
- env: getRuntimeEnvironments(b, nodeEnvironments),
319
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
319
320
  did, // root blocklet did
320
321
  notification: states.notification,
321
322
  context,
@@ -380,6 +381,9 @@ class BlockletManager extends BaseBlockletManager {
380
381
 
381
382
  try {
382
383
  const blocklet = await this.ensureBlocklet(did);
384
+ if (isDeletableBlocklet(blocklet) === false) {
385
+ throw new Error('Blocklet is protected from accidental deletion');
386
+ }
383
387
 
384
388
  const nodeEnvironments = await states.node.getEnvironments();
385
389
 
@@ -388,7 +392,7 @@ class BlockletManager extends BaseBlockletManager {
388
392
  hooks.preUninstall({
389
393
  appDir: b.env.appDir,
390
394
  hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
391
- env: getRuntimeEnvironments(b, nodeEnvironments),
395
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
392
396
  did, // root blocklet did
393
397
  notification: states.notification,
394
398
  context,
@@ -513,7 +517,7 @@ class BlockletManager extends BaseBlockletManager {
513
517
 
514
518
  // run hook
515
519
  const nodeEnvironments = await states.node.getEnvironments();
516
- newConfigs.forEach((x) => {
520
+ for (const x of newConfigs) {
517
521
  if (x.key === 'BLOCKLET_APP_SK') {
518
522
  try {
519
523
  fromSecretKey(x.value);
@@ -524,6 +528,13 @@ class BlockletManager extends BaseBlockletManager {
524
528
  throw new Error('Invalid custom blocklet secret key');
525
529
  }
526
530
  }
531
+
532
+ // Ensure sk is not used by other blocklets, otherwise we may encounter appDid collision
533
+ const blocklets = await states.blocklet.getBlocklets({});
534
+ const others = blocklets.filter((b) => b.meta.did !== did);
535
+ if (others.some((b) => b.environments.find((e) => e.key === 'BLOCKLET_APP_SK').value === x.value)) {
536
+ throw new Error('Invalid custom blocklet secret key: already used by another blocklet');
537
+ }
527
538
  }
528
539
 
529
540
  if (x.key === 'BLOCKLET_WALLET_TYPE') {
@@ -532,8 +543,16 @@ class BlockletManager extends BaseBlockletManager {
532
543
  }
533
544
  }
534
545
 
546
+ if (x.key === 'BLOCKLET_DELETABLE') {
547
+ if (['yes', 'no'].includes(x.value) === false) {
548
+ throw new Error('BLOCKLET_DELETABLE must be either "yes" or "no"');
549
+ }
550
+ }
551
+
535
552
  blocklet.configObj[x.key] = x.value;
536
- });
553
+ }
554
+
555
+ // FIXME: we should also call preConfig for child blocklets
537
556
  await hooks.preConfig({
538
557
  appDir: blocklet.env.appDir,
539
558
  hooks: Object.assign(blocklet.meta.hooks || {}, blocklet.meta.scripts || {}),
@@ -897,7 +916,7 @@ class BlockletManager extends BaseBlockletManager {
897
916
  };
898
917
 
899
918
  const childConfigs = await states.blockletExtras.getChildConfigs(did, childDid);
900
- fillBlockletConfigs(child, childConfigs);
919
+ fillBlockletConfigs(child, childConfigs, blocklet);
901
920
  }
902
921
 
903
922
  return blocklet;
@@ -1496,6 +1515,15 @@ class BlockletManager extends BaseBlockletManager {
1496
1515
  return null;
1497
1516
  }
1498
1517
 
1518
+ // When new version found from the store where the blocklet was installed from, we should use that store first
1519
+ if (blocklet.source === BlockletSource.registry && blocklet.deployedFrom) {
1520
+ const latestFromSameRegistry = versions.find((x) => x.registryUrl === blocklet.deployedFrom);
1521
+ if (latestFromSameRegistry) {
1522
+ return latestFromSameRegistry;
1523
+ }
1524
+ }
1525
+
1526
+ // Otherwise try upgrading from other store
1499
1527
  let latestBlockletVersion = versions[0];
1500
1528
  versions.forEach((item) => {
1501
1529
  if (semver.lt(latestBlockletVersion.version, item.version)) {
@@ -1561,7 +1589,7 @@ class BlockletManager extends BaseBlockletManager {
1561
1589
 
1562
1590
  await this._setConfigs(did);
1563
1591
 
1564
- logger.info('blocklet added to database', { meta });
1592
+ logger.info('blocklet added to database', { did: meta.did });
1565
1593
 
1566
1594
  const blocklet1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
1567
1595
  this.emit(BlockletEvents.added, blocklet1);
@@ -1855,7 +1883,7 @@ class BlockletManager extends BaseBlockletManager {
1855
1883
  const postInstall = (b) =>
1856
1884
  hooks.postInstall({
1857
1885
  hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
1858
- env: getRuntimeEnvironments(b, nodeEnvironments),
1886
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
1859
1887
  appDir: blocklet.env.appDir,
1860
1888
  did, // root blocklet did
1861
1889
  notification: states.notification,
@@ -1865,7 +1893,19 @@ class BlockletManager extends BaseBlockletManager {
1865
1893
 
1866
1894
  await states.blocklet.setBlockletStatus(did, BlockletStatus.installed);
1867
1895
  blocklet = await this.ensureBlocklet(did);
1868
- logger.info('blocklet installed', { source, meta });
1896
+ logger.info('blocklet installed', { source, did: meta.did });
1897
+ if (process.env.NODE_ENV !== 'test') {
1898
+ const nodeInfo = await states.node.read();
1899
+ const blockletInfo = getBlockletInfo(blocklet, nodeInfo.sk);
1900
+ const updateDidDnsResult = await updateDidDocument({
1901
+ wallet: blockletInfo.wallet,
1902
+ domain: nodeInfo.didDomain,
1903
+ nodeDid: nodeInfo.did,
1904
+ didRegistryUrl: nodeInfo.didRegistry,
1905
+ });
1906
+ logger.info('updated did document', { updateDidDnsResult, blockletId: blocklet.meta.did });
1907
+ }
1908
+
1869
1909
  this.emit(BlockletEvents.installed, { blocklet, context });
1870
1910
 
1871
1911
  states.notification.create({
@@ -1943,7 +1983,7 @@ class BlockletManager extends BaseBlockletManager {
1943
1983
  const postInstall = (b) =>
1944
1984
  hooks.postInstall({
1945
1985
  hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
1946
- env: getRuntimeEnvironments(b, nodeEnvironments),
1986
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
1947
1987
  appDir: b.env.appDir,
1948
1988
  did, // root blocklet did
1949
1989
  notification: states.notification,
@@ -1959,7 +1999,7 @@ class BlockletManager extends BaseBlockletManager {
1959
1999
  blocklet: b,
1960
2000
  oldVersion,
1961
2001
  newVersion: version,
1962
- env: getRuntimeEnvironments(b, nodeEnvironments),
2002
+ env: getRuntimeEnvironments(b, nodeEnvironments, blocklet),
1963
2003
  appDir: b.env.appDir,
1964
2004
  did: b.meta.did,
1965
2005
  notification: states.notification,
@@ -2251,8 +2291,9 @@ class BlockletManager extends BaseBlockletManager {
2251
2291
  try {
2252
2292
  const state = await states.blocklet.getBlocklet(did);
2253
2293
  if (state && util.shouldUpdateBlockletStatus(state.status)) {
2254
- const result = await states.blocklet.setBlockletStatus(did, pm2StatusMap[pm2Status]);
2255
- logger.info('sync pm2 status to blocklet', { result });
2294
+ const newStatus = pm2StatusMap[pm2Status];
2295
+ await states.blocklet.setBlockletStatus(did, newStatus);
2296
+ logger.info('sync pm2 status to blocklet', { did, pm2Status, newStatus });
2256
2297
  }
2257
2298
  } catch (error) {
2258
2299
  logger.error('sync pm2 status to blocklet failed', { did, pm2Status, error });
package/lib/cert.js CHANGED
@@ -70,6 +70,10 @@ class Cert extends EventEmitter {
70
70
  return this.manager.getAllNormal();
71
71
  }
72
72
 
73
+ getNormalByDomain(domain) {
74
+ return this.manager.getNormalByDomain(domain);
75
+ }
76
+
73
77
  getByDomain(domain) {
74
78
  return this.manager.getByDomain(domain);
75
79
  }
@@ -111,6 +115,10 @@ class Cert extends EventEmitter {
111
115
  async addWithoutValidations(data) {
112
116
  return this.manager.addWithoutValidations(data);
113
117
  }
118
+
119
+ async updateWithoutValidations(id, data) {
120
+ return this.manager.updateWithoutValidations(id, data);
121
+ }
114
122
  }
115
123
 
116
124
  module.exports = Cert;
package/lib/event.js CHANGED
@@ -1,5 +1,8 @@
1
+ const get = require('lodash/get');
2
+ const cloneDeep = require('lodash/cloneDeep');
1
3
  const { EventEmitter } = require('events');
2
4
  const { BLOCKLET_MODES } = require('@blocklet/meta/lib/constants');
5
+ const { wipeSensitiveData } = require('@blocklet/meta/lib/util');
3
6
  const logger = require('@abtnode/logger')('@abtnode/core:event');
4
7
  const { BlockletStatus, BlockletSource, BlockletEvents } = require('@blocklet/meta/lib/constants');
5
8
 
@@ -43,9 +46,13 @@ module.exports = ({
43
46
  let eventHandler = null;
44
47
 
45
48
  const onEvent = (name, data) => {
46
- events.emit(name, data);
49
+ let safeData = data;
50
+ if (get(data, 'meta.did', '')) {
51
+ safeData = wipeSensitiveData(cloneDeep(data));
52
+ }
53
+ events.emit(name, safeData);
47
54
  if (typeof eventHandler === 'function') {
48
- eventHandler({ name, data });
55
+ eventHandler({ name, data: safeData });
49
56
  }
50
57
  };
51
58
 
package/lib/index.js CHANGED
@@ -132,8 +132,6 @@ function ABTNode(options) {
132
132
  daemon: options.daemon,
133
133
  });
134
134
 
135
- certManager.start(); // 启动证书服务
136
-
137
135
  const {
138
136
  handleRouting,
139
137
  getRoutingRulesByDid,
@@ -169,10 +167,10 @@ function ABTNode(options) {
169
167
  ensureBlockletRoutingForUpgrade,
170
168
  removeBlockletRouting,
171
169
  takeRoutingSnapshot,
172
- routerManager,
173
170
  handleRouting,
174
171
  domainStatus,
175
172
  teamAPI,
173
+ certManager,
176
174
  });
177
175
 
178
176
  const isInitialized = async () => {
@@ -395,11 +393,23 @@ function ABTNode(options) {
395
393
  };
396
394
 
397
395
  if (options.daemon) {
396
+ certManager.start(); // 启动证书服务
397
+
398
398
  if (process.env.NODE_ENV === 'development') {
399
399
  initCron();
400
400
  } else {
401
401
  // We should only respond to pm2 events when node is alive
402
- events.on('node.started', () => {
402
+ events.on('node.started', async () => {
403
+ const info = await states.node.read();
404
+ certManager
405
+ .issue({ domain: `${info.did.toLowerCase()}.${info.didDomain}` })
406
+ .then(() => {
407
+ logger.info('add issue daemon certificate job');
408
+ })
409
+ .catch((error) => {
410
+ logger.error('issue daemon certificate job failed', { error });
411
+ });
412
+
403
413
  pm2Events.resume();
404
414
  initCron();
405
415
  });
@@ -0,0 +1,38 @@
1
+ /* eslint-disable no-await-in-loop */
2
+
3
+ const { DEFAULT_DID_REGISTRY, DEFAULT_DID_DOMAIN } = require('@abtnode/constant');
4
+ const { isEmpty, omit } = require('lodash');
5
+
6
+ const updateNodeInfo = async ({ printInfo, states }) => {
7
+ // add didRegistry and didDomain
8
+ const info = await states.node.read();
9
+ const data = {};
10
+ if (!info.didRegistry) {
11
+ data.didRegistry = DEFAULT_DID_REGISTRY;
12
+ }
13
+
14
+ if (!info.didDomain) {
15
+ data.didDomain = DEFAULT_DID_DOMAIN;
16
+ }
17
+
18
+ if (!isEmpty(data)) {
19
+ await states.node.update({ _id: info._id }, { $set: data });
20
+ }
21
+
22
+ printInfo('update did registry and did domain successfully');
23
+ };
24
+
25
+ const updateCertificate = async ({ node, printInfo }) => {
26
+ const certs = await node.certManager.getAllNormal();
27
+ for (const cert of certs || []) {
28
+ await node.certManager.updateWithoutValidations(cert.id, omit(cert, 'id'));
29
+ }
30
+
31
+ printInfo('update certificate successfully');
32
+ };
33
+
34
+ /* eslint-disable no-underscore-dangle */
35
+ module.exports = async ({ node, printInfo, states }) => {
36
+ await updateNodeInfo({ printInfo, states });
37
+ await updateCertificate({ node, printInfo, states });
38
+ };
@@ -48,7 +48,7 @@ const {
48
48
  getWellknownSitePort,
49
49
  } = require('../util');
50
50
  const { getServicesFromBlockletInterface } = require('../util/service');
51
- const getIpDnsDomainForBlocklet = require('../util/get-ip-dns-domain-for-blocklet');
51
+ const { getIpDnsDomainForBlocklet, getDidDomainForBlocklet } = require('../util/get-domain-for-blocklet');
52
52
  const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-accessible-external-node-ip');
53
53
 
54
54
  const Router = require('./index');
@@ -623,11 +623,16 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
623
623
  });
624
624
 
625
625
  const dashboardDomain = get(info, 'routing.dashboardDomain', '');
626
- if (dashboardDomain && !isExistsInAlias(dashboardDomain)) {
626
+ const didDomain = `${info.did.toLowerCase()}.${info.didDomain}`;
627
+ const dashboardAliasDomains = [dashboardDomain, didDomain]
628
+ .filter((item) => item && !isExistsInAlias(item))
629
+ .map((item) => ({ value: item, isProtected: true }));
630
+
631
+ if (dashboardAliasDomains.length > 0) {
627
632
  try {
628
633
  const result = await siteState.update(
629
634
  { _id: dashboardSite.id },
630
- { $push: { domainAliases: { value: dashboardDomain, isProtected: true } } }
635
+ { $push: { domainAliases: { $each: dashboardAliasDomains } } }
631
636
  );
632
637
 
633
638
  updatedResult.push(result);
@@ -690,7 +695,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
690
695
  };
691
696
 
692
697
  const domainGroup = `${blocklet.meta.did}${BLOCKLET_SITE_GROUP_SUFFIX}`;
693
- const domain = getIpDnsDomainForBlocklet(blocklet, webInterface);
698
+
694
699
  const pathPrefix = getPrefix(webInterface.prefix);
695
700
  const rule = {
696
701
  from: { pathPrefix },
@@ -705,11 +710,24 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
705
710
 
706
711
  const existSite = await states.site.findOne({ domain: domainGroup });
707
712
  if (!existSite) {
713
+ const ipEchoDnsDomain = getIpDnsDomainForBlocklet(blocklet, webInterface, nodeInfo.did);
714
+ const appIdEnv = blocklet.environments.find((e) => e.key === 'BLOCKLET_APP_ID');
715
+ const domainAliases = [{ value: ipEchoDnsDomain, isProtected: true }];
716
+
717
+ const didDomain = getDidDomainForBlocklet({
718
+ appId: appIdEnv.value,
719
+ didDomain: nodeInfo.didDomain,
720
+ });
721
+
722
+ if (blocklet.mode !== 'development') {
723
+ domainAliases.push({ value: didDomain, isProtected: true });
724
+ }
725
+
708
726
  await routerManager.addRoutingSite(
709
727
  {
710
728
  site: {
711
729
  domain: domainGroup,
712
- domainAliases: [{ value: domain, isProtected: true }],
730
+ domainAliases,
713
731
  isProtected: true,
714
732
  rules: [rule],
715
733
  },
@@ -717,7 +735,14 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
717
735
  },
718
736
  context
719
737
  );
720
- logger.info('add routing site', { site: domain });
738
+ logger.info('add routing site', { site: domainGroup });
739
+ if (
740
+ process.env.NODE_ENV !== 'development' &&
741
+ process.env.NODE_ENV !== 'test' &&
742
+ blocklet.mode !== 'development'
743
+ ) {
744
+ await certManager.issue({ domain: didDomain });
745
+ }
721
746
 
722
747
  return true;
723
748
  }
@@ -732,13 +757,13 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
732
757
  },
733
758
  skipProtectedRuleChecking: true,
734
759
  });
735
- logger.info('update routing rule for site', { site: domain });
760
+ logger.info('update routing rule for site', { site: domainGroup });
736
761
  } else {
737
762
  await routerManager.addRoutingRule({
738
763
  id: existSite.id,
739
764
  rule,
740
765
  });
741
- logger.info('add routing rule for site', { site: domain });
766
+ logger.info('add routing rule for site', { site: domainGroup });
742
767
  }
743
768
 
744
769
  return true;
@@ -459,9 +459,9 @@ class RouterManager extends EventEmitter {
459
459
  return {
460
460
  id: matchedCert.id,
461
461
  domain: matchedCert.domain,
462
- issuer: matchedCert.issuer,
463
- validFrom: matchedCert.validFrom,
464
- validTo: matchedCert.validTo,
462
+ issuer: matchedCert.meta.issuer,
463
+ validFrom: matchedCert.meta.validFrom,
464
+ validTo: matchedCert.meta.validTo,
465
465
  };
466
466
  }
467
467
 
@@ -90,6 +90,8 @@ class NodeState extends BaseState {
90
90
  runtimeConfig,
91
91
  ownerNft,
92
92
  launcherInfo,
93
+ didRegistry,
94
+ didDomain,
93
95
  } = this.options;
94
96
 
95
97
  if (nodeOwner && !validateOwner(nodeOwner)) {
@@ -122,6 +124,8 @@ class NodeState extends BaseState {
122
124
  ownerNft,
123
125
  diskAlertThreshold: DISK_ALERT_THRESHOLD_PERCENT,
124
126
  launcherInfo: launcherInfo || undefined,
127
+ didRegistry,
128
+ didDomain,
125
129
  },
126
130
  async (e, data) => {
127
131
  if (e) {
@@ -134,6 +138,10 @@ class NodeState extends BaseState {
134
138
  }
135
139
 
136
140
  logger.info('create', { data });
141
+ if (dek) {
142
+ data.sk = security.decrypt(data.sk, data.did, dek);
143
+ }
144
+
137
145
  return resolve(data);
138
146
  }
139
147
  )
@@ -5,6 +5,7 @@ const path = require('path');
5
5
  const os = require('os');
6
6
  const tar = require('tar');
7
7
  const get = require('lodash/get');
8
+ const intersection = require('lodash/intersection');
8
9
  const streamToPromise = require('stream-to-promise');
9
10
  const { Throttle } = require('stream-throttle');
10
11
  const ssri = require('ssri');
@@ -69,7 +70,7 @@ const statusMap = {
69
70
  stopped: BlockletStatus.stopped,
70
71
  };
71
72
 
72
- const nodePrivateEnvs = [
73
+ const PRIVATE_NODE_ENVS = [
73
74
  // 'NEDB_MULTI_PORT', // FIXME: 排查 abtnode 对外提供的 SDK(比如 @abtnode/queue), SDK 中不要自动使用 NEDB_MULTI_PORT 环境变量
74
75
  'ABT_NODE_UPDATER_PORT',
75
76
  'ABT_NODE_SESSION_TTL',
@@ -186,7 +187,7 @@ const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } =
186
187
  * @param {*} blocklet
187
188
  * @param {*} configs
188
189
  */
189
- const fillBlockletConfigs = (blocklet, configs) => {
190
+ const fillBlockletConfigs = (blocklet, configs, parent) => {
190
191
  blocklet.configs = configs || [];
191
192
  blocklet.configObj = blocklet.configs.reduce((acc, x) => {
192
193
  acc[x.key] = x.value;
@@ -196,6 +197,13 @@ const fillBlockletConfigs = (blocklet, configs) => {
196
197
  acc[x.key] = x.value;
197
198
  return acc;
198
199
  }, {});
200
+
201
+ const sharedConfigs = getSharedConfigs(blocklet, parent);
202
+ Object.keys(sharedConfigs).forEach((key) => {
203
+ blocklet.configObj[key] = sharedConfigs[key];
204
+ const item = blocklet.configs.find((x) => x.key === key);
205
+ item.value = sharedConfigs[key];
206
+ });
199
207
  };
200
208
 
201
209
  const ensureBlockletExpanded = async (meta, appDir) => {
@@ -297,10 +305,10 @@ const getSystemEnvironments = (blocklet) => {
297
305
  };
298
306
  };
299
307
 
300
- const getRuntimeEnvironments = (blocklet, nodeEnvironments) => {
308
+ const getRuntimeEnvironments = (blocklet, nodeEnvironments, parent) => {
301
309
  // pm2 will force inject env variables of daemon process to blocklet process
302
310
  // we can only rewrite these private env variables to empty
303
- const safeNodeEnvironments = nodePrivateEnvs.reduce((o, x) => {
311
+ const safeNodeEnvironments = PRIVATE_NODE_ENVS.reduce((o, x) => {
304
312
  o[x] = '';
305
313
  return o;
306
314
  }, {});
@@ -308,11 +316,28 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments) => {
308
316
  return {
309
317
  ...blocklet.environmentObj,
310
318
  ...blocklet.configObj,
319
+ ...getSharedConfigs(blocklet, parent),
311
320
  ...nodeEnvironments,
312
321
  ...safeNodeEnvironments,
313
322
  };
314
323
  };
315
324
 
325
+ // we support share insecure same configs between parent and child blocklets
326
+ const getSharedConfigs = (child, parent) => {
327
+ const sharedConfigs = {};
328
+ if (parent && Array.isArray(parent.configs) && child.meta.did !== parent.meta.did) {
329
+ const parentKeys = parent.configs.filter((x) => x.secure === false).map((x) => x.key);
330
+ const childKeys = child.configs.map((x) => x.key);
331
+ const sharedKeys = intersection(parentKeys, childKeys);
332
+ sharedKeys.forEach((key) => {
333
+ if (!child.configObj[key]) {
334
+ sharedConfigs[key] = parent.configObj[key];
335
+ }
336
+ });
337
+ }
338
+ return sharedConfigs;
339
+ };
340
+
316
341
  const isUsefulError = (err) => err && err.message !== 'process or namespace not found';
317
342
 
318
343
  const getHealthyCheckTimeout = (blocklet, { checkHealthImmediately } = {}) => {
@@ -16,4 +16,8 @@ const getIpDnsDomainForBlocklet = (blocklet, blockletInterface) => {
16
16
  }${iName}-${SLOT_FOR_IP_DNS_SITE}.${DEFAULT_IP_DNS_DOMAIN_SUFFIX}`;
17
17
  };
18
18
 
19
- module.exports = getIpDnsDomainForBlocklet;
19
+ const getDidDomainForBlocklet = ({ appId, didDomain }) => {
20
+ return `${appId.toLowerCase()}.${didDomain}`;
21
+ };
22
+
23
+ module.exports = { getIpDnsDomainForBlocklet, getDidDomainForBlocklet };
package/lib/util/index.js CHANGED
@@ -315,7 +315,6 @@ const getHttpsCertInfo = (certificate) => {
315
315
  validFrom,
316
316
  validTo,
317
317
  issuer,
318
- serialNumber: info.serialNumber,
319
318
  sans: info.dnsNames,
320
319
  validityPeriod: info.validTo - info.validFrom,
321
320
  fingerprintAlg: 'SHA256',
@@ -358,39 +357,53 @@ const formatEnvironments = (environments) => Object.keys(environments).map((x) =
358
357
  const transformIPToDomain = (ip) => ip.split('.').join('-');
359
358
 
360
359
  const getBaseUrls = async (node, ips) => {
361
- const ipTypes = {
362
- internal: 'private',
363
- external: 'public',
364
- };
365
360
  const info = await node.getNodeInfo();
366
361
  const { https, httpPort, httpsPort } = info.routing;
367
- const ipKeys = Object.keys(ips).filter((x) => ips[x]);
368
362
  const getPort = (port, defaultPort) => (port && port !== defaultPort ? `:${port}` : '');
363
+ const availableIps = ips.filter(Boolean);
364
+
365
+ const getHttpInfo = async (domain) => {
366
+ const certificate = https ? await node.certManager.getNormalByDomain(domain) : null;
367
+ const protocol = certificate ? 'https' : 'http';
368
+ const port = certificate ? getPort(httpsPort, DEFAULT_HTTPS_PORT) : getPort(httpPort, DEFAULT_HTTP_PORT);
369
+
370
+ return { protocol, port };
371
+ };
369
372
 
370
373
  if (info.routing.provider !== ROUTER_PROVIDER_NONE && info.routing.snapshotHash && info.routing.adminPath) {
371
374
  const sites = await node.getSitesFromSnapshot();
372
375
 
373
376
  const { dashboardDomain } = info.routing;
374
377
  const adminPath = normalizePathPrefix(info.routing.adminPath);
375
- const httpUrls = ipKeys.map((x) => {
376
- const port = getPort(httpPort, DEFAULT_HTTP_PORT);
378
+ const tmpHttpPort = getPort(httpPort, DEFAULT_HTTP_PORT);
379
+
380
+ const httpUrls = availableIps.map((ip) => {
377
381
  return {
378
- url: `http://${ips[x]}${port}${adminPath}`,
379
- type: ipTypes[x],
382
+ url: `http://${ip}${tmpHttpPort}${adminPath}`,
380
383
  };
381
384
  });
382
385
 
383
386
  if (dashboardDomain) {
384
387
  const site = sites.find((c) => (c.domainAliases || []).find((item) => item.value === dashboardDomain));
385
388
  if (site) {
386
- const certificate = https ? await node.findCertificateByDomain(dashboardDomain) : null;
387
- const protocol = certificate ? 'https' : 'http';
388
- const port = certificate ? getPort(httpsPort, DEFAULT_HTTPS_PORT) : getPort(httpPort, DEFAULT_HTTP_PORT);
389
- const httpsUrls = ipKeys.map((x) => ({
390
- url: `${protocol}://${transformIPToDomain(ips[x])}.${dashboardDomain.substring(2)}${port}${adminPath}`,
391
- type: ipTypes[x],
389
+ const httpInfo = await getHttpInfo(dashboardDomain);
390
+ const httpsUrls = availableIps.map((ip) => ({
391
+ url: `${httpInfo.protocol}://${transformIPToDomain(ip)}.${dashboardDomain.substring(2)}${
392
+ httpInfo.port
393
+ }${adminPath}`,
392
394
  }));
393
395
 
396
+ // add did domain access url
397
+ const didDomainAlias = site.domainAliases.find((item) => item.value.endsWith(info.didDomain));
398
+ if (didDomainAlias) {
399
+ const didDomain = didDomainAlias.value;
400
+ const didDomainHttpInfo = await getHttpInfo(didDomain);
401
+
402
+ httpsUrls.push({
403
+ url: `${didDomainHttpInfo.protocol}://${didDomain}${didDomainHttpInfo.port}${adminPath}`,
404
+ });
405
+ }
406
+
394
407
  return httpUrls.concat(httpsUrls);
395
408
  }
396
409
  }
@@ -399,9 +412,8 @@ const getBaseUrls = async (node, ips) => {
399
412
  }
400
413
 
401
414
  // port urls
402
- return ipKeys.map((x) => ({
403
- url: `http://${ips[x]}:${info.port}`,
404
- type: ipTypes[x],
415
+ return availableIps.map((ip) => ({
416
+ url: `http://${ip}:${info.port}`,
405
417
  }));
406
418
  };
407
419
 
package/lib/util/ready.js CHANGED
@@ -33,7 +33,7 @@ const createStateReadyHandler =
33
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 Blocklet Server by ${chalk.cyan('abtnode stop --force')}`);
36
+ console.log(` 1. Stop Blocklet Server by ${chalk.cyan('blocklet server stop --force')}`);
37
37
  console.log(` 2. Clear data dir by ${chalk.cyan(`rm -r ${options.dataDir}`)}`);
38
38
  console.log(' 3. Reinitialize and start Blocklet Server');
39
39
  process.exit(1);
@@ -66,7 +66,7 @@ module.exports = ({ events, dataDirs, instance }) => {
66
66
  const webhookList = await webhookState.list();
67
67
  const nodeInfo = await nodeState.read();
68
68
  const { internal, external } = await IP.get();
69
- const baseUrls = await getBaseUrls(instance, { internal, external });
69
+ const baseUrls = await getBaseUrls(instance, [internal, external]);
70
70
  const senderFns = {};
71
71
 
72
72
  if (webhookList.length) {
@@ -76,8 +76,8 @@ module.exports = ({ events, dataDirs, instance }) => {
76
76
  const senderInstance = WebHookSender.getMessageSender(item.type);
77
77
  senderFns[item.type] = senderInstance.send.bind(senderInstance);
78
78
  }
79
- const { description } = nodeInfo;
80
- const options = { ...message, nodeInfo: `*${description}*` };
79
+ const { name } = nodeInfo;
80
+ const options = { ...message, nodeInfo: `*${name}*` };
81
81
  if (item.type === 'slack') {
82
82
  options.urlInfo = getSlackUrlInfo(message.action, baseUrls);
83
83
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.6.8",
6
+ "version": "1.6.12",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,22 +19,22 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/certificate-manager": "1.6.8",
23
- "@abtnode/constant": "1.6.8",
24
- "@abtnode/cron": "1.6.8",
25
- "@abtnode/db": "1.6.8",
26
- "@abtnode/logger": "1.6.8",
27
- "@abtnode/queue": "1.6.8",
28
- "@abtnode/rbac": "1.6.8",
29
- "@abtnode/router-provider": "1.6.8",
30
- "@abtnode/static-server": "1.6.8",
31
- "@abtnode/timemachine": "1.6.8",
32
- "@abtnode/util": "1.6.8",
22
+ "@abtnode/certificate-manager": "1.6.12",
23
+ "@abtnode/constant": "1.6.12",
24
+ "@abtnode/cron": "1.6.12",
25
+ "@abtnode/db": "1.6.12",
26
+ "@abtnode/logger": "1.6.12",
27
+ "@abtnode/queue": "1.6.12",
28
+ "@abtnode/rbac": "1.6.12",
29
+ "@abtnode/router-provider": "1.6.12",
30
+ "@abtnode/static-server": "1.6.12",
31
+ "@abtnode/timemachine": "1.6.12",
32
+ "@abtnode/util": "1.6.12",
33
33
  "@arcblock/did": "^1.13.79",
34
34
  "@arcblock/event-hub": "1.13.79",
35
35
  "@arcblock/pm2-events": "^0.0.5",
36
36
  "@arcblock/vc": "^1.13.79",
37
- "@blocklet/meta": "1.6.8",
37
+ "@blocklet/meta": "1.6.12",
38
38
  "@fidm/x509": "^1.2.1",
39
39
  "@nedb/core": "^1.2.2",
40
40
  "@nedb/multi": "^1.2.2",
@@ -75,5 +75,5 @@
75
75
  "express": "^4.17.1",
76
76
  "jest": "^27.4.5"
77
77
  },
78
- "gitHead": "f97ec3a44250e034ff4b5e3f088c1417f448a7bb"
78
+ "gitHead": "dd79037978dc12f72330227a553a80a504f03fa7"
79
79
  }