@abtnode/core 1.16.13-beta-118c3420 → 1.16.13-beta-a83ad86d
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 +3 -0
- package/lib/blocklet/hooks.js +1 -1
- package/lib/blocklet/manager/disk.js +31 -2
- package/lib/blocklet/manager/helper/install-application-from-backup.js +3 -0
- package/lib/event.js +2 -0
- package/lib/index.js +20 -1
- package/lib/router/helper.js +59 -2
- package/lib/router/index.js +4 -0
- package/lib/router/manager.js +15 -15
- package/lib/states/audit-log.js +2 -0
- package/lib/states/node.js +15 -4
- package/lib/util/blocklet.js +11 -13
- package/lib/util/launcher.js +1 -1
- package/lib/validators/router.js +27 -12
- package/lib/validators/util.js +10 -0
- package/package.json +19 -19
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
|
}
|
package/lib/blocklet/hooks.js
CHANGED
|
@@ -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,31 @@ 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
|
+
if (validateConfig.cacheTtl) {
|
|
1401
|
+
sessionConfig.cacheTtl = validateConfig.cacheTtl;
|
|
1402
|
+
}
|
|
1403
|
+
if (validateConfig.ttl) {
|
|
1404
|
+
sessionConfig.ttl = validateConfig.ttl;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
await states.blockletExtras.setSettings(blocklet.meta.did, { session: sessionConfig });
|
|
1408
|
+
|
|
1409
|
+
const newState = await this.getBlocklet(did);
|
|
1410
|
+
this.emit(BlockletEvents.updated, newState);
|
|
1411
|
+
|
|
1412
|
+
return newState;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1388
1415
|
// eslint-disable-next-line no-unused-vars
|
|
1389
1416
|
async getRuntimeHistory({ did, hours }, context) {
|
|
1390
1417
|
const metaDid = await states.blocklet.getBlockletMetaDid(did);
|
|
@@ -1944,7 +1971,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1944
1971
|
}
|
|
1945
1972
|
|
|
1946
1973
|
async _onCheckIfStarted(jobInfo, { throwOnError } = {}) {
|
|
1947
|
-
const
|
|
1974
|
+
const startedAt = Date.now();
|
|
1975
|
+
const { did, context, minConsecutiveTime = 2000, timeout, componentDids } = jobInfo;
|
|
1948
1976
|
const blocklet = await this.getBlocklet(did);
|
|
1949
1977
|
|
|
1950
1978
|
const { meta } = blocklet;
|
|
@@ -1965,6 +1993,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1965
1993
|
});
|
|
1966
1994
|
|
|
1967
1995
|
this.emit(BlockletEvents.started, res);
|
|
1996
|
+
logger.info('blocklet healthy', { did, name, time: Date.now() - startedAt });
|
|
1968
1997
|
} catch (error) {
|
|
1969
1998
|
const status = await states.blocklet.getBlockletStatus(did);
|
|
1970
1999
|
if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
|
|
@@ -1974,7 +2003,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1974
2003
|
|
|
1975
2004
|
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
1976
2005
|
|
|
1977
|
-
await this.deleteProcess({ did }, context);
|
|
2006
|
+
await this.deleteProcess({ did, componentDids }, context);
|
|
1978
2007
|
await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
1979
2008
|
|
|
1980
2009
|
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:
|
|
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,
|
package/lib/router/helper.js
CHANGED
|
@@ -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;
|
package/lib/router/index.js
CHANGED
|
@@ -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
|
});
|
package/lib/router/manager.js
CHANGED
|
@@ -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 {*}
|
|
601
|
+
* @param {*} rawRule
|
|
602
602
|
*/
|
|
603
|
-
async getRulesForMutation(
|
|
604
|
-
if (
|
|
605
|
-
return [
|
|
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(
|
|
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
|
|
615
|
-
const blockletPrefix = normalizePathPrefix(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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 ?
|
|
662
|
-
groupId:
|
|
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:
|
|
671
|
-
interfaceName:
|
|
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 ?
|
|
674
|
+
isProtected: occupied ? rawRule.isProtected : true,
|
|
675
675
|
};
|
|
676
676
|
|
|
677
677
|
rules.push(childRule);
|
package/lib/states/audit-log.js
CHANGED
|
@@ -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':
|
package/lib/states/node.js
CHANGED
|
@@ -204,12 +204,19 @@ class NodeState extends BaseState {
|
|
|
204
204
|
return updated;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
updateNftHolder(holder) {
|
|
207
|
+
async updateNftHolder(holder) {
|
|
208
208
|
if (!holder) {
|
|
209
209
|
throw new Error('NFT holder can not be empty');
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
const { ownerNft } = await this.read();
|
|
213
|
+
if (isEmpty(ownerNft)) {
|
|
214
|
+
throw new Error('ownerNft is empty');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
ownerNft.holder = holder;
|
|
218
|
+
|
|
219
|
+
return this.update({ $set: { ownerNft } });
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
async enterMode(mode) {
|
|
@@ -273,8 +280,12 @@ class NodeState extends BaseState {
|
|
|
273
280
|
}
|
|
274
281
|
|
|
275
282
|
async updateGateway(gateway) {
|
|
283
|
+
const { routing } = await this.read();
|
|
284
|
+
routing.requestLimit = gateway.requestLimit;
|
|
285
|
+
routing.cacheEnabled = gateway.cacheEnabled;
|
|
286
|
+
|
|
276
287
|
const doc = await this.update({
|
|
277
|
-
$set: {
|
|
288
|
+
$set: { routing },
|
|
278
289
|
});
|
|
279
290
|
|
|
280
291
|
this.emit(EVENTS.RELOAD_GATEWAY, doc);
|
|
@@ -296,7 +307,7 @@ class NodeState extends BaseState {
|
|
|
296
307
|
}
|
|
297
308
|
|
|
298
309
|
async update(updates) {
|
|
299
|
-
await this.read();
|
|
310
|
+
await this.read(); // CAUTION: 这一行不要删,当 node state 不存在时,read() 会插入新数据
|
|
300
311
|
const [, [updated]] = await super.update({ did: this.config.nodeDid }, updates);
|
|
301
312
|
return updated;
|
|
302
313
|
}
|
package/lib/util/blocklet.js
CHANGED
|
@@ -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 =
|
|
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 =
|
|
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:
|
|
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
|
|
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 <
|
|
801
|
-
const t = process.env.NODE_ENV !== 'test' ?
|
|
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;
|
package/lib/util/launcher.js
CHANGED
package/lib/validators/router.js
CHANGED
|
@@ -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:
|
|
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()
|
|
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()
|
|
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:
|
|
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
|
package/lib/validators/util.js
CHANGED
|
@@ -22,8 +22,18 @@ 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
|
+
ttl: Joi.number()
|
|
30
|
+
.min(86400) // 1d
|
|
31
|
+
.max(86400 * 30), // 30d
|
|
32
|
+
});
|
|
33
|
+
|
|
25
34
|
module.exports = {
|
|
26
35
|
createValidator,
|
|
27
36
|
getMultipleLangParams,
|
|
28
37
|
blockletController,
|
|
38
|
+
sessionConfigSchema,
|
|
29
39
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.13-beta-
|
|
6
|
+
"version": "1.16.13-beta-a83ad86d",
|
|
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-
|
|
23
|
-
"@abtnode/certificate-manager": "1.16.13-beta-
|
|
24
|
-
"@abtnode/constant": "1.16.13-beta-
|
|
25
|
-
"@abtnode/cron": "1.16.13-beta-
|
|
26
|
-
"@abtnode/logger": "1.16.13-beta-
|
|
27
|
-
"@abtnode/models": "1.16.13-beta-
|
|
28
|
-
"@abtnode/queue": "1.16.13-beta-
|
|
29
|
-
"@abtnode/rbac": "1.16.13-beta-
|
|
30
|
-
"@abtnode/router-provider": "1.16.13-beta-
|
|
31
|
-
"@abtnode/static-server": "1.16.13-beta-
|
|
32
|
-
"@abtnode/timemachine": "1.16.13-beta-
|
|
33
|
-
"@abtnode/util": "1.16.13-beta-
|
|
22
|
+
"@abtnode/auth": "1.16.13-beta-a83ad86d",
|
|
23
|
+
"@abtnode/certificate-manager": "1.16.13-beta-a83ad86d",
|
|
24
|
+
"@abtnode/constant": "1.16.13-beta-a83ad86d",
|
|
25
|
+
"@abtnode/cron": "1.16.13-beta-a83ad86d",
|
|
26
|
+
"@abtnode/logger": "1.16.13-beta-a83ad86d",
|
|
27
|
+
"@abtnode/models": "1.16.13-beta-a83ad86d",
|
|
28
|
+
"@abtnode/queue": "1.16.13-beta-a83ad86d",
|
|
29
|
+
"@abtnode/rbac": "1.16.13-beta-a83ad86d",
|
|
30
|
+
"@abtnode/router-provider": "1.16.13-beta-a83ad86d",
|
|
31
|
+
"@abtnode/static-server": "1.16.13-beta-a83ad86d",
|
|
32
|
+
"@abtnode/timemachine": "1.16.13-beta-a83ad86d",
|
|
33
|
+
"@abtnode/util": "1.16.13-beta-a83ad86d",
|
|
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.
|
|
37
|
+
"@arcblock/did-motif": "^1.1.12",
|
|
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-
|
|
45
|
-
"@blocklet/meta": "1.16.13-beta-
|
|
46
|
-
"@blocklet/resolver": "1.16.13-beta-
|
|
47
|
-
"@blocklet/sdk": "1.16.13-beta-
|
|
44
|
+
"@blocklet/constant": "1.16.13-beta-a83ad86d",
|
|
45
|
+
"@blocklet/meta": "1.16.13-beta-a83ad86d",
|
|
46
|
+
"@blocklet/resolver": "1.16.13-beta-a83ad86d",
|
|
47
|
+
"@blocklet/sdk": "1.16.13-beta-a83ad86d",
|
|
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": "
|
|
100
|
+
"gitHead": "dc2a4f7d5b55da109ebf873d8aa4d24f27a088c9"
|
|
101
101
|
}
|