@abtnode/core 1.16.4 → 1.16.5

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.
@@ -6,6 +6,7 @@ const tar = require('tar');
6
6
  const isUrl = require('is-url');
7
7
  const get = require('lodash/get');
8
8
  const cloneDeep = require('lodash/cloneDeep');
9
+ const groupBy = require('lodash/groupBy');
9
10
  const isEqual = require('lodash/isEqual');
10
11
  const joinUrl = require('url-join');
11
12
  const { replaceSlotToIp, findComponentById, findWebInterface } = require('@blocklet/meta/lib/util');
@@ -58,6 +59,7 @@ const {
58
59
  getWellknownSitePort,
59
60
  getServerDidDomain,
60
61
  isGatewayCacheEnabled,
62
+ isBlockletSite,
61
63
  } = require('../util');
62
64
  const { getIpDnsDomainForBlocklet, getDidDomainForBlocklet } = require('../util/get-domain-for-blocklet');
63
65
  const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-accessible-external-node-ip');
@@ -242,13 +244,11 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
242
244
  });
243
245
  };
244
246
 
245
- const ensureWellknownRule = async (sites) => {
246
- const tempSites = sites || [];
247
+ const ensureWellknownRule = async (sites = []) => {
247
248
  const wellknownPort = await getWellknownSitePort();
248
249
 
249
- for (const site of tempSites) {
250
- // 不向 default site & ip site & wellknown site 添加 wellknown rule
251
- if (![DOMAIN_FOR_INTERNAL_SITE, DOMAIN_FOR_IP_SITE, DOMAIN_FOR_DEFAULT_SITE].includes(site.domain)) {
250
+ for (const site of sites) {
251
+ if (isBlockletSite(site.domain)) {
252
252
  // add /.well-known for blocklet
253
253
  const isExists = site.rules.find((x) => x.from.pathPrefix === WELLKNOWN_PATH_PREFIX);
254
254
  if (!isExists) {
@@ -262,31 +262,50 @@ const ensureWellknownRule = async (sites) => {
262
262
  isProtected: true,
263
263
  });
264
264
  }
265
+ }
265
266
 
266
- // add /.well-known/service for blocklet
267
- const blockletRules = site.rules
268
- .filter((x) => x.to.type === ROUTING_RULE_TYPES.BLOCKLET)
269
- // 可能存在挂载的 blocklet 不是自己, 是其他 blocklet
270
- // 这里默认 pathPrefix 最短的是自己 ( 通常自己在 /, 其他 blocklet 在 /xxxx )
271
- // 挂载其他 blocklet 的使用方式不推荐, 将来可能会被废弃
272
- .sort((a, b) => (a.from.pathPrefix.length > b.from.pathPrefix.length ? 1 : -1));
267
+ // add /.well-known/service for blocklet
268
+ const blockletRules = site.rules
269
+ .filter((x) => x.to.type === ROUTING_RULE_TYPES.BLOCKLET)
270
+ // 可能存在挂载的 blocklet 不是自己, 是其他 blocklet
271
+ // 这里默认 pathPrefix 最短的是自己 ( 通常自己在 /, 其他 blocklet 在 /xxxx )
272
+ // 挂载其他 blocklet 的使用方式不推荐, 将来可能会被废弃
273
+ .sort((a, b) => (a.from.pathPrefix.length > b.from.pathPrefix.length ? 1 : -1));
274
+
275
+ // Group component rules and ensure that there is always a group even if there are no components
276
+ const grouped = groupBy(blockletRules, (x) => x.from.groupPathPrefix);
277
+ if (isBlockletSite(site.domain)) {
278
+ if (Object.keys(grouped).length === 0) {
279
+ grouped['/'] = [
280
+ {
281
+ id: '',
282
+ groupId: '',
283
+ to: {
284
+ did: site.blockletDid,
285
+ componentId: site.blockletDid,
286
+ },
287
+ },
288
+ ];
289
+ }
290
+ }
273
291
 
274
- const rootRule = blockletRules[0];
292
+ Object.keys(grouped).forEach((groupPathPrefix) => {
293
+ const rule = grouped[groupPathPrefix][0];
275
294
 
276
295
  // Serve blocklet service always
277
- const servicePathPrefix = joinUrl(WELLKNOWN_SERVICE_PATH_PREFIX);
296
+ const servicePathPrefix = joinUrl(groupPathPrefix, WELLKNOWN_SERVICE_PATH_PREFIX);
278
297
  if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
279
298
  site.rules.push({
280
- id: rootRule?.id || '',
281
- groupId: rootRule?.groupId || '',
299
+ id: rule.id,
300
+ groupId: rule.groupId,
282
301
  from: {
283
302
  pathPrefix: servicePathPrefix,
284
- groupPathPrefix: '/',
303
+ groupPathPrefix,
285
304
  },
286
305
  to: {
287
306
  type: 'blocklet',
288
- did: site.blockletDid,
289
- componentId: site.blockletDid,
307
+ did: rule.to.did,
308
+ componentId: rule.to.componentId,
290
309
  target: servicePathPrefix,
291
310
  },
292
311
  isProtected: true,
@@ -298,16 +317,16 @@ const ensureWellknownRule = async (sites) => {
298
317
  const avatarPathPrefix = joinUrl(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
299
318
  if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
300
319
  site.rules.push({
301
- id: rootRule?.id || '',
302
- groupId: rootRule?.groupId || '',
320
+ id: rule.id,
321
+ groupId: rule.groupId,
303
322
  from: {
304
323
  pathPrefix: avatarPathPrefix,
305
- groupPathPrefix: '/',
324
+ groupPathPrefix,
306
325
  },
307
326
  to: {
308
327
  type: 'blocklet',
309
- did: site.blockletDid,
310
- componentId: site.blockletDid,
328
+ did: rule.to.did,
329
+ componentId: rule.to.componentId,
311
330
  cacheGroup: 'blockletProxy',
312
331
  target: avatarPathPrefix,
313
332
  },
@@ -315,10 +334,10 @@ const ensureWellknownRule = async (sites) => {
315
334
  dynamic: true,
316
335
  });
317
336
  }
318
- }
337
+ });
319
338
  }
320
339
 
321
- return tempSites;
340
+ return sites;
322
341
  };
323
342
 
324
343
  const ensureBlockletDid = async (sites) => {
@@ -15,7 +15,7 @@ const { BLOCKLET_UI_INTERFACES, BLOCKLET_MODES } = require('@blocklet/constant')
15
15
 
16
16
  const logger = require('@abtnode/logger')('@abtnode/core:router');
17
17
 
18
- const { isGatewayCacheEnabled } = require('../util');
18
+ const { isGatewayCacheEnabled, isBlockletSite } = require('../util');
19
19
 
20
20
  const expandSites = (sites = []) => {
21
21
  const result = [];
@@ -184,96 +184,112 @@ Router.formatSites = (sites = []) => {
184
184
  break;
185
185
  }
186
186
  }
187
+ if (!daemonRule) {
188
+ return result;
189
+ }
187
190
 
188
191
  result.forEach((site) => {
189
- if (Array.isArray(site.rules) && site.rules.length > 0) {
190
- const rules = cloneDeep(site.rules);
191
-
192
- rules.forEach((rule) => {
193
- if ([ROUTING_RULE_TYPES.BLOCKLET].includes(rule.to.type) === false) {
194
- return;
195
- }
196
-
197
- if (BLOCKLET_UI_INTERFACES.includes(rule.to.interfaceName) === false) {
198
- return;
199
- }
200
-
201
- if (rule.dynamic) {
202
- return;
203
- }
204
-
205
- if (daemonRule) {
206
- // Serve meta js: both prefix and suffix do not contain trailing slash
207
- // NOTICE: 这里隐含了一个约定
208
- // 如果安装的 blockletA 和 blockletB 都需要 __blocklet__.js
209
- // 则不可以将 blockletA mount 在 /a, 将 blockletB mount 在 /a/b (实际上也不会有这种需求)
210
- site.rules.push({
211
- from: {
212
- pathPrefix: rule.from.pathPrefix.replace(/\/$/, ''),
213
- groupPathPrefix: (rule.from.groupPathPrefix || '').replace(/\/$/, ''),
214
- pathSuffix: '/__meta__.js',
215
- },
216
- to: {
217
- type: ROUTING_RULE_TYPES.DAEMON,
218
- port: daemonRule.to.port,
219
- did: rule.to.did,
220
- componentId: rule.to.componentId,
221
- cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
222
- },
223
- });
224
- site.rules.push({
225
- from: {
226
- pathPrefix: rule.from.pathPrefix.replace(/\/$/, ''),
227
- groupPathPrefix: (rule.from.groupPathPrefix || '').replace(/\/$/, ''),
228
- pathSuffix: '/__blocklet__.js',
229
- },
230
- to: {
231
- type: ROUTING_RULE_TYPES.DAEMON,
232
- port: daemonRule.to.port,
233
- did: rule.to.did,
234
- componentId: rule.to.componentId,
235
- cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
236
- },
237
- });
238
- }
239
- });
192
+ const rules = Array.isArray(site.rules) ? cloneDeep(site.rules) : [];
193
+ const grouped = {};
240
194
 
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)) {
262
- site.rules.push({
263
- from: {
264
- pathPrefix: BLOCKLET_PROXY_PATH_PREFIX,
265
- },
266
- to: {
267
- port: daemonRule.to.port,
268
- type: ROUTING_RULE_TYPES.DAEMON,
269
- target: BLOCKLET_PROXY_PATH_PREFIX,
270
- cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
271
- did: site.blockletDid,
272
- },
273
- });
274
- }
195
+ // 1. serve blocklet.js for each component: both prefix and suffix do not contain trailing slash
196
+ rules.forEach((rule) => {
197
+ if ([ROUTING_RULE_TYPES.BLOCKLET].includes(rule.to.type) === false) {
198
+ return;
199
+ }
200
+
201
+ if (BLOCKLET_UI_INTERFACES.includes(rule.to.interfaceName) === false) {
202
+ return;
203
+ }
204
+
205
+ if (rule.dynamic) {
206
+ return;
275
207
  }
208
+
209
+ grouped[rule.from.groupPathPrefix] = rule;
210
+
211
+ site.rules.push({
212
+ dynamic: true,
213
+ from: {
214
+ pathPrefix: rule.from.pathPrefix,
215
+ groupPathPrefix: rule.from.groupPathPrefix,
216
+ pathSuffix: '/__meta__.js',
217
+ },
218
+ to: {
219
+ type: ROUTING_RULE_TYPES.DAEMON,
220
+ port: daemonRule.to.port,
221
+ did: rule.to.did,
222
+ componentId: rule.to.componentId,
223
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
224
+ },
225
+ });
226
+ site.rules.push({
227
+ dynamic: true,
228
+ from: {
229
+ pathPrefix: rule.from.pathPrefix,
230
+ groupPathPrefix: rule.from.groupPathPrefix,
231
+ pathSuffix: '/__blocklet__.js',
232
+ },
233
+ to: {
234
+ type: ROUTING_RULE_TYPES.DAEMON,
235
+ port: daemonRule.to.port,
236
+ did: rule.to.did,
237
+ componentId: rule.to.componentId,
238
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
239
+ },
240
+ });
241
+ });
242
+
243
+ // 2. ensure blocklet.js and proxy always served even if there are no components
244
+ if (isBlockletSite(site.domain) && Object.keys(grouped).length === 0) {
245
+ grouped['/'] = {
246
+ id: '',
247
+ groupId: '',
248
+ to: {
249
+ did: site.blockletDid,
250
+ componentId: site.blockletDid,
251
+ },
252
+ };
276
253
  }
254
+ Object.keys(grouped).forEach((groupPathPrefix) => {
255
+ const rootFrom = {
256
+ pathPrefix: groupPathPrefix,
257
+ groupPathPrefix,
258
+ pathSuffix: '/__blocklet__.js',
259
+ };
260
+
261
+ const rule = grouped[groupPathPrefix];
262
+
263
+ // 2.1 ensure /__blocklet__.js should be proxy to daemon
264
+ if (!site.rules.find((x) => isEqual(x.from, rootFrom))) {
265
+ site.rules.push({
266
+ dynamic: true,
267
+ from: rootFrom,
268
+ to: {
269
+ type: ROUTING_RULE_TYPES.DAEMON,
270
+ port: daemonRule.to.port,
271
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
272
+ did: rule.to.did,
273
+ },
274
+ });
275
+ }
276
+ // 2.2 ensure /.blocklet/proxy should be proxy to daemon
277
+ if (!site.rules.find((x) => x.from.pathPrefix === BLOCKLET_PROXY_PATH_PREFIX)) {
278
+ site.rules.push({
279
+ dynamic: true,
280
+ from: {
281
+ pathPrefix: BLOCKLET_PROXY_PATH_PREFIX,
282
+ },
283
+ to: {
284
+ port: daemonRule.to.port,
285
+ type: ROUTING_RULE_TYPES.DAEMON,
286
+ target: BLOCKLET_PROXY_PATH_PREFIX,
287
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
288
+ did: rule.to.did,
289
+ },
290
+ });
291
+ }
292
+ });
277
293
  });
278
294
 
279
295
  return result;
@@ -190,6 +190,7 @@ class User extends BaseState {
190
190
  */
191
191
  async getUsers({ query, sort, paging: inputPaging } = {}) {
192
192
  const { approved, role, search, connectedDid } = query || {};
193
+ const queryParamList = [];
193
194
 
194
195
  // make query param
195
196
  const queryParam = {};
@@ -222,7 +223,16 @@ class User extends BaseState {
222
223
 
223
224
  // 根据 connectedDid 查询 user 信息(wallet 账户绑定 oauth 账户后,会有该字段)
224
225
  if (connectedDid) {
225
- queryParam['extraConfigs.connectedAccounts.did'] = connectedDid;
226
+ queryParamList.push({
227
+ ...queryParam,
228
+ 'extraConfigs.connectedAccounts.did': connectedDid,
229
+ });
230
+ // HACK: 在某些情况下,查询的条件可能是 version2 版本的用户 did,并且查村的 did 是派生出来的,没有实际的用户记录,只能通过这个条件查询出来
231
+ // version 1 的用户不需要通过这个条件来查询
232
+ queryParamList.push({
233
+ ...queryParam,
234
+ 'extraConfigs.derivedAccount.did': connectedDid,
235
+ });
226
236
  }
227
237
 
228
238
  const sortParam = pickBy(sort, (x) => !isNullOrUndefined(x));
@@ -232,7 +242,11 @@ class User extends BaseState {
232
242
  }
233
243
 
234
244
  // get data
235
- const { list, paging } = await this.paginate(queryParam, sortParam, inputPaging);
245
+ const { list, paging } = await this.paginate(
246
+ queryParamList.length > 0 ? { $or: queryParamList } : queryParam,
247
+ sortParam,
248
+ inputPaging
249
+ );
236
250
 
237
251
  return {
238
252
  list,
package/lib/util/index.js CHANGED
@@ -26,6 +26,7 @@ const {
26
26
  DEFAULT_HTTP_PORT,
27
27
  DEFAULT_HTTPS_PORT,
28
28
  SLOT_FOR_IP_DNS_SITE,
29
+ BLOCKLET_SITE_GROUP_SUFFIX,
29
30
  NODE_MODES,
30
31
  } = require('@abtnode/constant');
31
32
 
@@ -458,6 +459,10 @@ const isGatewayCacheEnabled = (info) => {
458
459
  return true;
459
460
  };
460
461
 
462
+ const isBlockletSite = (domain) => domain.endsWith(BLOCKLET_SITE_GROUP_SUFFIX);
463
+ const isServerSite = (domain) =>
464
+ [DOMAIN_FOR_DEFAULT_SITE, DOMAIN_FOR_IP_SITE, DOMAIN_FOR_IP_SITE_REGEXP].includes(domain);
465
+
461
466
  const lib = {
462
467
  validateOwner,
463
468
  getProviderFromNodeInfo,
@@ -491,6 +496,8 @@ const lib = {
491
496
  prettyURL,
492
497
  templateReplace,
493
498
  isGatewayCacheEnabled,
499
+ isBlockletSite,
500
+ isServerSite,
494
501
  };
495
502
 
496
503
  module.exports = lib;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.4",
6
+ "version": "1.16.5",
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.4",
23
- "@abtnode/certificate-manager": "1.16.4",
24
- "@abtnode/constant": "1.16.4",
25
- "@abtnode/cron": "1.16.4",
26
- "@abtnode/db": "1.16.4",
27
- "@abtnode/logger": "1.16.4",
28
- "@abtnode/queue": "1.16.4",
29
- "@abtnode/rbac": "1.16.4",
30
- "@abtnode/router-provider": "1.16.4",
31
- "@abtnode/static-server": "1.16.4",
32
- "@abtnode/timemachine": "1.16.4",
33
- "@abtnode/util": "1.16.4",
34
- "@arcblock/did": "1.18.67",
22
+ "@abtnode/auth": "1.16.5",
23
+ "@abtnode/certificate-manager": "1.16.5",
24
+ "@abtnode/constant": "1.16.5",
25
+ "@abtnode/cron": "1.16.5",
26
+ "@abtnode/db": "1.16.5",
27
+ "@abtnode/logger": "1.16.5",
28
+ "@abtnode/queue": "1.16.5",
29
+ "@abtnode/rbac": "1.16.5",
30
+ "@abtnode/router-provider": "1.16.5",
31
+ "@abtnode/static-server": "1.16.5",
32
+ "@abtnode/timemachine": "1.16.5",
33
+ "@abtnode/util": "1.16.5",
34
+ "@arcblock/did": "1.18.68",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
- "@arcblock/did-util": "1.18.67",
37
- "@arcblock/event-hub": "1.18.67",
38
- "@arcblock/jwt": "^1.18.67",
36
+ "@arcblock/did-util": "1.18.68",
37
+ "@arcblock/event-hub": "1.18.68",
38
+ "@arcblock/jwt": "^1.18.68",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
- "@arcblock/vc": "1.18.67",
41
- "@blocklet/constant": "1.16.4",
42
- "@blocklet/meta": "1.16.4",
43
- "@blocklet/sdk": "1.16.4",
44
- "@did-space/client": "^0.2.67",
40
+ "@arcblock/vc": "1.18.68",
41
+ "@blocklet/constant": "1.16.5",
42
+ "@blocklet/meta": "1.16.5",
43
+ "@blocklet/sdk": "1.16.5",
44
+ "@did-space/client": "^0.2.72",
45
45
  "@fidm/x509": "^1.2.1",
46
- "@ocap/client": "1.18.67",
47
- "@ocap/mcrypto": "1.18.67",
48
- "@ocap/util": "1.18.67",
49
- "@ocap/wallet": "1.18.67",
46
+ "@ocap/client": "1.18.68",
47
+ "@ocap/mcrypto": "1.18.68",
48
+ "@ocap/util": "1.18.68",
49
+ "@ocap/wallet": "1.18.68",
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": "8d1062af0f4e4f491b6a7205c9d6542328ca6b20"
96
+ "gitHead": "229effc24ce7e12a0dbe551b2cc57825c3803745"
97
97
  }