@abtnode/core 1.6.11 → 1.6.15
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/blocklet/manager/disk.js +13 -2
- package/lib/index.js +0 -10
- package/lib/router/helper.js +65 -34
- package/lib/router/manager.js +24 -6
- package/lib/states/node.js +1 -0
- package/lib/util/blocklet.js +5 -1
- package/lib/util/router.js +13 -0
- package/lib/validators/permission.js +16 -1
- package/package.json +20 -20
|
@@ -2332,7 +2332,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2332
2332
|
async _rollback(action, did, oldBlocklet) {
|
|
2333
2333
|
if (action === 'install') {
|
|
2334
2334
|
// remove blocklet
|
|
2335
|
-
return this._deleteBlocklet({ did, keepData:
|
|
2335
|
+
return this._deleteBlocklet({ did, keepData: true });
|
|
2336
2336
|
}
|
|
2337
2337
|
|
|
2338
2338
|
if (['upgrade', 'downgrade'].includes(action)) {
|
|
@@ -2374,7 +2374,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2374
2374
|
const result = await states.blocklet.deleteBlocklet(did);
|
|
2375
2375
|
logger.info('blocklet removed successfully', { did });
|
|
2376
2376
|
|
|
2377
|
-
|
|
2377
|
+
let keepRouting = true;
|
|
2378
|
+
if (keepData === false || keepConfigs === false) {
|
|
2379
|
+
keepRouting = false;
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
this.emit(BlockletEvents.removed, {
|
|
2383
|
+
blocklet: result,
|
|
2384
|
+
context: {
|
|
2385
|
+
...context,
|
|
2386
|
+
keepRouting,
|
|
2387
|
+
},
|
|
2388
|
+
});
|
|
2378
2389
|
return blocklet;
|
|
2379
2390
|
}
|
|
2380
2391
|
|
package/lib/index.js
CHANGED
|
@@ -400,16 +400,6 @@ function ABTNode(options) {
|
|
|
400
400
|
} else {
|
|
401
401
|
// We should only respond to pm2 events when node is alive
|
|
402
402
|
events.on('node.started', async () => {
|
|
403
|
-
const info = await states.node.read();
|
|
404
|
-
certManager
|
|
405
|
-
.issue({ domain: `${info.did.toLowerCase()}.${info.didDomain}` })
|
|
406
|
-
.then(() => {
|
|
407
|
-
logger.info('add issue daemon certificate job');
|
|
408
|
-
})
|
|
409
|
-
.catch((error) => {
|
|
410
|
-
logger.error('issue daemon certificate job failed', { error });
|
|
411
|
-
});
|
|
412
|
-
|
|
413
403
|
pm2Events.resume();
|
|
414
404
|
initCron();
|
|
415
405
|
});
|
package/lib/router/helper.js
CHANGED
|
@@ -5,6 +5,7 @@ const path = require('path');
|
|
|
5
5
|
const tar = require('tar');
|
|
6
6
|
const get = require('lodash/get');
|
|
7
7
|
const cloneDeep = require('lodash/cloneDeep');
|
|
8
|
+
const isEqual = require('lodash/isEqual');
|
|
8
9
|
const joinUrl = require('url-join');
|
|
9
10
|
const { getProvider } = require('@abtnode/router-provider');
|
|
10
11
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
@@ -28,6 +29,7 @@ const {
|
|
|
28
29
|
SLOT_FOR_IP_DNS_SITE,
|
|
29
30
|
BLOCKLET_SITE_GROUP_SUFFIX,
|
|
30
31
|
WELLKNOWN_ACME_CHALLENGE_PREFIX,
|
|
32
|
+
WELLKNOWN_DID_RESOLVER_PREFIX,
|
|
31
33
|
} = require('@abtnode/constant');
|
|
32
34
|
const {
|
|
33
35
|
BLOCKLET_DYNAMIC_PATH_PREFIX,
|
|
@@ -53,6 +55,7 @@ const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-acces
|
|
|
53
55
|
|
|
54
56
|
const Router = require('./index');
|
|
55
57
|
const states = require('../states');
|
|
58
|
+
const { getBlockletDomainGroupName, getDidFromDomainGroupName } = require('../util/router');
|
|
56
59
|
|
|
57
60
|
/**
|
|
58
61
|
* replace 888-888-888-888 with accessible ip for domain
|
|
@@ -351,6 +354,18 @@ const ensureCorsForWebWallet = async (sites) => {
|
|
|
351
354
|
return sites;
|
|
352
355
|
};
|
|
353
356
|
|
|
357
|
+
const filterSitesForRemovedBlocklets = async (sites = []) => {
|
|
358
|
+
const blocklets = await states.blocklet.getBlocklets();
|
|
359
|
+
return sites.filter((site) => {
|
|
360
|
+
if (!site.domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX)) {
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const did = getDidFromDomainGroupName(site.domain);
|
|
365
|
+
return blocklets.some((x) => x.meta.did === did);
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
|
|
354
369
|
const ensureLatestInfo = async (sites = [], { withDefaultCors = true } = {}) => {
|
|
355
370
|
let result = await ensureLatestNodeInfo(sites, { withDefaultCors });
|
|
356
371
|
result = await ensureWellknownRule(result);
|
|
@@ -499,6 +514,30 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
499
514
|
return { status: 'downloaded' };
|
|
500
515
|
};
|
|
501
516
|
|
|
517
|
+
const upsertSiteRule = async ({ site, rule }, context) => {
|
|
518
|
+
const findExistingRule = (prefix) => site.rules.find((r) => r.from.pathPrefix === normalizePathPrefix(prefix));
|
|
519
|
+
|
|
520
|
+
const newSiteRule = {
|
|
521
|
+
id: site.id,
|
|
522
|
+
rule,
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
const existingRule = findExistingRule(get(rule, 'from.pathPrefix'));
|
|
526
|
+
if (!existingRule) {
|
|
527
|
+
await routerManager.addRoutingRule(newSiteRule, context);
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (!isEqual(existingRule.to, rule.to)) {
|
|
532
|
+
newSiteRule.rule.id = existingRule.id;
|
|
533
|
+
newSiteRule.skipProtectedRuleChecking = true;
|
|
534
|
+
await routerManager.updateRoutingRule(newSiteRule, context);
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return false;
|
|
539
|
+
};
|
|
540
|
+
|
|
502
541
|
const addWellknownSite = async (sites, context) => {
|
|
503
542
|
const site = (sites || []).find((x) => x.name === NAME_FOR_WELLKNOWN_SITE);
|
|
504
543
|
|
|
@@ -511,42 +550,35 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
511
550
|
};
|
|
512
551
|
|
|
513
552
|
const didResolverWellknownRule = {
|
|
514
|
-
|
|
553
|
+
isProtected: true,
|
|
554
|
+
from: { pathPrefix: WELLKNOWN_DID_RESOLVER_PREFIX },
|
|
515
555
|
to: proxyTarget,
|
|
516
556
|
};
|
|
517
557
|
|
|
518
558
|
const acmeChallengeWellknownRule = {
|
|
559
|
+
isProtected: true,
|
|
519
560
|
from: { pathPrefix: WELLKNOWN_ACME_CHALLENGE_PREFIX },
|
|
520
561
|
to: proxyTarget,
|
|
521
562
|
};
|
|
522
563
|
|
|
523
564
|
if (site) {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
rule: didResolverWellknownRule,
|
|
532
|
-
},
|
|
533
|
-
context
|
|
534
|
-
);
|
|
535
|
-
changed = true;
|
|
536
|
-
}
|
|
565
|
+
const didResolverRuleUpdateRes = await upsertSiteRule(
|
|
566
|
+
{
|
|
567
|
+
site,
|
|
568
|
+
rule: didResolverWellknownRule,
|
|
569
|
+
},
|
|
570
|
+
context
|
|
571
|
+
);
|
|
537
572
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
);
|
|
546
|
-
changed = true;
|
|
547
|
-
}
|
|
573
|
+
const acmeRuleUpdateRes = await upsertSiteRule(
|
|
574
|
+
{
|
|
575
|
+
site,
|
|
576
|
+
rule: acmeChallengeWellknownRule,
|
|
577
|
+
},
|
|
578
|
+
context
|
|
579
|
+
);
|
|
548
580
|
|
|
549
|
-
return
|
|
581
|
+
return didResolverRuleUpdateRes || acmeRuleUpdateRes;
|
|
550
582
|
}
|
|
551
583
|
|
|
552
584
|
await routerManager.addRoutingSite(
|
|
@@ -694,7 +726,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
694
726
|
return `/${str}`.replace(/^\/+/, '/');
|
|
695
727
|
};
|
|
696
728
|
|
|
697
|
-
const domainGroup =
|
|
729
|
+
const domainGroup = getBlockletDomainGroupName(blocklet.meta.did);
|
|
698
730
|
|
|
699
731
|
const pathPrefix = getPrefix(webInterface.prefix);
|
|
700
732
|
const rule = {
|
|
@@ -736,13 +768,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
736
768
|
context
|
|
737
769
|
);
|
|
738
770
|
logger.info('add routing site', { site: domainGroup });
|
|
739
|
-
if (
|
|
740
|
-
process.env.NODE_ENV !== 'development' &&
|
|
741
|
-
process.env.NODE_ENV !== 'test' &&
|
|
742
|
-
blocklet.mode !== 'development'
|
|
743
|
-
) {
|
|
744
|
-
await certManager.issue({ domain: didDomain });
|
|
745
|
-
}
|
|
746
771
|
|
|
747
772
|
return true;
|
|
748
773
|
}
|
|
@@ -1061,7 +1086,10 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1061
1086
|
const nodeInfo = await nodeState.read();
|
|
1062
1087
|
|
|
1063
1088
|
const ruleChanged = await routerManager.deleteRoutingRulesItemByDid({ did: blocklet.meta.did }, context);
|
|
1064
|
-
|
|
1089
|
+
let siteChanged;
|
|
1090
|
+
if (!context.keepRouting) {
|
|
1091
|
+
siteChanged = await _removeBlockletSites(blocklet, nodeInfo, context);
|
|
1092
|
+
}
|
|
1065
1093
|
|
|
1066
1094
|
return ruleChanged || siteChanged;
|
|
1067
1095
|
};
|
|
@@ -1121,6 +1149,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1121
1149
|
try {
|
|
1122
1150
|
const info = await nodeState.read();
|
|
1123
1151
|
let { sites } = await readRoutingSites();
|
|
1152
|
+
sites = await filterSitesForRemovedBlocklets(sites);
|
|
1124
1153
|
sites = await ensureLatestInfo(sites);
|
|
1125
1154
|
sites = await ensureAuthService(sites, blockletManager);
|
|
1126
1155
|
sites = await ensureServiceRule(sites);
|
|
@@ -1354,6 +1383,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1354
1383
|
getCertificates,
|
|
1355
1384
|
checkDomain,
|
|
1356
1385
|
ensureDashboardCertificate,
|
|
1386
|
+
addWellknownSite,
|
|
1387
|
+
upsertSiteRule,
|
|
1357
1388
|
|
|
1358
1389
|
getRoutingCrons: () => [
|
|
1359
1390
|
{
|
package/lib/router/manager.js
CHANGED
|
@@ -186,19 +186,37 @@ class RouterManager extends EventEmitter {
|
|
|
186
186
|
return dbSite;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
async addDomainAlias({ id, domainAlias }, context = {}) {
|
|
189
|
+
async addDomainAlias({ id, domainAlias, force }, context = {}) {
|
|
190
190
|
await validateAddDomainAlias(domainAlias, context);
|
|
191
191
|
const dbSite = await states.site.findOne({ _id: id });
|
|
192
192
|
if (!dbSite) {
|
|
193
193
|
throw new Error(`site ${id} does not exist`);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
// check domain exists in site domain
|
|
197
|
+
const mainDomainSiteCount = await states.site.count({
|
|
198
|
+
domain: domainAlias,
|
|
198
199
|
});
|
|
199
200
|
|
|
200
|
-
if (
|
|
201
|
-
|
|
201
|
+
if (mainDomainSiteCount > 0) {
|
|
202
|
+
if (!force) {
|
|
203
|
+
throw new Error(`${domainAlias} already exists`);
|
|
204
|
+
} else {
|
|
205
|
+
throw new Error(`${domainAlias} cannot be forced-added`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// check domain exists in site alias domain
|
|
210
|
+
const aliasDomainSite = await states.site.findOne({
|
|
211
|
+
$or: [{ domainAliases: domainAlias }, { 'domainAliases.value': domainAlias }],
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (aliasDomainSite) {
|
|
215
|
+
if (!force) {
|
|
216
|
+
throw new Error(`${domainAlias} already exists`);
|
|
217
|
+
} else {
|
|
218
|
+
await this.deleteDomainAlias({ id: aliasDomainSite.id, domainAlias });
|
|
219
|
+
}
|
|
202
220
|
}
|
|
203
221
|
|
|
204
222
|
const updateResult = await states.site.update(
|
|
@@ -302,7 +320,7 @@ class RouterManager extends EventEmitter {
|
|
|
302
320
|
|
|
303
321
|
// update rules
|
|
304
322
|
const newRules = [
|
|
305
|
-
...dbSite.rules.filter((x) => x.groupId !== rule.id || x.id !== rule.id), // 有些路由没有 rule.groupId
|
|
323
|
+
...dbSite.rules.filter((x) => (x.groupId && x.groupId !== rule.id) || x.id !== rule.id), // 有些路由没有 rule.groupId
|
|
306
324
|
...(await this.getRules(rule)),
|
|
307
325
|
];
|
|
308
326
|
|
package/lib/states/node.js
CHANGED
package/lib/util/blocklet.js
CHANGED
|
@@ -74,7 +74,6 @@ const PRIVATE_NODE_ENVS = [
|
|
|
74
74
|
// 'NEDB_MULTI_PORT', // FIXME: 排查 abtnode 对外提供的 SDK(比如 @abtnode/queue), SDK 中不要自动使用 NEDB_MULTI_PORT 环境变量
|
|
75
75
|
'ABT_NODE_UPDATER_PORT',
|
|
76
76
|
'ABT_NODE_SESSION_TTL',
|
|
77
|
-
'ABT_NODE_MODE',
|
|
78
77
|
'ABT_NODE_ROUTER_PROVIDER',
|
|
79
78
|
'ABT_NODE_DATA_DIR',
|
|
80
79
|
'ABT_NODE_TOKEN_SECRET',
|
|
@@ -85,6 +84,11 @@ const PRIVATE_NODE_ENVS = [
|
|
|
85
84
|
'ABT_NODE_BASE_URL',
|
|
86
85
|
'ABT_NODE_LOG_LEVEL',
|
|
87
86
|
'ABT_NODE_LOG_DIR',
|
|
87
|
+
// in /core/cli/bin/blocklet.js
|
|
88
|
+
'CLI_MODE',
|
|
89
|
+
'ABT_NODE_HOME',
|
|
90
|
+
'PM2_HOME',
|
|
91
|
+
'ABT_NODE_CONFIG_FILE',
|
|
88
92
|
];
|
|
89
93
|
|
|
90
94
|
/**
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { BLOCKLET_SITE_GROUP_SUFFIX } = require('@abtnode/constant');
|
|
2
|
+
|
|
3
|
+
const getBlockletDomainGroupName = (did) => `${did}${BLOCKLET_SITE_GROUP_SUFFIX}`;
|
|
4
|
+
|
|
5
|
+
const getDidFromDomainGroupName = (name) => {
|
|
6
|
+
const did = name.replace(BLOCKLET_SITE_GROUP_SUFFIX, '');
|
|
7
|
+
return did;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
getBlockletDomainGroupName,
|
|
12
|
+
getDidFromDomainGroupName,
|
|
13
|
+
};
|
|
@@ -2,7 +2,22 @@
|
|
|
2
2
|
const JOI = require('joi');
|
|
3
3
|
const { getMultipleLangParams } = require('./util');
|
|
4
4
|
|
|
5
|
-
const nameSchema = JOI.string()
|
|
5
|
+
const nameSchema = JOI.string()
|
|
6
|
+
.trim()
|
|
7
|
+
.max(64)
|
|
8
|
+
.custom((name) => {
|
|
9
|
+
const arr = name.split('_');
|
|
10
|
+
const formatTip = 'The format of permission name should be "{action}_{resource}", e.g. query_data';
|
|
11
|
+
if (arr.length > 2) {
|
|
12
|
+
throw new Error(`Too much "_". ${formatTip}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (arr.length < 2) {
|
|
16
|
+
throw new Error(formatTip);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return name;
|
|
20
|
+
});
|
|
6
21
|
const descriptionSchema = JOI.string().trim().max(600);
|
|
7
22
|
|
|
8
23
|
const createPermissionSchema = JOI.object({
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.6.
|
|
6
|
+
"version": "1.6.15",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,28 +19,28 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.6.
|
|
23
|
-
"@abtnode/constant": "1.6.
|
|
24
|
-
"@abtnode/cron": "1.6.
|
|
25
|
-
"@abtnode/db": "1.6.
|
|
26
|
-
"@abtnode/logger": "1.6.
|
|
27
|
-
"@abtnode/queue": "1.6.
|
|
28
|
-
"@abtnode/rbac": "1.6.
|
|
29
|
-
"@abtnode/router-provider": "1.6.
|
|
30
|
-
"@abtnode/static-server": "1.6.
|
|
31
|
-
"@abtnode/timemachine": "1.6.
|
|
32
|
-
"@abtnode/util": "1.6.
|
|
33
|
-
"@arcblock/did": "^1.13.
|
|
34
|
-
"@arcblock/event-hub": "1.13.
|
|
22
|
+
"@abtnode/certificate-manager": "1.6.15",
|
|
23
|
+
"@abtnode/constant": "1.6.15",
|
|
24
|
+
"@abtnode/cron": "1.6.15",
|
|
25
|
+
"@abtnode/db": "1.6.15",
|
|
26
|
+
"@abtnode/logger": "1.6.15",
|
|
27
|
+
"@abtnode/queue": "1.6.15",
|
|
28
|
+
"@abtnode/rbac": "1.6.15",
|
|
29
|
+
"@abtnode/router-provider": "1.6.15",
|
|
30
|
+
"@abtnode/static-server": "1.6.15",
|
|
31
|
+
"@abtnode/timemachine": "1.6.15",
|
|
32
|
+
"@abtnode/util": "1.6.15",
|
|
33
|
+
"@arcblock/did": "^1.13.84",
|
|
34
|
+
"@arcblock/event-hub": "1.13.84",
|
|
35
35
|
"@arcblock/pm2-events": "^0.0.5",
|
|
36
|
-
"@arcblock/vc": "^1.13.
|
|
37
|
-
"@blocklet/meta": "1.6.
|
|
36
|
+
"@arcblock/vc": "^1.13.84",
|
|
37
|
+
"@blocklet/meta": "1.6.15",
|
|
38
38
|
"@fidm/x509": "^1.2.1",
|
|
39
39
|
"@nedb/core": "^1.2.2",
|
|
40
40
|
"@nedb/multi": "^1.2.2",
|
|
41
|
-
"@ocap/mcrypto": "^1.13.
|
|
42
|
-
"@ocap/util": "^1.13.
|
|
43
|
-
"@ocap/wallet": "^1.13.
|
|
41
|
+
"@ocap/mcrypto": "^1.13.84",
|
|
42
|
+
"@ocap/util": "^1.13.84",
|
|
43
|
+
"@ocap/wallet": "^1.13.84",
|
|
44
44
|
"@slack/webhook": "^5.0.3",
|
|
45
45
|
"axios": "^0.21.4",
|
|
46
46
|
"axon": "^2.0.3",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"express": "^4.17.1",
|
|
76
76
|
"jest": "^27.4.5"
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "1b7b07da04387b1daa838b251a9388355009142d"
|
|
79
79
|
}
|