@abtnode/core 1.16.13-beta-118c3420 → 1.16.13-beta-423a40b1

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
@@ -340,6 +340,7 @@ class TeamAPI extends EventEmitter {
340
340
  logger.info('user approval updated successfully', { teamDid, userDid: user.did, approved: user.approved });
341
341
 
342
342
  this.emit(EVENTS.USER_UPDATED, { teamDid, user: doc2 });
343
+ this.emit(EVENTS.USER_PERMISSION_UPDATED, { teamDid, user: doc2 });
343
344
 
344
345
  return doc2;
345
346
  }
@@ -442,6 +443,7 @@ class TeamAPI extends EventEmitter {
442
443
  logger.info('user passport revoked successfully', { teamDid, userDid, passportId });
443
444
 
444
445
  this.emit(EVENTS.USER_UPDATED, { teamDid, user: doc });
446
+ this.emit(EVENTS.USER_PERMISSION_UPDATED, { teamDid, user: doc });
445
447
 
446
448
  return doc;
447
449
  }
@@ -458,6 +460,7 @@ class TeamAPI extends EventEmitter {
458
460
  logger.info('user passport enabled successfully', { teamDid, userDid, passportId });
459
461
 
460
462
  this.emit(EVENTS.USER_UPDATED, { teamDid, user: doc });
463
+ this.emit(EVENTS.USER_PERMISSION_UPDATED, { teamDid, user: doc });
461
464
 
462
465
  return doc;
463
466
  }
