@abtnode/core 1.16.3 → 1.16.4-beta-8682e092
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 -2
- package/lib/blocklet/manager/disk.js +6 -9
- package/lib/blocklet/manager/helper/install-application-from-general.js +2 -1
- package/lib/blocklet/manager/helper/install-component-from-upload.js +1 -1
- package/lib/blocklet/manager/helper/migrate-application-to-struct-v2.js +8 -4
- package/lib/event.js +3 -4
- package/lib/router/helper.js +47 -33
- package/lib/router/index.js +25 -27
- package/lib/router/manager.js +20 -4
- package/lib/states/blocklet.js +35 -15
- package/lib/states/user.js +37 -8
- package/lib/util/blocklet.js +2 -8
- package/lib/util/index.js +1 -18
- package/lib/validators/router.js +2 -2
- package/package.json +27 -27
package/lib/api/team.js
CHANGED
|
@@ -12,7 +12,6 @@ const {
|
|
|
12
12
|
WELLKNOWN_SERVICE_PATH_PREFIX,
|
|
13
13
|
MAX_USER_PAGE_SIZE,
|
|
14
14
|
STORE_DETAIL_PAGE_PATH_PREFIX,
|
|
15
|
-
USER_TYPE,
|
|
16
15
|
} = require('@abtnode/constant');
|
|
17
16
|
const { isValid: isValidDid } = require('@arcblock/did');
|
|
18
17
|
const { BlockletEvents } = require('@blocklet/constant');
|
|
@@ -634,7 +633,9 @@ class TeamAPI extends EventEmitter {
|
|
|
634
633
|
const state = await this.getSessionState(teamDid);
|
|
635
634
|
|
|
636
635
|
const currentUser = await this.getUser({ teamDid, user: { did: ownerDid } });
|
|
637
|
-
|
|
636
|
+
const isRawWalletAccount =
|
|
637
|
+
!currentUser?.extraConfigs?.sourceProvider || currentUser?.extraConfigs?.sourceProvider === 'wallet';
|
|
638
|
+
if (!isRawWalletAccount) {
|
|
638
639
|
const userDid = currentUser.did;
|
|
639
640
|
const blocklet = await getBlocklet({ did: teamDid, states: this.states, dataDirs: this.dataDirs });
|
|
640
641
|
const nodeInfo = await this.node.read();
|
|
@@ -34,6 +34,8 @@ const {
|
|
|
34
34
|
getComponentId,
|
|
35
35
|
isPreferenceKey,
|
|
36
36
|
getRolesFromAuthConfig,
|
|
37
|
+
isInProgress,
|
|
38
|
+
isBeforeInstalled,
|
|
37
39
|
} = require('@blocklet/meta/lib/util');
|
|
38
40
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
39
41
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
@@ -124,14 +126,7 @@ const BlockletDownloader = require('../downloader/blocklet-downloader');
|
|
|
124
126
|
const RollbackCache = require('./helper/rollback-cache');
|
|
125
127
|
const { migrateApplicationToStructV2 } = require('./helper/migrate-application-to-struct-v2');
|
|
126
128
|
|
|
127
|
-
const {
|
|
128
|
-
isInProgress,
|
|
129
|
-
isBeforeInstalled,
|
|
130
|
-
formatEnvironments,
|
|
131
|
-
shouldUpdateBlockletStatus,
|
|
132
|
-
getBlockletMeta,
|
|
133
|
-
validateOwner,
|
|
134
|
-
} = util;
|
|
129
|
+
const { formatEnvironments, shouldUpdateBlockletStatus, getBlockletMeta, validateOwner } = util;
|
|
135
130
|
|
|
136
131
|
const statusLock = new Lock('blocklet-status-lock');
|
|
137
132
|
|
|
@@ -237,6 +232,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
237
232
|
* description: string;
|
|
238
233
|
* storeUrl: string;
|
|
239
234
|
* appSk: string;
|
|
235
|
+
* skSource: string;
|
|
240
236
|
* sync: boolean = false; // download synchronously, not use queue
|
|
241
237
|
* delay: number; // push download task to queue after a delay
|
|
242
238
|
* downloadTokenList: Array<{did: string, token: string}>;
|
|
@@ -1839,7 +1835,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1839
1835
|
return children;
|
|
1840
1836
|
}
|
|
1841
1837
|
|
|
1842
|
-
async _addBlocklet({ component, mode = BLOCKLET_MODES.PRODUCTION, name, did, title, description }) {
|
|
1838
|
+
async _addBlocklet({ component, mode = BLOCKLET_MODES.PRODUCTION, name, did, title, description, skSource = '' }) {
|
|
1843
1839
|
const meta = {
|
|
1844
1840
|
name,
|
|
1845
1841
|
did,
|
|
@@ -1898,6 +1894,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1898
1894
|
source: BlockletSource.custom,
|
|
1899
1895
|
children,
|
|
1900
1896
|
mode,
|
|
1897
|
+
externalSkSource: skSource,
|
|
1901
1898
|
};
|
|
1902
1899
|
|
|
1903
1900
|
if (containerSourceUrl) {
|
|
@@ -20,6 +20,7 @@ const { getBlockletMetaFromUrl, ensureMeta, validateStore, validateInServerless
|
|
|
20
20
|
const installApplicationFromGeneral = async ({
|
|
21
21
|
type,
|
|
22
22
|
appSk,
|
|
23
|
+
skSource,
|
|
23
24
|
sync,
|
|
24
25
|
delay,
|
|
25
26
|
controller,
|
|
@@ -104,7 +105,7 @@ const installApplicationFromGeneral = async ({
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
// create app
|
|
107
|
-
const blocklet = await manager._addBlocklet({ component, name, did, title, description });
|
|
108
|
+
const blocklet = await manager._addBlocklet({ component, name, did, title, description, skSource });
|
|
108
109
|
logger.info('blocklet added to database', { did: blocklet.meta.did });
|
|
109
110
|
|
|
110
111
|
// create config
|
|
@@ -2,9 +2,9 @@ const path = require('path');
|
|
|
2
2
|
|
|
3
3
|
const logger = require('@abtnode/logger')('@abtnode/core:install-component-upload');
|
|
4
4
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
5
|
+
const { isInProgress } = require('@blocklet/meta/lib/util');
|
|
5
6
|
|
|
6
7
|
const { BlockletSource, BlockletGroup, fromBlockletStatus } = require('@blocklet/constant');
|
|
7
|
-
const { isInProgress } = require('../../../util');
|
|
8
8
|
const {
|
|
9
9
|
parseComponents,
|
|
10
10
|
filterDuplicateComponents,
|
|
@@ -3,13 +3,18 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const pick = require('lodash/pick');
|
|
4
4
|
const pRetry = require('p-retry');
|
|
5
5
|
const Client = require('@ocap/client');
|
|
6
|
-
const
|
|
6
|
+
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
7
7
|
const { slugify } = require('transliteration');
|
|
8
8
|
const Lock = require('@abtnode/util/lib/lock');
|
|
9
9
|
|
|
10
10
|
const logger = require('@abtnode/logger')('@abtnode/core:migrate-application-to-struct-v2');
|
|
11
11
|
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
forEachBlockletSync,
|
|
14
|
+
getSharedConfigObj,
|
|
15
|
+
getBlockletChainInfo,
|
|
16
|
+
isInProgress,
|
|
17
|
+
} = require('@blocklet/meta/lib/util');
|
|
13
18
|
const { SLOT_FOR_IP_DNS_SITE, MAIN_CHAIN_ENDPOINT } = require('@abtnode/constant');
|
|
14
19
|
|
|
15
20
|
const {
|
|
@@ -33,7 +38,6 @@ const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
|
33
38
|
const getBlockletWallet = require('@blocklet/meta/lib/wallet');
|
|
34
39
|
const { cloneDeep } = require('lodash');
|
|
35
40
|
|
|
36
|
-
const { isInProgress } = require('../../../util');
|
|
37
41
|
const { getBlockletDomainGroupName } = require('../../../util/router');
|
|
38
42
|
const { getIpDnsDomainForBlocklet } = require('../../../util/get-domain-for-blocklet');
|
|
39
43
|
const { getBundleDir } = require('../../../util/blocklet');
|
|
@@ -107,7 +111,7 @@ const ensureAccountOnMainChain = async (blocklet, newWallet) => {
|
|
|
107
111
|
if (!newResultOnMainChain.state) {
|
|
108
112
|
logger.info('declare account on main chain', { address: newWallet.address, did: blocklet.meta.did });
|
|
109
113
|
const hash = await mainChainClient.declare({
|
|
110
|
-
moniker: (
|
|
114
|
+
moniker: (urlPathFriendly(slugify(blocklet.meta.title || blocklet.meta.name)) || 'application').toLowerCase(),
|
|
111
115
|
wallet: newWallet,
|
|
112
116
|
});
|
|
113
117
|
logger.info('declare account on main chain done', { did: blocklet.meta.did, hash });
|
package/lib/event.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const cloneDeep = require('lodash/cloneDeep');
|
|
3
3
|
const { EventEmitter } = require('events');
|
|
4
|
-
const { wipeSensitiveData } = require('@blocklet/meta/lib/util');
|
|
4
|
+
const { wipeSensitiveData, isBeforeInstalled } = require('@blocklet/meta/lib/util');
|
|
5
5
|
const logger = require('@abtnode/logger')('@abtnode/core:event');
|
|
6
6
|
const { BLOCKLET_MODES, BlockletStatus, BlockletSource, BlockletEvents } = require('@blocklet/constant');
|
|
7
7
|
const { EVENTS } = require('@abtnode/constant');
|
|
@@ -12,7 +12,6 @@ const eventHub =
|
|
|
12
12
|
process.env.NODE_ENV === 'test' ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
|
|
13
13
|
|
|
14
14
|
const states = require('./states');
|
|
15
|
-
const { isBeforeInstalled } = require('./util');
|
|
16
15
|
|
|
17
16
|
const routingSnapshotPrefix = (blocklet) => (blocklet.mode === BLOCKLET_MODES.DEVELOPMENT ? '[DEV] ' : '');
|
|
18
17
|
|
|
@@ -104,7 +103,7 @@ module.exports = ({
|
|
|
104
103
|
notificationState.create({
|
|
105
104
|
title: 'Blocklet URL Mapping Error',
|
|
106
105
|
// eslint-disable-next-line max-len
|
|
107
|
-
description: `Failed to create URL mapping for blocklet ${blocklet.meta.
|
|
106
|
+
description: `Failed to create URL mapping for blocklet ${blocklet.meta.title}, due to: ${error.message}`,
|
|
108
107
|
entityType: 'blocklet',
|
|
109
108
|
entityId: blocklet.meta.did,
|
|
110
109
|
severity: 'error',
|
|
@@ -155,7 +154,7 @@ module.exports = ({
|
|
|
155
154
|
notificationState.create({
|
|
156
155
|
title: 'Blocklet URL Mapping Error',
|
|
157
156
|
// eslint-disable-next-line max-len
|
|
158
|
-
description: `Failed to upgrade URL mapping for blocklet ${blocklet.meta.
|
|
157
|
+
description: `Failed to upgrade URL mapping for blocklet ${blocklet.meta.title}, due to: ${error.message}`,
|
|
159
158
|
entityType: 'blocklet',
|
|
160
159
|
entityId: blocklet.meta.did,
|
|
161
160
|
severity: 'error',
|
package/lib/router/helper.js
CHANGED
|
@@ -270,39 +270,50 @@ const ensureWellknownRule = async (sites) => {
|
|
|
270
270
|
// 这里默认 pathPrefix 最短的是自己 ( 通常自己在 /, 其他 blocklet 在 /xxxx )
|
|
271
271
|
// 挂载其他 blocklet 的使用方式不推荐, 将来可能会被废弃
|
|
272
272
|
.sort((a, b) => (a.from.pathPrefix.length > b.from.pathPrefix.length ? 1 : -1));
|
|
273
|
-
if (blockletRules.length) {
|
|
274
|
-
// get pathPrefix for blocklet-service
|
|
275
|
-
const rootBlockletRule = blockletRules.find((x) => x.to.did === x.to.componentId);
|
|
276
|
-
|
|
277
|
-
const servicePathPrefix = joinUrl(
|
|
278
|
-
// rootBlockletRule?.from?.pathPrefix is for backwards compatibility
|
|
279
|
-
// rootBlockletRule?.from?.groupPathPrefix 在旧的场景中可能不为 '/' (blocklet 只能挂载在 relative prefix 下)
|
|
280
|
-
rootBlockletRule?.from?.groupPathPrefix || rootBlockletRule?.from?.pathPrefix || '/',
|
|
281
|
-
WELLKNOWN_SERVICE_PATH_PREFIX
|
|
282
|
-
);
|
|
283
273
|
|
|
284
|
-
|
|
285
|
-
// so any rule is ok to be cloned
|
|
286
|
-
if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
|
|
287
|
-
const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
|
|
288
|
-
rule.from.pathPrefix = servicePathPrefix;
|
|
289
|
-
rule.to.target = servicePathPrefix;
|
|
290
|
-
rule.isProtected = true;
|
|
291
|
-
rule.dynamic = true; // mark as dynamic to avoid redundant generated rules
|
|
292
|
-
site.rules.push(rule);
|
|
293
|
-
}
|
|
274
|
+
const rootRule = blockletRules[0];
|
|
294
275
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
276
|
+
// Serve blocklet service always
|
|
277
|
+
const servicePathPrefix = joinUrl(WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
278
|
+
if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
|
|
279
|
+
site.rules.push({
|
|
280
|
+
id: rootRule?.id || '',
|
|
281
|
+
groupId: rootRule?.groupId || '',
|
|
282
|
+
from: {
|
|
283
|
+
pathPrefix: servicePathPrefix,
|
|
284
|
+
groupPathPrefix: '/',
|
|
285
|
+
},
|
|
286
|
+
to: {
|
|
287
|
+
type: 'blocklet',
|
|
288
|
+
did: site.blockletDid,
|
|
289
|
+
componentId: site.blockletDid,
|
|
290
|
+
target: servicePathPrefix,
|
|
291
|
+
},
|
|
292
|
+
isProtected: true,
|
|
293
|
+
dynamic: true,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Cache user avatar from gateway
|
|
298
|
+
const avatarPathPrefix = joinUrl(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
|
|
299
|
+
if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
|
|
300
|
+
site.rules.push({
|
|
301
|
+
id: rootRule?.id || '',
|
|
302
|
+
groupId: rootRule?.groupId || '',
|
|
303
|
+
from: {
|
|
304
|
+
pathPrefix: avatarPathPrefix,
|
|
305
|
+
groupPathPrefix: '/',
|
|
306
|
+
},
|
|
307
|
+
to: {
|
|
308
|
+
type: 'blocklet',
|
|
309
|
+
did: site.blockletDid,
|
|
310
|
+
componentId: site.blockletDid,
|
|
311
|
+
cacheGroup: 'blockletProxy',
|
|
312
|
+
target: avatarPathPrefix,
|
|
313
|
+
},
|
|
314
|
+
isProtected: true,
|
|
315
|
+
dynamic: true,
|
|
316
|
+
});
|
|
306
317
|
}
|
|
307
318
|
}
|
|
308
319
|
}
|
|
@@ -901,7 +912,10 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
901
912
|
};
|
|
902
913
|
|
|
903
914
|
if (!existedRule) {
|
|
904
|
-
await routerManager.addRoutingRule(
|
|
915
|
+
await routerManager.addRoutingRule(
|
|
916
|
+
{ id: wellknownSite.id, rule, skipCheckDynamicBlacklist: true, formatPathPrefix: false },
|
|
917
|
+
context
|
|
918
|
+
);
|
|
905
919
|
return true;
|
|
906
920
|
}
|
|
907
921
|
|
|
@@ -910,7 +924,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
910
924
|
existedRule.to = rule.to;
|
|
911
925
|
|
|
912
926
|
await routerManager.updateRoutingRule(
|
|
913
|
-
{ id: wellknownSite.id, rule: existedRule, skipProtectedRuleChecking: true },
|
|
927
|
+
{ id: wellknownSite.id, rule: existedRule, skipProtectedRuleChecking: true, formatPathPrefix: false },
|
|
914
928
|
context
|
|
915
929
|
);
|
|
916
930
|
|
package/lib/router/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
|
+
const isEqual = require('lodash/isEqual');
|
|
3
4
|
const cloneDeep = require('lodash/cloneDeep');
|
|
4
5
|
const {
|
|
5
6
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
@@ -188,9 +189,6 @@ Router.formatSites = (sites = []) => {
|
|
|
188
189
|
if (Array.isArray(site.rules) && site.rules.length > 0) {
|
|
189
190
|
const rules = cloneDeep(site.rules);
|
|
190
191
|
|
|
191
|
-
let hasRootPathBlockletRule = false;
|
|
192
|
-
let tmpBlockletRule;
|
|
193
|
-
|
|
194
192
|
rules.forEach((rule) => {
|
|
195
193
|
if ([ROUTING_RULE_TYPES.BLOCKLET].includes(rule.to.type) === false) {
|
|
196
194
|
return;
|
|
@@ -205,11 +203,6 @@ Router.formatSites = (sites = []) => {
|
|
|
205
203
|
}
|
|
206
204
|
|
|
207
205
|
if (daemonRule) {
|
|
208
|
-
if (rule.from.pathPrefix === '/') {
|
|
209
|
-
hasRootPathBlockletRule = true;
|
|
210
|
-
}
|
|
211
|
-
tmpBlockletRule = rule;
|
|
212
|
-
|
|
213
206
|
// Serve meta js: both prefix and suffix do not contain trailing slash
|
|
214
207
|
// NOTICE: 这里隐含了一个约定
|
|
215
208
|
// 如果安装的 blockletA 和 blockletB 都需要 __blocklet__.js
|
|
@@ -242,38 +235,43 @@ Router.formatSites = (sites = []) => {
|
|
|
242
235
|
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
|
|
243
236
|
},
|
|
244
237
|
});
|
|
238
|
+
}
|
|
239
|
+
});
|
|
245
240
|
|
|
241
|
+
if (daemonRule) {
|
|
242
|
+
const rootFrom = {
|
|
243
|
+
pathPrefix: '/',
|
|
244
|
+
groupPathPrefix: '/',
|
|
245
|
+
pathSuffix: '/__blocklet__.js',
|
|
246
|
+
};
|
|
247
|
+
// ensure /__blocklet__.js should be proxy to daemon
|
|
248
|
+
if (!site.rules.find((x) => isEqual(x.from, rootFrom))) {
|
|
249
|
+
site.rules.push({
|
|
250
|
+
from: rootFrom,
|
|
251
|
+
to: {
|
|
252
|
+
type: ROUTING_RULE_TYPES.DAEMON,
|
|
253
|
+
port: daemonRule.to.port,
|
|
254
|
+
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
|
|
255
|
+
did: site.blockletDid,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ensure /.blocklet/proxy should be proxy to daemon
|
|
261
|
+
if (!site.rules.find((x) => x.from.pathPrefix === BLOCKLET_PROXY_PATH_PREFIX)) {
|
|
246
262
|
site.rules.push({
|
|
247
263
|
from: {
|
|
248
264
|
pathPrefix: BLOCKLET_PROXY_PATH_PREFIX,
|
|
249
265
|
},
|
|
250
266
|
to: {
|
|
251
267
|
port: daemonRule.to.port,
|
|
252
|
-
did: rule.to.did,
|
|
253
268
|
type: ROUTING_RULE_TYPES.DAEMON,
|
|
254
269
|
target: BLOCKLET_PROXY_PATH_PREFIX,
|
|
255
270
|
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
|
|
271
|
+
did: site.blockletDid,
|
|
256
272
|
},
|
|
257
273
|
});
|
|
258
274
|
}
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// ensure /__blocklet__.js should be proxy to daemon
|
|
262
|
-
if (daemonRule && !hasRootPathBlockletRule && tmpBlockletRule) {
|
|
263
|
-
site.rules.push({
|
|
264
|
-
from: {
|
|
265
|
-
pathPrefix: '/',
|
|
266
|
-
groupPathPrefix: '/',
|
|
267
|
-
pathSuffix: '/__blocklet__.js',
|
|
268
|
-
},
|
|
269
|
-
to: {
|
|
270
|
-
type: ROUTING_RULE_TYPES.DAEMON,
|
|
271
|
-
port: daemonRule.to.port,
|
|
272
|
-
did: tmpBlockletRule.to.did,
|
|
273
|
-
componentId: tmpBlockletRule.to.did,
|
|
274
|
-
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
|
|
275
|
-
},
|
|
276
|
-
});
|
|
277
275
|
}
|
|
278
276
|
}
|
|
279
277
|
});
|
package/lib/router/manager.js
CHANGED
|
@@ -258,8 +258,16 @@ class RouterManager extends EventEmitter {
|
|
|
258
258
|
return dbSite;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
async addRoutingRule(
|
|
261
|
+
async addRoutingRule(
|
|
262
|
+
{ id, rule: tempRule, skipCheckDynamicBlacklist = false, formatPathPrefix = true },
|
|
263
|
+
context = {}
|
|
264
|
+
) {
|
|
262
265
|
const { rule } = await validateAddRule({ id, rule: tempRule }, context);
|
|
266
|
+
|
|
267
|
+
if (!formatPathPrefix) {
|
|
268
|
+
rule.from.pathPrefix = tempRule.from.pathPrefix;
|
|
269
|
+
}
|
|
270
|
+
|
|
263
271
|
const dbSite = await states.site.findOne({ _id: id });
|
|
264
272
|
if (!dbSite) {
|
|
265
273
|
throw new Error(`site ${id} does not exist`);
|
|
@@ -275,7 +283,7 @@ class RouterManager extends EventEmitter {
|
|
|
275
283
|
const existedRule = dbSite.rules.find((x) => x.from.pathPrefix === rule.from.pathPrefix);
|
|
276
284
|
|
|
277
285
|
if (existedRule) {
|
|
278
|
-
throw new Error(`path prefix '${originalPathPrefix}' already exists`);
|
|
286
|
+
throw new Error(`addRoutingRule: path prefix '${originalPathPrefix}' already exists`);
|
|
279
287
|
}
|
|
280
288
|
}
|
|
281
289
|
|
|
@@ -294,8 +302,16 @@ class RouterManager extends EventEmitter {
|
|
|
294
302
|
return newSite;
|
|
295
303
|
}
|
|
296
304
|
|
|
297
|
-
async updateRoutingRule(
|
|
305
|
+
async updateRoutingRule(
|
|
306
|
+
{ id, rule: tmpRule, skipProtectedRuleChecking = false, formatPathPrefix = true },
|
|
307
|
+
context = {}
|
|
308
|
+
) {
|
|
298
309
|
const { rule } = await validateEditRule({ id, rule: tmpRule }, context);
|
|
310
|
+
|
|
311
|
+
if (!formatPathPrefix) {
|
|
312
|
+
rule.from.pathPrefix = tmpRule.from.pathPrefix;
|
|
313
|
+
}
|
|
314
|
+
|
|
299
315
|
const dbSite = await states.site.findOne({ _id: id, 'rules.id': rule.id });
|
|
300
316
|
if (!dbSite) {
|
|
301
317
|
throw new Error(`site ${id}, rule ${rule.id} does not exist`);
|
|
@@ -310,7 +326,7 @@ class RouterManager extends EventEmitter {
|
|
|
310
326
|
// Ensure path prefix is unique across the site
|
|
311
327
|
const existedRule = dbSite.rules.find((x) => x.id !== rule.id && x.from.pathPrefix === rule.from.pathPrefix);
|
|
312
328
|
if (existedRule) {
|
|
313
|
-
throw new Error(`path prefix '${originalPathPrefix}' already exists`);
|
|
329
|
+
throw new Error(`updateRoutingRule: path prefix '${originalPathPrefix}' already exists`);
|
|
314
330
|
}
|
|
315
331
|
|
|
316
332
|
// Ensure we are not updating protected rules
|
package/lib/states/blocklet.js
CHANGED
|
@@ -9,14 +9,14 @@ const detectPort = require('detect-port');
|
|
|
9
9
|
const Lock = require('@abtnode/util/lib/lock');
|
|
10
10
|
const security = require('@abtnode/util/lib/security');
|
|
11
11
|
const { fixPerson, fixInterfaces } = require('@blocklet/meta/lib/fix');
|
|
12
|
-
const { getDisplayName, forEachBlocklet, forEachBlockletSync, forEachChildSync } = require('@blocklet/meta/lib/util');
|
|
13
12
|
const {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} = require('@blocklet/
|
|
13
|
+
getDisplayName,
|
|
14
|
+
forEachBlocklet,
|
|
15
|
+
forEachBlockletSync,
|
|
16
|
+
forEachChildSync,
|
|
17
|
+
getBlockletServices,
|
|
18
|
+
} = require('@blocklet/meta/lib/util');
|
|
19
|
+
const { BlockletStatus, BlockletSource, BLOCKLET_MODES, BLOCKLET_DEFAULT_PORT_NAME } = require('@blocklet/constant');
|
|
20
20
|
const { APP_STRUCT_VERSION } = require('@abtnode/constant');
|
|
21
21
|
|
|
22
22
|
const logger = require('@abtnode/logger')('state-blocklet');
|
|
@@ -259,6 +259,7 @@ class BlockletState extends BaseState {
|
|
|
259
259
|
// whether sk is managed by some party beside server, such as did-wallet
|
|
260
260
|
// externalSk is always true in struct V2 blocklet
|
|
261
261
|
externalSk = true,
|
|
262
|
+
externalSkSource = '',
|
|
262
263
|
} = {}) {
|
|
263
264
|
return this.getBlocklet(meta.did).then(
|
|
264
265
|
(exist) =>
|
|
@@ -300,6 +301,7 @@ class BlockletState extends BaseState {
|
|
|
300
301
|
children,
|
|
301
302
|
migratedFrom,
|
|
302
303
|
externalSk,
|
|
304
|
+
externalSkSource,
|
|
303
305
|
structVersion: APP_STRUCT_VERSION,
|
|
304
306
|
};
|
|
305
307
|
|
|
@@ -489,16 +491,34 @@ class BlockletState extends BaseState {
|
|
|
489
491
|
}
|
|
490
492
|
|
|
491
493
|
async getServices() {
|
|
492
|
-
const blocklets = await this.getBlocklets({}, {
|
|
494
|
+
const blocklets = await this.getBlocklets({}, { meta: 1, children: 1, ports: 1 });
|
|
493
495
|
const services = [];
|
|
496
|
+
|
|
494
497
|
blocklets.forEach((blocklet) => {
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
498
|
+
const list = getBlockletServices(blocklet);
|
|
499
|
+
list.forEach((x) => {
|
|
500
|
+
if (!x.port) {
|
|
501
|
+
logger.error('Missing service port', { appId: blocklet.meta.did, x });
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (!x.protocol) {
|
|
506
|
+
logger.error('Missing service protocol', { appId: blocklet.meta.did, x });
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!x.upstreamPort) {
|
|
511
|
+
logger.error('Missing service upstreamPort', { appId: blocklet.meta.did, x });
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (services.find((s) => s.port === x.port)) {
|
|
516
|
+
// should not be here
|
|
517
|
+
logger.error('Duplicate service port', { appId: blocklet.meta.did, x });
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
services.push(x);
|
|
502
522
|
});
|
|
503
523
|
});
|
|
504
524
|
|
package/lib/states/user.js
CHANGED
|
@@ -24,6 +24,32 @@ const isNullOrUndefined = (x) => x === undefined || x === null;
|
|
|
24
24
|
* @property {string} role - passport's role
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Auth0Account
|
|
29
|
+
* @typedef {Object} Auth0Account
|
|
30
|
+
* @property {'auth0'} provider
|
|
31
|
+
* @property {string} id - id from auth0
|
|
32
|
+
* @property {string} did - did for auth0 account
|
|
33
|
+
* @property {string} pk - pk for auth0 account
|
|
34
|
+
* @property {string} lastLoginAt - Last login time new Date().toISOString()
|
|
35
|
+
* @property {string} firstLoginAt - First login time new Date().toISOString()
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* WalletAccount
|
|
40
|
+
* @typedef {Object} WalletAccount
|
|
41
|
+
* @property {'wallet'} provider
|
|
42
|
+
* @property {string} did - did for auth0 account
|
|
43
|
+
* @property {string} pk - pk for auth0 account
|
|
44
|
+
* @property {string} lastLoginAt - Last login time new Date().toISOString()
|
|
45
|
+
* @property {string} firstLoginAt - First login time new Date().toISOString()
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* ConnectedAccount
|
|
50
|
+
* @typedef {(Auth0Account|WalletAccount)} ConnectedAccount
|
|
51
|
+
*/
|
|
52
|
+
|
|
27
53
|
/**
|
|
28
54
|
* The Data structure of blocklet-service user
|
|
29
55
|
* @typedef {Object} BlockletUser - Blocklet Service User Table
|
|
@@ -31,13 +57,16 @@ const isNullOrUndefined = (x) => x === undefined || x === null;
|
|
|
31
57
|
* @property {('profile')} type - type of user
|
|
32
58
|
* @property {string} fullName - user profile's name
|
|
33
59
|
* @property {string} avatar - url of user's avatar, eg: bn://avatar/7f8848569405f8cdf8b1b2788ebf7d0f.jpg
|
|
34
|
-
* @property {string} did - user's did
|
|
60
|
+
* @property {string} did - user's did -> 实际上变为 uid, 是不可变的;真正的 wallet-did 转移到 extraConfigs 中去了
|
|
61
|
+
* @property {string} pk - user's publicKey
|
|
35
62
|
* @property {('owner'|'admin'|'member'|'guest'|string)} role - user's role
|
|
36
63
|
* @property {UserPassport[]} passports - user's passport list
|
|
37
|
-
* @property {string} pk - user's publicKey
|
|
38
64
|
* @property {boolean} approved - enable user to login
|
|
39
65
|
* @property {string} locale - locale
|
|
40
|
-
* @property {Object} extra - extra data of user
|
|
66
|
+
* @property {Object} [extra] - extra data of user
|
|
67
|
+
* @property {Object} [extraConfigs] - extra data of user
|
|
68
|
+
* @property {ConnectedAccount[]} [extraConfigs.connectedAccounts] - connectedAccounts
|
|
69
|
+
* @property {('wallet'|'auth0')} [extraConfigs.sourceProvider] - sourceProvider, the main account provider
|
|
41
70
|
* @property {Date} firstLoginAt - firstLoginAt
|
|
42
71
|
* @property {Date} lastLoginAt - lastLoginAt
|
|
43
72
|
* @property {string} lastLoginIp - lastLoginIp
|
|
@@ -139,7 +168,7 @@ class User extends BaseState {
|
|
|
139
168
|
/**
|
|
140
169
|
* update user's role
|
|
141
170
|
* @param {string} did user's did
|
|
142
|
-
* @param {BlockletUser.role} role user's
|
|
171
|
+
* @param {BlockletUser.role} role user's role
|
|
143
172
|
* @returns {BlockletUser}
|
|
144
173
|
*/
|
|
145
174
|
async updateRole({ did, role }) {
|
|
@@ -160,7 +189,7 @@ class User extends BaseState {
|
|
|
160
189
|
* @returns {{list: BlockletUser[]; paging: any;}}
|
|
161
190
|
*/
|
|
162
191
|
async getUsers({ query, sort, paging: inputPaging } = {}) {
|
|
163
|
-
const { approved, role, search,
|
|
192
|
+
const { approved, role, search, connectedDid } = query || {};
|
|
164
193
|
|
|
165
194
|
// make query param
|
|
166
195
|
const queryParam = {};
|
|
@@ -191,9 +220,9 @@ class User extends BaseState {
|
|
|
191
220
|
}
|
|
192
221
|
}
|
|
193
222
|
|
|
194
|
-
// 根据
|
|
195
|
-
if (
|
|
196
|
-
queryParam['extraConfigs.
|
|
223
|
+
// 根据 connectedDid 查询 user 信息(wallet 账户绑定 oauth 账户后,会有该字段)
|
|
224
|
+
if (connectedDid) {
|
|
225
|
+
queryParam['extraConfigs.connectedAccounts.did'] = connectedDid;
|
|
197
226
|
}
|
|
198
227
|
|
|
199
228
|
const sortParam = pickBy(sort, (x) => !isNullOrUndefined(x));
|
package/lib/util/blocklet.js
CHANGED
|
@@ -77,6 +77,7 @@ const {
|
|
|
77
77
|
getComponentName,
|
|
78
78
|
isEnvShareable,
|
|
79
79
|
getBlockletAppIdList,
|
|
80
|
+
isBeforeInstalled,
|
|
80
81
|
} = require('@blocklet/meta/lib/util');
|
|
81
82
|
const toBlockletDid = require('@blocklet/meta/lib/did');
|
|
82
83
|
const { titleSchema, descriptionSchema, logoSchema } = require('@blocklet/meta/lib/schema');
|
|
@@ -91,14 +92,7 @@ const { validate: validateEngine, get: getEngine } = require('../blocklet/manage
|
|
|
91
92
|
|
|
92
93
|
const isRequirementsSatisfied = require('./requirement');
|
|
93
94
|
const { getDidDomainForBlocklet } = require('./get-domain-for-blocklet');
|
|
94
|
-
const {
|
|
95
|
-
isBeforeInstalled,
|
|
96
|
-
expandBundle,
|
|
97
|
-
findInterfacePortByName,
|
|
98
|
-
prettyURL,
|
|
99
|
-
getNFTState,
|
|
100
|
-
templateReplace,
|
|
101
|
-
} = require('./index');
|
|
95
|
+
const { expandBundle, findInterfacePortByName, prettyURL, getNFTState, templateReplace } = require('./index');
|
|
102
96
|
|
|
103
97
|
const getComponentConfig = (meta) => {
|
|
104
98
|
const components = meta.components || meta.children || [];
|
package/lib/util/index.js
CHANGED
|
@@ -17,7 +17,7 @@ const axios = require('@abtnode/util/lib/axios');
|
|
|
17
17
|
const { encode: encodeBase32 } = require('@abtnode/util/lib/base32');
|
|
18
18
|
const parseBlockletMeta = require('@blocklet/meta/lib/parse');
|
|
19
19
|
const { BlockletStatus } = require('@blocklet/constant');
|
|
20
|
-
const { replaceSlotToIp } = require('@blocklet/meta/lib/util');
|
|
20
|
+
const { replaceSlotToIp, isInProgress } = require('@blocklet/meta/lib/util');
|
|
21
21
|
const {
|
|
22
22
|
StatusCode,
|
|
23
23
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
@@ -93,21 +93,6 @@ const getBlockletHost = ({ domain, context, nodeIp }) => {
|
|
|
93
93
|
|
|
94
94
|
const isRoutingEnabled = (routing) => !!routing && !!routing.provider;
|
|
95
95
|
|
|
96
|
-
const isInProgress = (status) =>
|
|
97
|
-
[
|
|
98
|
-
BlockletStatus.downloading,
|
|
99
|
-
BlockletStatus.waiting,
|
|
100
|
-
BlockletStatus.starting,
|
|
101
|
-
BlockletStatus.installing,
|
|
102
|
-
BlockletStatus.stopping,
|
|
103
|
-
BlockletStatus.upgrading,
|
|
104
|
-
].includes(status);
|
|
105
|
-
|
|
106
|
-
const isBeforeInstalled = (status) =>
|
|
107
|
-
[BlockletStatus.added, BlockletStatus.waiting, BlockletStatus.downloading, BlockletStatus.installing].includes(
|
|
108
|
-
status
|
|
109
|
-
);
|
|
110
|
-
|
|
111
96
|
// Check whether a domain is setup
|
|
112
97
|
const checkDomainDNS = (domain) =>
|
|
113
98
|
new Promise((resolve) => {
|
|
@@ -479,8 +464,6 @@ const lib = {
|
|
|
479
464
|
toStatus,
|
|
480
465
|
fromStatus,
|
|
481
466
|
formatEnvironments,
|
|
482
|
-
isInProgress,
|
|
483
|
-
isBeforeInstalled,
|
|
484
467
|
replaceDomainSlot,
|
|
485
468
|
getBlockletHost,
|
|
486
469
|
isRoutingEnabled,
|
package/lib/validators/router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable newline-per-chained-call */
|
|
2
2
|
const Joi = require('joi');
|
|
3
3
|
const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES, ROUTER_CACHE_GROUPS } = require('@abtnode/constant');
|
|
4
|
-
const
|
|
4
|
+
const urlPathFriendly = require('@blocklet/meta/lib/url-path-friendly').default;
|
|
5
5
|
const { getMultipleLangParams } = require('./util');
|
|
6
6
|
|
|
7
7
|
const WILDCARD_DOMAIN_REGEX = /^\*.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/;
|
|
@@ -29,7 +29,7 @@ const ruleSchema = {
|
|
|
29
29
|
zh: { 'string.empty': 'URL 前缀不能为空', 'string.max': 'URL 前缀的最大长度是 150' },
|
|
30
30
|
en: { 'string.empty': 'URL prefix cannot be empty', 'string.max': 'The maximum length of URL prefix is 150' },
|
|
31
31
|
})
|
|
32
|
-
.custom((value) =>
|
|
32
|
+
.custom((value) => urlPathFriendly(value)),
|
|
33
33
|
groupPathPrefix: Joi.string().trim().min(1).max(150), // path prefix of interface of root blocklet
|
|
34
34
|
header: Joi.any(), // TODO: header does not take effect
|
|
35
35
|
}),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.
|
|
6
|
+
"version": "1.16.4-beta-8682e092",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,34 +19,34 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/auth": "1.16.
|
|
23
|
-
"@abtnode/certificate-manager": "1.16.
|
|
24
|
-
"@abtnode/constant": "1.16.
|
|
25
|
-
"@abtnode/cron": "1.16.
|
|
26
|
-
"@abtnode/db": "1.16.
|
|
27
|
-
"@abtnode/logger": "1.16.
|
|
28
|
-
"@abtnode/queue": "1.16.
|
|
29
|
-
"@abtnode/rbac": "1.16.
|
|
30
|
-
"@abtnode/router-provider": "1.16.
|
|
31
|
-
"@abtnode/static-server": "1.16.
|
|
32
|
-
"@abtnode/timemachine": "1.16.
|
|
33
|
-
"@abtnode/util": "1.16.
|
|
34
|
-
"@arcblock/did": "1.18.
|
|
22
|
+
"@abtnode/auth": "1.16.4-beta-8682e092",
|
|
23
|
+
"@abtnode/certificate-manager": "1.16.4-beta-8682e092",
|
|
24
|
+
"@abtnode/constant": "1.16.4-beta-8682e092",
|
|
25
|
+
"@abtnode/cron": "1.16.4-beta-8682e092",
|
|
26
|
+
"@abtnode/db": "1.16.4-beta-8682e092",
|
|
27
|
+
"@abtnode/logger": "1.16.4-beta-8682e092",
|
|
28
|
+
"@abtnode/queue": "1.16.4-beta-8682e092",
|
|
29
|
+
"@abtnode/rbac": "1.16.4-beta-8682e092",
|
|
30
|
+
"@abtnode/router-provider": "1.16.4-beta-8682e092",
|
|
31
|
+
"@abtnode/static-server": "1.16.4-beta-8682e092",
|
|
32
|
+
"@abtnode/timemachine": "1.16.4-beta-8682e092",
|
|
33
|
+
"@abtnode/util": "1.16.4-beta-8682e092",
|
|
34
|
+
"@arcblock/did": "1.18.67",
|
|
35
35
|
"@arcblock/did-motif": "^1.1.10",
|
|
36
|
-
"@arcblock/did-util": "1.18.
|
|
37
|
-
"@arcblock/event-hub": "1.18.
|
|
38
|
-
"@arcblock/jwt": "^1.18.
|
|
36
|
+
"@arcblock/did-util": "1.18.67",
|
|
37
|
+
"@arcblock/event-hub": "1.18.67",
|
|
38
|
+
"@arcblock/jwt": "^1.18.67",
|
|
39
39
|
"@arcblock/pm2-events": "^0.0.5",
|
|
40
|
-
"@arcblock/vc": "1.18.
|
|
41
|
-
"@blocklet/constant": "1.16.
|
|
42
|
-
"@blocklet/meta": "1.16.
|
|
43
|
-
"@blocklet/sdk": "1.16.
|
|
44
|
-
"@did-space/client": "^0.2.
|
|
40
|
+
"@arcblock/vc": "1.18.67",
|
|
41
|
+
"@blocklet/constant": "1.16.4-beta-8682e092",
|
|
42
|
+
"@blocklet/meta": "1.16.4-beta-8682e092",
|
|
43
|
+
"@blocklet/sdk": "1.16.4-beta-8682e092",
|
|
44
|
+
"@did-space/client": "^0.2.67",
|
|
45
45
|
"@fidm/x509": "^1.2.1",
|
|
46
|
-
"@ocap/client": "1.18.
|
|
47
|
-
"@ocap/mcrypto": "1.18.
|
|
48
|
-
"@ocap/util": "1.18.
|
|
49
|
-
"@ocap/wallet": "1.18.
|
|
46
|
+
"@ocap/client": "1.18.67",
|
|
47
|
+
"@ocap/mcrypto": "1.18.67",
|
|
48
|
+
"@ocap/util": "1.18.67",
|
|
49
|
+
"@ocap/wallet": "1.18.67",
|
|
50
50
|
"@slack/webhook": "^5.0.4",
|
|
51
51
|
"archiver": "^5.3.1",
|
|
52
52
|
"axios": "^0.27.2",
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
"express": "^4.18.2",
|
|
94
94
|
"jest": "^27.5.1"
|
|
95
95
|
},
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "ab6fc7aeaec32f14ec2153976f2121aa893486b5"
|
|
97
97
|
}
|