@abtnode/core 1.8.65-beta-81d3340c → 1.8.65-beta-f7af64a4

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.
@@ -71,6 +71,8 @@ module.exports = async ({ url, blockletSecretKey, moveDir, context = {}, states,
71
71
  const skConfig = extra.configs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
72
72
  if (skConfig) {
73
73
  skConfig.value = blockletSecretKey;
74
+ skConfig.secure = true;
75
+ skConfig.shared = false;
74
76
  } else {
75
77
  extra.configs.push({
76
78
  key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK,
@@ -21,6 +21,7 @@ const {
21
21
  DOMAIN_FOR_INTERNAL_SITE,
22
22
  WELLKNOWN_PATH_PREFIX,
23
23
  WELLKNOWN_SERVICE_PATH_PREFIX,
24
+ USER_AVATAR_PATH_PREFIX,
24
25
  DOMAIN_FOR_IP_SITE,
25
26
  NAME_FOR_WELLKNOWN_SITE,
26
27
  DEFAULT_HTTP_PORT,
@@ -210,6 +211,9 @@ const ensureLatestInterfaceInfo = async (sites = []) => {
210
211
  if (rule.isProtected && rule.to.target === WELLKNOWN_SERVICE_PATH_PREFIX) {
211
212
  return rule;
212
213
  }
214
+ if (rule.isProtected && rule.to.target === joinUrl(WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX)) {
215
+ return rule;
216
+ }
213
217
 
214
218
  const { did, interfaceName } = rule.to;
215
219
  if (interfaces[did] && interfaces[did][interfaceName]) {
@@ -273,6 +277,18 @@ const ensureWellknownRule = async (sites) => {
273
277
  if (!site.rules.some((x) => x.from.pathPrefix === servicePathPrefix)) {
274
278
  const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
275
279
  rule.from.pathPrefix = servicePathPrefix;
280
+ rule.to.target = servicePathPrefix;
281
+ rule.isProtected = true;
282
+ site.rules.push(rule);
283
+ }
284
+
285
+ // Cache user avatar in nginx
286
+ const avatarPathPrefix = joinUrl(servicePathPrefix, USER_AVATAR_PATH_PREFIX);
287
+ if (!site.rules.some((x) => x.from.pathPrefix === avatarPathPrefix)) {
288
+ const rule = cloneDeep(rootBlockletRule || blockletRules[0]);
289
+ rule.from.pathPrefix = avatarPathPrefix;
290
+ rule.to.cacheGroup = 'blockletProxy';
291
+ rule.to.target = avatarPathPrefix;
276
292
  rule.isProtected = true;
277
293
  site.rules.push(rule);
278
294
  }
@@ -321,7 +337,12 @@ const filterSitesForRemovedBlocklets = async (sites = []) => {
321
337
  }
322
338
 
323
339
  const did = getDidFromDomainGroupName(site.domain);
324
- return blocklets.some((x) => x.meta.did === did);
340
+ const blocklet = blocklets.find((x) => x.meta.did === did);
341
+ if (blocklet) {
342
+ site.mode = blocklet.mode;
343
+ }
344
+
345
+ return !!blocklet;
325
346
  });
326
347
  };
327
348
 
@@ -728,6 +749,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
728
749
  rules: [rule],
729
750
  },
730
751
  skipCheckDynamicBlacklist: true,
752
+ skipValidation: true,
731
753
  },
732
754
  context
733
755
  );
@@ -1124,7 +1146,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1124
1146
  // Ensure we have system rules for blocklets
1125
1147
  const blocklets = await blockletState.getBlocklets();
1126
1148
  const ensureBlocklet = async (x) => {
1127
- const blocklet = await blockletManager.ensureBlocklet(x.meta.did);
1149
+ const blocklet = await blockletManager.getBlocklet(x.meta.did);
1128
1150
  return ensureBlockletRouting(blocklet, context);
1129
1151
  };
1130
1152
  const ensureBlockletResults = await Promise.all(blocklets.map((x) => ensureBlocklet(x)));
@@ -10,7 +10,7 @@ const {
10
10
  BLOCKLET_SITE_GROUP_SUFFIX,
11
11
  GATEWAY_REQ_LIMIT,
12
12
  } = require('@abtnode/constant');
13
- const { BLOCKLET_UI_INTERFACES } = require('@blocklet/constant');
13
+ const { BLOCKLET_UI_INTERFACES, BLOCKLET_MODES } = require('@blocklet/constant');
14
14
  const logger = require('@abtnode/logger')('@abtnode/core:router');
15
15
 
16
16
  const expandSites = (sites = []) => {
@@ -208,6 +208,7 @@ Router.formatSites = (sites = []) => {
208
208
  port: daemonRule.to.port,
209
209
  did: rule.to.did,
210
210
  componentId: rule.to.componentId,
211
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
211
212
  },
212
213
  });
213
214
  site.rules.push({
@@ -221,6 +222,7 @@ Router.formatSites = (sites = []) => {
221
222
  port: daemonRule.to.port,
222
223
  did: rule.to.did,
223
224
  componentId: rule.to.componentId,
225
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
224
226
  },
225
227
  });
226
228
 
@@ -233,6 +235,7 @@ Router.formatSites = (sites = []) => {
233
235
  did: rule.to.did,
234
236
  type: ROUTING_RULE_TYPES.DAEMON,
235
237
  target: BLOCKLET_PROXY_PATH_PREFIX,
238
+ cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletProxy' : '',
236
239
  },
237
240
  });
