@abtnode/core 1.8.66-beta-b56e3b54 → 1.8.66

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.
@@ -15,18 +15,20 @@ const { isNFTExpired, getNftExpirationDate } = require('@abtnode/util/lib/nft');
15
15
  const didDocument = require('@abtnode/util/lib/did-document');
16
16
  const { sign } = require('@arcblock/jwt');
17
17
  const { isValid: isValidDid } = require('@arcblock/did');
18
+ const { verifyPresentation } = require('@arcblock/vc');
18
19
  const { toSvg: createDidLogo } =
19
20
  process.env.NODE_ENV !== 'test' ? require('@arcblock/did-motif') : require('@arcblock/did-motif/dist/did-motif.cjs');
20
21
  const getBlockletInfo = require('@blocklet/meta/lib/info');
21
22
  const sleep = require('@abtnode/util/lib/sleep');
22
23
 
23
24
  const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
25
+ const { getVcFromPresentation } = require('@abtnode/util/lib/vc');
24
26
  const {
27
+ VC_TYPE_BLOCKLET_PURCHASE,
25
28
  WHO_CAN_ACCESS,
26
29
  SERVER_ROLES,
27
30
  WHO_CAN_ACCESS_PREFIX_ROLES,
28
31
  BLOCKLET_INSTALL_TYPE,
29
- NODE_MODES,
30
32
  } = require('@abtnode/constant');
31
33
 
32
34
  const getBlockletEngine = require('@blocklet/meta/lib/engine');
@@ -109,8 +111,6 @@ const {
109
111
  validateAppConfig,
110
112
  checkDuplicateAppSk,
111
113
  checkDuplicateMountPoint,
112
- validateStore,
113
- validateInServerless,
114
114
  } = require('../../util/blocklet');
115
115
  const StoreUtil = require('../../util/store');
116
116
  const states = require('../../states');
