@abtnode/core 1.16.28-beta-bfbab430 → 1.16.28-beta-641c9f13
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 -3
- package/lib/blocklet/hooks.js +9 -1
- package/lib/blocklet/manager/disk.js +49 -31
- package/lib/blocklet/manager/helper/install-component-from-upload.js +2 -1
- package/lib/blocklet/manager/helper/install-component-from-url.js +2 -2
- package/lib/monitor/blocklet-runtime-monitor.js +1 -1
- package/lib/monitor/node-runtime-monitor.js +1 -1
- package/lib/router/helper.js +8 -8
- package/lib/router/manager.js +2 -2
- package/lib/states/audit-log.js +5 -5
- package/lib/states/user.js +3 -0
- package/lib/util/blocklet.js +30 -11
- package/lib/util/get-accessible-external-node-ip.js +2 -2
- package/lib/util/index.js +3 -3
- package/lib/util/launcher.js +3 -3
- package/lib/util/spaces.js +4 -2
- package/lib/util/store.js +8 -6
- package/lib/validators/node.js +1 -0
- package/package.json +24 -24
package/lib/api/team.js
CHANGED
|
@@ -2,7 +2,7 @@ const { EventEmitter } = require('events');
|
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const defaults = require('lodash/defaults');
|
|
4
4
|
const cloneDeep = require('lodash/cloneDeep');
|
|
5
|
-
const
|
|
5
|
+
const { joinURL } = require('ufo');
|
|
6
6
|
|
|
7
7
|
const logger = require('@abtnode/logger')('@abtnode/core:api:team');
|
|
8
8
|
const {
|
|
@@ -511,7 +511,7 @@ class TeamAPI extends EventEmitter {
|
|
|
511
511
|
role,
|
|
512
512
|
}),
|
|
513
513
|
endpoint: getPassportStatusEndpoint({
|
|
514
|
-
baseUrl:
|
|
514
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
515
515
|
userDid,
|
|
516
516
|
teamDid,
|
|
517
517
|
}),
|
|
@@ -966,7 +966,7 @@ class TeamAPI extends EventEmitter {
|
|
|
966
966
|
role,
|
|
967
967
|
}),
|
|
968
968
|
endpoint: getPassportStatusEndpoint({
|
|
969
|
-
baseUrl:
|
|
969
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
970
970
|
userDid,
|
|
971
971
|
teamDid,
|
|
972
972
|
}),
|
package/lib/blocklet/hooks.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const camelCase = require('lodash/camelCase');
|
|
3
3
|
const runScript = require('@abtnode/util/lib/run-script');
|
|
4
|
+
const { getSecurityNodeOptions } = require('@abtnode/util/lib/security');
|
|
4
5
|
|
|
5
6
|
// eslint-disable-next-line global-require
|
|
6
7
|
const logger = require('@abtnode/logger')(`${require('../../package.json').name}:blocklet:hooks`);
|
|
7
8
|
|
|
8
9
|
const { getSafeEnv } = require('../util');
|
|
10
|
+
const states = require('../states');
|
|
9
11
|
|
|
10
12
|
const runUserHook = async (label, hookName, args) => {
|
|
11
13
|
const {
|
|
@@ -27,10 +29,16 @@ const runUserHook = async (label, hookName, args) => {
|
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
logger.info(`run hook:${hookName}:`, { label, hook });
|
|
32
|
+
|
|
33
|
+
const nodeInfo = await states.node.read();
|
|
30
34
|
// FIXME @linchen timeout 应该动态设置或不设置
|
|
31
35
|
await runScript(hook, [label, hookName].join(':'), {
|
|
32
36
|
cwd: appDir,
|
|
33
|
-
env: {
|
|
37
|
+
env: {
|
|
38
|
+
...getSafeEnv(env),
|
|
39
|
+
BLOCKLET_HOOK_NAME: hookName,
|
|
40
|
+
NODE_OPTIONS: getSecurityNodeOptions({ environmentObj: env, ...args }, nodeInfo.enableFileSystemIsolation),
|
|
41
|
+
},
|
|
34
42
|
silent,
|
|
35
43
|
output: outputFile,
|
|
36
44
|
error: errorFile,
|
|
@@ -5,6 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const flat = require('flat');
|
|
6
6
|
const LRU = require('lru-cache');
|
|
7
7
|
const get = require('lodash/get');
|
|
8
|
+
const uniq = require('lodash/uniq');
|
|
8
9
|
const omit = require('lodash/omit');
|
|
9
10
|
const merge = require('lodash/merge');
|
|
10
11
|
const pick = require('lodash/pick');
|
|
@@ -15,7 +16,7 @@ const { sign } = require('@arcblock/jwt');
|
|
|
15
16
|
const { isInServerlessMode } = require('@abtnode/util/lib/serverless');
|
|
16
17
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
17
18
|
const getBlockletInfo = require('@blocklet/meta/lib/info');
|
|
18
|
-
const
|
|
19
|
+
const { joinURL } = require('ufo');
|
|
19
20
|
const { sendToUser } = require('@blocklet/sdk/lib/util/send-notification');
|
|
20
21
|
|
|
21
22
|
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
|
|
@@ -614,7 +615,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
614
615
|
if (!blocklet.children) {
|
|
615
616
|
return componentDids;
|
|
616
617
|
}
|
|
617
|
-
|
|
618
618
|
const targetDid = !inputComponentDids?.length ? componentDids[0] : inputComponentDids[0];
|
|
619
619
|
|
|
620
620
|
const canStartStatus = {
|
|
@@ -629,26 +629,37 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
629
629
|
filter: (child) => atomic || canStartStatus[child.status],
|
|
630
630
|
});
|
|
631
631
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
componentDids
|
|
632
|
+
logger.info('start required components', {
|
|
633
|
+
did: blocklet.meta.did,
|
|
634
|
+
targetDid,
|
|
635
|
+
componentDids,
|
|
636
|
+
inputComponentDids,
|
|
637
|
+
checkHealthImmediately,
|
|
638
|
+
requiredDidsLayers,
|
|
636
639
|
});
|
|
637
|
-
targetChild.status = BlockletStatus.starting;
|
|
638
|
-
this.emit(BlockletEvents.statusChange, doc);
|
|
639
640
|
|
|
640
|
-
//
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
641
|
+
// 让当前的组件的状态提前变成 starting, 不然用户会很奇怪, 明明点了启动, 但是当前组件没变化.
|
|
642
|
+
if (requiredDidsLayers.length) {
|
|
643
|
+
const targetChild = blocklet.children.find((x) => x.meta.did === targetDid);
|
|
644
|
+
const doc = await states.blocklet.setBlockletStatus(blocklet.meta?.did, BlockletStatus.starting, {
|
|
645
|
+
componentDids: [targetDid],
|
|
646
|
+
});
|
|
647
|
+
targetChild.status = BlockletStatus.starting;
|
|
648
|
+
this.emit(BlockletEvents.statusChange, doc);
|
|
649
|
+
|
|
650
|
+
// start by dependency
|
|
651
|
+
for (const dids of requiredDidsLayers) {
|
|
652
|
+
if (atomic) {
|
|
653
|
+
await this._start({ blocklet, throwOnError, checkHealthImmediately, e2eMode, componentDids: dids }, context);
|
|
654
|
+
} else {
|
|
655
|
+
const tasks = dids.map(
|
|
656
|
+
(x) => () =>
|
|
657
|
+
this._start({ blocklet, throwOnError, checkHealthImmediately, e2eMode, componentDids: [x] }, context)
|
|
658
|
+
);
|
|
659
|
+
await pAll(tasks, { concurrency: 4 }).catch((err) => {
|
|
660
|
+
throw new Error(err.errors.join(', '));
|
|
661
|
+
});
|
|
662
|
+
}
|
|
652
663
|
}
|
|
653
664
|
}
|
|
654
665
|
|
|
@@ -658,12 +669,13 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
658
669
|
}
|
|
659
670
|
|
|
660
671
|
async start(
|
|
661
|
-
{ did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids:
|
|
672
|
+
{ did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids: inputComponentDids, atomic },
|
|
662
673
|
context
|
|
663
674
|
) {
|
|
664
675
|
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
665
|
-
|
|
666
|
-
|
|
676
|
+
let componentDids = uniq(
|
|
677
|
+
inputComponentDids?.length ? inputComponentDids : blocklet.children.map((x) => x.meta.did)
|
|
678
|
+
);
|
|
667
679
|
|
|
668
680
|
// sync component config before at first to ensure resource component config is ready
|
|
669
681
|
const serverSk = (await states.node.read()).sk;
|
|
@@ -2787,7 +2799,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2787
2799
|
* @type {import('@abtnode/client').NodeState}
|
|
2788
2800
|
*/
|
|
2789
2801
|
const node = await states.node.read();
|
|
2790
|
-
referrer =
|
|
2802
|
+
referrer = joinURL(
|
|
2791
2803
|
`https://${encode(node.did)}.${DEFAULT_DID_DOMAIN}`,
|
|
2792
2804
|
node.routing.adminPath,
|
|
2793
2805
|
`/blocklets/${did}/storage`
|
|
@@ -3637,11 +3649,17 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3637
3649
|
}
|
|
3638
3650
|
}
|
|
3639
3651
|
if (runningDids.length) {
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3652
|
+
const initialized = !!blocklet.settings?.initialized;
|
|
3653
|
+
if (initialized) {
|
|
3654
|
+
try {
|
|
3655
|
+
await this.start({ did, componentDids: runningDids }, context);
|
|
3656
|
+
logger.info('started blocklet for upgrading', { did, version, runningDids });
|
|
3657
|
+
} catch (error) {
|
|
3658
|
+
logger.error('failed to start blocklet for upgrading', { did, version, runningDids, error });
|
|
3659
|
+
}
|
|
3660
|
+
} else {
|
|
3661
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids: runningDids });
|
|
3662
|
+
logger.info('set blocklet as stopped since not initialized', { did, version, runningDids });
|
|
3645
3663
|
}
|
|
3646
3664
|
}
|
|
3647
3665
|
if (stoppedDids.length) {
|
|
@@ -4468,7 +4486,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4468
4486
|
async joinFederatedLogin({ appUrl, did }, context) {
|
|
4469
4487
|
const url = new URL(appUrl);
|
|
4470
4488
|
// master service api 的地址
|
|
4471
|
-
url.pathname =
|
|
4489
|
+
url.pathname = joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/api/federated/join');
|
|
4472
4490
|
|
|
4473
4491
|
const blocklet = await this.getBlocklet(did);
|
|
4474
4492
|
const nodeInfo = await states.node.read();
|
|
@@ -4485,7 +4503,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4485
4503
|
aliasDomain: domainAliases.map((x) => x.value),
|
|
4486
4504
|
appLogo:
|
|
4487
4505
|
blocklet.environmentObj.BLOCKLET_APP_LOGO ||
|
|
4488
|
-
normalizePathPrefix(
|
|
4506
|
+
normalizePathPrefix(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, '/blocklet/logo')) ||
|
|
4489
4507
|
'/',
|
|
4490
4508
|
appLogoRect: blocklet.environmentObj.BLOCKLET_APP_LOGO_RECT,
|
|
4491
4509
|
did: permanentWallet.address,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
|
|
3
3
|
const logger = require('@abtnode/logger')('@abtnode/core:install-component-upload');
|
|
4
|
+
const uniq = require('lodash/uniq');
|
|
4
5
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
5
6
|
const { isInProgress, hasStartEngine } = require('@blocklet/meta/lib/util');
|
|
6
7
|
|
|
@@ -119,7 +120,7 @@ const installComponentFromUpload = async ({
|
|
|
119
120
|
// backup rollback data
|
|
120
121
|
await manager._rollbackCache.backup({ did: newBlocklet.meta.did, action, oldBlocklet });
|
|
121
122
|
|
|
122
|
-
const componentDids = [newChild.meta.did, ...newChildren.map((x) => x.meta.did)];
|
|
123
|
+
const componentDids = uniq([newChild.meta.did, ...newChildren.map((x) => x.meta.did)]);
|
|
123
124
|
|
|
124
125
|
await manager._downloadAndInstall({
|
|
125
126
|
blocklet: newBlocklet,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { sign } = require('@arcblock/jwt');
|
|
2
2
|
|
|
3
3
|
const logger = require('@abtnode/logger')('@abtnode/core:install-component-url');
|
|
4
|
-
|
|
4
|
+
const uniq = require('lodash/uniq');
|
|
5
5
|
const { isFreeBlocklet, hasStartEngine } = require('@blocklet/meta/lib/util');
|
|
6
6
|
const { titleSchema, updateMountPointSchema } = require('@blocklet/meta/lib/schema');
|
|
7
7
|
const hasReservedKey = require('@blocklet/meta/lib/has-reserved-key');
|
|
@@ -141,7 +141,7 @@ const installComponentFromUrl = async ({
|
|
|
141
141
|
throw err;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const componentDids = [newChild.meta.did, ...newChildren.map((x) => x.meta.did)];
|
|
144
|
+
const componentDids = uniq([newChild.meta.did, ...newChildren.map((x) => x.meta.did)]);
|
|
145
145
|
|
|
146
146
|
// new blocklet
|
|
147
147
|
const newBlocklet = await states.blocklet.setBlockletStatus(rootDid, BlockletStatus.waiting, { componentDids });
|
package/lib/router/helper.js
CHANGED
|
@@ -10,7 +10,7 @@ const get = require('lodash/get');
|
|
|
10
10
|
const cloneDeep = require('lodash/cloneDeep');
|
|
11
11
|
const groupBy = require('lodash/groupBy');
|
|
12
12
|
const isEqual = require('lodash/isEqual');
|
|
13
|
-
const
|
|
13
|
+
const { joinURL } = require('ufo');
|
|
14
14
|
const {
|
|
15
15
|
replaceSlotToIp,
|
|
16
16
|
findComponentById,
|
|
@@ -288,7 +288,7 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
|
|
|
288
288
|
if (rule.isProtected && rule.to.target === WELLKNOWN_SERVICE_PATH_PREFIX) {
|
|
289
289
|
return rule;
|
|
290
290
|
}
|
|
291
|
-
if (rule.isProtected && rule.to.target ===
|
|
291
|
+
if (rule.isProtected && rule.to.target === joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX)) {
|
|
292
292
|
return rule;
|
|
293
293
|
}
|
|
294
294
|
|
|
@@ -359,7 +359,7 @@ const ensureWellknownRule = async (sites = []) => {
|
|
|
359
359
|
const rule = grouped[groupPathPrefix][0];
|
|
360
360
|
|
|
361
361
|
// Serve blocklet service always
|
|
362
|
-
const servicePathPrefix =
|
|
362
|
+
const servicePathPrefix = joinURL(groupPathPrefix, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
363
363
|
if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
|
|
364
364
|
site.rules.push({
|
|
365
365
|
id: rule.id,
|
|
@@ -380,7 +380,7 @@ const ensureWellknownRule = async (sites = []) => {
|
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
// Cache user avatar from gateway
|
|
383
|
-
const avatarPathPrefix =
|
|
383
|
+
const avatarPathPrefix = joinURL(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
|
|
384
384
|
if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
|
|
385
385
|
site.rules.push({
|
|
386
386
|
id: rule.id,
|
|
@@ -492,7 +492,7 @@ const ensureBlockletWellknownRules = (sites, blocklets) => {
|
|
|
492
492
|
|
|
493
493
|
const tmpMountPoint = mountPoint || blocklet.mountPoint;
|
|
494
494
|
if (tmpMountPoint) {
|
|
495
|
-
pathPrefix =
|
|
495
|
+
pathPrefix = joinURL(tmpMountPoint, pathPrefix);
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
const port = findInterfacePortByName(blocklet, tmpInterface.name);
|
|
@@ -585,7 +585,7 @@ const expandComponentRules = (sites = [], blocklets) => {
|
|
|
585
585
|
newRule.from.pathPrefix = baseRule.from.pathPrefix;
|
|
586
586
|
newRule.to.pageGroup = baseRule.to.pageGroup;
|
|
587
587
|
} else {
|
|
588
|
-
newRule.from.pathPrefix =
|
|
588
|
+
newRule.from.pathPrefix = joinURL(baseRule.from.pathPrefix, x.mountPoint);
|
|
589
589
|
}
|
|
590
590
|
|
|
591
591
|
expandedRules.push(newRule);
|
|
@@ -633,7 +633,7 @@ const ensureBlockletCache = (sites = [], blocklets) => {
|
|
|
633
633
|
const cacheable = get(findWebInterface(component), 'cacheable', []);
|
|
634
634
|
cacheable.forEach((cachePrefix) => {
|
|
635
635
|
const clone = cloneDeep(rule);
|
|
636
|
-
clone.from.pathPrefix =
|
|
636
|
+
clone.from.pathPrefix = joinURL(rule.from.pathPrefix, cachePrefix);
|
|
637
637
|
clone.to.cacheGroup = isServiceFeDevelopment ? '' : 'blockletProxy';
|
|
638
638
|
clone.to.targetPrefix = cachePrefix;
|
|
639
639
|
clone.dynamic = true; // mark as dynamic to avoid redundant generated rules
|
|
@@ -674,7 +674,7 @@ const decompressCertificates = async (source, dest) => {
|
|
|
674
674
|
return dest;
|
|
675
675
|
};
|
|
676
676
|
|
|
677
|
-
const joinCertDownUrl = (baseUrl, name) =>
|
|
677
|
+
const joinCertDownUrl = (baseUrl, name) => joinURL(baseUrl, '/certs', name);
|
|
678
678
|
|
|
679
679
|
const getIpEchoCertDownloadUrl = (baseUrl) => joinCertDownUrl(baseUrl, 'ip-abtnet-io.tar.gz');
|
|
680
680
|
const getDidDomainCertDownloadUrl = (baseUrl) => joinCertDownUrl(baseUrl, 'did-abtnet-io.tar.gz');
|
package/lib/router/manager.js
CHANGED
|
@@ -13,7 +13,7 @@ const toLower = require('lodash/toLower');
|
|
|
13
13
|
const { EventEmitter } = require('events');
|
|
14
14
|
const uuid = require('uuid');
|
|
15
15
|
const isUrl = require('is-url');
|
|
16
|
-
const
|
|
16
|
+
const { joinURL } = require('ufo');
|
|
17
17
|
const cloneDeep = require('lodash/cloneDeep');
|
|
18
18
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
19
19
|
const logger = require('@abtnode/logger')('@abtnode/core:router:manager');
|
|
@@ -704,7 +704,7 @@ class RouterManager extends EventEmitter {
|
|
|
704
704
|
const blockletPrefix = normalizePathPrefix(rawRule.from.pathPrefix);
|
|
705
705
|
|
|
706
706
|
// root component's mountPoint may not be '/'
|
|
707
|
-
const rootComponentPrefix =
|
|
707
|
+
const rootComponentPrefix = joinURL(blockletPrefix, blocklet.mountPoint || '/');
|
|
708
708
|
rawRule.from.pathPrefix = normalizePathPrefix(rootComponentPrefix);
|
|
709
709
|
|
|
710
710
|
const isOccupiable = isGatewayBlocklet(blocklet.meta);
|
package/lib/states/audit-log.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const pick = require('lodash/pick');
|
|
4
4
|
const get = require('lodash/get');
|
|
5
5
|
const uniq = require('lodash/uniq');
|
|
6
|
-
const
|
|
6
|
+
const { joinURL } = require('ufo');
|
|
7
7
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
8
8
|
const { BLOCKLET_SITE_GROUP_SUFFIX, NODE_SERVICES } = require('@abtnode/constant');
|
|
9
9
|
const logger = require('@abtnode/logger')('@abtnode/core:states:audit-log');
|
|
@@ -12,7 +12,7 @@ const BaseState = require('./base');
|
|
|
12
12
|
|
|
13
13
|
const { parse } = require('../util/ua');
|
|
14
14
|
|
|
15
|
-
const getServerInfo = (info) => `[${info.name}](${
|
|
15
|
+
const getServerInfo = (info) => `[${info.name}](${joinURL(info.routing.adminPath, '/settings/about')})`;
|
|
16
16
|
/**
|
|
17
17
|
* @description
|
|
18
18
|
* @param {import('@abtnode/client').BlockletState} blocklet
|
|
@@ -21,7 +21,7 @@ const getServerInfo = (info) => `[${info.name}](${joinUrl(info.routing.adminPath
|
|
|
21
21
|
* }} info
|
|
22
22
|
* @returns {string}
|
|
23
23
|
*/
|
|
24
|
-
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)}](${
|
|
24
|
+
const getBlockletInfo = (blocklet, info) => `[${getDisplayName(blocklet)}](${joinURL(info.routing.adminPath, '/blocklets/', blocklet.meta.did, '/overview')})`; // prettier-ignore
|
|
25
25
|
const componentOrApplication = (componentDids) => (componentDids?.length ? 'component' : 'application');
|
|
26
26
|
const getComponentNames = (blocklet, componentDids, withVersion) =>
|
|
27
27
|
uniq(componentDids || [])
|
|
@@ -82,10 +82,10 @@ const expandUser = async (teamDid, userDid, passportId, info, node) => {
|
|
|
82
82
|
const passport = user.passports.find((x) => x.id === passportId);
|
|
83
83
|
|
|
84
84
|
if (teamDid === info.did) {
|
|
85
|
-
return [`[${user.fullName}](${
|
|
85
|
+
return [`[${user.fullName}](${joinURL(info.routing.adminPath, '/team/members')})`, passport ? passport.name : ''];
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
return [`[${user.fullName}](${
|
|
88
|
+
return [`[${user.fullName}](${joinURL(info.routing.adminPath, '/blocklets/', teamDid, '/members')})`, passport ? passport.name : '']; // prettier-ignore
|
|
89
89
|
};
|
|
90
90
|
|
|
91
91
|
/**
|
package/lib/states/user.js
CHANGED
|
@@ -393,6 +393,7 @@ class User extends ExtendBase {
|
|
|
393
393
|
'email',
|
|
394
394
|
'avatar',
|
|
395
395
|
'role',
|
|
396
|
+
|
|
396
397
|
'locale',
|
|
397
398
|
'extra',
|
|
398
399
|
'lastLoginIp',
|
|
@@ -413,6 +414,8 @@ class User extends ExtendBase {
|
|
|
413
414
|
if (updates.sourceAppPid) {
|
|
414
415
|
delete updates.sourceAppPid;
|
|
415
416
|
}
|
|
417
|
+
// 登录不再更新 locale
|
|
418
|
+
delete updates.locale;
|
|
416
419
|
// update user, connectedAccount, passport
|
|
417
420
|
updates.connectedAccounts = updateConnectedAccount(exist.connectedAccounts, user.connectedAccount);
|
|
418
421
|
updated = await this.updateUser(exist.did, updates);
|
package/lib/util/blocklet.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
1
2
|
/* eslint-disable no-await-in-loop */
|
|
2
3
|
|
|
3
4
|
const fs = require('fs-extra');
|
|
@@ -27,7 +28,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:util:blocklet');
|
|
|
27
28
|
const pm2 = require('@abtnode/util/lib/async-pm2');
|
|
28
29
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
29
30
|
const getPm2ProcessInfo = require('@abtnode/util/lib/get-pm2-process-info');
|
|
30
|
-
const { formatEnv } = require('@abtnode/util/lib/security');
|
|
31
|
+
const { formatEnv, getSecurityNodeOptions } = require('@abtnode/util/lib/security');
|
|
31
32
|
const ensureEndpointHealthy = require('@abtnode/util/lib/ensure-endpoint-healthy');
|
|
32
33
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
33
34
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
@@ -180,7 +181,9 @@ const getComponentDirs = (component, { dataDirs, ensure = false, ancestors = []
|
|
|
180
181
|
};
|
|
181
182
|
|
|
182
183
|
/**
|
|
183
|
-
* @
|
|
184
|
+
* @param component {import('@abtnode/client').ComponentState & { environmentObj: {[key: string]: string } } }
|
|
185
|
+
* @returns {{cwd, script, args, environmentObj, interpreter, interpreterArgs}: { args: []}}
|
|
186
|
+
* @return {*}
|
|
184
187
|
*/
|
|
185
188
|
const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
186
189
|
if (!hasStartEngine(component.meta)) {
|
|
@@ -208,14 +211,14 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
let script = null;
|
|
211
|
-
let interpreter
|
|
212
|
-
let interpreterArgs =
|
|
214
|
+
let interpreter;
|
|
215
|
+
let interpreterArgs = [];
|
|
213
216
|
const environmentObj = {};
|
|
214
217
|
let args = [];
|
|
215
218
|
|
|
216
219
|
if (startFromDevEntry) {
|
|
217
220
|
script = startFromDevEntry;
|
|
218
|
-
} else if (group === 'dapp'
|
|
221
|
+
} else if (group === 'dapp') {
|
|
219
222
|
script = blockletEngineInfo.source || BLOCKLET_ENTRY_FILE;
|
|
220
223
|
args = blockletEngineInfo.args || [];
|
|
221
224
|
} else if (group === 'static') {
|
|
@@ -226,11 +229,18 @@ const getComponentStartEngine = (component, { e2eMode = false } = {}) => {
|
|
|
226
229
|
|
|
227
230
|
if (component.mode !== BLOCKLET_MODES.DEVELOPMENT) {
|
|
228
231
|
const engine = getEngine(blockletEngineInfo.interpreter);
|
|
229
|
-
interpreter = engine.interpreter === 'node' ?
|
|
230
|
-
interpreterArgs = engine.args
|
|
232
|
+
interpreter = engine.interpreter === 'node' ? undefined : engine.interpreter;
|
|
233
|
+
interpreterArgs = interpreterArgs.concat(engine.args ? [engine.args] : []);
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
cwd,
|
|
238
|
+
script,
|
|
239
|
+
args,
|
|
240
|
+
environmentObj,
|
|
241
|
+
interpreter,
|
|
242
|
+
interpreterArgs: interpreterArgs.join(' ').trim(),
|
|
243
|
+
};
|
|
234
244
|
};
|
|
235
245
|
|
|
236
246
|
const getBlockletConfigObj = (blocklet, { excludeSecure } = {}) => {
|
|
@@ -248,7 +258,6 @@ const getBlockletConfigObj = (blocklet, { excludeSecure } = {}) => {
|
|
|
248
258
|
|
|
249
259
|
return obj;
|
|
250
260
|
};
|
|
251
|
-
|
|
252
261
|
/**
|
|
253
262
|
* set 'configs', configObj', 'environmentObj' to blocklet TODO
|
|
254
263
|
* @param {*} blocklet
|
|
@@ -531,6 +540,12 @@ const startBlockletProcess = async (
|
|
|
531
540
|
|
|
532
541
|
await forEachBlocklet(
|
|
533
542
|
blocklet,
|
|
543
|
+
/**
|
|
544
|
+
*
|
|
545
|
+
* @param {import('@abtnode/client').BlockletState} b
|
|
546
|
+
* @param {*} param1
|
|
547
|
+
* @returns
|
|
548
|
+
*/
|
|
534
549
|
async (b, { ancestors }) => {
|
|
535
550
|
if (b.meta.group === BlockletGroup.gateway) {
|
|
536
551
|
return;
|
|
@@ -572,10 +587,10 @@ const startBlockletProcess = async (
|
|
|
572
587
|
await installExternalDependencies({ appDir: env?.BLOCKLET_APP_DIR });
|
|
573
588
|
|
|
574
589
|
// run hook
|
|
575
|
-
await preFlight(b, { env });
|
|
590
|
+
await preFlight(b, { env: { ...env } });
|
|
576
591
|
|
|
577
592
|
// run hook
|
|
578
|
-
await preStart(b, { env });
|
|
593
|
+
await preStart(b, { env: { ...env } });
|
|
579
594
|
|
|
580
595
|
// kill process if port is occupied
|
|
581
596
|
try {
|
|
@@ -588,6 +603,9 @@ const startBlockletProcess = async (
|
|
|
588
603
|
// start process
|
|
589
604
|
const maxMemoryRestart = get(nodeInfo, 'runtimeConfig.blockletMaxMemoryLimit', BLOCKLET_MAX_MEM_LIMIT_IN_MB);
|
|
590
605
|
|
|
606
|
+
/**
|
|
607
|
+
* @type {pm2.StartOptions}
|
|
608
|
+
*/
|
|
591
609
|
const options = {
|
|
592
610
|
namespace: 'blocklets',
|
|
593
611
|
name: processId,
|
|
@@ -606,6 +624,7 @@ const startBlockletProcess = async (
|
|
|
606
624
|
...env,
|
|
607
625
|
NODE_ENV: 'production',
|
|
608
626
|
BLOCKLET_START_AT: now,
|
|
627
|
+
NODE_OPTIONS: getSecurityNodeOptions(b, nodeInfo.enableFileSystemIsolation),
|
|
609
628
|
},
|
|
610
629
|
script,
|
|
611
630
|
args,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { joinURL } = require('ufo');
|
|
2
2
|
const axios = require('@abtnode/util/lib/axios');
|
|
3
3
|
const { DEFAULT_IP_DOMAIN, WELLKNOWN_SERVER_ADMIN_PATH } = require('@abtnode/constant');
|
|
4
4
|
const logger = require('@abtnode/logger')('@abtnode/core:util:get-accessible-external-node-ip');
|
|
@@ -15,7 +15,7 @@ const timeout = process.env.NODE_ENV === 'test' ? 500 : 5000;
|
|
|
15
15
|
const checkConnected = async ({ ip, info }) => {
|
|
16
16
|
const { adminPath = WELLKNOWN_SERVER_ADMIN_PATH } = info.routing || {};
|
|
17
17
|
const origin = `https://${getNodeDomain(ip)}`;
|
|
18
|
-
const endpoint =
|
|
18
|
+
const endpoint = joinURL(origin, adminPath);
|
|
19
19
|
await axios.get(endpoint, { timeout });
|
|
20
20
|
};
|
|
21
21
|
|
package/lib/util/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const camelCase = require('lodash/camelCase');
|
|
|
8
8
|
const get = require('lodash/get');
|
|
9
9
|
const pickBy = require('lodash/pickBy');
|
|
10
10
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
11
|
-
const
|
|
11
|
+
const { joinURL } = require('ufo');
|
|
12
12
|
const { Certificate } = require('@fidm/x509');
|
|
13
13
|
const getPortLib = require('get-port');
|
|
14
14
|
const v8 = require('v8');
|
|
@@ -362,7 +362,7 @@ const getStateCrons = (states) => [
|
|
|
362
362
|
|
|
363
363
|
const getDelegateState = async (chainHost, address) => {
|
|
364
364
|
const result = await axios.post(
|
|
365
|
-
|
|
365
|
+
joinURL(chainHost, '/gql/'),
|
|
366
366
|
JSON.stringify({
|
|
367
367
|
query: `{
|
|
368
368
|
getDelegateState(address: "${address}") {
|
|
@@ -388,7 +388,7 @@ const getDelegateState = async (chainHost, address) => {
|
|
|
388
388
|
};
|
|
389
389
|
|
|
390
390
|
const getNFTState = async (chainHost, nftId) => {
|
|
391
|
-
const url =
|
|
391
|
+
const url = joinURL(new URL(chainHost).origin, '/api/gql/');
|
|
392
392
|
|
|
393
393
|
const result = await axios.post(
|
|
394
394
|
url,
|
package/lib/util/launcher.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
|
-
const
|
|
3
|
+
const { joinURL } = require('ufo');
|
|
4
4
|
const dayjs = require('@abtnode/util/lib/dayjs');
|
|
5
5
|
const pick = require('lodash/pick');
|
|
6
6
|
const uniq = require('lodash/uniq');
|
|
@@ -206,7 +206,7 @@ const setupAppOwner = async (node, sessionId) => {
|
|
|
206
206
|
throw new Error(`Owner user not found from launcher: ${launcherUrl}`);
|
|
207
207
|
}
|
|
208
208
|
appOwnerProfile = pick(user, ['fullName', 'email', 'avatar']);
|
|
209
|
-
const avatarBase64 = await getAvatarByUrl(
|
|
209
|
+
const avatarBase64 = await getAvatarByUrl(joinURL(launcherUrl, user.avatar));
|
|
210
210
|
appOwnerProfile.avatar = await extractUserAvatar(avatarBase64, { dataDir });
|
|
211
211
|
logger.info('Create owner from launcher for blocklet', { appDid, ownerDid, ownerPk, sessionId, appOwnerProfile });
|
|
212
212
|
} else {
|
|
@@ -242,7 +242,7 @@ const setupAppOwner = async (node, sessionId) => {
|
|
|
242
242
|
endpoint: appUrl,
|
|
243
243
|
}),
|
|
244
244
|
endpoint: getPassportStatusEndpoint({
|
|
245
|
-
baseUrl:
|
|
245
|
+
baseUrl: joinURL(appUrl, WELLKNOWN_SERVICE_PATH_PREFIX),
|
|
246
246
|
userDid: ownerDid,
|
|
247
247
|
teamDid: appDid,
|
|
248
248
|
}),
|
package/lib/util/spaces.js
CHANGED
|
@@ -3,7 +3,7 @@ const { default: axios } = require('axios');
|
|
|
3
3
|
const isUrl = require('is-url');
|
|
4
4
|
const isArray = require('lodash/isArray');
|
|
5
5
|
const isEmpty = require('lodash/isEmpty');
|
|
6
|
-
const
|
|
6
|
+
const { joinURL, withQuery } = require('ufo');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @description
|
|
@@ -35,7 +35,9 @@ function getBackupFilesUrlFromEndpoint(endpoint) {
|
|
|
35
35
|
const spaceDid = strArray.at(-4);
|
|
36
36
|
const appDid = strArray.at(-2);
|
|
37
37
|
|
|
38
|
-
return
|
|
38
|
+
return withQuery(joinURL(prefix, 'space', spaceDid, 'apps', appDid, 'explorer'), {
|
|
39
|
+
key: `/apps/${appDid}/.did-objects/${appDid}/`,
|
|
40
|
+
});
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
function getDIDSpacesUrlFromEndpoint(endpoint) {
|
package/lib/util/store.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { joinURL, withQuery } = require('ufo');
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const isBase64 = require('is-base64');
|
|
4
4
|
|
|
@@ -48,7 +48,9 @@ const fixAndVerifyMetaFromStore = (meta) => {
|
|
|
48
48
|
|
|
49
49
|
const getStoreMeta = async (registry) => {
|
|
50
50
|
try {
|
|
51
|
-
const url =
|
|
51
|
+
const url = withQuery(joinURL(registry, BLOCKLET_STORE_META_PATH), {
|
|
52
|
+
__t__: Date.now(),
|
|
53
|
+
});
|
|
52
54
|
const { data } = await request.get(url);
|
|
53
55
|
|
|
54
56
|
if (!data) {
|
|
@@ -69,7 +71,7 @@ const getStoreMeta = async (registry) => {
|
|
|
69
71
|
} else if (isBase64(logoUrl, { allowMime: true })) {
|
|
70
72
|
result.logoUrl = logoUrl;
|
|
71
73
|
} else {
|
|
72
|
-
result.logoUrl =
|
|
74
|
+
result.logoUrl = joinURL(registry, logoUrl);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
|
|
@@ -124,14 +126,14 @@ const resolveTarballURL = ({ did, tarball = '', storeUrl = '' }) => {
|
|
|
124
126
|
return '';
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
return
|
|
129
|
+
return joinURL(storeUrl, 'api', 'blocklets', did, tarball);
|
|
128
130
|
};
|
|
129
131
|
|
|
130
132
|
const getBlockletMetaUrl = ({ did, storeUrl }) =>
|
|
131
|
-
|
|
133
|
+
joinURL(storeUrl, BLOCKLET_STORE_API_PREFIX, `/blocklets/${did}/blocklet.json`);
|
|
132
134
|
|
|
133
135
|
const getBlockletMeta = async ({ did, storeUrl }) => {
|
|
134
|
-
const url =
|
|
136
|
+
const url = joinURL(storeUrl, BLOCKLET_STORE_API_PREFIX, `/blocklets/${did}/blocklet.json?__t__=${Date.now()}`);
|
|
135
137
|
|
|
136
138
|
const { data } = await request.get(url);
|
|
137
139
|
try {
|
package/lib/validators/node.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.28-beta-
|
|
6
|
+
"version": "1.16.28-beta-641c9f13",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.28-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.28-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.28-beta-
|
|
25
|
-
"@abtnode/constant": "1.16.28-beta-
|
|
26
|
-
"@abtnode/cron": "1.16.28-beta-
|
|
27
|
-
"@abtnode/logger": "1.16.28-beta-
|
|
28
|
-
"@abtnode/models": "1.16.28-beta-
|
|
29
|
-
"@abtnode/queue": "1.16.28-beta-
|
|
30
|
-
"@abtnode/rbac": "1.16.28-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.16.28-beta-
|
|
32
|
-
"@abtnode/static-server": "1.16.28-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.16.28-beta-
|
|
34
|
-
"@abtnode/util": "1.16.28-beta-
|
|
22
|
+
"@abtnode/analytics": "1.16.28-beta-641c9f13",
|
|
23
|
+
"@abtnode/auth": "1.16.28-beta-641c9f13",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.28-beta-641c9f13",
|
|
25
|
+
"@abtnode/constant": "1.16.28-beta-641c9f13",
|
|
26
|
+
"@abtnode/cron": "1.16.28-beta-641c9f13",
|
|
27
|
+
"@abtnode/logger": "1.16.28-beta-641c9f13",
|
|
28
|
+
"@abtnode/models": "1.16.28-beta-641c9f13",
|
|
29
|
+
"@abtnode/queue": "1.16.28-beta-641c9f13",
|
|
30
|
+
"@abtnode/rbac": "1.16.28-beta-641c9f13",
|
|
31
|
+
"@abtnode/router-provider": "1.16.28-beta-641c9f13",
|
|
32
|
+
"@abtnode/static-server": "1.16.28-beta-641c9f13",
|
|
33
|
+
"@abtnode/timemachine": "1.16.28-beta-641c9f13",
|
|
34
|
+
"@abtnode/util": "1.16.28-beta-641c9f13",
|
|
35
35
|
"@arcblock/did": "1.18.123",
|
|
36
36
|
"@arcblock/did-auth": "1.18.123",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.123",
|
|
@@ -42,20 +42,20 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.123",
|
|
44
44
|
"@arcblock/vc": "1.18.123",
|
|
45
|
-
"@blocklet/constant": "1.16.28-beta-
|
|
46
|
-
"@blocklet/env": "1.16.28-beta-
|
|
47
|
-
"@blocklet/meta": "1.16.28-beta-
|
|
48
|
-
"@blocklet/resolver": "1.16.28-beta-
|
|
49
|
-
"@blocklet/sdk": "1.16.28-beta-
|
|
50
|
-
"@blocklet/store": "1.16.28-beta-
|
|
51
|
-
"@did-space/client": "^0.
|
|
45
|
+
"@blocklet/constant": "1.16.28-beta-641c9f13",
|
|
46
|
+
"@blocklet/env": "1.16.28-beta-641c9f13",
|
|
47
|
+
"@blocklet/meta": "1.16.28-beta-641c9f13",
|
|
48
|
+
"@blocklet/resolver": "1.16.28-beta-641c9f13",
|
|
49
|
+
"@blocklet/sdk": "1.16.28-beta-641c9f13",
|
|
50
|
+
"@blocklet/store": "1.16.28-beta-641c9f13",
|
|
51
|
+
"@did-space/client": "^0.5.1",
|
|
52
52
|
"@fidm/x509": "^1.2.1",
|
|
53
53
|
"@ocap/mcrypto": "1.18.123",
|
|
54
54
|
"@ocap/util": "1.18.123",
|
|
55
55
|
"@ocap/wallet": "1.18.123",
|
|
56
56
|
"@slack/webhook": "^5.0.4",
|
|
57
57
|
"archiver": "^7.0.1",
|
|
58
|
-
"axios": "^
|
|
58
|
+
"axios": "^1.7.2",
|
|
59
59
|
"axon": "^2.0.3",
|
|
60
60
|
"chalk": "^4.1.2",
|
|
61
61
|
"cross-spawn": "^7.0.3",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"tar": "^6.1.11",
|
|
93
93
|
"transliteration": "^2.3.5",
|
|
94
94
|
"ua-parser-js": "^1.0.2",
|
|
95
|
-
"
|
|
95
|
+
"ufo": "^1.5.3",
|
|
96
96
|
"uuid": "^9.0.1",
|
|
97
97
|
"valid-url": "^1.0.9",
|
|
98
98
|
"xbytes": "^1.8.0"
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"jest": "^29.7.0",
|
|
104
104
|
"unzipper": "^0.10.11"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "eb1fa63e4ed26fe5ba230845a318faa29408138b"
|
|
107
107
|
}
|