238
241
  }
@@ -8,6 +8,7 @@ const path = require('path');
8
8
  const os = require('os');
9
9
  const fse = require('fs-extra');
10
10
  const get = require('lodash/get');
11
+ const toLower = require('lodash/toLower');
11
12
  const { EventEmitter } = require('events');
12
13
  const uuid = require('uuid');
13
14
  const isUrl = require('is-url');
@@ -154,20 +155,20 @@ class RouterManager extends EventEmitter {
154
155
 
155
156
  // eslint-disable-next-line no-unused-vars
156
157
  async updateRoutingSite(params, context = {}) {
157
- await validateUpdateSite(params, context);
158
- const site = await states.site.findOne({ _id: params.id });
159
- if (!site) {
158
+ const site = await validateUpdateSite(params, context);
159
+ const existed = await states.site.findOne({ _id: site.id });
160
+ if (!existed) {
160
161
  throw new Error('Can not update non-existing site');
161
162
  }
162
163
 
163
164
  const updateSet = {};
164
165
 
165
- if (params.corsAllowedOrigins) {
166
- updateSet.corsAllowedOrigins = params.corsAllowedOrigins.filter((x) => x !== '__none__');
166
+ if (site.corsAllowedOrigins) {
167
+ updateSet.corsAllowedOrigins = site.corsAllowedOrigins.filter((x) => x !== '__none__');
167
168
  }
168
169
 
169
- if (params.domain) {
170
- const newDomain = params.domain;
170
+ if (site.domain) {
171
+ const newDomain = site.domain;
171
172
  const ruleCountInDB = await states.site.count({
172
173
  $or: [{ domain: newDomain }, { domainAliases: newDomain }, { 'domainAliases.value': newDomain }],
173
174
  });
@@ -179,18 +180,18 @@ class RouterManager extends EventEmitter {
179
180
  updateSet.domain = newDomain;
180
181
  }
181
182
 
182
- const updated = await states.site.update({ _id: params.id }, { $set: updateSet }, { multi: false, upsert: false });
183
+ const updated = await states.site.update({ _id: site.id }, { $set: updateSet }, { multi: false, upsert: false });
183
184
 
184
- logger.info('router.site.updated', { params, updated });
185
- this.emit('router.site.updated', params.id);
185
+ logger.info('router.site.updated', { site, updated });
186
+ this.emit('router.site.updated', site.id);
186
187
 
187
- const dbSite = await states.site.findOne({ _id: params.id });
188
+ const dbSite = await states.site.findOne({ _id: site.id });
188
189
  await attachRuntimeDomainAliases({ sites: dbSite, context, node: states.node });
189
190
  return dbSite;
190
191
  }
191
192
 
192
- async addDomainAlias({ id, domainAlias, force }, context = {}) {
193
- await validateAddDomainAlias(domainAlias, context);
193
+ async addDomainAlias({ id, domainAlias: tmpAlias, force }, context = {}) {
194
+ const domainAlias = await validateAddDomainAlias(tmpAlias, context);
194
195
  const dbSite = await states.site.findOne({ _id: id });
195
196
  if (!dbSite) {
196
197
  throw new Error(`site ${id} does not exist`);
@@ -222,10 +223,10 @@ class RouterManager extends EventEmitter {
222
223
  }
223
224
  }
224
225
 
225
- // let custom domain in front of protected domain
226
- const domainAliases = [{ value: domainAlias, isProtected: false }, ...(dbSite.domainAliases || [])];
227
-
228
- const updateResult = await states.site.update({ _id: id }, { $set: { domainAliases } });
226
+ const updateResult = await states.site.update(
227
+ { _id: id },
228
+ { $push: { domainAliases: { value: domainAlias, isProtected: false } } }
229
+ );
229
230
  logger.debug('add domain alias update result', { id, updateResult, domainAlias });
230
231
 
231
232
  const newSite = await states.site.findOne({ _id: id });
@@ -234,8 +235,8 @@ class RouterManager extends EventEmitter {
234
235
  return newSite;
235
236
  }
236
237
 
237
- async deleteDomainAlias({ id, domainAlias }, context = {}) {
238
- await validateAddDomainAlias(domainAlias, context);
238
+ async deleteDomainAlias({ id, domainAlias: tmpAlias }, context = {}) {
239
+ const domainAlias = await validateAddDomainAlias(tmpAlias, context);
239
240
  const dbSite = await states.site.findOne({ _id: id });
240
241
  if (!dbSite) {
241
242
  throw new Error(`site ${id} does not exist`);
@@ -243,10 +244,10 @@ class RouterManager extends EventEmitter {
243
244
 
244
245
  dbSite.domainAliases = dbSite.domainAliases.filter((x) => {
245
246
  if (typeof x === 'string') {
246
- return x !== domainAlias;
247
+ return toLower(x) !== domainAlias;
247
248
  }
248
249
 
249
- return x.value !== domainAlias;
250
+ return toLower(x.value) !== domainAlias;
250
251
  });
251
252
 
252
253
  const updateResult = await states.site.update({ _id: id }, { $set: { domainAliases: dbSite.domainAliases } });
@@ -53,6 +53,9 @@ const formatBlocklet = (blocklet, phase, dek) => {
53
53
  if (!env) {
54
54
  return;
55
55
  }
56
+ // salt in blocklet state is different from the salt in blocklet-extra state
57
+ // in blocklet-extra state, salt is app meta did in each component
58
+ // in blocklet state, salt is component meta did in each component
56
59
  if (phase === 'onUpdate' && isHex(env.value) === true) {
57
60
  env.value = security.encrypt(env.value, b.meta.did, dek);
58
61
  }
@@ -77,6 +77,7 @@ class SiteState extends BaseState {
77
77
 
78
78
  async findOneByBlocklet(did) {
79
79
  const result = await this.findOne({ domain: getBlockletDomainGroupName(did) });
80
+
80
81
  return BaseState.renameIdFiledName(result);
81
82
  }
82
83
 
@@ -142,8 +142,9 @@ const PRIVATE_NODE_ENVS = [
142
142
  */
143
143
  const getComponentDirs = (
144
144
  component,
145
- { dataDirs, ensure = false, e2eMode = false, validate = true, ancestors = [] } = {}
145
+ { dataDirs, ensure = false, e2eMode = false, validate = false, ancestors = [] } = {}
146
146
  ) => {
147
+ // FIXME 这个函数做了太多的事
147
148
  // get data dirs
148
149
 
149
150
  const { name: appName } = ancestors.concat(component)[0].meta;
@@ -1360,9 +1361,8 @@ const getBlocklet = async ({
1360
1361
  dataDirs,
1361
1362
  states,
1362
1363
  e2eMode = false,
1363
- validateEnv = true,
1364
1364
  throwOnNotExist = true,
1365
- ensureDirs = true,
1365
+ ensureIntegrity = false,
1366
1366
  } = {}) => {
1367
1367
  if (!did) {
1368
1368
  throw new Error('Blocklet did does not exist');
@@ -1381,7 +1381,7 @@ const getBlocklet = async ({
1381
1381
 
1382
1382
  const blocklet = await states.blocklet.getBlocklet(did);
1383
1383
  if (!blocklet) {
1384
- if (throwOnNotExist) {
1384
+ if (throwOnNotExist || ensureIntegrity) {
1385
1385
  throw new Error(`can not find blocklet in database by did ${did}`);
1386
1386
  }
1387
1387
  return null;
@@ -1418,8 +1418,8 @@ const getBlocklet = async ({
1418
1418
  processId: getComponentProcessId(component, ancestors),
1419
1419
  ...getComponentDirs(component, {
1420
1420
  dataDirs,
1421
- ensure: ensureDirs,
1422
- validate: validateEnv,
1421
+ ensure: ensureIntegrity,
1422
+ validate: ensureIntegrity,
1423
1423
  ancestors,
1424
1424
  e2eMode: level === 0 ? e2eMode : false,
1425
1425
  }),
@@ -1554,6 +1554,9 @@ const createDataArchive = (dataDir, fileName) => {
1554
1554
  const validateAppConfig = async (config, blockletDid, states) => {
1555
1555
  const x = config;
1556
1556
 
1557
+ // sk should be force secured while other app prop should not be secured
1558
+ config.secure = x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK;
1559
+
1557
1560
  if (x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK) {
1558
1561
  if (x.value) {
1559
1562
  try {
@@ -1,10 +1,12 @@
1
1
  /* eslint-disable newline-per-chained-call */
2
2
  const Joi = require('joi');
3
- const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES } = require('@abtnode/constant');
3
+ const { DOMAIN_FOR_DEFAULT_SITE, ROUTING_RULE_TYPES, ROUTER_CACHE_GROUPS } = require('@abtnode/constant');
4
4
  const { getMultipleLangParams } = require('./util');
5
5
 
6
6
  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]/;
7
7
 
8
+ const DOMAIN_SCHEMA = Joi.string().domain({ minDomainSegments: 1, tlds: false }).lowercase();
9
+
8
10
  const domainMessages = {
9
11
  en: {
10
12
  'alternatives.match': 'Illegal domain, please enter a domain like arcblock, arcblock.io, *.arcblock.io',
@@ -60,6 +62,12 @@ const ruleSchema = {
60
62
  then: Joi.required(),
61
63
  }),
62
64
  componentId: Joi.string().label('component id'), // component global id
65
+ // FUTURE: blocklets can register routing rules for provider cache
66
+ cacheGroup: Joi.string()
67
+ .label('cache group')
68
+ .valid(...Object.keys(ROUTER_CACHE_GROUPS))
69
+ .allow('')
70
+ .default(''),
63
71
  },
64
72
 
65
73
  // List of services that manipulate the request before the upstream blocklet
@@ -79,11 +87,7 @@ const ruleSchema = {
79
87
  };
80
88
 
81
89
  const corsSchema = Joi.array()
82
- .items(
83
- Joi.string().domain({ minDomainSegments: 1, tlds: false }),
84
- Joi.string().valid(DOMAIN_FOR_DEFAULT_SITE, '__none__'),
85
- Joi.string().ip()
86
- )
90
+ .items(DOMAIN_SCHEMA, Joi.string().valid(DOMAIN_FOR_DEFAULT_SITE, '__none__'), Joi.string().ip())
87
91
  .min(1)
88
92
  .optional();
89
93
 
@@ -91,7 +95,7 @@ const ruleJoiSchema = Joi.object(ruleSchema);
91
95
 
92
96
  const addDomainAlias = Joi.alternatives()
93
97
  .try(
94
- Joi.string().domain({ minDomainSegments: 1, tlds: false }),
98
+ DOMAIN_SCHEMA,
95
99
  Joi.string().regex(WILDCARD_DOMAIN_REGEX) // 这种其实是一种特殊的 tld
96
100
  )
97
101
  .required();
@@ -108,7 +112,7 @@ const updateAliases = domainAliases.required();
108
112
  const addSiteSchema = Joi.object({
109
113
  domain: Joi.alternatives()
110
114
  .try(
111
- Joi.string().domain({ minDomainSegments: 1, tlds: false }),
115
+ DOMAIN_SCHEMA,
112
116
  Joi.string().valid('', DOMAIN_FOR_DEFAULT_SITE),
113
117
  Joi.string().regex(WILDCARD_DOMAIN_REGEX) // 这种其实是一种特殊的 tld
114
118
  )
@@ -125,7 +129,7 @@ const updateSite = Joi.object({
125
129
  corsAllowedOrigins: corsSchema,
126
130
  domain: Joi.alternatives()
127
131
  .try(
128
- Joi.string().domain({ minDomainSegments: 1, tlds: false }),
132
+ DOMAIN_SCHEMA,
129
133
  Joi.string().regex(WILDCARD_DOMAIN_REGEX) // 这种其实是一种特殊的 tld
130
134
  )
131
135
  .optional()
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.8.65-beta-81d3340c",
6
+ "version": "1.8.65-beta-f7af64a4",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,18 +19,18 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.8.65-beta-81d3340c",
23
- "@abtnode/certificate-manager": "1.8.65-beta-81d3340c",
24
- "@abtnode/constant": "1.8.65-beta-81d3340c",
25
- "@abtnode/cron": "1.8.65-beta-81d3340c",
26
- "@abtnode/db": "1.8.65-beta-81d3340c",
27
- "@abtnode/logger": "1.8.65-beta-81d3340c",
28
- "@abtnode/queue": "1.8.65-beta-81d3340c",
29
- "@abtnode/rbac": "1.8.65-beta-81d3340c",
30
- "@abtnode/router-provider": "1.8.65-beta-81d3340c",
31
- "@abtnode/static-server": "1.8.65-beta-81d3340c",
32
- "@abtnode/timemachine": "1.8.65-beta-81d3340c",
33
- "@abtnode/util": "1.8.65-beta-81d3340c",
22
+ "@abtnode/auth": "1.8.65-beta-f7af64a4",
23
+ "@abtnode/certificate-manager": "1.8.65-beta-f7af64a4",
24
+ "@abtnode/constant": "1.8.65-beta-f7af64a4",
25
+ "@abtnode/cron": "1.8.65-beta-f7af64a4",
26
+ "@abtnode/db": "1.8.65-beta-f7af64a4",
27
+ "@abtnode/logger": "1.8.65-beta-f7af64a4",
28
+ "@abtnode/queue": "1.8.65-beta-f7af64a4",
29
+ "@abtnode/rbac": "1.8.65-beta-f7af64a4",
30
+ "@abtnode/router-provider": "1.8.65-beta-f7af64a4",
31
+ "@abtnode/static-server": "1.8.65-beta-f7af64a4",
32
+ "@abtnode/timemachine": "1.8.65-beta-f7af64a4",
33
+ "@abtnode/util": "1.8.65-beta-f7af64a4",
34
34
  "@arcblock/did": "1.18.37",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
36
  "@arcblock/did-util": "1.18.37",
@@ -38,9 +38,9 @@
38
38
  "@arcblock/jwt": "^1.18.37",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
40
  "@arcblock/vc": "1.18.37",
41
- "@blocklet/constant": "1.8.65-beta-81d3340c",
42
- "@blocklet/meta": "1.8.65-beta-81d3340c",
43
- "@blocklet/sdk": "1.8.65-beta-81d3340c",
41
+ "@blocklet/constant": "1.8.65-beta-f7af64a4",
42
+ "@blocklet/meta": "1.8.65-beta-f7af64a4",
43
+ "@blocklet/sdk": "1.8.65-beta-f7af64a4",
44
44
  "@did-space/client": "^0.1.66",
45
45
  "@fidm/x509": "^1.2.1",
46
46
  "@ocap/mcrypto": "1.18.37",
@@ -88,5 +88,5 @@
88
88
  "express": "^4.18.2",
89
89
  "jest": "^27.5.1"
90
90
  },
91
- "gitHead": "5a904b9192febd1d09a759d929ca4de639a50cd1"
91
+ "gitHead": "97607d6e12bf8508ac29ab6546110c4ae3b31a82"
92
92
  }