@abtnode/core 1.8.62 → 1.8.63-beta-b71f5f80

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.
@@ -146,7 +146,22 @@ const parseConfigs = ({ data, did, dek }) => {
146
146
  return data;
147
147
  };
148
148
 
149
+ const encryptConfigs = ({ data, did, dek }) => {
150
+ const enableSecurity = dek && did;
151
+
152
+ if (enableSecurity && Array.isArray(data)) {
153
+ data.forEach((x) => {
154
+ if (x.secure) {
155
+ x.value = security.encrypt(x.value, did, dek);
156
+ }
157
+ });
158
+ }
159
+
160
+ return data;
161
+ };
162
+
149
163
  module.exports = {
150
164
  mergeConfigs,
151
165
  parseConfigs,
166
+ encryptConfigs,
152
167
  };
@@ -31,6 +31,7 @@ const {
31
31
  WHO_CAN_ACCESS,
32
32
  SERVER_ROLES,
33
33
  WHO_CAN_ACCESS_PREFIX_ROLES,
34
+ BLOCKLET_INSTALL_TYPE,
34
35
  } = require('@abtnode/constant');
35
36
 
36
37
  const getBlockletEngine = require('@blocklet/meta/lib/engine');
@@ -104,7 +105,7 @@ const {
104
105
  getDiskInfo,
105
106
  getUpdateMetaList,
106
107
  getRuntimeEnvironments,
107
- getSourceFromInstallParams,
108
+ getTypeFromInstallParams,
108
109
  parseChildrenFromMeta,
109
110
  checkDuplicateComponents,
110
111
  getDiffFiles,
@@ -133,6 +134,7 @@ const handleInstanceInStore = require('../../util/public-to-store');
133
134
  const { getNFTState, getServerDidDomain } = require('../../util');
134
135
  const { BlockletRuntimeMonitor } = require('../../monitor/blocklet-runtime-monitor');
135
136
  const getHistoryList = require('../../monitor/get-history-list');
137
+ const installFromBackup = require('./helper/install-from-backup');
136
138
 
137
139
  const {
138
140
  isInProgress,
@@ -253,6 +255,7 @@ class BlockletManager extends BaseBlockletManager {
253
255
  * downloadTokenList: Array<{did: string, token: string}>;
254
256
  * startImmediately: boolean;
255
257
  * controller: Controller
258
+ * type: BLOCKLET_INSTALL_TYPE
256
259
  * }} params
257
260
  * @param {{
258
261
  * [key: string]: any
@@ -274,32 +277,37 @@ class BlockletManager extends BaseBlockletManager {
274
277
  });
275
278
  context.downloadTokenList = params.downloadTokenList || [];
276
279
 
277
- const source = getSourceFromInstallParams(params);
280
+ const type = getTypeFromInstallParams(params);
278
281
  if (typeof context.startImmediately === 'undefined') {
279
282
  context.startImmediately = !!params.startImmediately;
280
283
  }
281
284
 
282
- if (source === BlockletSource.url) {
285
+ if (type === BLOCKLET_INSTALL_TYPE.URL) {
283
286
  const { url, controller, sync, delay } = params;
284
287
  return this._installFromUrl({ url, controller, sync, delay }, context);
285
288
  }
286
289
 
287
- if (source === BlockletSource.upload) {
290
+ if (type === BLOCKLET_INSTALL_TYPE.UPLOAD) {
288
291
  const { file, did, diffVersion, deleteSet } = params;
289
292
  return this._installFromUpload({ file, did, diffVersion, deleteSet, context });
290
293
  }
291
294
 
292
- if (source === BlockletSource.registry) {
295
+ if (type === BLOCKLET_INSTALL_TYPE.STORE) {
293
296
  const { did, controller, sync, delay, storeUrl } = params;
294
297
  return this._installFromStore({ did, controller, sync, delay, storeUrl }, context);
295
298
  }
296
299
 
297
- if (source === BlockletSource.custom) {
300
+ if (type === BLOCKLET_INSTALL_TYPE.CREATE) {
298
301
  return this._installFromCreate({ title: params.title, description: params.description }, context);
299
302
  }
300
303
 
304
+ if (type === BLOCKLET_INSTALL_TYPE.RESTORE) {
305
+ const { url, blockletSecretKey } = params;
306
+ return this._installFromBackup({ url, blockletSecretKey }, context);
307
+ }
308
+
301
309
  // should not be here
302
- throw new Error('Unknown source');
310
+ throw new Error('Unknown type');
303
311
  }
304
312
 
305
313
  /**
@@ -1601,6 +1609,19 @@ class BlockletManager extends BaseBlockletManager {
1601
1609
  return blocklet;
1602
1610
  }
1603
1611
 
1612
+ /**
1613
+ * backup 目录结构
1614
+ * /blocklets/<name1>version>
1615
+ * /blocklets/<name2>version>
1616
+ * /blocklets/<name3>version>
1617
+ * /data
1618
+ * /blocklet.json
1619
+ * /blocklet_extras.json
1620
+ */
1621
+ async _installFromBackup({ url, blockletSecretKey, moveDir } = {}, context = {}) {
1622
+ return installFromBackup({ url, blockletSecretKey, moveDir, context, manager: this, states });
1623
+ }
1624
+
1604
1625
  async ensureBlocklet(did, opts = {}) {
1605
1626
  return getBlocklet({ ...opts, states, dataDirs: this.dataDirs, did });
1606
1627
  }
@@ -1705,10 +1726,10 @@ class BlockletManager extends BaseBlockletManager {
1705
1726
  }));
1706
1727
  }
1707
1728
 
1708
- if (!fromCache) {
1709
- // app runtime info, app status
1710
- blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
1729
+ // app runtime info, app status
1730
+ blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
1711
1731
 
1732
+ if (!fromCache) {
1712
1733
  // app disk info, component runtime info, component status, component engine
1713
1734
  await forEachBlocklet(blocklet, async (component, { level }) => {
1714
1735
  component.engine = getEngine(getBlockletEngineNameByPlatform(component.meta)).describe();
@@ -0,0 +1,160 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+ const omit = require('lodash/omit');
4
+
5
+ const { forEachBlockletSync } = require('@blocklet/meta/lib/util');
6
+ const getBlockletInfo = require('@blocklet/meta/lib/info');
7
+
8
+ const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
9
+
10
+ const logger = require('@abtnode/logger')('@abtnode/core:install-from-backup');
11
+
12
+ const { validateBlocklet, checkDuplicateAppSk, getAppDirs } = require('../../../util/blocklet');
13
+
14
+ module.exports = async ({ url, blockletSecretKey, moveDir, context = {}, states, manager } = {}) => {
15
+ // TODO: support more url schema feature (http, did-spaces)
16
+ if (!url.startsWith('file://')) {
17
+ throw new Error('url must starts with file://');
18
+ }
19
+
20
+ const dir = url.replace('file://', '');
21
+
22
+ if (!dir || !fs.existsSync(dir)) {
23
+ throw new Error(`dir(${dir}) does not exist`);
24
+ }
25
+
26
+ // parse data from source dir
27
+
28
+ const srcBundleDirs = await getAppDirs(path.join(dir, 'blocklets'));
29
+ if (!srcBundleDirs.length) {
30
+ throw new Error(`bundle dirs does not found in ${dir}`);
31
+ }
32
+
33
+ const srcDataDir = path.join(dir, 'data');
34
+
35
+ /** @type {import('@abtnode/client').BlockletState} */
36
+ const state = omit(fs.readJSONSync(path.join(dir, 'blocklet.json')), [
37
+ '_id',
38
+ 'createdAt',
39
+ 'updatedAt',
40
+ 'installedAt',
41
+ 'startedAt',
42
+ ]);
43
+
44
+ const extra = omit(fs.readJSONSync(path.join(dir, 'blocklet-extras.json')), ['_id', 'createdAt', 'updatedAt']);
45
+
46
+ if (state.meta.did !== extra.did) {
47
+ throw new Error('did does not match in blocklet.json and blocklet_extra.json');
48
+ }
49
+
50
+ forEachBlockletSync(state, (component) => {
51
+ delete component.status;
52
+ delete component.ports;
53
+ delete component.environments;
54
+ });
55
+
56
+ const { meta } = state;
57
+
58
+ await validateBlocklet({ meta });
59
+
60
+ const { did, name: appName } = meta;
61
+
62
+ // FIXME: meta.did and meta.name should be dynamic created when installing multiple blocklet is supported
63
+ const existState = await states.blocklet.hasBlocklet(did);
64
+ if (existState) {
65
+ logger.error('blocklet is already exist', { did });
66
+ throw new Error('blocklet is already exist');
67
+ }
68
+
69
+ if (blockletSecretKey) {
70
+ extra.configs = extra.configs || [];
71
+ const skConfig = extra.configs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
72
+ if (skConfig) {
73
+ skConfig.value = blockletSecretKey;
74
+ } else {
75
+ extra.configs.push({
76
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK,
77
+ value: blockletSecretKey,
78
+ secure: true,
79
+ shared: false,
80
+ });
81
+ }
82
+ }
83
+
84
+ // validate appDid
85
+ const nodeInfo = await states.node.read();
86
+ const { wallet } = getBlockletInfo({ meta: state.meta, configs: extra.configs, environments: [] }, nodeInfo.sk);
87
+ if (state.appDid !== wallet.address) {
88
+ throw new Error('blocklet appDid is different from the previous one');
89
+ }
90
+ await checkDuplicateAppSk({ sk: wallet.secretKey, states });
91
+
92
+ states.blockletExtras.encryptSecurityData({ data: extra, rootDid: extra.did });
93
+
94
+ logger.info('installFromBackup', { srcBundleDirs, srcDataDir });
95
+
96
+ try {
97
+ // copy extra
98
+ const existExtra = await states.blockletExtras.find({ did });
99
+ if (existExtra) {
100
+ // 如果数据存在, 当前视为脏数据, 直接删除
101
+ // FIXME 另一个人的数据可能被删除. 修复方式: 动态生成 meta.did 或通过 blocklet sk 生成 meta.did
102
+ // FIXME 简单粗暴的删掉数据可能不是理想的方式,需要考虑旧数据存在时, 如何与新数据 merge
103
+ logger.error('old extra state exists and will be force removed', { existExtra });
104
+ await states.blockletExtras.remove({ did });
105
+ }
106
+ await states.blockletExtras.insert(extra);
107
+ logger.info('blocklet extra is copied successfully');
108
+
109
+ // add blocklet
110
+ await states.blocklet.addBlocklet(state);
111
+ logger.info('blocklet state is added successfully');
112
+
113
+ // copy bundle
114
+ // 假设相同名称的应用,肯定是同一个应用
115
+ // 假设版本号相同时, 应用不会变更
116
+ // FIXME: blocklet bundle name/did 不是唯一的. 修改 blocklet bundle name/did 生成方式 使 name/bundle 唯一
117
+ await Promise.all(
118
+ srcBundleDirs.map(async ({ key: bundleName, dir: srcDir }) => {
119
+ const installDir = path.join(manager.dataDirs.blocklets, bundleName);
120
+ if (fs.existsSync(installDir)) {
121
+ logger.info(`${bundleName} is already exist`);
122
+ return;
123
+ }
124
+
125
+ fs.mkdirSync(installDir, { recursive: true });
126
+ if (moveDir) {
127
+ await fs.move(srcDir, installDir, { overwrite: true });
128
+ } else {
129
+ await fs.copy(srcDir, installDir);
130
+ }
131
+ logger.info(`bundle is ${moveDir ? 'moved' : 'copied'} successfully`, { installDir });
132
+ })
133
+ );
134
+
135
+ // FIXME same as copy extra
136
+ const dataDir = path.join(manager.dataDirs.data, appName);
137
+ if (fs.existsSync(dataDir)) {
138
+ logger.error('old data exists and will be force removed', { dataDir });
139
+ await fs.remove(dataDir);
140
+ }
141
+ fs.mkdirSync(dataDir, { recursive: true });
142
+ if (fs.existsSync(srcDataDir)) {
143
+ if (moveDir) {
144
+ await fs.move(srcDataDir, dataDir, { overwrite: true });
145
+ } else {
146
+ await fs.copy(srcDataDir, dataDir);
147
+ }
148
+ logger.info(`data is ${moveDir ? 'moved' : 'copied'} successfully`);
149
+ }
150
+ } catch (error) {
151
+ logger.error('installFromBackup failed', { error });
152
+
153
+ await manager._rollback('install', did);
154
+
155
+ throw error;
156
+ }
157
+
158
+ logger.info('start install blocklet', { did });
159
+ return manager._installBlocklet({ did, context });
160
+ };
@@ -281,6 +281,25 @@ const ensureWellknownRule = async (sites) => {
281
281
  return tempSites;
282
282
  };
283
283
 
284
+ const ensureBlockletDid = async (sites) => {
285
+ const info = await states.node.read();
286
+
287
+ return (sites || []).map((site) => {
288
+ if (site.domain === DOMAIN_FOR_INTERNAL_SITE) {
289
+ return site;
290
+ }
291
+
292
+ if ([DOMAIN_FOR_IP_SITE, DOMAIN_FOR_DEFAULT_SITE, DOMAIN_FOR_IP_SITE_REGEXP].includes(site.domain)) {
293
+ site.blockletDid = info.did;
294
+ return site;
295
+ }
296
+
297
+ site.blockletDid = site.domain.replace(BLOCKLET_SITE_GROUP_SUFFIX, '');
298
+
299
+ return site;
300
+ });
301
+ };
302
+
284
303
  const ensureCorsForWebWallet = async (sites) => {
285
304
  const info = await states.node.read();
286
305
  for (const site of sites) {
@@ -306,8 +325,10 @@ const filterSitesForRemovedBlocklets = async (sites = []) => {
306
325
 
307
326
  const ensureLatestInfo = async (sites = [], { withDefaultCors = true } = {}) => {
308
327
  let result = await ensureLatestNodeInfo(sites, { withDefaultCors });
328
+ result = await ensureBlockletDid(result);
309
329
  result = await ensureWellknownRule(result);
310
330
  result = await ensureCorsForWebWallet(result);
331
+
311
332
  return ensureLatestInterfaceInfo(result);
312
333
  };
313
334
 
@@ -9,7 +9,7 @@ const dayjs = require('dayjs');
9
9
 
10
10
  const BaseState = require('./base');
11
11
 
12
- const { mergeConfigs, parseConfigs } = require('../blocklet/extras');
12
+ const { mergeConfigs, parseConfigs, encryptConfigs } = require('../blocklet/extras');
13
13
  const { validateAddMeta, validateExpiredInfo } = require('../validators/blocklet-extra');
14
14
 
15
15
  const noop = (k) => (v) => v[k];
@@ -214,6 +214,34 @@ class BlockletExtrasState extends BaseState {
214
214
  expiredAt: { $exists: true, $lte: now.subtract(EXPIRED_BLOCKLET_DATA_RETENTION_DAYS, 'days').toISOString() },
215
215
  });
216
216
  }
217
+
218
+ encryptSecurityData({ data, _rootDid } = {}) {
219
+ if (!data) {
220
+ return data;
221
+ }
222
+
223
+ const { dek } = this.config;
224
+
225
+ if (!dek) {
226
+ return data;
227
+ }
228
+
229
+ const did = _rootDid || data.did;
230
+
231
+ if (!did) {
232
+ throw new Error('data.did does not exist');
233
+ }
234
+
235
+ encryptConfigs({ data: data.configs, did, dek });
236
+
237
+ if (Array.isArray(data.children)) {
238
+ for (const child of data.children) {
239
+ this.encryptSecurityData({ data: child, _rootDid: did });
240
+ }
241
+ }
242
+
243
+ return data;
244
+ }
217
245
  }
218
246
 
219
247
  module.exports = BlockletExtrasState;
@@ -31,8 +31,7 @@ const getFolderSize = require('@abtnode/util/lib/get-folder-size');
31
31
  const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
32
32
  const hashFiles = require('@abtnode/util/lib/hash-files');
33
33
  const isPathPrefixEqual = require('@abtnode/util/lib/is-path-prefix-equal');
34
- const { BLOCKLET_MAX_MEM_LIMIT_IN_MB, BLOCKLET_STORE } = require('@abtnode/constant');
35
- const { BLOCKLET_PREFERENCE_FILE, BLOCKLET_PREFERENCE_PREFIX } = require('@blocklet/constant');
34
+ const { BLOCKLET_MAX_MEM_LIMIT_IN_MB, BLOCKLET_STORE, BLOCKLET_INSTALL_TYPE } = require('@abtnode/constant');
36
35
  const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
37
36
 
38
37
  const SCRIPT_ENGINES_WHITE_LIST = ['npm', 'npx', 'pnpm', 'yarn'];
@@ -50,6 +49,8 @@ const {
50
49
  BLOCKLET_CONFIGURABLE_KEY,
51
50
  BLOCKLET_DYNAMIC_PATH_PREFIX,
52
51
  fromBlockletStatus,
52
+ BLOCKLET_PREFERENCE_FILE,
53
+ BLOCKLET_PREFERENCE_PREFIX,
53
54
  } = require('@blocklet/constant');
54
55
  const verifyMultiSig = require('@blocklet/meta/lib/verify-multi-sig');
55
56
  const validateBlockletEntry = require('@blocklet/meta/lib/entry');
@@ -926,6 +927,59 @@ const verifyIntegrity = async ({ file, integrity: expected }) => {
926
927
  return true;
927
928
  };
928
929
 
930
+ /**
931
+ * @param {string} installDir
932
+ * @returns {Array<{ key: <[scope/]name/version>, dir: appDir }>}
933
+ */
934
+ const getAppDirs = async (installDir) => {
935
+ const appDirs = [];
936
+
937
+ const getNextLevel = (level, name) => {
938
+ if (level === 'root') {
939
+ if (name.startsWith('@')) {
940
+ return 'scope';
941
+ }
942
+ return 'name';
943
+ }
944
+ if (level === 'scope') {
945
+ return 'name';
946
+ }
947
+ if (level === 'name') {
948
+ return 'version';
949
+ }
950
+ throw new Error(`Invalid level ${level}`);
951
+ };
952
+
953
+ const fillAppDirs = async (dir, level = 'root') => {
954
+ if (level === 'version') {
955
+ appDirs.push({
956
+ key: formatBackSlash(path.relative(installDir, dir)),
957
+ dir,
958
+ });
959
+
960
+ return;
961
+ }
962
+
963
+ const nextDirs = [];
964
+ for (const x of await fs.promises.readdir(dir)) {
965
+ if (!fs.lstatSync(path.join(dir, x)).isDirectory()) {
966
+ logger.error('pruneBlockletBundle: invalid file in bundle storage', { dir, file: x });
967
+ // eslint-disable-next-line no-continue
968
+ continue;
969
+ }
970
+ nextDirs.push(x);
971
+ }
972
+
973
+ for (const x of nextDirs) {
974
+ await fillAppDirs(path.join(dir, x), getNextLevel(level, x));
975
+ }
976
+ };
977
+
978
+ await fillAppDirs(installDir, 'root');
979
+
980
+ return appDirs;
981
+ };
982
+
929
983
  const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings }) => {
930
984
  for (const blocklet of blocklets) {
931
985
  if (
@@ -961,53 +1015,10 @@ const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings })
961
1015
  }
962
1016
  }
963
1017
 
964
- // appDirs: [{ key: <[scope/]name/version>, dir: appDir }]
965
- const appDirs = [];
966
-
967
1018
  // fill appDirs
1019
+ let appDirs = [];
968
1020
  try {
969
- // @return root/scope/bundle/version
970
- const getNextLevel = (level, name) => {
971
- if (level === 'root') {
972
- if (name.startsWith('@')) {
973
- return 'scope';
974
- }
975
- return 'bundle';
976
- }
977
- if (level === 'scope') {
978
- return 'bundle';
979
- }
980
- if (level === 'bundle') {
981
- return 'version';
982
- }
983
- throw new Error(`Invalid level ${level}`);
984
- };
985
-
986
- const fillAppDirs = async (dir, level = 'root') => {
987
- if (level === 'version') {
988
- appDirs.push({
989
- key: formatBackSlash(path.relative(installDir, dir)),
990
- dir,
991
- });
992
-
993
- return;
994
- }
995
-
996
- const nextDirs = [];
997
- for (const x of await fs.promises.readdir(dir)) {
998
- if (!fs.lstatSync(path.join(dir, x)).isDirectory()) {
999
- logger.error('pruneBlockletBundle: invalid file in bundle storage', { dir, file: x });
1000
- // eslint-disable-next-line no-continue
1001
- continue;
1002
- }
1003
- nextDirs.push(x);
1004
- }
1005
-
1006
- for (const x of nextDirs) {
1007
- await fillAppDirs(path.join(dir, x), getNextLevel(level, x));
1008
- }
1009
- };
1010
- await fillAppDirs(installDir, 'root');
1021
+ appDirs = await getAppDirs(installDir);
1011
1022
  } catch (error) {
1012
1023
  logger.error('fill app dirs failed', { error });
1013
1024
  }
@@ -1197,24 +1208,34 @@ const getUpdateMetaList = (oldBlocklet = {}, newBlocklet = {}) => {
1197
1208
  return res;
1198
1209
  };
1199
1210
 
1200
- const getSourceFromInstallParams = (params) => {
1211
+ /**
1212
+ * @returns BLOCKLET_INSTALL_TYPE
1213
+ */
1214
+ const getTypeFromInstallParams = (params) => {
1215
+ if (params.type) {
1216
+ if (!Object.values(BLOCKLET_INSTALL_TYPE).includes(params.type)) {
1217
+ throw new Error(`Can only install blocklet from ${Object.values(BLOCKLET_INSTALL_TYPE).join('/')}`);
1218
+ }
1219
+ return params.type;
1220
+ }
1221
+
1201
1222
  if (params.url) {
1202
- return BlockletSource.url;
1223
+ return BLOCKLET_INSTALL_TYPE.URL;
1203
1224
  }
1204
1225
 
1205
1226
  if (params.file) {
1206
- return BlockletSource.upload;
1227
+ return BLOCKLET_INSTALL_TYPE.UPLOAD;
1207
1228
  }
1208
1229
 
1209
1230
  if (params.did) {
1210
- return BlockletSource.registry;
1231
+ return BLOCKLET_INSTALL_TYPE.STORE;
1211
1232
  }
1212
1233
 
1213
1234
  if (params.title && params.description) {
1214
- return BlockletSource.custom;
1235
+ return BLOCKLET_INSTALL_TYPE.CREATE;
1215
1236
  }
1216
1237
 
1217
- throw new Error('Can only install blocklet from store/url/upload/custom');
1238
+ throw new Error(`Can only install blocklet from ${Object.values(BLOCKLET_INSTALL_TYPE).join('/')}`);
1218
1239
  };
1219
1240
 
1220
1241
  const checkDuplicateComponents = (components = []) => {
@@ -1599,25 +1620,32 @@ const validateAppConfig = async (config, blockletDid, states) => {
1599
1620
  }
1600
1621
  };
1601
1622
 
1602
- const checkDuplicateAppSk = async ({ did, states }) => {
1603
- const nodeInfo = await states.node.read();
1604
- const blocklets = await states.blocklet.getBlocklets({});
1605
- const blocklet = await states.blocklet.getBlocklet(did);
1606
- const configs = await states.blockletExtras.getConfigs([did]);
1623
+ const checkDuplicateAppSk = async ({ sk, did, states }) => {
1624
+ if (!sk && !did) {
1625
+ throw new Error('sk and did is empty');
1626
+ }
1607
1627
 
1608
- const { wallet } = getBlockletInfo(
1609
- {
1610
- meta: blocklet.meta,
1611
- environments: (configs || []).filter((x) => x.value),
1612
- },
1613
- nodeInfo.sk
1614
- );
1628
+ let appSk = sk;
1629
+ if (!sk) {
1630
+ const nodeInfo = await states.node.read();
1631
+ const blocklet = await states.blocklet.getBlocklet(did);
1632
+ const configs = await states.blockletExtras.getConfigs([did]);
1633
+ const { wallet } = getBlockletInfo(
1634
+ {
1635
+ meta: blocklet.meta,
1636
+ environments: (configs || []).filter((x) => x.value),
1637
+ },
1638
+ nodeInfo.sk
1639
+ );
1640
+ appSk = wallet.secretKey;
1641
+ }
1615
1642
 
1616
- const others = blocklets.filter((b) => b.meta.did !== did);
1643
+ const blocklets = await states.blocklet.getBlocklets({});
1644
+ const others = did ? blocklets.filter((b) => b.meta.did !== did) : blocklets;
1617
1645
 
1618
1646
  const exist = others.find((b) => {
1619
1647
  const item = (b.environments || []).find((e) => e.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
1620
- return item?.value === toHex(wallet.secretKey);
1648
+ return item?.value === toHex(appSk);
1621
1649
  });
1622
1650
 
1623
1651
  if (exist) {
@@ -1663,13 +1691,14 @@ module.exports = {
1663
1691
  expandTarball,
1664
1692
  verifyIntegrity,
1665
1693
  statusMap,
1694
+ getAppDirs,
1666
1695
  pruneBlockletBundle,
1667
1696
  getDiskInfo,
1668
1697
  getRuntimeInfo,
1669
1698
  mergeMeta,
1670
1699
  fixAndVerifyMetaFromStore,
1671
1700
  getUpdateMetaList,
1672
- getSourceFromInstallParams,
1701
+ getTypeFromInstallParams,
1673
1702
  findWebInterface,
1674
1703
  checkDuplicateComponents,
1675
1704
  getDiffFiles,
@@ -81,7 +81,7 @@ const ruleSchema = {
81
81
  const corsSchema = Joi.array()
82
82
  .items(
83
83
  Joi.string().domain({ minDomainSegments: 1, tlds: false }),
84
- Joi.string().valid(DOMAIN_FOR_DEFAULT_SITE),
84
+ Joi.string().valid(DOMAIN_FOR_DEFAULT_SITE, '__none__'),
85
85
  Joi.string().ip()
86
86
  )
87
87
  .min(1)
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.8.62",
6
+ "version": "1.8.63-beta-b71f5f80",
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.62",
23
- "@abtnode/certificate-manager": "1.8.62",
24
- "@abtnode/constant": "1.8.62",
25
- "@abtnode/cron": "1.8.62",
26
- "@abtnode/db": "1.8.62",
27
- "@abtnode/logger": "1.8.62",
28
- "@abtnode/queue": "1.8.62",
29
- "@abtnode/rbac": "1.8.62",
30
- "@abtnode/router-provider": "1.8.62",
31
- "@abtnode/static-server": "1.8.62",
32
- "@abtnode/timemachine": "1.8.62",
33
- "@abtnode/util": "1.8.62",
22
+ "@abtnode/auth": "1.8.63-beta-b71f5f80",
23
+ "@abtnode/certificate-manager": "1.8.63-beta-b71f5f80",
24
+ "@abtnode/constant": "1.8.63-beta-b71f5f80",
25
+ "@abtnode/cron": "1.8.63-beta-b71f5f80",
26
+ "@abtnode/db": "1.8.63-beta-b71f5f80",
27
+ "@abtnode/logger": "1.8.63-beta-b71f5f80",
28
+ "@abtnode/queue": "1.8.63-beta-b71f5f80",
29
+ "@abtnode/rbac": "1.8.63-beta-b71f5f80",
30
+ "@abtnode/router-provider": "1.8.63-beta-b71f5f80",
31
+ "@abtnode/static-server": "1.8.63-beta-b71f5f80",
32
+ "@abtnode/timemachine": "1.8.63-beta-b71f5f80",
33
+ "@abtnode/util": "1.8.63-beta-b71f5f80",
34
34
  "@arcblock/did": "1.18.36",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
36
  "@arcblock/did-util": "1.18.36",
@@ -38,9 +38,9 @@
38
38
  "@arcblock/jwt": "^1.18.36",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
40
  "@arcblock/vc": "1.18.36",
41
- "@blocklet/constant": "1.8.62",
42
- "@blocklet/meta": "1.8.62",
43
- "@blocklet/sdk": "1.8.62",
41
+ "@blocklet/constant": "1.8.63-beta-b71f5f80",
42
+ "@blocklet/meta": "1.8.63-beta-b71f5f80",
43
+ "@blocklet/sdk": "1.8.63-beta-b71f5f80",
44
44
  "@fidm/x509": "^1.2.1",
45
45
  "@ocap/mcrypto": "1.18.36",
46
46
  "@ocap/util": "1.18.36",
@@ -85,5 +85,5 @@
85
85
  "express": "^4.18.2",
86
86
  "jest": "^27.5.1"
87
87
  },
88
- "gitHead": "ea6ab48149eb9e1157ef37ab1505fa36a9ce598f"
88
+ "gitHead": "ad50b6425a056b2db12b07283d0c08af62532c64"
89
89
  }