@@ -30,7 +30,7 @@ const runUserHook = async (label, hookName, args) => {
30
30
  // FIXME @linchen timeout 应该动态设置或不设置
31
31
  await runScript(hook, [label, hookName].join(':'), {
32
32
  cwd: appDir,
33
- env: getSafeEnv(env),
33
+ env: { ...getSafeEnv(env), BLOCKLET_HOOK_NAME: hookName },
34
34
  silent,
35
35
  output: outputFile,
36
36
  error: errorFile,
@@ -9,6 +9,7 @@ const omit = require('lodash/omit');
9
9
  const merge = require('lodash/merge');
10
10
  const pick = require('lodash/pick');
11
11
  const isEmpty = require('lodash/isEmpty');
12
+ const cloneDeep = require('lodash/cloneDeep');
12
13
  const { isNFTExpired, getNftExpirationDate } = require('@abtnode/util/lib/nft');
13
14
  const didDocument = require('@abtnode/util/lib/did-document');
14
15
  const { sign } = require('@arcblock/jwt');
@@ -142,6 +143,7 @@ const RollbackCache = require('./helper/rollback-cache');
142
143
  const { migrateApplicationToStructV2 } = require('./helper/migrate-application-to-struct-v2');
143
144
  const { getBackupFilesUrlFromEndpoint, getBackupEndpoint, getSpaceNameByEndpoint } = require('../../util/spaces');
144
145
  const { validateAddSpaceGateway, validateUpdateSpaceGateway } = require('../../validators/space-gateway');
146
+ const { sessionConfigSchema } = require('../../validators/util');
145
147
 
146
148
  const { formatEnvironments, getBlockletMeta, validateOwner } = util;
147
149
 
@@ -1385,6 +1387,27 @@ class BlockletManager extends BaseBlockletManager {
1385
1387
  return this.getBlocklet(rootDid);
1386
1388
  }
1387
1389
 
1390
+ async updateAppSessionConfig({ did, config }) {
1391
+ const validateConfig = await sessionConfigSchema.validateAsync(config);
1392
+
1393
+ const blocklet = await this.getBlocklet(did);
1394
+ if (!blocklet) {
1395
+ throw new Error('blocklet does not exist');
1396
+ }
1397
+
1398
+ const sessionConfig = cloneDeep(blocklet.settings.session || {});
1399
+
1400
+ sessionConfig.cacheTtl = validateConfig.cacheTtl;
1401
+ sessionConfig.ttl = validateConfig.ttl;
1402
+
1403
+ await states.blockletExtras.setSettings(blocklet.meta.did, { session: sessionConfig });
1404
+
1405
+ const newState = await this.getBlocklet(did);
1406
+ this.emit(BlockletEvents.updated, newState);
1407
+
1408
+ return newState;
1409
+ }
1410
+
1388
1411
  // eslint-disable-next-line no-unused-vars
1389
1412
  async getRuntimeHistory({ did, hours }, context) {
1390
1413
  const metaDid = await states.blocklet.getBlockletMetaDid(did);
@@ -1944,7 +1967,8 @@ class BlockletManager extends BaseBlockletManager {
1944
1967
  }
1945
1968
 
1946
1969
  async _onCheckIfStarted(jobInfo, { throwOnError } = {}) {
1947
- const { did, context, minConsecutiveTime = 5000, timeout, componentDids } = jobInfo;
1970
+ const startedAt = Date.now();
1971
+ const { did, context, minConsecutiveTime = 2000, timeout, componentDids } = jobInfo;
1948
1972
  const blocklet = await this.getBlocklet(did);
1949
1973
 
1950
1974
  const { meta } = blocklet;
@@ -1965,6 +1989,7 @@ class BlockletManager extends BaseBlockletManager {
1965
1989
  });
1966
1990
 
1967
1991
  this.emit(BlockletEvents.started, res);
1992
+ logger.info('blocklet healthy', { did, name, time: Date.now() - startedAt });
1968
1993
  } catch (error) {
1969
1994
  const status = await states.blocklet.getBlockletStatus(did);
1970
1995
  if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
@@ -1974,7 +1999,7 @@ class BlockletManager extends BaseBlockletManager {
1974
1999
 
1975
2000
  logger.error('check blocklet if started failed', { did, name, context, timeout, error });
1976
2001
 
1977
- await this.deleteProcess({ did }, context);
2002
+ await this.deleteProcess({ did, componentDids }, context);
1978
2003
  await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
1979
2004
 
1980
2005
  this._createNotification(did, {
@@ -145,6 +145,9 @@ const installApplicationFromBackup = async ({
145
145
  extra.controller = controller;
146
146
  }
147
147
 
148
+ // 在旧版本中安装的 Blocklet 不存在 extra.meta 字段,这里补充一下
149
+ extra.meta = extra.meta || { did, name: appName };
150
+
148
151
  await states.blockletExtras.insert(extra);
149
152
  logger.info('blocklet extra is copied successfully');
150
153
 
package/lib/event.js CHANGED
@@ -105,6 +105,7 @@ module.exports = ({
105
105
 
106
106
  // Emit events to node listener
107
107
  // Call eventHandler
108
+ // NOT emit events to event hub
108
109
  const onInternalEvent = (name, data) => {
109
110
  events.emit(name, data);
110
111
  if (typeof eventHandler === 'function') {
@@ -421,6 +422,7 @@ module.exports = ({
421
422
  listen(teamAPI, EVENTS.USER_ADDED, onEvent);
422
423
  listen(teamAPI, EVENTS.USER_REMOVED, onEvent);
423
424
  listen(teamAPI, EVENTS.USER_UPDATED, onEvent);
425
+ listen(teamAPI, EVENTS.USER_PERMISSION_UPDATED, onEvent);
424
426
  listen(teamAPI, BlockletEvents.updated, onEvent);
425
427
  listen(teamManager, BlockletEvents.storeChange, onEvent);
426
428
 
package/lib/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const uniq = require('lodash/uniq');
3
4
  const md5 = require('@abtnode/util/lib/md5');
4
5
  const formatContext = require('@abtnode/util/lib/format-context');
5
6
  const Cron = require('@abtnode/cron');
@@ -259,6 +260,7 @@ function ABTNode(options) {
259
260
  configOAuth: blockletManager.configOAuth.bind(blockletManager),
260
261
  configNotification: blockletManager.configNotification.bind(blockletManager),
261
262
  updateWhoCanAccess: blockletManager.updateWhoCanAccess.bind(blockletManager),
263
+ updateAppSessionConfig: blockletManager.updateAppSessionConfig.bind(blockletManager),
262
264
  updateComponentTitle: blockletManager.updateComponentTitle.bind(blockletManager),
263
265
  updateComponentMountPoint: blockletManager.updateComponentMountPoint.bind(blockletManager),
264
266
  backupBlocklet: blockletManager.backup.bind(blockletManager),
@@ -390,7 +392,24 @@ function ABTNode(options) {
390
392
 
391
393
  // AuditLog
392
394
  createAuditLog: (params) => states.auditLog.create(params, instance),
393
- getAuditLogs: states.auditLog.findPaginated.bind(states.auditLog),
395
+ getAuditLogs: async (params) => {
396
+ if (params.scope) {
397
+ const blocklet = await states.blocklet.getBlocklet(params.scope);
398
+ if (blocklet) {
399
+ params.scope = uniq(
400
+ [
401
+ params.scope,
402
+ blocklet.appDid,
403
+ blocklet.appPid,
404
+ blocklet.structV1Did,
405
+ ...blocklet.migratedFrom.map((x) => x.appDid),
406
+ ].filter(Boolean)
407
+ );
408
+ }
409
+ }
410
+
411
+ return states.auditLog.findPaginated.call(states.auditLog, params);
412
+ },
394
413
 
395
414
  // Routing
396
415
  routerManager,
@@ -3,13 +3,14 @@
3
3
  const fs = require('fs-extra');
4
4
  const path = require('path');
5
5
  const tar = require('tar');
6
+ const UUID = require('uuid');
6
7
  const isUrl = require('is-url');
7
8
  const get = require('lodash/get');
8
9
  const cloneDeep = require('lodash/cloneDeep');
9
10
  const groupBy = require('lodash/groupBy');
10
11
  const isEqual = require('lodash/isEqual');
11
12
  const joinUrl = require('url-join');
12
- const { replaceSlotToIp, findComponentById, findWebInterface } = require('@blocklet/meta/lib/util');
13
+ const { replaceSlotToIp, findComponentById, findWebInterface, getComponentId } = require('@blocklet/meta/lib/util');
13
14
  const { getProvider } = require('@abtnode/router-provider');
14
15
  const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
15
16
  const getTmpDir = require('@abtnode/util/lib/get-tmp-directory');
@@ -488,6 +489,60 @@ const ensureBlockletWellknownRules = (sites, blocklets) => {
488
489
  .filter(Boolean);
489
490
  };
490
491
 
492
+ // Expand component rules to blocklet rules
493
+ const isComponentRule = (x) => x.to.type === ROUTING_RULE_TYPES.COMPONENT;
494
+ const expandComponentRules = (sites = [], blocklets) => {
495
+ return sites
496
+ .map((site) => {
497
+ if (!site.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX)) {
498
+ return site;
499
+ }
500
+
501
+ if (site.componentExpanded) {
502
+ return site;
503
+ }
504
+
505
+ const blocklet = blocklets.find((x) => x.meta.did === site.blockletDid);
506
+ const components = blocklet.children.filter((x) => x.mountPoint !== '/' && x.mode === BLOCKLET_MODES.PRODUCTION);
507
+ const expandedRules = [];
508
+
509
+ site.rules.filter(isComponentRule).forEach((baseRule) => {
510
+ components.forEach((x) => {
511
+ const newRule = {
512
+ id: UUID.v4(),
513
+ groupId: baseRule.groupId,
514
+ from: {
515
+ groupPathPrefix: '/',
516
+ },
517
+ to: {
518
+ type: ROUTING_RULE_TYPES.BLOCKLET,
519
+ componentId: getComponentId(x, [blocklet]),
520
+ interfaceName: BLOCKLET_INTERFACE_PUBLIC,
521
+ port: findInterfacePortByName(x, BLOCKLET_INTERFACE_PUBLIC),
522
+ did: blocklet.meta.did,
523
+ target: '/',
524
+ },
525
+ };
526
+
527
+ if (x.meta.did === baseRule.to.componentId) {
528
+ newRule.from.pathPrefix = baseRule.from.pathPrefix;
529
+ newRule.to.pageGroup = baseRule.to.pageGroup;
530
+ } else {
531
+ newRule.from.pathPrefix = joinUrl(baseRule.from.pathPrefix, x.mountPoint);
532
+ }
533
+
534
+ expandedRules.push(newRule);
535
+ });
536
+ });
537
+
538
+ site.rules = site.rules.filter((x) => !isComponentRule(x)).concat(expandedRules);
539
+ site.componentExpanded = true;
540
+
541
+ return site;
542
+ })
543
+ .filter(Boolean);
544
+ };
545
+
491
546
  const ensureBlockletCache = (sites = [], blocklets) => {
492
547
  return sites
493
548
  .map((site) => {
@@ -545,12 +600,13 @@ const ensureLatestInfo = async (sites = [], { withDefaultCors = true } = {}) =>
545
600
  let result = await ensureLatestNodeInfo(sites, { withDefaultCors });
546
601
  result = await ensureBlockletDid(result);
547
602
  result = await filterSitesForRemovedBlocklets(sites, blocklets);
548
- result = await ensureBlockletWellknownRules(result, blocklets);
549
603
  result = await ensureBlockletCache(result, blocklets);
550
604
  result = await ensureWellknownRule(result);
551
605
  result = await ensureCorsForWebWallet(result);
552
606
  result = await ensureCorsForDidSpace(result, blocklets);
553
607
  result = await ensureLatestInterfaceInfo(result);
608
+ result = await ensureBlockletWellknownRules(result, blocklets);
609
+ result = await expandComponentRules(result, blocklets);
554
610
 
555
611
  return result;
556
612
  };
@@ -1457,3 +1513,4 @@ module.exports.ensureLatestInterfaceInfo = ensureLatestInterfaceInfo;
1457
1513
  module.exports.ensureLatestInfo = ensureLatestInfo;
1458
1514
  module.exports.ensureWellknownRule = ensureWellknownRule;
1459
1515
  module.exports.ensureBlockletWellknownRules = ensureBlockletWellknownRules;
1516
+ module.exports.expandComponentRules = expandComponentRules;
@@ -223,6 +223,7 @@ Router.formatSites = (sites = []) => {
223
223
  did: rule.to.did,
224
224
  componentId: rule.to.componentId,
225
225
  cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
226
+ pageGroup: rule.to.pageGroup,
226
227
  },
227
228
  });
228
229
  site.rules.push({
@@ -238,6 +239,7 @@ Router.formatSites = (sites = []) => {
238
239
  did: rule.to.did,
239
240
  componentId: rule.to.componentId,
240
241
  cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
242
+ pageGroup: rule.to.pageGroup,
241
243
  },
242
244
  });
243
245
  });
@@ -271,6 +273,7 @@ Router.formatSites = (sites = []) => {
271
273
  type: ROUTING_RULE_TYPES.DAEMON,
272
274
  port: daemonRule.to.port,
273
275
  cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
276
+ pageGroup: rule.to.pageGroup,
274
277
  did: rule.to.did,
275
278
  },
276
279
  });
@@ -287,6 +290,7 @@ Router.formatSites = (sites = []) => {
287
290
  type: ROUTING_RULE_TYPES.DAEMON,
288
291
  target: BLOCKLET_PROXY_PATH_PREFIX,
289
292
  cacheGroup: !isServiceFeDevelopment && site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
293
+ pageGroup: rule.to.pageGroup,
290
294
  did: rule.to.did,
291
295
  },
292
296
  });
@@ -598,30 +598,30 @@ class RouterManager extends EventEmitter {
598
598
 
599
599
  /**
600
600
  * get all rules to be add or update to site from root rule
601
- * @param {*} rootRule
601
+ * @param {*} rawRule
602
602
  */
603
- async getRulesForMutation(rootRule) {
604
- if (rootRule.to.type !== ROUTING_RULE_TYPES.BLOCKLET) {
605
- return [rootRule];
603
+ async getRulesForMutation(rawRule) {
604
+ if (rawRule.to.type !== ROUTING_RULE_TYPES.BLOCKLET) {
605
+ return [rawRule];
606
606
  }
607
607
 
608
608
  const rules = [];
609
609
 
610
610
  // get child rules
611
- const blocklet = await states.blocklet.getBlocklet(rootRule.to.did);
611
+ const blocklet = await states.blocklet.getBlocklet(rawRule.to.did);
612
612
 
613
613
  // blocklet may be mounted in relative prefix (for old usage), so blockletPrefix may not be '/'
614
- // blocklet prefix is the origin pathPrefix in rootRule
615
- const blockletPrefix = normalizePathPrefix(rootRule.from.pathPrefix);
614
+ // blocklet prefix is the origin pathPrefix in rawRule
615
+ const blockletPrefix = normalizePathPrefix(rawRule.from.pathPrefix);
616
616
 
617
617
  // root component's mountPoint may not be '/'
618
618
  const rootComponentPrefix = joinUrl(blockletPrefix, blocklet.mountPoint || '/');
619
- rootRule.from.pathPrefix = normalizePathPrefix(rootComponentPrefix);
619
+ rawRule.from.pathPrefix = normalizePathPrefix(rootComponentPrefix);
620
620
 
621
621
  const isOccupiable = blocklet.meta.group === BlockletGroup.gateway;
622
622
 
623
623
  if (!isOccupiable) {
624
- rules.push(rootRule);
624
+ rules.push(rawRule);
625
625
  }
626
626
 
627
627
  forEachChildSync(blocklet, (component, { id, ancestors }) => {
@@ -650,7 +650,7 @@ class RouterManager extends EventEmitter {
650
650
  mountPoint
651
651
  );
652
652
 
653
- const occupied = normalizePathPrefix(pathPrefix) === normalizePathPrefix(rootRule.from.pathPrefix);
653
+ const occupied = normalizePathPrefix(pathPrefix) === normalizePathPrefix(rawRule.from.pathPrefix);
654
654
 
655
655
  if (occupied && !isOccupiable) {
656
656
  return;
@@ -658,8 +658,8 @@ class RouterManager extends EventEmitter {
658
658
 
659
659
  // if is root path, child rule become root rule
660
660
  const childRule = {
661
- id: occupied ? rootRule.id : uuid.v4(),
662
- groupId: rootRule.id,
661
+ id: occupied ? rawRule.id : uuid.v4(),
662
+ groupId: rawRule.id,
663
663
  from: {
664
664
  pathPrefix: normalizePathPrefix(pathPrefix),
665
665
  groupPathPrefix: blockletPrefix,
@@ -667,11 +667,11 @@ class RouterManager extends EventEmitter {
667
667
  to: {
668
668
  type: ROUTING_RULE_TYPES.BLOCKLET,
669
669
  port: findInterfacePortByName(component, childWebInterface.name),
670
- did: rootRule.to.did, // root component did
671
- interfaceName: rootRule.to.interfaceName, // root component interface
670
+ did: rawRule.to.did, // root component did
671
+ interfaceName: rawRule.to.interfaceName, // root component interface
672
672
  componentId: id,
673
673
  },
674
- isProtected: occupied ? rootRule.isProtected : true,
674
+ isProtected: occupied ? rawRule.isProtected : true,
675
675
  };
676
676
 
677
677
  rules.push(childRule);
@@ -167,6 +167,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
167
167
  return `removed blocklet store ${args.url}`;
168
168
  case 'selectBlockletStore':
169
169
  return `selected blocklet store ${args.url}`;
170
+ case 'updateAppSessionConfig':
171
+ return `updated session config: ${JSON.stringify(args.config)}`;
170
172
 
171
173
  // teams: members/passports
172
174
  case 'addUser':
@@ -463,11 +463,11 @@ const isUsefulError = (err) =>
463
463
  !/^Process \d+ not found$/.test(err.message);
464
464
 
465
465
  const getHealthyCheckTimeout = (blocklet, { checkHealthImmediately } = {}) => {
466
- let minConsecutiveTime = 5000;
466
+ let minConsecutiveTime = 2000;
467
467
  if (process.env.NODE_ENV === 'test' && process.env.ABT_NODE_TEST_MIN_CONSECUTIVE_TIME !== undefined) {
468
468
  minConsecutiveTime = process.env.ABT_NODE_TEST_MIN_CONSECUTIVE_TIME;
469
469
  } else if (checkHealthImmediately) {
470
- minConsecutiveTime = 3000;
470
+ minConsecutiveTime = 1000;
471
471
  }
472
472
 
473
473
  if (process.env.BLOCKLET_START_TIMEOUT) {
@@ -534,6 +534,7 @@ const startBlockletProcess = async (
534
534
 
535
535
  // get env
536
536
  const env = getRuntimeEnvironments(b, nodeEnvironments, ancestors);
537
+ const startedAt = Date.now();
537
538
 
538
539
  // run hook
539
540
  await preStart(b, { env });
@@ -558,7 +559,7 @@ const startBlockletProcess = async (
558
559
  output: path.join(logsDir, 'output.log'),
559
560
  error: path.join(logsDir, 'error.log'),
560
561
  wait_ready: process.env.NODE_ENV !== 'test',
561
- listen_timeout: 5000,
562
+ listen_timeout: 3000,
562
563
  max_memory_restart: `${maxMemoryRestart}M`,
563
564
  max_restarts: b.mode === BLOCKLET_MODES.DEVELOPMENT ? 0 : 3,
564
565
  env: {
@@ -612,9 +613,9 @@ const startBlockletProcess = async (
612
613
 
613
614
  const status = await getProcessState(processId);
614
615
  if (status === BlockletStatus.error) {
615
- throw new Error(`${processId} is not running within 5 seconds`);
616
+ throw new Error(`${processId} is not running within 3 seconds`);
616
617
  }
617
- logger.info('blocklet started', { processId, status });
618
+ logger.info('blocklet started', { processId, status, time: Date.now() - startedAt });
618
619
 
619
620
  // run hook
620
621
  postStart(b, { env }).catch((err) => {
@@ -766,7 +767,9 @@ const checkBlockletProcessHealthy = async (blocklet, { minConsecutiveTime, timeo
766
767
 
767
768
  const logToTerminal = [blocklet.mode, b.mode].includes(BLOCKLET_MODES.DEVELOPMENT);
768
769
 
770
+ const startedAt = Date.now();
769
771
  await _checkProcessHealthy(b, { minConsecutiveTime, timeout, logToTerminal });
772
+ logger.info('component healthy', { did: b.meta.did, time: Date.now() - startedAt });
770
773
  },
771
774
  { parallel: true }
772
775
  );
@@ -795,10 +798,9 @@ const _checkProcessHealthy = async (blocklet, { minConsecutiveTime, timeout, log
795
798
  }
796
799
  };
797
800
 
798
- await sleep(400);
799
801
  let status = await getStatus();
800
- for (let i = 0; i < 10 && status !== 'online'; i++) {
801
- const t = process.env.NODE_ENV !== 'test' ? 1000 : 30;
802
+ for (let i = 0; i < 20 && status !== 'online'; i++) {
803
+ const t = process.env.NODE_ENV !== 'test' ? 500 : 30;
802
804
  await sleep(t);
803
805
  status = await getStatus();
804
806
  }
@@ -817,11 +819,7 @@ const _checkProcessHealthy = async (blocklet, { minConsecutiveTime, timeout, log
817
819
  );
818
820
  }
819
821
  try {
820
- await ensureEndpointHealthy({
821
- port,
822
- minConsecutiveTime,
823
- timeout,
824
- });
822
+ await ensureEndpointHealthy({ port, minConsecutiveTime, timeout });
825
823
  } catch (error) {
826
824
  logger.error('ensure endpoint healthy failed', { port, minConsecutiveTime, timeout });
827
825
  throw error;
@@ -181,7 +181,7 @@ const setupAppOwner = async (node, sessionId) => {
181
181
  passport,
182
182
  role,
183
183
  secret: appSecret,
184
- expiresIn: '7d',
184
+ expiresIn: '1d',
185
185
  });
186
186
 
187
187
  await node.setBlockletOwner({ did: appDid, owner: { did: ownerDid, pk: ownerPk } });
@@ -17,19 +17,21 @@ const domainMessages = {
17
17
  },
18
18
  };
19
19
 
20
+ const getPrefixSchema = (field) =>
21
+ Joi.string()
22
+ .trim()
23
+ .max(150)
24
+ .messages({
25
+ zh: { 'string.empty': `${field} 不能为空`, 'string.max': `${field} 的最大长度是 150` },
26
+ en: { 'string.empty': `${field} cannot be empty`, 'string.max': `The maximum length of ${field} is 150` },
27
+ })
28
+ .custom((value) => urlPathFriendly(value));
29
+
20
30
  const ruleSchema = {
21
31
  isProtected: Joi.boolean(),
22
32
 
23
33
  from: Joi.object({
24
- pathPrefix: Joi.string()
25
- .required()
26
- .trim()
27
- .max(150)
28
- .messages({
29
- zh: { 'string.empty': 'URL 前缀不能为空', 'string.max': 'URL 前缀的最大长度是 150' },
30
- en: { 'string.empty': 'URL prefix cannot be empty', 'string.max': 'The maximum length of URL prefix is 150' },
31
- })
32
- .custom((value) => urlPathFriendly(value)),
34
+ pathPrefix: getPrefixSchema('from.pathPrefix').required(),
33
35
  groupPathPrefix: Joi.string().trim().min(1).max(150), // path prefix of interface of root blocklet
34
36
  header: Joi.any(), // TODO: header does not take effect
35
37
  }),
@@ -44,12 +46,24 @@ const ruleSchema = {
44
46
  ROUTING_RULE_TYPES.REDIRECT,
45
47
  ROUTING_RULE_TYPES.GENERAL_PROXY,
46
48
  ROUTING_RULE_TYPES.DIRECT_RESPONSE,
49
+ ROUTING_RULE_TYPES.GENERAL_REWRITE,
50
+ ROUTING_RULE_TYPES.COMPONENT,
47
51
  ROUTING_RULE_TYPES.NONE
48
52
  )
49
53
  .required(),
50
- did: Joi.string().label('did').when('type', { is: ROUTING_RULE_TYPES.BLOCKLET, then: Joi.required() }), // root blocklet did
54
+ did: Joi.string()
55
+ .label('did')
56
+ .when('type', {
57
+ is: Joi.string().valid(ROUTING_RULE_TYPES.BLOCKLET, ROUTING_RULE_TYPES.COMPONENT),
58
+ then: Joi.required(),
59
+ }), // root blocklet did
51
60
  port: Joi.number().label('port').port().when('type', { is: ROUTING_RULE_TYPES.BLOCKLET, then: Joi.required() }),
52
- url: Joi.string().label('url').when('type', { is: ROUTING_RULE_TYPES.REDIRECT, then: Joi.required() }),
61
+ url: Joi.string()
62
+ .label('url')
63
+ .when('type', {
64
+ is: Joi.string().valid(ROUTING_RULE_TYPES.REDIRECT, ROUTING_RULE_TYPES.GENERAL_REWRITE),
65
+ then: Joi.required(),
66
+ }),
53
67
  redirectCode: Joi.alternatives()
54
68
  .try(301, 302, 307, 308)
55
69
  .label('redirect code')
@@ -70,7 +84,8 @@ const ruleSchema = {
70
84
  .valid(...Object.keys(ROUTER_CACHE_GROUPS))
71
85
  .allow('')
72
86
  .default(''),
73
- targetPrefix: Joi.string().trim().max(150), // path prefix of interface of target blocklet
87
+ targetPrefix: getPrefixSchema('to.targetPrefix'), // path prefix of interface of target blocklet
88
+ pageGroup: Joi.string().allow('').default(''),
74
89
  },
75
90
 
76
91
  // List of services that manipulate the request before the upstream blocklet
@@ -22,8 +22,20 @@ const blockletController = Joi.object({
22
22
 
23
23
  const createValidator = (schema) => (entity) => schema.validateAsync(entity);
24
24
 
25
+ const sessionConfigSchema = Joi.object({
26
+ cacheTtl: Joi.number()
27
+ .min(5 * 60) // 5min
28
+ .max(86400) // 1d
29
+ .default(10 * 60), // 10min
30
+ ttl: Joi.number()
31
+ .min(86400) // 1d
32
+ .max(86400 * 30) // 30d
33
+ .default(86400 * 7), // 7d
34
+ });
35
+
25
36
  module.exports = {
26
37
  createValidator,
27
38
  getMultipleLangParams,
28
39
  blockletController,
40
+ sessionConfigSchema,
29
41
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.13-beta-118c3420",
6
+ "version": "1.16.13-beta-423a40b1",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,32 +19,32 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "Apache-2.0",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.16.13-beta-118c3420",
23
- "@abtnode/certificate-manager": "1.16.13-beta-118c3420",
24
- "@abtnode/constant": "1.16.13-beta-118c3420",
25
- "@abtnode/cron": "1.16.13-beta-118c3420",
26
- "@abtnode/logger": "1.16.13-beta-118c3420",
27
- "@abtnode/models": "1.16.13-beta-118c3420",
28
- "@abtnode/queue": "1.16.13-beta-118c3420",
29
- "@abtnode/rbac": "1.16.13-beta-118c3420",
30
- "@abtnode/router-provider": "1.16.13-beta-118c3420",
31
- "@abtnode/static-server": "1.16.13-beta-118c3420",
32
- "@abtnode/timemachine": "1.16.13-beta-118c3420",
33
- "@abtnode/util": "1.16.13-beta-118c3420",
22
+ "@abtnode/auth": "1.16.13-beta-423a40b1",
23
+ "@abtnode/certificate-manager": "1.16.13-beta-423a40b1",
24
+ "@abtnode/constant": "1.16.13-beta-423a40b1",
25
+ "@abtnode/cron": "1.16.13-beta-423a40b1",
26
+ "@abtnode/logger": "1.16.13-beta-423a40b1",
27
+ "@abtnode/models": "1.16.13-beta-423a40b1",
28
+ "@abtnode/queue": "1.16.13-beta-423a40b1",
29
+ "@abtnode/rbac": "1.16.13-beta-423a40b1",
30
+ "@abtnode/router-provider": "1.16.13-beta-423a40b1",
31
+ "@abtnode/static-server": "1.16.13-beta-423a40b1",
32
+ "@abtnode/timemachine": "1.16.13-beta-423a40b1",
33
+ "@abtnode/util": "1.16.13-beta-423a40b1",
34
34
  "@arcblock/did": "1.18.84",
35
35
  "@arcblock/did-auth": "1.18.84",
36
36
  "@arcblock/did-ext": "^1.18.84",
37
- "@arcblock/did-motif": "^1.1.10",
37
+ "@arcblock/did-motif": "^1.1.11",
38
38
  "@arcblock/did-util": "1.18.84",
39
39
  "@arcblock/event-hub": "1.18.84",
40
40
  "@arcblock/jwt": "^1.18.84",
41
41
  "@arcblock/pm2-events": "^0.0.5",
42
42
  "@arcblock/validator": "^1.18.84",
43
43
  "@arcblock/vc": "1.18.84",
44
- "@blocklet/constant": "1.16.13-beta-118c3420",
45
- "@blocklet/meta": "1.16.13-beta-118c3420",
46
- "@blocklet/resolver": "1.16.13-beta-118c3420",
47
- "@blocklet/sdk": "1.16.13-beta-118c3420",
44
+ "@blocklet/constant": "1.16.13-beta-423a40b1",
45
+ "@blocklet/meta": "1.16.13-beta-423a40b1",
46
+ "@blocklet/resolver": "1.16.13-beta-423a40b1",
47
+ "@blocklet/sdk": "1.16.13-beta-423a40b1",
48
48
  "@did-space/client": "^0.2.117",
49
49
  "@fidm/x509": "^1.2.1",
50
50
  "@ocap/mcrypto": "1.18.84",
@@ -97,5 +97,5 @@
97
97
  "express": "^4.18.2",
98
98
  "jest": "^27.5.1"
99
99
  },
100
- "gitHead": "93e00311f882c8c153a1c6c3d18aa29c154f08f6"
100
+ "gitHead": "1aee04f45042bd4784ca72f9f8b93918980be4d4"
101
101
  }