@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 +3 -0
- package/lib/blocklet/hooks.js +1 -1
- package/lib/blocklet/manager/disk.js +27 -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/util/blocklet.js +11 -13
- package/lib/util/launcher.js +1 -1
- package/lib/validators/router.js +27 -12
- package/lib/validators/util.js +12 -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,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
|
|
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:
|
|
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/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,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-
|
|
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-
|
|
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-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.
|
|
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-
|
|
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-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": "
|
|
100
|
+
"gitHead": "1aee04f45042bd4784ca72f9f8b93918980be4d4"
|
|
101
101
|
}
|