@@ -242,8 +242,6 @@ class BlockletManager extends BaseBlockletManager {
242
242
  * did: string;
243
243
  * title: string;
244
244
  * description: string;
245
- * storeUrl: string;
246
- * appSk: string;
247
245
  * sync: boolean = false; // download synchronously, not use queue
248
246
  * delay: number; // push download task to queue after a delay
249
247
  * downloadTokenList: Array<{did: string, token: string}>;
@@ -280,31 +278,28 @@ class BlockletManager extends BaseBlockletManager {
280
278
  context.startImmediately = !!params.startImmediately;
281
279
  }
282
280
 
283
- const { appSk } = params;
284
-
285
281
  if (type === BLOCKLET_INSTALL_TYPE.URL) {
286
282
  const { url, controller, sync, delay } = params;
287
- return this._installFromUrl({ url, controller, sync, delay, appSk }, context);
283
+ return this._installFromUrl({ url, controller, sync, delay }, context);
288
284
  }
289
285
 
290
286
  if (type === BLOCKLET_INSTALL_TYPE.UPLOAD) {
291
287
  const { file, did, diffVersion, deleteSet } = params;
292
- return this._installFromUpload({ file, did, diffVersion, deleteSet, appSk }, context);
288
+ return this._installFromUpload({ file, did, diffVersion, deleteSet, context });
293
289
  }
294
290
 
295
291
  if (type === BLOCKLET_INSTALL_TYPE.STORE) {
296
292
  const { did, controller, sync, delay, storeUrl } = params;
297
- return this._installFromStore({ did, controller, sync, delay, storeUrl, appSk }, context);
293
+ return this._installFromStore({ did, controller, sync, delay, storeUrl }, context);
298
294
  }
299
295
 
300
296
  if (type === BLOCKLET_INSTALL_TYPE.CREATE) {
301
- const { title, description } = params;
302
- return this._installFromCreate({ title, description, appSk }, context);
297
+ return this._installFromCreate({ title: params.title, description: params.description }, context);
303
298
  }
304
299
 
305
300
  if (type === BLOCKLET_INSTALL_TYPE.RESTORE) {
306
- const { url } = params;
307
- return this._installFromBackup({ url, appSk }, context);
301
+ const { url, blockletSecretKey } = params;
302
+ return this._installFromBackup({ url, blockletSecretKey }, context);
308
303
  }
309
304
 
310
305
  // should not be here
@@ -334,7 +329,7 @@ class BlockletManager extends BaseBlockletManager {
334
329
  async installComponent(
335
330
  {
336
331
  rootDid,
337
- mountPoint,
332
+ mountPoint: tmpMountPoint,
338
333
  url,
339
334
  file,
340
335
  did,
@@ -348,15 +343,10 @@ class BlockletManager extends BaseBlockletManager {
348
343
  },
349
344
  context = {}
350
345
  ) {
346
+ const mountPoint = await mountPointSchema.validateAsync(tmpMountPoint);
351
347
  logger.debug('start install component', { rootDid, mountPoint, url });
352
348
 
353
349
  if (file) {
354
- // TODO: 如何触发这种场景?
355
- const info = await states.node.read();
356
- if (info.mode === NODE_MODES.SERVERLESS) {
357
- throw new Error("Can't install component in serverless-mode server via upload");
358
- }
359
-
360
350
  return this._installComponentFromUpload({
361
351
  rootDid,
362
352
  mountPoint,
@@ -370,11 +360,6 @@ class BlockletManager extends BaseBlockletManager {
370
360
  }
371
361
 
372
362
  if (url) {
373
- const info = await states.node.read();
374
- if (info.mode === NODE_MODES.SERVERLESS) {
375
- validateStore(info, url);
376
- }
377
-
378
363
  return this._installComponentFromUrl({
379
364
  rootDid,
380
365
  mountPoint,
@@ -446,6 +431,25 @@ class BlockletManager extends BaseBlockletManager {
446
431
  return { isInstalled: !!blocklet, isRunning, blockletDid, isExternal };
447
432
  }
448
433
 
434
+ async installBlockletFromVc({ vcPresentation, challenge }, context) {
435
+ logger.info('Install from vc');
436
+ const vc = getVcFromPresentation(vcPresentation);
437
+
438
+ // FIXME: 这里的 trustedIssuers 相当于相信任何 VC,需要想更安全的方法
439
+ verifyPresentation({ presentation: vcPresentation, trustedIssuers: [get(vc, 'issuer.id')], challenge });
440
+
441
+ if (!vc.type.includes(VC_TYPE_BLOCKLET_PURCHASE)) {
442
+ throw new Error(`Expect ${VC_TYPE_BLOCKLET_PURCHASE} VC type`);
443
+ }
444
+
445
+ const blockletUrl = get(vc, 'credentialSubject.purchased.blocklet.url');
446
+ const urlObject = new URL(blockletUrl);
447
+ const did = get(vc, 'credentialSubject.purchased.blocklet.id');
448
+ const registry = urlObject.origin;
449
+
450
+ return this._installFromStore({ did, registry }, context);
451
+ }
452
+
449
453
  async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
450
454
  logger.info('start blocklet', { did });
451
455
  // should check blocklet integrity
@@ -627,7 +631,7 @@ class BlockletManager extends BaseBlockletManager {
627
631
  // FIXME: 需要改成队列执行,本次失败,下次还需要重试,页面刷新后也能知道最新的状态
628
632
  await this._installFromBackup({
629
633
  url: `file://${spacesRestore.blockletRestoreDir}`,
630
- appSk: spacesRestore.blockletWallet.secretKey,
634
+ blockletSecretKey: spacesRestore.blockletWallet.secretKey,
631
635
  moveDir: true,
632
636
  });
633
637
  }
@@ -1000,7 +1004,7 @@ class BlockletManager extends BaseBlockletManager {
1000
1004
  }
1001
1005
 
1002
1006
  // eslint-disable-next-line no-unused-vars
1003
- async config({ did, configs: newConfigs, skipHook, skipDidDocument }, context) {
1007
+ async config({ did, configs: newConfigs, skipHook }, context) {
1004
1008
  if (!Array.isArray(newConfigs)) {
1005
1009
  throw new Error('configs list is not an array');
1006
1010
  }
@@ -1060,7 +1064,7 @@ class BlockletManager extends BaseBlockletManager {
1060
1064
  [BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK, BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_WALLET_TYPE].includes(item.key)
1061
1065
  );
1062
1066
 
1063
- if (isSkOrWalletTypeChanged && !skipDidDocument) {
1067
+ if (isSkOrWalletTypeChanged) {
1064
1068
  await this._updateDidDocument(blocklet);
1065
1069
  }
1066
1070
 
@@ -1193,8 +1197,8 @@ class BlockletManager extends BaseBlockletManager {
1193
1197
  return this.getBlocklet(rootDid);
1194
1198
  }
1195
1199
 
1196
- async updateComponentMountPoint({ did, rootDid: inputRootDid, mountPoint }, context) {
1197
- await mountPointSchema.validateAsync(mountPoint);
1200
+ async updateComponentMountPoint({ did, rootDid: inputRootDid, mountPoint: tmpMountPoint }, context) {
1201
+ const mountPoint = await mountPointSchema.validateAsync(tmpMountPoint);
1198
1202
 
1199
1203
  const blocklet = await states.blocklet.getBlocklet(inputRootDid);
1200
1204
 
@@ -1675,13 +1679,13 @@ class BlockletManager extends BaseBlockletManager {
1675
1679
  * /blocklet.json
1676
1680
  * /blocklet_extras.json
1677
1681
  * @see Blocklet 端到端备份方案的设计与实现(一期) https://team.arcblock.io/comment/discussions/e62084d5-fafa-489e-91d5-defcd6e93223
1678
- * @param {{ url: string, appSk: string, moveDir: boolean}} [{ url }={}]
1682
+ * @param {{ url: string, blockletSecretKey: string, moveDir: boolean}} [{ url }={}]
1679
1683
  * @param {Record<string, string>} [context={}]
1680
1684
  * @return {Promise<any>}
1681
1685
  * @memberof BlockletManager
1682
1686
  */
1683
- async _installFromBackup({ url, appSk, moveDir } = {}, context = {}) {
1684
- return installFromBackup({ url, appSk, moveDir, context, manager: this, states });
1687
+ async _installFromBackup({ url, blockletSecretKey, moveDir } = {}, context = {}) {
1688
+ return installFromBackup({ url, blockletSecretKey, moveDir, context, manager: this, states });
1685
1689
  }
1686
1690
 
1687
1691
  async ensureBlocklet(did, opts = {}) {
@@ -2080,18 +2084,17 @@ class BlockletManager extends BaseBlockletManager {
2080
2084
  *
2081
2085
  * @param {{
2082
2086
  * did: string;
2087
+ * registry: string;
2083
2088
  * sync: boolean;
2084
2089
  * delay: number;
2085
2090
  * controller: Controller;
2086
- * appSk: string;
2087
- * storeUrl: string;
2088
2091
  * }} params
2089
2092
  * @param {*} context
2090
2093
  * @return {*}
2091
2094
  * @memberof BlockletManager
2092
2095
  */
2093
2096
  async _installFromStore(params, context) {
2094
- const { did, storeUrl, sync, delay, controller, appSk } = params;
2097
+ const { did, storeUrl, sync, delay, controller } = params;
2095
2098
 
2096
2099
  logger.debug('start install blocklet', { did });
2097
2100
  if (!isValidDid(did)) {
@@ -2135,7 +2138,6 @@ class BlockletManager extends BaseBlockletManager {
2135
2138
  sync,
2136
2139
  delay,
2137
2140
  controller,
2138
- appSk,
2139
2141
  context,
2140
2142
  });
2141
2143
  }
@@ -2152,14 +2154,13 @@ class BlockletManager extends BaseBlockletManager {
2152
2154
  * sync: boolean;
2153
2155
  * delay: number;
2154
2156
  * controller: Controller;
2155
- * appSk: string;
2156
2157
  * }} params
2157
2158
  * @param {{}} context
2158
2159
  * @return {*}
2159
2160
  * @memberof BlockletManager
2160
2161
  */
2161
2162
  async _installFromUrl(params, context) {
2162
- const { url, sync, delay, controller, appSk } = params;
2163
+ const { url, sync, delay, controller } = params;
2163
2164
 
2164
2165
  logger.debug('start install blocklet', { url });
2165
2166
 
@@ -2173,18 +2174,13 @@ class BlockletManager extends BaseBlockletManager {
2173
2174
 
2174
2175
  // install from store if url is a store url
2175
2176
  const { inStore, registryUrl, blockletDid: bundleDid } = await StoreUtil.parseSourceUrl(url, controller);
2176
-
2177
- const nodeInfo = await states.node.read();
2178
-
2179
- await validateStore(nodeInfo, registryUrl);
2180
-
2181
2177
  if (inStore) {
2182
2178
  const exist = await states.blocklet.getBlocklet(blockletDid);
2183
2179
  if (exist) {
2184
2180
  return this.upgrade({ did: blockletDid, storeUrl: registryUrl, sync, delay }, context);
2185
2181
  }
2186
2182
 
2187
- return this._installFromStore({ did: bundleDid, storeUrl: registryUrl, controller, sync, delay, appSk }, context);
2183
+ return this._installFromStore({ did: bundleDid, storeUrl: registryUrl, controller, sync, delay }, context);
2188
2184
  }
2189
2185
 
2190
2186
  const meta = ensureMeta(bundleMeta, { name: blockletName, did: blockletDid });
@@ -2210,7 +2206,6 @@ class BlockletManager extends BaseBlockletManager {
2210
2206
  sync,
2211
2207
  delay,
2212
2208
  controller,
2213
- appSk,
2214
2209
  context,
2215
2210
  });
2216
2211
  }
@@ -2315,7 +2310,7 @@ class BlockletManager extends BaseBlockletManager {
2315
2310
  );
2316
2311
  }
2317
2312
 
2318
- async _installFromCreate({ title, description, appSk }, context = {}) {
2313
+ async _installFromCreate({ title, description }, context = {}) {
2319
2314
  logger.debug('create blocklet', { title, description });
2320
2315
 
2321
2316
  await joi.string().label('title').max(20).required().validateAsync(title);
@@ -2343,9 +2338,11 @@ class BlockletManager extends BaseBlockletManager {
2343
2338
  };
2344
2339
  const meta = validateMeta(rawMeta);
2345
2340
 
2346
- await states.blocklet.addBlocklet({ meta, source: BlockletSource.custom });
2341
+ await states.blocklet.addBlocklet({
2342
+ meta,
2343
+ source: BlockletSource.custom,
2344
+ });
2347
2345
  await this._setConfigsFromMeta(did);
2348
- await this._setAppSk(did, appSk);
2349
2346
 
2350
2347
  // check duplicate appSk
2351
2348
  await checkDuplicateAppSk({ did, states });
@@ -2385,7 +2382,7 @@ class BlockletManager extends BaseBlockletManager {
2385
2382
  return { cwd, tarFile };
2386
2383
  }
2387
2384
 
2388
- async _installFromUpload({ file, did, diffVersion, deleteSet, appSk }, context) {
2385
+ async _installFromUpload({ file, did, diffVersion, deleteSet, context }) {
2389
2386
  logger.info('install blocklet', { from: 'upload file' });
2390
2387
  const { tarFile } = await this._downloadFromUpload(file);
2391
2388
 
@@ -2483,7 +2480,6 @@ class BlockletManager extends BaseBlockletManager {
2483
2480
  const oldState = { extraState: oldExtraState };
2484
2481
  try {
2485
2482
  await this._setConfigsFromMeta(meta.did);
2486
- await this._setAppSk(appSk);
2487
2483
  await validateBlocklet(blocklet);
2488
2484
 
2489
2485
  // check duplicate appSk
@@ -2780,7 +2776,6 @@ class BlockletManager extends BaseBlockletManager {
2780
2776
  * meta: {}; // blocklet meta
2781
2777
  * source: number; // example: BlockletSource.registry,
2782
2778
  * deployedFrom: string;
2783
- * appSk: string;
2784
2779
  * context: {}
2785
2780
  * sync: boolean = false;
2786
2781
  * delay: number;
@@ -2790,15 +2785,10 @@ class BlockletManager extends BaseBlockletManager {
2790
2785
  * @memberof BlockletManager
2791
2786
  */
2792
2787
  async _install(params) {
2793
- const { meta, source, deployedFrom, context, sync, delay, controller, appSk } = params;
2788
+ const { meta, source, deployedFrom, context, sync, delay, controller } = params;
2794
2789
 
2795
2790
  validateBlockletMeta(meta, { ensureDist: true });
2796
2791
 
2797
- const info = await states.node.read();
2798
- if (info.mode === NODE_MODES.SERVERLESS) {
2799
- validateInServerless({ blockletMeta: meta });
2800
- }
2801
-
2802
2792
  const { name, did, version } = meta;
2803
2793
 
2804
2794
  const oldExtraState = await states.blockletExtras.findOne({ did: meta.did });
@@ -2818,7 +2808,6 @@ class BlockletManager extends BaseBlockletManager {
2818
2808
  await states.blockletExtras.addMeta({ did, meta: { did, name }, controller });
2819
2809
 
2820
2810
  await this._setConfigsFromMeta(did);
2821
- await this._setAppSk(did, appSk);
2822
2811
 
2823
2812
  // check duplicate appSk
2824
2813
  await checkDuplicateAppSk({ did, states });
@@ -3416,31 +3405,12 @@ class BlockletManager extends BaseBlockletManager {
3416
3405
  }
3417
3406
  }
3418
3407
 
3419
- async _setAppSk(did, appSk, context) {
3420
- if (process.env.NODE_ENV === 'production' && !appSk) {
3421
- throw new Error(`appSk for blocklet ${did} is required`);
3422
- }
3423
-
3424
- if (appSk) {
3425
- await this.config(
3426
- {
3427
- did,
3428
- configs: [{ key: 'BLOCKLET_APP_SK', value: appSk, secure: true }],
3429
- skipHook: true,
3430
- skipDidDocument: true,
3431
- },
3432
- context
3433
- );
3434
- }
3435
- }
3436
-
3437
3408
  async _findNextCustomBlockletName(leftTimes = 10) {
3438
3409
  if (leftTimes <= 0) {
3439
3410
  throw new Error('Generate custom blocklet did too many times');
3440
3411
  }
3441
3412
  const number = await states.node.increaseCustomBlockletNumber();
3442
3413
  const name = `custom-${number}`;
3443
- // MEMO: 空壳 APP可以保留原有的 did 生成逻辑
3444
3414
  const did = toBlockletDid(name);
3445
3415
  const blocklet = await states.blocklet.getBlocklet(did);
3446
3416
  if (blocklet) {
@@ -19,7 +19,7 @@ const { validateBlocklet, checkDuplicateAppSk, getAppDirs } = require('../../../
19
19
  * }} param0
20
20
  * @returns
21
21
  */
22
- module.exports = async ({ url, appSk, moveDir, context = {}, states, manager } = {}) => {
22
+ module.exports = async ({ url, blockletSecretKey, moveDir, context = {}, states, manager } = {}) => {
23
23
  // TODO: support more url schema feature (http, did-spaces)
24
24
  if (!url.startsWith('file://')) {
25
25
  throw new Error('url must starts with file://');
@@ -71,17 +71,17 @@ module.exports = async ({ url, appSk, moveDir, context = {}, states, manager } =
71
71
  throw new Error('blocklet is already exist');
72
72
  }
73
73
 
74
- if (appSk) {
74
+ if (blockletSecretKey) {
75
75
  extra.configs = extra.configs || [];
76
76
  const skConfig = extra.configs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
77
77
  if (skConfig) {
78
- skConfig.value = appSk;
78
+ skConfig.value = blockletSecretKey;
79
79
  skConfig.secure = true;
80
80
  skConfig.shared = false;
81
81
  } else {
82
82
  extra.configs.push({
83
83
  key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK,
84
- value: appSk,
84
+ value: blockletSecretKey,
85
85
  secure: true,
86
86
  shared: false,
87
87
  });
@@ -150,10 +150,10 @@ class SpacesBackup {
150
150
  const { errorCount } = await spaceClient.send(
151
151
  new SyncFolderPushCommand({
152
152
  source: join(this.blockletBackupDir, '/'),
153
- target: join('.did-objects', this.blocklet.appDid, '/'),
153
+ target: join('.did-objects', this.blocklet.appDid),
154
154
  debug: true,
155
- concurrency: 32,
156
- retryCount: 10,
155
+ concurrency: 64,
156
+ retryCount: 100,
157
157
  filter: (object) => {
158
158
  return object.name !== '.DS_Store';
159
159
  },
@@ -1,4 +1,4 @@
1
- const { existsSync, remove, ensureDirSync } = require('fs-extra');
1
+ const { existsSync, remove } = require('fs-extra');
2
2
  const { join } = require('path');
3
3
  const fg = require('fast-glob');
4
4
  const { BaseRestore } = require('./base');
@@ -10,11 +10,8 @@ class BlockletsRestore extends BaseRestore {
10
10
  async import() {
11
11
  const blockletsDir = join(this.blockletRestoreDir, this.filename);
12
12
 
13
- // blockletsDir 可以不存在, 因为还原的 blocklet 可能所有的组件都是来自 store 的
14
13
  if (!existsSync(blockletsDir)) {
15
- // FIXME: 如果文件夹不存在,需要创建文件夹,因为 installFromBackup 未做容错处理
16
- ensureDirSync(blockletsDir);
17
- return;
14
+ throw new Error(`dir not found: ${blockletsDir}`);
18
15
  }
19
16
 
20
17
  const paths = await fg('**/*.zip', {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @typedef {{
3
3
  * endpoint: string;
4
- * appSk: string;
4
+ * blockletSecretKey: string;
5
5
  * }} SpaceRestoreInput
6
6
  */
7
7
 
@@ -98,7 +98,7 @@ class SpacesRestore {
98
98
 
99
99
  async getBlockletWallet() {
100
100
  // @FIXME: blocklet 钱包类型如何得知呢?
101
- const wallet = fromSecretKey(this.input.appSk, WalletType({ role: types.RoleType.ROLE_APPLICATION }));
101
+ const wallet = fromSecretKey(this.input.blockletSecretKey, WalletType({ role: types.RoleType.ROLE_APPLICATION }));
102
102
 
103
103
  return wallet;
104
104
  }
@@ -115,10 +115,10 @@ class SpacesRestore {
115
115
  const { errorCount } = await spaceClient.send(
116
116
  new SyncFolderPullCommand({
117
117
  source: join('.did-objects', this.blockletWallet.address, '/'),
118
- target: join(this.blockletRestoreDir, '/'),
118
+ target: this.blockletRestoreDir,
119
119
  debug: true,
120
- concurrency: 32,
121
- retryCount: 10,
120
+ concurrency: 64,
121
+ retryCount: 100,
122
122
  })
123
123
  );
124
124
 
package/lib/event.js CHANGED
@@ -81,7 +81,7 @@ module.exports = ({
81
81
  }
82
82
  };
83
83
 
84
- const handleBlockletInstall = async (name, { blocklet, context }) => {
84
+ const handleBlockletAdd = async (name, { blocklet, context }) => {
85
85
  try {
86
86
  const changed = await ensureBlockletRouting(blocklet, context);
87
87
  if (changed) {
@@ -173,7 +173,7 @@ module.exports = ({
173
173
  const blocklet = payload.blocklet || payload;
174
174
 
175
175
  if ([BlockletEvents.installed].includes(eventName)) {
176
- await handleBlockletInstall(eventName, payload);
176
+ await handleBlockletAdd(eventName, payload);
177
177
 
178
178
  try {
179
179
  await node.createAuditLog({
package/lib/index.js CHANGED
@@ -192,6 +192,7 @@ function ABTNode(options) {
192
192
 
193
193
  // Blocklet manager
194
194
  installBlocklet: blockletManager.install.bind(blockletManager),
195
+ installBlockletFromVc: blockletManager.installBlockletFromVc.bind(blockletManager),
195
196
  installComponent: blockletManager.installComponent.bind(blockletManager),
196
197
  startBlocklet: blockletManager.start.bind(blockletManager),
197
198
  stopBlocklet: blockletManager.stop.bind(blockletManager),
@@ -518,7 +518,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
518
518
 
519
519
  const ensureDomainCert = async (domain, url) => {
520
520
  const cert = await certManager.getByDomain(domain);
521
- if (!cert || get(cert, 'meta.validTo') <= Date.now()) {
521
+ if (!cert) {
522
522
  await downloadCert({
523
523
  domain,
524
524
  url,
@@ -258,8 +258,8 @@ class RouterManager extends EventEmitter {
258
258
  return dbSite;
259
259
  }
260
260
 
261
- async addRoutingRule({ id, rule, skipCheckDynamicBlacklist = false }, context = {}) {
262
- await validateAddRule({ id, rule }, context);
261
+ async addRoutingRule({ id, rule: tempRule, skipCheckDynamicBlacklist = false }, context = {}) {
262
+ const { rule } = await validateAddRule({ id, rule: tempRule }, context);
263
263
  const dbSite = await states.site.findOne({ _id: id });
264
264
  if (!dbSite) {
265
265
  throw new Error(`site ${id} does not exist`);
@@ -294,8 +294,8 @@ class RouterManager extends EventEmitter {
294
294
  return newSite;
295
295
  }
296
296
 
297
- async updateRoutingRule({ id, rule, skipProtectedRuleChecking = false }, context = {}) {
298
- await validateEditRule({ id, rule }, context);
297
+ async updateRoutingRule({ id, rule: tmpRule, skipProtectedRuleChecking = false }, context = {}) {
298
+ const { rule } = await validateEditRule({ id, rule: tmpRule }, context);
299
299
  const dbSite = await states.site.findOne({ _id: id, 'rules.id': rule.id });
300
300
  if (!dbSite) {
301
301
  throw new Error(`site ${id}, rule ${rule.id} does not exist`);
@@ -124,7 +124,7 @@ class NodeState extends BaseState {
124
124
  routing,
125
125
  docker,
126
126
  mode,
127
- enableWelcomePage: mode !== NODE_MODES.SERVERLESS,
127
+ enableWelcomePage: true,
128
128
  runtimeConfig,
129
129
  ownerNft,
130
130
  diskAlertThreshold: DISK_ALERT_THRESHOLD_PERCENT,
@@ -31,12 +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 {
35
- BLOCKLET_MAX_MEM_LIMIT_IN_MB,
36
- BLOCKLET_STORE,
37
- BLOCKLET_INSTALL_TYPE,
38
- BLOCKLET_STORE_DEV,
39
- } = require('@abtnode/constant');
34
+ const { BLOCKLET_MAX_MEM_LIMIT_IN_MB, BLOCKLET_STORE, BLOCKLET_INSTALL_TYPE } = require('@abtnode/constant');
40
35
  const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
41
36
 
42
37
  const SCRIPT_ENGINES_WHITE_LIST = ['npm', 'npx', 'pnpm', 'yarn'];
@@ -840,7 +835,7 @@ const parseChildrenFromMeta = async (src, context = {}) => {
840
835
  };
841
836
 
842
837
  const validateBlocklet = (blocklet) =>
843
- forEachBlocklet(blocklet, async (b) => {
838
+ forEachBlocklet(blocklet, (b) => {
844
839
  isRequirementsSatisfied(b.meta.requirements);
845
840
  validateEngine(getBlockletEngineNameByPlatform(b.meta));
846
841
  });
@@ -1405,14 +1400,12 @@ const getBlocklet = async ({
1405
1400
 
1406
1401
  blocklet.settings.storeList = blocklet.settings.storeList || [];
1407
1402
 
1408
- [BLOCKLET_STORE_DEV, BLOCKLET_STORE].forEach((store) => {
1409
- if (!blocklet.settings.storeList.find((x) => x.url === store.url)) {
1410
- blocklet.settings.storeList.unshift({
1411
- ...store,
1412
- protected: true,
1413
- });
1414
- }
1415
- });
1403
+ if (!blocklet.settings.storeList.find((x) => x.url === BLOCKLET_STORE.url)) {
1404
+ blocklet.settings.storeList.unshift({
1405
+ ...BLOCKLET_STORE,
1406
+ protected: true,
1407
+ });
1408
+ }
1416
1409
 
1417
1410
  // app site
1418
1411
  blocklet.site = await states.site.findOneByBlocklet(blocklet.meta.did);
@@ -1697,32 +1690,6 @@ const checkDuplicateMountPoint = (blocklet, mountPoint) => {
1697
1690
  }
1698
1691
  };
1699
1692
 
1700
- const validateStore = (nodeInfo, storeUrl) => {
1701
- if (nodeInfo.mode !== 'serverless') {
1702
- return;
1703
- }
1704
-
1705
- const inStoreList = nodeInfo.blockletRegistryList.find((item) => {
1706
- const itemURLObj = new URL(item.url);
1707
- const storeUrlObj = new URL(storeUrl);
1708
-
1709
- return itemURLObj.host === storeUrlObj.host;
1710
- });
1711
-
1712
- if (!inStoreList) {
1713
- throw new Error('Must be installed from the compliant blocklet store list');
1714
- }
1715
- };
1716
-
1717
- const validateInServerless = ({ blockletMeta }) => {
1718
- const { interfaces } = blockletMeta;
1719
- const externalPortInterfaces = (interfaces || []).filter((item) => !!item.port?.external);
1720
-
1721
- if (externalPortInterfaces.length > 0) {
1722
- throw new Error('Blocklets with exposed ports cannot be installed');
1723
- }
1724
- };
1725
-
1726
1693
  module.exports = {
1727
1694
  consumeServerlessNFT,
1728
1695
  forEachBlocklet,
@@ -1770,6 +1737,4 @@ module.exports = {
1770
1737
  validateAppConfig,
1771
1738
  checkDuplicateAppSk,
1772
1739
  checkDuplicateMountPoint,
1773
- validateStore,
1774
- validateInServerless,
1775
1740
  };
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable newline-per-chained-call */
2
2
  const Joi = require('joi');
3
3
  const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES, ROUTER_CACHE_GROUPS } = require('@abtnode/constant');
4
+ const urlFriendly = require('@blocklet/meta/lib/url-friendly').default;
4
5
  const { getMultipleLangParams } = require('./util');
5
6
 
6
7
  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]/;
@@ -27,7 +28,8 @@ const ruleSchema = {
27
28
  .messages({
28
29
  zh: { 'string.empty': 'URL 前缀不能为空', 'string.max': 'URL 前缀的最大长度是 150' },
29
30
  en: { 'string.empty': 'URL prefix cannot be empty', 'string.max': 'The maximum length of URL prefix is 150' },
30
- }),
31
+ })
32
+ .custom((value) => urlFriendly(value)),
31
33
  groupPathPrefix: Joi.string().trim().min(1).max(150), // path prefix of interface of root blocklet
32
34
  header: Joi.any(), // TODO: header does not take effect
33
35
  }),
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.8.66-beta-b56e3b54",
6
+ "version": "1.8.66",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,33 +19,33 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.8.66-beta-b56e3b54",
23
- "@abtnode/certificate-manager": "1.8.66-beta-b56e3b54",
24
- "@abtnode/constant": "1.8.66-beta-b56e3b54",
25
- "@abtnode/cron": "1.8.66-beta-b56e3b54",
26
- "@abtnode/db": "1.8.66-beta-b56e3b54",
27
- "@abtnode/logger": "1.8.66-beta-b56e3b54",
28
- "@abtnode/queue": "1.8.66-beta-b56e3b54",
29
- "@abtnode/rbac": "1.8.66-beta-b56e3b54",
30
- "@abtnode/router-provider": "1.8.66-beta-b56e3b54",
31
- "@abtnode/static-server": "1.8.66-beta-b56e3b54",
32
- "@abtnode/timemachine": "1.8.66-beta-b56e3b54",
33
- "@abtnode/util": "1.8.66-beta-b56e3b54",
34
- "@arcblock/did": "1.18.52",
22
+ "@abtnode/auth": "1.8.66",
23
+ "@abtnode/certificate-manager": "1.8.66",
24
+ "@abtnode/constant": "1.8.66",
25
+ "@abtnode/cron": "1.8.66",
26
+ "@abtnode/db": "1.8.66",
27
+ "@abtnode/logger": "1.8.66",
28
+ "@abtnode/queue": "1.8.66",
29
+ "@abtnode/rbac": "1.8.66",
30
+ "@abtnode/router-provider": "1.8.66",
31
+ "@abtnode/static-server": "1.8.66",
32
+ "@abtnode/timemachine": "1.8.66",
33
+ "@abtnode/util": "1.8.66",
34
+ "@arcblock/did": "1.18.42",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
- "@arcblock/did-util": "1.18.52",
37
- "@arcblock/event-hub": "1.18.52",
38
- "@arcblock/jwt": "^1.18.52",
36
+ "@arcblock/did-util": "1.18.42",
37
+ "@arcblock/event-hub": "1.18.42",
38
+ "@arcblock/jwt": "^1.18.42",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
- "@arcblock/vc": "1.18.52",
41
- "@blocklet/constant": "1.8.66-beta-b56e3b54",
42
- "@blocklet/meta": "1.8.66-beta-b56e3b54",
43
- "@blocklet/sdk": "1.8.66-beta-b56e3b54",
44
- "@did-space/client": "^0.1.76",
40
+ "@arcblock/vc": "1.18.42",
41
+ "@blocklet/constant": "1.8.66",
42
+ "@blocklet/meta": "1.8.66",
43
+ "@blocklet/sdk": "1.8.66",
44
+ "@did-space/client": "^0.1.66",
45
45
  "@fidm/x509": "^1.2.1",
46
- "@ocap/mcrypto": "1.18.52",
47
- "@ocap/util": "1.18.52",
48
- "@ocap/wallet": "1.18.52",
46
+ "@ocap/mcrypto": "1.18.42",
47
+ "@ocap/util": "1.18.42",
48
+ "@ocap/wallet": "1.18.42",
49
49
  "@slack/webhook": "^5.0.4",
50
50
  "archiver": "^5.3.1",
51
51
  "axios": "^0.27.2",
@@ -72,6 +72,7 @@
72
72
  "pm2": "^5.2.0",
73
73
  "semver": "^7.3.8",
74
74
  "shelljs": "^0.8.5",
75
+ "slugify": "^1.6.5",
75
76
  "ssri": "^8.0.1",
76
77
  "stream-throttle": "^0.1.3",
77
78
  "stream-to-promise": "^3.0.0",
@@ -89,5 +90,5 @@
89
90
  "express": "^4.18.2",
90
91
  "jest": "^27.5.1"
91
92
  },
92
- "gitHead": "4d95b431526128c14cd04c0741cac423afce8f48"
93
+ "gitHead": "282247fd0ce6702e1d6920e90e2b3be0408cf879"
93
94
  }