@abtnode/core 1.8.65-beta-5405baf2 → 1.8.65-beta-f7af64a4

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/api/team.js CHANGED
@@ -178,6 +178,7 @@ class TeamAPI extends EventEmitter {
178
178
  'passports',
179
179
  'firstLoginAt',
180
180
  'lastLoginAt',
181
+ 'lastLoginIp',
181
182
  'remark',
182
183
  'avatar',
183
184
  'locale',
@@ -444,6 +444,7 @@ class BlockletManager extends BaseBlockletManager {
444
444
 
445
445
  async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
446
446
  logger.info('start blocklet', { did });
447
+ // should check blocklet integrity
447
448
  const blocklet = await this.ensureBlocklet(did, { e2eMode });
448
449
 
449
450
  try {
@@ -557,7 +558,7 @@ class BlockletManager extends BaseBlockletManager {
557
558
  async stop({ did, updateStatus = true, silent = false }, context) {
558
559
  logger.info('stop blocklet', { did });
559
560
 
560
- const blocklet = await this.ensureBlocklet(did);
561
+ const blocklet = await this.getBlocklet(did);
561
562
  const { processId } = blocklet.env;
562
563
 
563
564
  if (updateStatus) {
@@ -655,7 +656,7 @@ class BlockletManager extends BaseBlockletManager {
655
656
 
656
657
  // eslint-disable-next-line no-unused-vars
657
658
  async reload({ did }, context) {
658
- const blocklet = await this.ensureBlocklet(did);
659
+ const blocklet = await this.getBlocklet(did);
659
660
 
660
661
  await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
661
662
  await reloadBlockletProcess(blocklet);
@@ -671,13 +672,12 @@ class BlockletManager extends BaseBlockletManager {
671
672
  logger.info('delete blocklet', { did, keepData });
672
673
 
673
674
  try {
674
- const blocklet = await this.ensureBlocklet(did, { validateEnv: false });
675
+ const blocklet = await this.getBlocklet(did);
675
676
  if (isDeletableBlocklet(blocklet) === false) {
676
677
  throw new Error('Blocklet is protected from accidental deletion');
677
678
  }
678
679
 
679
680
  const nodeEnvironments = await states.node.getEnvironments();
680
-
681
681
  await deleteBlockletProcess(blocklet, {
682
682
  preDelete: (b, { ancestors }) =>
683
683
  hooks.preUninstall(b.env.processId, {
@@ -700,31 +700,27 @@ class BlockletManager extends BaseBlockletManager {
700
700
  severity: 'success',
701
701
  });
702
702
  return doc;
703
- } catch (err) {
703
+ } catch (error) {
704
704
  // If we installed a corrupted blocklet accidentally, just cleanup the disk and state db
705
- if (err.code === 'BLOCKLET_CORRUPTED') {
706
- logger.info('blocklet is corrupted, will delete again', { did });
707
- const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
708
-
709
- this._createNotification(doc.meta.did, {
710
- title: 'Blocklet Deleted',
711
- description: `Blocklet ${doc.meta.name}@${doc.meta.version} is deleted.`,
712
- entityType: 'blocklet',
713
- entityId: doc.meta.did,
714
- severity: 'success',
715
- });
705
+ logger.error('blocklet delete failed, will delete again', { did, error });
706
+ const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
716
707
 
717
- return doc;
718
- }
708
+ this._createNotification(doc.meta.did, {
709
+ title: 'Blocklet Deleted',
710
+ description: `Blocklet ${doc.meta.name}@${doc.meta.version} is deleted.`,
711
+ entityType: 'blocklet',
712
+ entityId: doc.meta.did,
713
+ severity: 'success',
714
+ });
719
715
 
720
- throw err;
716
+ return doc;
721
717
  }
722
718
  }
723
719
 
724
720
  async reset({ did, childDid }, context = {}) {
725
721
  logger.info('reset blocklet', { did, childDid });
726
722
 
727
- const blocklet = await this.ensureBlocklet(did);
723
+ const blocklet = await this.getBlocklet(did);
728
724
 
729
725
  if (isInProgress(blocklet.status || blocklet.status === BlockletStatus.running)) {
730
726
  throw new Error('Cannot reset when blocklet is in progress');
@@ -774,7 +770,7 @@ class BlockletManager extends BaseBlockletManager {
774
770
  async deleteComponent({ did, rootDid, keepData, keepState }, context) {
775
771
  logger.info('delete blocklet component', { did, rootDid, keepData });
776
772
 
777
- const blocklet = await this.ensureBlocklet(rootDid, { validateEnv: false });
773
+ const blocklet = await this.getBlocklet(rootDid);
778
774
  const child = blocklet.children.find((x) => x.meta.did === did);
779
775
  if (!child) {
780
776
  throw new Error('Component does not exist');
@@ -828,7 +824,7 @@ class BlockletManager extends BaseBlockletManager {
828
824
  await states.blockletExtras.delConfigs([blocklet.meta.did, child.meta.did]);
829
825
  }
830
826
 
831
- const newBlocklet = await this.ensureBlocklet(rootDid);
827
+ const newBlocklet = await this.getBlocklet(rootDid);
832
828
  this.emit(BlockletEvents.upgraded, { blocklet: newBlocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
833
829
 
834
830
  this._createNotification(newBlocklet.meta.did, {
@@ -881,7 +877,7 @@ class BlockletManager extends BaseBlockletManager {
881
877
 
882
878
  // eslint-disable-next-line no-unused-vars
883
879
  async deleteProcess({ did }, context) {
884
- const blocklet = await this.ensureBlocklet(did);
880
+ const blocklet = await this.getBlocklet(did);
885
881
 
886
882
  logger.info('delete blocklet process', { did });
887
883
 
@@ -904,17 +900,17 @@ class BlockletManager extends BaseBlockletManager {
904
900
 
905
901
  if (!attachRuntimeInfo) {
906
902
  try {
907
- const blocklet = await this.ensureBlocklet(did, { throwOnNotExist: false });
903
+ const blocklet = await this.getBlocklet(did, { throwOnNotExist: false });
908
904
  return blocklet;
909
905
  } catch (e) {
910
906
  logger.error('get blocklet detail error', { error: e });
911
- return null; // TODO: 直接返回没有 runtime info 的数据
907
+ return states.blocklet.getBlocklet(did);
912
908
  }
913
909
  }
914
910
 
915
911
  const nodeInfo = await states.node.read();
916
912
 
917
- return this.attachRuntimeInfo({ did, nodeInfo, diskInfo: true, context });
913
+ return this._attachRuntimeInfo({ did, nodeInfo, diskInfo: true, context });
918
914
  }
919
915
 
920
916
  async attachBlockletListRuntimeInfo({ blocklets, useCache }, context) {
@@ -929,7 +925,7 @@ class BlockletManager extends BaseBlockletManager {
929
925
  const cachedBlocklet =
930
926
  useCache && this.cachedBlocklets ? this.cachedBlocklets.find((y) => y.meta.did === x.meta.did) : null;
931
927
 
932
- return this.attachRuntimeInfo({
928
+ return this._attachRuntimeInfo({
933
929
  did: x.meta.did,
934
930
  nodeInfo,
935
931
  diskInfo: false,
@@ -977,7 +973,7 @@ class BlockletManager extends BaseBlockletManager {
977
973
  const [rootDid, ...childDids] = dids;
978
974
  logger.info('config blocklet', { dids });
979
975
 
980
- let blocklet = await this.ensureBlocklet(rootDid);
976
+ let blocklet = await this.getBlocklet(rootDid);
981
977
  for (const childDid of childDids) {
982
978
  blocklet = blocklet.children.find((x) => x.meta.did === childDid);
983
979
  if (!blocklet) {
@@ -1035,20 +1031,20 @@ class BlockletManager extends BaseBlockletManager {
1035
1031
  await this.updateBlockletEnvironment(rootDid);
1036
1032
 
1037
1033
  // response
1038
- const newState = await this.ensureBlocklet(rootDid);
1034
+ const newState = await this.getBlocklet(rootDid);
1039
1035
  this.emit(BlockletEvents.updated, newState);
1040
1036
  return newState;
1041
1037
  }
1042
1038
 
1043
1039
  async configPublicToStore({ did, publicToStore = false }) {
1044
- const blocklet = await this.ensureBlocklet(did);
1040
+ const blocklet = await this.getBlocklet(did);
1045
1041
  // publicToStore 由用户传入
1046
1042
  // handleInstanceInStore 方法写在前面,保证向 store 操作成功后才会更改 blocklet 中的 publicToStore值
1047
1043
  // handleInstanceInStore 中会校验修改 publicToStore字段 的条件,不符合则会抛错,就不会执行下面更新 publicToStore 的逻辑
1048
1044
  await handleInstanceInStore(blocklet, { publicToStore });
1049
1045
  await states.blockletExtras.setSettings(did, { publicToStore });
1050
1046
 
1051
- const newState = await this.ensureBlocklet(did);
1047
+ const newState = await this.getBlocklet(did);
1052
1048
  return newState;
1053
1049
  }
1054
1050
 
@@ -1058,7 +1054,7 @@ class BlockletManager extends BaseBlockletManager {
1058
1054
  }
1059
1055
  await states.blockletExtras.setSettings(did, { navigations });
1060
1056
 
1061
- const newState = await this.ensureBlocklet(did);
1057
+ const newState = await this.getBlocklet(did);
1062
1058
  this.emit(BlockletEvents.updated, newState);
1063
1059
  return newState;
1064
1060
  }
@@ -1110,7 +1106,7 @@ class BlockletManager extends BaseBlockletManager {
1110
1106
  await states.blockletExtras.setConfigs(dids, configs);
1111
1107
  }
1112
1108
 
1113
- const blocklet = await this.ensureBlocklet(rootDid);
1109
+ const blocklet = await this.getBlocklet(rootDid);
1114
1110
 
1115
1111
  this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
1116
1112
 
@@ -1158,7 +1154,7 @@ class BlockletManager extends BaseBlockletManager {
1158
1154
  // trigger dashboard frontend refresh
1159
1155
  this.emit(BlockletEvents.updated, blocklet);
1160
1156
 
1161
- return this.ensureBlocklet(rootDid);
1157
+ return this.getBlocklet(rootDid);
1162
1158
  }
1163
1159
 
1164
1160
  async updateComponentMountPoint({ did, rootDid: inputRootDid, mountPoint }, context) {
@@ -1194,7 +1190,7 @@ class BlockletManager extends BaseBlockletManager {
1194
1190
 
1195
1191
  this.emit(BlockletEvents.upgraded, { blocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
1196
1192
 
1197
- return this.ensureBlocklet(rootDid);
1193
+ return this.getBlocklet(rootDid);
1198
1194
  }
1199
1195
 
1200
1196
  /**
@@ -1540,6 +1536,8 @@ class BlockletManager extends BaseBlockletManager {
1540
1536
 
1541
1537
  // Add Config
1542
1538
  await this._setConfigsFromMeta(did);
1539
+
1540
+ // should ensure blocklet integrity
1543
1541
  let blocklet = await this.ensureBlocklet(did);
1544
1542
 
1545
1543
  // pre install
@@ -1547,14 +1545,14 @@ class BlockletManager extends BaseBlockletManager {
1547
1545
 
1548
1546
  // Add environments
1549
1547
  await this.updateBlockletEnvironment(did);
1550
- blocklet = await this.ensureBlocklet(did);
1548
+ blocklet = await this.getBlocklet(did);
1551
1549
 
1552
1550
  // post install
1553
1551
  await this._runPostInstallHook(blocklet);
1554
1552
 
1555
1553
  await states.blocklet.setBlockletStatus(did, BlockletStatus.installed);
1556
1554
 
1557
- blocklet = await this.ensureBlocklet(did);
1555
+ blocklet = await this.getBlocklet(did);
1558
1556
 
1559
1557
  await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
1560
1558
 
@@ -1607,6 +1605,8 @@ class BlockletManager extends BaseBlockletManager {
1607
1605
 
1608
1606
  // Add Config
1609
1607
  await this._setConfigsFromMeta(rootDid);
1608
+
1609
+ // should ensure blocklet integrity
1610
1610
  let blocklet = await this.ensureBlocklet(rootDid);
1611
1611
 
1612
1612
  // pre install
@@ -1614,14 +1614,14 @@ class BlockletManager extends BaseBlockletManager {
1614
1614
 
1615
1615
  // Add environments
1616
1616
  await this.updateBlockletEnvironment(rootDid);
1617
- blocklet = await this.ensureBlocklet(rootDid);
1617
+ blocklet = await this.getBlocklet(rootDid);
1618
1618
 
1619
1619
  // post install
1620
1620
  await this._runPostInstallHook(blocklet);
1621
1621
 
1622
1622
  logger.info('add blocklet component for dev', { did, version, meta });
1623
1623
 
1624
- blocklet = await this.ensureBlocklet(rootDid);
1624
+ blocklet = await this.getBlocklet(rootDid);
1625
1625
 
1626
1626
  return blocklet;
1627
1627
  }
@@ -1645,7 +1645,11 @@ class BlockletManager extends BaseBlockletManager {
1645
1645
  }
1646
1646
 
1647
1647
  async ensureBlocklet(did, opts = {}) {
1648
- return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did });
1648
+ return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did, ensureIntegrity: true });
1649
+ }
1650
+
1651
+ async getBlocklet(did, opts = {}) {
1652
+ return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did, ensureIntegrity: false });
1649
1653
  }
1650
1654
 
1651
1655
  async hasBlocklet({ did }) {
@@ -1663,7 +1667,7 @@ class BlockletManager extends BaseBlockletManager {
1663
1667
 
1664
1668
  this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
1665
1669
 
1666
- return this.ensureBlocklet(did);
1670
+ return this.getBlocklet(did);
1667
1671
  }
1668
1672
 
1669
1673
  async status(did, { forceSync = false } = {}) {
@@ -1680,7 +1684,7 @@ class BlockletManager extends BaseBlockletManager {
1680
1684
  return res;
1681
1685
  };
1682
1686
 
1683
- const blocklet = await this.ensureBlocklet(did);
1687
+ const blocklet = await this.getBlocklet(did);
1684
1688
 
1685
1689
  let shouldUpdateStatus = forceSync || shouldUpdateBlockletStatus(blocklet.status);
1686
1690
  if (isInProgress(blocklet.status)) {
@@ -1709,80 +1713,6 @@ class BlockletManager extends BaseBlockletManager {
1709
1713
  }
1710
1714
  }
1711
1715
 
1712
- async attachRuntimeInfo({ did, nodeInfo, diskInfo = true, context, cachedBlocklet }) {
1713
- if (!did) {
1714
- throw new Error('did should not be empty');
1715
- }
1716
-
1717
- try {
1718
- const blocklet = await this.ensureBlocklet(did, { throwOnNotExist: false });
1719
-
1720
- if (!blocklet) {
1721
- return null;
1722
- }
1723
-
1724
- const fromCache = !!cachedBlocklet;
1725
-
1726
- // if from cached data, only use cache data of runtime info (engine, diskInfo, runtimeInfo...)
1727
- if (fromCache) {
1728
- const cached = {};
1729
- forEachBlockletSync(cachedBlocklet, (component, { id }) => {
1730
- cached[id] = component;
1731
- });
1732
-
1733
- Object.assign(blocklet, pick(cachedBlocklet, ['appRuntimeInfo', 'diskInfo']));
1734
-
1735
- forEachBlockletSync(blocklet, (component, { id }) => {
1736
- if (cached[id]) {
1737
- Object.assign(component, pick(cached[id], ['runtimeInfo']));
1738
- }
1739
- });
1740
- }
1741
-
1742
- // 处理 domainAliases#value SLOT_FOR_IP_DNS_SITE
1743
- if (blocklet?.site?.domainAliases?.length) {
1744
- const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
1745
- blocklet.site.domainAliases = blocklet.site.domainAliases.map((x) => ({
1746
- ...x,
1747
- value: util.replaceDomainSlot({ domain: x.value, context, nodeIp }),
1748
- }));
1749
- }
1750
-
1751
- // app runtime info, app status
1752
- blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
1753
-
1754
- if (!fromCache) {
1755
- // app disk info, component runtime info, component status, component engine
1756
- await forEachBlocklet(blocklet, async (component, { level }) => {
1757
- component.engine = getEngine(getBlockletEngineNameByPlatform(component.meta)).describe();
1758
-
1759
- if (level === 0) {
1760
- component.diskInfo = await getDiskInfo(component, {
1761
- useFakeDiskInfo: !diskInfo,
1762
- });
1763
- }
1764
-
1765
- component.runtimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did, component.env.id);
1766
-
1767
- if (component.runtimeInfo?.status && shouldUpdateBlockletStatus(component.status)) {
1768
- component.status = statusMap[component.runtimeInfo.status];
1769
- }
1770
- });
1771
- }
1772
-
1773
- return blocklet;
1774
- } catch (err) {
1775
- const simpleState = await states.blocklet.getBlocklet(did);
1776
- logger.error('failed to get blocklet info', {
1777
- did,
1778
- name: get(simpleState, 'meta.name'),
1779
- status: get(simpleState, 'status'),
1780
- error: err,
1781
- });
1782
- return simpleState;
1783
- }
1784
- }
1785
-
1786
1716
  async refreshListCache() {
1787
1717
  this.list({ useCache: false }).catch((err) => {
1788
1718
  logger.error('refresh blocklet list failed', { error: err });
@@ -1981,7 +1911,7 @@ class BlockletManager extends BaseBlockletManager {
1981
1911
 
1982
1912
  async onCheckIfStarted(jobInfo, { throwOnError } = {}) {
1983
1913
  const { did, context, minConsecutiveTime = 5000, timeout } = jobInfo;
1984
- const blocklet = await this.ensureBlocklet(did);
1914
+ const blocklet = await this.getBlocklet(did);
1985
1915
 
1986
1916
  const { meta } = blocklet;
1987
1917
  const { name } = meta;
@@ -2022,7 +1952,7 @@ class BlockletManager extends BaseBlockletManager {
2022
1952
  }
2023
1953
 
2024
1954
  async updateBlockletEnvironment(did) {
2025
- const blockletWithEnv = await this.ensureBlocklet(did);
1955
+ const blockletWithEnv = await this.getBlocklet(did);
2026
1956
  const blocklet = await states.blocklet.getBlocklet(did);
2027
1957
  const nodeInfo = await states.node.read();
2028
1958
 
@@ -2650,6 +2580,80 @@ class BlockletManager extends BaseBlockletManager {
2650
2580
  ];
2651
2581
  }
2652
2582
 
2583
+ async _attachRuntimeInfo({ did, nodeInfo, diskInfo = true, context, cachedBlocklet }) {
2584
+ if (!did) {
2585
+ throw new Error('did should not be empty');
2586
+ }
2587
+
2588
+ try {
2589
+ const blocklet = await this.getBlocklet(did, { throwOnNotExist: false });
2590
+
2591
+ if (!blocklet) {
2592
+ return null;
2593
+ }
2594
+
2595
+ const fromCache = !!cachedBlocklet;
2596
+
2597
+ // if from cached data, only use cache data of runtime info (engine, diskInfo, runtimeInfo...)
2598
+ if (fromCache) {
2599
+ const cached = {};
2600
+ forEachBlockletSync(cachedBlocklet, (component, { id }) => {
2601
+ cached[id] = component;
2602
+ });
2603
+
2604
+ Object.assign(blocklet, pick(cachedBlocklet, ['appRuntimeInfo', 'diskInfo']));
2605
+
2606
+ forEachBlockletSync(blocklet, (component, { id }) => {
2607
+ if (cached[id]) {
2608
+ Object.assign(component, pick(cached[id], ['runtimeInfo']));
2609
+ }
2610
+ });
2611
+ }
2612
+
2613
+ // 处理 domainAliases#value SLOT_FOR_IP_DNS_SITE
2614
+ if (blocklet?.site?.domainAliases?.length) {
2615
+ const nodeIp = await getAccessibleExternalNodeIp(nodeInfo);
2616
+ blocklet.site.domainAliases = blocklet.site.domainAliases.map((x) => ({
2617
+ ...x,
2618
+ value: util.replaceDomainSlot({ domain: x.value, context, nodeIp }),
2619
+ }));
2620
+ }
2621
+
2622
+ // app runtime info, app status
2623
+ blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
2624
+
2625
+ if (!fromCache) {
2626
+ // app disk info, component runtime info, component status, component engine
2627
+ await forEachBlocklet(blocklet, async (component, { level }) => {
2628
+ component.engine = getEngine(getBlockletEngineNameByPlatform(component.meta)).describe();
2629
+
2630
+ if (level === 0) {
2631
+ component.diskInfo = await getDiskInfo(component, {
2632
+ useFakeDiskInfo: !diskInfo,
2633
+ });
2634
+ }
2635
+
2636
+ component.runtimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did, component.env.id);
2637
+
2638
+ if (component.runtimeInfo?.status && shouldUpdateBlockletStatus(component.status)) {
2639
+ component.status = statusMap[component.runtimeInfo.status];
2640
+ }
2641
+ });
2642
+ }
2643
+
2644
+ return blocklet;
2645
+ } catch (err) {
2646
+ const simpleState = await states.blocklet.getBlocklet(did);
2647
+ logger.error('failed to get blocklet info', {
2648
+ did,
2649
+ name: get(simpleState, 'meta.name'),
2650
+ status: get(simpleState, 'status'),
2651
+ error: err,
2652
+ });
2653
+ return simpleState;
2654
+ }
2655
+ }
2656
+
2653
2657
  async _syncBlockletStatus() {
2654
2658
  const run = async (blocklet) => {
2655
2659
  try {
@@ -2898,6 +2902,7 @@ class BlockletManager extends BaseBlockletManager {
2898
2902
  */
2899
2903
  async _installBlocklet({ did, oldBlocklet, context }) {
2900
2904
  try {
2905
+ // should ensure blocklet integrity
2901
2906
  let blocklet = await this.ensureBlocklet(did);
2902
2907
  const { meta, source, deployedFrom } = blocklet;
2903
2908
 
@@ -2914,13 +2919,13 @@ class BlockletManager extends BaseBlockletManager {
2914
2919
 
2915
2920
  // Add environments
2916
2921
  await this.updateBlockletEnvironment(meta.did);
2917
- blocklet = await this.ensureBlocklet(did);
2922
+ blocklet = await this.getBlocklet(did);
2918
2923
 
2919
2924
  // post install
2920
2925
  await this._runPostInstallHook(blocklet, context);
2921
2926
 
2922
2927
  await states.blocklet.setBlockletStatus(did, BlockletStatus.installed);
2923
- blocklet = await this.ensureBlocklet(did);
2928
+ blocklet = await this.getBlocklet(did);
2924
2929
  logger.info('blocklet installed', { source, did: meta.did });
2925
2930
 
2926
2931
  await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
@@ -3005,6 +3010,7 @@ class BlockletManager extends BaseBlockletManager {
3005
3010
  await states.blocklet.upgradeBlocklet({ meta, source, deployedFrom, children });
3006
3011
  await this._setConfigsFromMeta(did);
3007
3012
 
3013
+ // should ensure blocklet integrity
3008
3014
  let blocklet = await this.ensureBlocklet(did);
3009
3015
 
3010
3016
  // pre install
@@ -3012,7 +3018,7 @@ class BlockletManager extends BaseBlockletManager {
3012
3018
 
3013
3019
  // Add environments
3014
3020
  await this.updateBlockletEnvironment(did);
3015
- blocklet = await this.ensureBlocklet(did);
3021
+ blocklet = await this.getBlocklet(did);
3016
3022
 
3017
3023
  // post install
3018
3024
  await this._runPostInstallHook(blocklet, context);
@@ -3052,7 +3058,7 @@ class BlockletManager extends BaseBlockletManager {
3052
3058
  logger.info('started blocklet for upgrading', { did, version });
3053
3059
  }
3054
3060
 
3055
- blocklet = await this.ensureBlocklet(did, context);
3061
+ blocklet = await this.getBlocklet(did, context);
3056
3062
 
3057
3063
  await fs.writeFile(path.join(blocklet.env.dataDir, 'logo.svg'), createDidLogo(blocklet.meta.did));
3058
3064
 
@@ -3283,7 +3289,7 @@ class BlockletManager extends BaseBlockletManager {
3283
3289
  }
3284
3290
 
3285
3291
  async _setConfigsFromMeta(did, childDid) {
3286
- const blocklet = await getBlocklet({ states, dataDirs: this.dataDirs, did, validateEnv: false, ensureDirs: false });
3292
+ const blocklet = await getBlocklet({ states, dataDirs: this.dataDirs, did });
3287
3293
 
3288
3294
  if (!childDid) {
3289
3295
  await forEachBlocklet(blocklet, async (b, { ancestors }) => {
@@ -3563,7 +3569,7 @@ class BlockletManager extends BaseBlockletManager {
3563
3569
 
3564
3570
  this.emit(BlockletEvents.appDidChanged, blocklet);
3565
3571
 
3566
- const blockletWithEnv = await this.ensureBlocklet(blocklet.meta.did);
3572
+ const blockletWithEnv = await this.getBlocklet(blocklet.meta.did);
3567
3573
  const appSystemEnvironments = getAppOverwrittenEnvironments(blockletWithEnv, nodeInfo);
3568
3574
 
3569
3575
  await didDocument.updateBlockletDocument({
@@ -71,6 +71,8 @@ module.exports = async ({ url, blockletSecretKey, moveDir, context = {}, states,
71
71
  const skConfig = extra.configs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
72
72
  if (skConfig) {
73
73
  skConfig.value = blockletSecretKey;
74
+ skConfig.secure = true;
75
+ skConfig.shared = false;
74
76
  } else {
75
77
  extra.configs.push({
76
78
  key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK,
@@ -21,6 +21,7 @@ const {
21
21
  DOMAIN_FOR_INTERNAL_SITE,
22
22
  WELLKNOWN_PATH_PREFIX,
23
23
  WELLKNOWN_SERVICE_PATH_PREFIX,
24
+ USER_AVATAR_PATH_PREFIX,
24
25
  DOMAIN_FOR_IP_SITE,
25
26
  NAME_FOR_WELLKNOWN_SITE,
26
27
  DEFAULT_HTTP_PORT,
@@ -210,6 +211,9 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
210
211
  if (rule.isProtected && rule.to.target === WELLKNOWN_SERVICE_PATH_PREFIX) {
211
212
  return rule;
212
213
  }
214
+ if (rule.isProtected && rule.to.target === joinUrl(WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX)) {
215
+ return rule;
216
+ }
213
217
 
214
218
  const { did, interfaceName } = rule.to;
215
219
  if (interfaces[did] && interfaces[did][interfaceName]) {
@@ -273,6 +277,18 @@ const ensureWellknownRule = async (sites) => {
273
277
  if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
274
278
  const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
275
279
  rule.from.pathPrefix = servicePathPrefix;
280
+ rule.to.target = servicePathPrefix;
281
+ rule.isProtected = true;
282
+ site.rules.push(rule);
283
+ }
284
+
285
+ // Cache user avatar in nginx
286
+ const avatarPathPrefix = joinUrl(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
287
+ if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
288
+ const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
289
+ rule.from.pathPrefix = avatarPathPrefix;
290
+ rule.to.cacheGroup = 'blockletProxy';
291
+ rule.to.target = avatarPathPrefix;
276
292
  rule.isProtected = true;
277
293
  site.rules.push(rule);
278
294
  }
@@ -321,7 +337,12 @@ const filterSitesForRemovedBlocklets = async (sites = []) => {
321
337
  }
322
338
 
323
339
  const did = getDidFromDomainGroupName(site.domain);
324
- return blocklets.some((x) => x.meta.did === did);
340
+ const blocklet = blocklets.find((x) => x.meta.did === did);
341
+ if (blocklet) {
342
+ site.mode = blocklet.mode;
343
+ }
344
+
345
+ return !!blocklet;
325
346
  });
326
347
  };
327
348
 
@@ -1125,7 +1146,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1125
1146
  // Ensure we have system rules for blocklets
1126
1147
  const blocklets = await blockletState.getBlocklets();
1127
1148
  const ensureBlocklet = async (x) => {
1128
- const blocklet = await blockletManager.ensureBlocklet(x.meta.did);
1149
+ const blocklet = await blockletManager.getBlocklet(x.meta.did);
1129
1150
  return ensureBlockletRouting(blocklet, context);
1130
1151
  };
1131
1152
  const ensureBlockletResults = await Promise.all(blocklets.map((x) => ensureBlocklet(x)));
@@ -10,7 +10,7 @@ const {
10
10
  BLOCKLET_SITE_GROUP_SUFFIX,
11
11
  GATEWAY_REQ_LIMIT,
12
12
  } = require('@abtnode/constant');
13
- const { BLOCKLET_UI_INTERFACES } = require('@blocklet/constant');
13
+ const { BLOCKLET_UI_INTERFACES, BLOCKLET_MODES } = require('@blocklet/constant');
14
14
  const logger = require('@abtnode/logger')('@abtnode/core:router');
15
15
 
16
16
  const expandSites = (sites = []) => {
@@ -208,6 +208,7 @@ Router.formatSites = (sites = []) => {
208
208
  port: daemonRule.to.port,
209
209
  did: rule.to.did,
210
210
  componentId: rule.to.componentId,
211
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
211
212
  },
212
213
  });
213
214
  site.rules.push({
@@ -221,6 +222,7 @@ Router.formatSites = (sites = []) => {
221
222
  port: daemonRule.to.port,
222
223
  did: rule.to.did,
223
224
  componentId: rule.to.componentId,
225
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
224
226
  },
225
227
  });
226
228
 
@@ -233,6 +235,7 @@ Router.formatSites = (sites = []) => {
233
235
  did: rule.to.did,
234
236
  type: ROUTING_RULE_TYPES.DAEMON,
235
237
  target: BLOCKLET_PROXY_PATH_PREFIX,
238
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
236
239
  },
237
240
  });
238
241
  }
@@ -53,6 +53,9 @@ const formatBlocklet = (blocklet, phase, dek) => {
53
53
  if (!env) {
54
54
  return;
55
55
  }
56
+ // salt in blocklet state is different from the salt in blocklet-extra state
57
+ // in blocklet-extra state, salt is app meta did in each component
58
+ // in blocklet state, salt is component meta did in each component
56
59
  if (phase === 'onUpdate' && isHex(env.value) === true) {
57
60
  env.value = security.encrypt(env.value, b.meta.did, dek);
58
61
  }
@@ -142,8 +142,9 @@ const PRIVATE_NODE_ENVS = [
142
142
  */
143
143
  const getComponentDirs = (
144
144
  component,
145
- { dataDirs, ensure = false, e2eMode = false, validate = true, ancestors = [] } = {}
145
+ { dataDirs, ensure = false, e2eMode = false, validate = false, ancestors = [] } = {}
146
146
  ) => {
147
+ // FIXME 这个函数做了太多的事
147
148
  // get data dirs
148
149
 
149
150
  const { name: appName } = ancestors.concat(component)[0].meta;
@@ -1360,9 +1361,8 @@ const getBlocklet = async ({
1360
1361
  dataDirs,
1361
1362
  states,
1362
1363
  e2eMode = false,
1363
- validateEnv = true,
1364
1364
  throwOnNotExist = true,
1365
- ensureDirs = true,
1365
+ ensureIntegrity = false,
1366
1366
  } = {}) => {
1367
1367
  if (!did) {
1368
1368
  throw new Error('Blocklet did does not exist');
@@ -1381,7 +1381,7 @@ const getBlocklet = async ({
1381
1381
 
1382
1382
  const blocklet = await states.blocklet.getBlocklet(did);
1383
1383
  if (!blocklet) {
1384
- if (throwOnNotExist) {
1384
+ if (throwOnNotExist || ensureIntegrity) {
1385
1385
  throw new Error(`can not find blocklet in database by did ${did}`);
1386
1386
  }
1387
1387
  return null;
@@ -1418,8 +1418,8 @@ const getBlocklet = async ({
1418
1418
  processId: getComponentProcessId(component, ancestors),
1419
1419
  ...getComponentDirs(component, {
1420
1420
  dataDirs,
1421
- ensure: ensureDirs,
1422
- validate: validateEnv,
1421
+ ensure: ensureIntegrity,
1422
+ validate: ensureIntegrity,
1423
1423
  ancestors,
1424
1424
  e2eMode: level === 0 ? e2eMode : false,
1425
1425
  }),
@@ -1554,6 +1554,9 @@ const createDataArchive = (dataDir, fileName) => {
1554
1554
  const validateAppConfig = async (config, blockletDid, states) => {
1555
1555
  const x = config;
1556
1556
 
1557
+ // sk should be force secured while other app prop should not be secured
1558
+ config.secure = x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK;
1559
+
1557
1560
  if (x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK) {
1558
1561
  if (x.value) {
1559
1562
  try {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable newline-per-chained-call */
2
2
  const Joi = require('joi');
3
- const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES } = require('@abtnode/constant');
3
+ const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES, ROUTER_CACHE_GROUPS } = require('@abtnode/constant');
4
4
  const { getMultipleLangParams } = require('./util');
5
5
 
6
6
  const WILDCARD_DOMAIN_REGEX = /^\*.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/;
@@ -62,6 +62,12 @@ const ruleSchema = {
62
62
  then: Joi.required(),
63
63
  }),
64
64
  componentId: Joi.string().label('component id'), // component global id
65
+ // FUTURE: blocklets can register routing rules for provider cache
66
+ cacheGroup: Joi.string()
67
+ .label('cache group')
68
+ .valid(...Object.keys(ROUTER_CACHE_GROUPS))
69
+ .allow('')
70
+ .default(''),
65
71
  },
66
72
 
67
73
  // List of services that manipulate the request before the upstream blocklet
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.8.65-beta-5405baf2",
6
+ "version": "1.8.65-beta-f7af64a4",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,18 +19,18 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.8.65-beta-5405baf2",
23
- "@abtnode/certificate-manager": "1.8.65-beta-5405baf2",
24
- "@abtnode/constant": "1.8.65-beta-5405baf2",
25
- "@abtnode/cron": "1.8.65-beta-5405baf2",
26
- "@abtnode/db": "1.8.65-beta-5405baf2",
27
- "@abtnode/logger": "1.8.65-beta-5405baf2",
28
- "@abtnode/queue": "1.8.65-beta-5405baf2",
29
- "@abtnode/rbac": "1.8.65-beta-5405baf2",
30
- "@abtnode/router-provider": "1.8.65-beta-5405baf2",
31
- "@abtnode/static-server": "1.8.65-beta-5405baf2",
32
- "@abtnode/timemachine": "1.8.65-beta-5405baf2",
33
- "@abtnode/util": "1.8.65-beta-5405baf2",
22
+ "@abtnode/auth": "1.8.65-beta-f7af64a4",
23
+ "@abtnode/certificate-manager": "1.8.65-beta-f7af64a4",
24
+ "@abtnode/constant": "1.8.65-beta-f7af64a4",
25
+ "@abtnode/cron": "1.8.65-beta-f7af64a4",
26
+ "@abtnode/db": "1.8.65-beta-f7af64a4",
27
+ "@abtnode/logger": "1.8.65-beta-f7af64a4",
28
+ "@abtnode/queue": "1.8.65-beta-f7af64a4",
29
+ "@abtnode/rbac": "1.8.65-beta-f7af64a4",
30
+ "@abtnode/router-provider": "1.8.65-beta-f7af64a4",
31
+ "@abtnode/static-server": "1.8.65-beta-f7af64a4",
32
+ "@abtnode/timemachine": "1.8.65-beta-f7af64a4",
33
+ "@abtnode/util": "1.8.65-beta-f7af64a4",
34
34
  "@arcblock/did": "1.18.37",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
36
  "@arcblock/did-util": "1.18.37",
@@ -38,9 +38,9 @@
38
38
  "@arcblock/jwt": "^1.18.37",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
40
  "@arcblock/vc": "1.18.37",
41
- "@blocklet/constant": "1.8.65-beta-5405baf2",
42
- "@blocklet/meta": "1.8.65-beta-5405baf2",
43
- "@blocklet/sdk": "1.8.65-beta-5405baf2",
41
+ "@blocklet/constant": "1.8.65-beta-f7af64a4",
42
+ "@blocklet/meta": "1.8.65-beta-f7af64a4",
43
+ "@blocklet/sdk": "1.8.65-beta-f7af64a4",
44
44
  "@did-space/client": "^0.1.66",
45
45
  "@fidm/x509": "^1.2.1",
46
46
  "@ocap/mcrypto": "1.18.37",
@@ -88,5 +88,5 @@
88
88
  "express": "^4.18.2",
89
89
  "jest": "^27.5.1"
90
90
  },
91
- "gitHead": "e5dc838baded7031096118462a604fd70d78ff1c"
91
+ "gitHead": "97607d6e12bf8508ac29ab6546110c4ae3b31a82"
92
92
  }