@abtnode/core 1.16.39 → 1.16.40-beta-20250227-092112-1815be0a

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.
@@ -4,6 +4,7 @@ const fs = require('fs-extra');
4
4
  const path = require('path');
5
5
  const flat = require('flat');
6
6
  const { LRUCache } = require('lru-cache');
7
+ const isUrl = require('is-url');
7
8
  const get = require('lodash/get');
8
9
  const uniq = require('lodash/uniq');
9
10
  const omit = require('lodash/omit');
@@ -787,13 +788,6 @@ class DiskBlockletManager extends BaseBlockletManager {
787
788
 
788
789
  const nodeInfo = await states.node.read();
789
790
 
790
- if (checkDockerRunHistory(nodeInfo)) {
791
- await dockerExecChown(`${blocklet?.meta?.did}-start`, [
792
- path.join(process.env.ABT_NODE_DATA_DIR, 'data', blocklet?.meta?.did),
793
- path.join(process.env.ABT_NODE_DATA_DIR, 'tmp', 'pnpm-stores'),
794
- ]);
795
- }
796
-
797
791
  const nodeEnvironments = await states.node.getEnvironments();
798
792
 
799
793
  if (checkDockerRunHistory(nodeInfo)) {
@@ -2042,6 +2036,13 @@ class DiskBlockletManager extends BaseBlockletManager {
2042
2036
  return newState;
2043
2037
  }
2044
2038
 
2039
+ async updateVault({ did, vaults }, context) {
2040
+ await states.blocklet.updateBlockletVaults(did, vaults);
2041
+ const newState = await this.getBlocklet(did);
2042
+ this.emit(BlockletEvents.updated, { ...newState, context });
2043
+ return newState;
2044
+ }
2045
+
2045
2046
  // eslint-disable-next-line no-unused-vars
2046
2047
  async getRuntimeHistory({ did, hours }, context) {
2047
2048
  const metaDid = await states.blocklet.getBlockletMetaDid(did);
@@ -2409,6 +2410,36 @@ class DiskBlockletManager extends BaseBlockletManager {
2409
2410
  return spaceGateways;
2410
2411
  }
2411
2412
 
2413
+ async updateUserSpaceHosts({ did, url }) {
2414
+ if (isUrl(url)) {
2415
+ try {
2416
+ const { data } = await request.get(joinURL(url, '__blocklet__.js?type=json'), { timeout: 5000 });
2417
+ if (Array.isArray(data.domainAliases)) {
2418
+ const userSpaceHosts = await this.getUserSpaceHosts({ did });
2419
+ const validHosts = data.domainAliases.filter(
2420
+ (x) => x.endsWith('.did.abtnet.io') === false && x.endsWith('.ip.abtnet.io') === false
2421
+ );
2422
+ if (validHosts.every((x) => userSpaceHosts.includes(x))) {
2423
+ return;
2424
+ }
2425
+
2426
+ logger.info('updateUserSpaceHosts', { did, url, domains: data.domainAliases });
2427
+ await states.blockletExtras.setSettings(did, {
2428
+ userSpaceHosts: uniq([...userSpaceHosts, ...validHosts]),
2429
+ });
2430
+ this.emit(BlockletInternalEvents.appSettingChanged, { appDid: did });
2431
+ }
2432
+ } catch (error) {
2433
+ logger.error('updateUserSpaceHosts', { did, url, error });
2434
+ }
2435
+ }
2436
+ }
2437
+
2438
+ async getUserSpaceHosts({ did }) {
2439
+ const userSpaceHosts = await states.blockletExtras.getSettings(did, 'userSpaceHosts', []);
2440
+ return userSpaceHosts;
2441
+ }
2442
+
2412
2443
  /**
2413
2444
  * @description
2414
2445
  * @param {{
@@ -4331,25 +4362,6 @@ class DiskBlockletManager extends BaseBlockletManager {
4331
4362
  }
4332
4363
  }
4333
4364
 
4334
- // to be deleted
4335
- async _setAppSk(did, appSk, context) {
4336
- if (process.env.NODE_ENV === 'production' && !appSk) {
4337
- throw new Error(`appSk for blocklet ${did} is required`);
4338
- }
4339
-
4340
- if (appSk) {
4341
- await this.config(
4342
- {
4343
- did,
4344
- configs: [{ key: 'BLOCKLET_APP_SK', value: appSk, secure: true }],
4345
- skipHook: true,
4346
- skipDidDocument: true,
4347
- },
4348
- context
4349
- );
4350
- }
4351
- }
4352
-
4353
4365
  async _getBlockletForInstallation(did) {
4354
4366
  const blocklet = await states.blocklet.getBlocklet(did, { decryptSk: false });
4355
4367
  if (!blocklet) {
@@ -214,6 +214,10 @@ const RBAC_CONFIG = {
214
214
  name: 'mutate_blocklet',
215
215
  description: 'Perform state changing actions on a blocklet, such as upgrade/config/start/stop',
216
216
  },
217
+ {
218
+ name: 'mutate_vault',
219
+ description: 'Manage vault for a blocklet',
220
+ },
217
221
  ]),
218
222
  grants: Object.freeze({
219
223
  [SERVER_ROLES.GUEST]: [
@@ -247,7 +251,7 @@ const RBAC_CONFIG = {
247
251
 
248
252
  // blocklet app or blocklet user
249
253
  [SERVER_ROLES.BLOCKLET_SDK]: ['query_team', 'mutate_team', 'query_blocklet'],
250
- [SERVER_ROLES.BLOCKLET_OWNER]: [SERVER_ROLES.BLOCKLET_ADMIN],
254
+ [SERVER_ROLES.BLOCKLET_OWNER]: [SERVER_ROLES.BLOCKLET_ADMIN, 'mutate_vault'],
251
255
  [SERVER_ROLES.BLOCKLET_ADMIN]: [
252
256
  SERVER_ROLES.BLOCKLET_MEMBER,
253
257
  'mutate_team',
@@ -710,6 +714,7 @@ module.exports = Object.freeze({
710
714
  'deleteBlockletSecurityRule',
711
715
  'deleteBlockletResponseHeaderPolicy',
712
716
  'deleteBlockletAccessPolicy',
717
+ 'configVault',
713
718
  ],
714
719
 
715
720
  // 如果是 multiple tenant 的情况下, 这些白名单不会验证 RBAC
@@ -38677,7 +38682,7 @@ module.exports = require("zlib");
38677
38682
  /***/ ((module) => {
38678
38683
 
38679
38684
  "use strict";
38680
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.38","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.38","@abtnode/auth":"1.16.38","@abtnode/certificate-manager":"1.16.38","@abtnode/constant":"1.16.38","@abtnode/cron":"1.16.38","@abtnode/docker-utils":"1.16.38","@abtnode/logger":"1.16.38","@abtnode/models":"1.16.38","@abtnode/queue":"1.16.38","@abtnode/rbac":"1.16.38","@abtnode/router-provider":"1.16.38","@abtnode/static-server":"1.16.38","@abtnode/timemachine":"1.16.38","@abtnode/util":"1.16.38","@arcblock/did":"1.19.10","@arcblock/did-auth":"1.19.10","@arcblock/did-ext":"^1.19.10","@arcblock/did-motif":"^1.1.13","@arcblock/did-util":"1.19.10","@arcblock/event-hub":"1.19.10","@arcblock/jwt":"^1.19.10","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"^1.19.10","@arcblock/vc":"1.19.10","@blocklet/constant":"1.16.38","@blocklet/did-space-js":"^1.0.19","@blocklet/env":"1.16.38","@blocklet/meta":"1.16.38","@blocklet/resolver":"1.16.38","@blocklet/sdk":"1.16.38","@blocklet/store":"1.16.38","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.19.10","@ocap/util":"1.19.10","@ocap/wallet":"1.19.10","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","lru-cache":"^11.0.2","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^9.0.1","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
38685
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.39","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.39","@abtnode/auth":"1.16.39","@abtnode/certificate-manager":"1.16.39","@abtnode/constant":"1.16.39","@abtnode/cron":"1.16.39","@abtnode/docker-utils":"1.16.39","@abtnode/logger":"1.16.39","@abtnode/models":"1.16.39","@abtnode/queue":"1.16.39","@abtnode/rbac":"1.16.39","@abtnode/router-provider":"1.16.39","@abtnode/static-server":"1.16.39","@abtnode/timemachine":"1.16.39","@abtnode/util":"1.16.39","@arcblock/did":"1.19.12","@arcblock/did-auth":"1.19.12","@arcblock/did-ext":"^1.19.12","@arcblock/did-motif":"^1.1.13","@arcblock/did-util":"1.19.12","@arcblock/event-hub":"1.19.12","@arcblock/jwt":"^1.19.12","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"^1.19.12","@arcblock/vc":"1.19.12","@blocklet/constant":"1.16.39","@blocklet/did-space-js":"^1.0.21","@blocklet/env":"1.16.39","@blocklet/meta":"1.16.39","@blocklet/resolver":"1.16.39","@blocklet/sdk":"1.16.39","@blocklet/store":"1.16.39","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.19.12","@ocap/util":"1.19.12","@ocap/wallet":"1.19.12","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","lru-cache":"^11.0.2","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^9.0.1","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
38681
38686
 
38682
38687
  /***/ }),
38683
38688
 
@@ -260,7 +260,12 @@ const createPackRelease = async ({
260
260
  script: 120,
261
261
  };
262
262
 
263
- meta.interfaces.push(...dockerParsePublishPorts(blockletDocker.dockerImage, blockletDocker.dockerArgs));
263
+ meta.interfaces.push(
264
+ ...dockerParsePublishPorts(
265
+ `${meta.title || blockletDocker.dockerImage}-${meta.did?.slice(-6)}`,
266
+ blockletDocker.dockerArgs
267
+ )
268
+ );
264
269
  }
265
270
 
266
271
  // merge extended blocklet.yml
@@ -0,0 +1,133 @@
1
+ const cloneDeep = require('lodash/cloneDeep');
2
+ const { schemas } = require('@arcblock/validator');
3
+ const { isValid, isFromPublicKey } = require('@arcblock/did');
4
+ const { getBlockletAppIdList } = require('@blocklet/meta/lib/util');
5
+ const { verifyVault } = require('@blocklet/meta/lib/security');
6
+ const formatError = require('@abtnode/util/lib/format-error');
7
+
8
+ const logger = require('@abtnode/logger')('@abtnode/core');
9
+
10
+ const validateVault = async (node, vaultDid, teamDid) => {
11
+ if (!isValid(vaultDid)) {
12
+ throw new Error('Invalid vault did');
13
+ }
14
+
15
+ const { error } = schemas.tokenHolder.validate(vaultDid);
16
+ if (error) {
17
+ throw new Error(`Invalid vault did type: ${formatError(error)}`);
18
+ }
19
+
20
+ const blocklet = await node.getBlocklet({ did: teamDid });
21
+ if (!blocklet) {
22
+ throw new Error('Blocklet not found');
23
+ }
24
+
25
+ // Do we need to do online check?
26
+ const appDids = getBlockletAppIdList(blocklet);
27
+ if (appDids.includes(vaultDid)) {
28
+ throw new Error('Can not use current blocklet did as vault');
29
+ }
30
+
31
+ // Ensure vault history is valid
32
+ const { vaults } = blocklet;
33
+ if (vaults.length > 0) {
34
+ if (vaults.some((vault) => vault.did === vaultDid)) {
35
+ throw new Error('Can not add same vault twice');
36
+ }
37
+
38
+ const result = await verifyVault(vaults, blocklet.appDid);
39
+ if (!result) {
40
+ throw new Error('Vault history verification failed');
41
+ }
42
+ }
43
+
44
+ return blocklet;
45
+ };
46
+
47
+ const validateSession = async (node, sessionId) => {
48
+ const session = await node.getSession({ id: sessionId });
49
+ if (!session) {
50
+ throw new Error('Vault config session not found');
51
+ }
52
+
53
+ if (session.type !== 'configVault') {
54
+ logger.error('Vault config session type mismatch', session);
55
+ throw new Error('Vault config session type mismatch');
56
+ }
57
+
58
+ const { vaultDid, teamDid } = session;
59
+ if (!isValid(vaultDid)) {
60
+ throw new Error('Invalid vault did');
61
+ }
62
+
63
+ if (!isValid(teamDid)) {
64
+ throw new Error('Invalid team did');
65
+ }
66
+
67
+ return session;
68
+ };
69
+
70
+ const configVault = async (node, { teamDid, vaultDid }, context) => {
71
+ await validateVault(node, vaultDid, teamDid);
72
+
73
+ // create a new session
74
+ const session = await node.startSession({
75
+ data: {
76
+ type: 'configVault',
77
+ vaultDid,
78
+ teamDid,
79
+ context,
80
+ },
81
+ });
82
+ logger.info('vault config attempt', session);
83
+
84
+ return session.id;
85
+ };
86
+
87
+ const commitVault = async (node, { sessionId, userDid, userPk, signature }) => {
88
+ if (!isFromPublicKey(userDid, userPk)) {
89
+ throw new Error('Vault pk and did mismatch');
90
+ }
91
+
92
+ const session = await validateSession(node, sessionId);
93
+ logger.info('vault config commit', { session, userDid, userPk, signature });
94
+
95
+ const { vaultDid, teamDid, context } = session;
96
+ if (userDid !== vaultDid) {
97
+ throw new Error('Vault did not match');
98
+ }
99
+
100
+ const blocklet = await validateVault(node, vaultDid, teamDid);
101
+ const vaults = cloneDeep(blocklet.vaults);
102
+ vaults.push({
103
+ did: userDid,
104
+ pk: userPk,
105
+ at: Date.now(),
106
+ sig: signature,
107
+ });
108
+
109
+ const result = await verifyVault(vaults, blocklet.appDid);
110
+ if (!result) {
111
+ throw new Error('Vault signature verification failed');
112
+ }
113
+
114
+ await node.updateBlockletVault({ did: teamDid, vaults }, context);
115
+ await node.endSession({ id: sessionId });
116
+ logger.info('vault config committed', { teamDid, vaultDid, context, sessionId: session.id });
117
+
118
+ await node.createAuditLog(
119
+ {
120
+ action: 'configVault',
121
+ args: { teamDid, vaultDid },
122
+ context,
123
+ },
124
+ node
125
+ );
126
+ };
127
+
128
+ module.exports = {
129
+ validateVault,
130
+ validateSession,
131
+ configVault,
132
+ commitVault,
133
+ };
@@ -12,8 +12,9 @@ const {
12
12
  TeamEvents,
13
13
  BLOCKLET_CONFIGURABLE_KEY,
14
14
  } = require('@blocklet/constant');
15
- const { EVENTS, BACKUPS, NODE_MODES } = require('@abtnode/constant');
16
-
15
+ const { EVENTS, BACKUPS, NODE_MODES, DEFAULT_DID_DOMAIN, WELLKNOWN_BLOCKLET_ADMIN_PATH } = require('@abtnode/constant');
16
+ const { joinURL } = require('ufo');
17
+ const { encode } = require('@abtnode/util/lib/base32');
17
18
  const { NodeMonitSender } = require('../monitor/node-monit-sender');
18
19
  const { isCLI } = require('../util');
19
20
 
@@ -241,6 +242,9 @@ module.exports = ({
241
242
  * @param {any} payload
242
243
  */
243
244
  const handleBlockletEvent = async (eventName, payload) => {
245
+ /**
246
+ * @type {import('@abtnode/client').BlockletState} payload
247
+ */
244
248
  const blocklet = payload.blocklet || payload;
245
249
 
246
250
  if (isCLI() && process.env.NODE_ENV !== 'test') {
@@ -335,6 +339,12 @@ module.exports = ({
335
339
  }
336
340
 
337
341
  if (payload?.progress !== 100) {
342
+ const nodeInfo = await node.getNodeInfo();
343
+ const appUrl = blocklet?.environments.find((x) => x.key === 'BLOCKLET_APP_URL')?.value;
344
+ /**
345
+ *
346
+ * @type {import('@blocklet/sdk/lib/types/notification').TNotificationInput | import('@blocklet/sdk/lib/types/notification').TNotification]} param
347
+ */
338
348
  const param = {
339
349
  title: 'App Backup Failed',
340
350
  description: `Failed to backup ${getDisplayName(blocklet)} to ${args.url}, due to: ${args.errorMessage}`,
@@ -342,8 +352,24 @@ module.exports = ({
342
352
  entityId: args.did,
343
353
  severity: 'error',
344
354
  sticky: true,
355
+ actions: [
356
+ {
357
+ name: 'View in server',
358
+ title: 'View in server',
359
+ link: joinURL(
360
+ `https://${encode(nodeInfo.did)}.${DEFAULT_DID_DOMAIN}`,
361
+ nodeInfo.routing.adminPath,
362
+ `/blocklets/${blocklet.appPid}/didSpaces`
363
+ ),
364
+ },
365
+ {
366
+ name: 'View in app',
367
+ title: 'View in app',
368
+ link: joinURL(appUrl, WELLKNOWN_BLOCKLET_ADMIN_PATH, 'did-spaces'),
369
+ },
370
+ ],
345
371
  };
346
- const nodeInfo = await node.getNodeInfo();
372
+
347
373
  await node.createNotification({ ...param, teamDid: nodeInfo.did });
348
374
  await node.createNotification({ ...param, teamDid: args.did });
349
375
  }
package/lib/index.js CHANGED
@@ -43,6 +43,7 @@ const getDynamicComponents = require('./util/get-dynamic-components');
43
43
  const SecurityAPI = require('./blocklet/security');
44
44
  const dockerRestartAllContainers = require('./util/docker/docker-restart-all-containers');
45
45
  const RouterBlocker = require('./router/security/blocker');
46
+ const BlockletVault = require('./blocklet/security/vault');
46
47
 
47
48
  /**
48
49
  * @typedef {{} & import('./api/team')}} TNode
@@ -333,6 +334,7 @@ function ABTNode(options) {
333
334
  fromStatus,
334
335
 
335
336
  states,
337
+ getUserState: teamManager.getUserState.bind(teamManager),
336
338
 
337
339
  onReady: onStatesReady,
338
340
 
@@ -411,6 +413,7 @@ function ABTNode(options) {
411
413
  setBlockletInitialized: blockletManager.setInitialized.bind(blockletManager),
412
414
  setBlockletOwner: blockletManager.updateOwner.bind(blockletManager),
413
415
  updateBlockletOwner: blockletManager.updateOwner.bind(blockletManager),
416
+ updateBlockletVault: blockletManager.updateVault.bind(blockletManager),
414
417
  getBlockletRuntimeHistory: blockletManager.getRuntimeHistory.bind(blockletManager),
415
418
 
416
419
  // blocklet spaces gateways
@@ -419,6 +422,9 @@ function ABTNode(options) {
419
422
  updateBlockletSpaceGateway: blockletManager.updateBlockletSpaceGateway.bind(blockletManager),
420
423
  getBlockletSpaceGateways: blockletManager.getBlockletSpaceGateways.bind(blockletManager),
421
424
 
425
+ updateUserSpaceHosts: blockletManager.updateUserSpaceHosts.bind(blockletManager),
426
+ getUserSpaceHosts: blockletManager.getUserSpaceHosts.bind(blockletManager),
427
+
422
428
  // auto backup related
423
429
  updateAutoBackup: blockletManager.updateAutoBackup.bind(blockletManager),
424
430
  getBlockletBackups: blockletManager.getBlockletBackups.bind(blockletManager),
@@ -699,6 +705,10 @@ function ABTNode(options) {
699
705
  addBlockletAccessPolicy: securityAPI.addBlockletAccessPolicy.bind(securityAPI),
700
706
  updateBlockletAccessPolicy: securityAPI.updateBlockletAccessPolicy.bind(securityAPI),
701
707
  deleteBlockletAccessPolicy: securityAPI.deleteBlockletAccessPolicy.bind(securityAPI),
708
+
709
+ // blocklet vault
710
+ configVault: (params, context) => BlockletVault.configVault(instance, params, context),
711
+ commitVault: (params) => BlockletVault.commitVault(instance, params),
702
712
  };
703
713
 
704
714
  const events = createEvents({
@@ -248,6 +248,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
248
248
  return `removed ${result.deletedComponent.meta.title}@${result.deletedComponent.meta.version} ${args.keepData !== false ? 'but kept its data and config' : 'and its data and config'}`; // prettier-ignore
249
249
  case 'configBlocklet':
250
250
  return `updated following config for ${args.did?.length > 1 ? componentOrApplicationInfo(result, [args.did[1]]) : 'application'}: ${args.configs.map(x => `*${x.key}*`).join(', ')}`; // prettier-ignore
251
+ case 'configVault':
252
+ return `updated vault for ${args.teamDid} to ${args.vaultDid}`;
251
253
  // @see: core/state/lib/event.js#311
252
254
  case 'backupToSpaces':
253
255
  if (args?.success) {
@@ -520,6 +522,7 @@ const getLogCategory = (action) => {
520
522
  case 'deleteBlocklet':
521
523
  case 'deleteComponent':
522
524
  case 'configBlocklet':
525
+ case 'configVault':
523
526
  case 'upgradeBlocklet':
524
527
  case 'upgradeComponents':
525
528
  case 'configNavigations':
@@ -28,6 +28,7 @@ const {
28
28
  BlockletGroup,
29
29
  } = require('@blocklet/constant');
30
30
  const { refreshPorts } = require('@abtnode/util/lib/port');
31
+ const { verifyVault } = require('@blocklet/meta/lib/security');
31
32
  const { APP_STRUCT_VERSION } = require('@abtnode/constant');
32
33
 
33
34
  const logger = require('@abtnode/logger')('@abtnode/core:states:blocklet');
@@ -299,7 +300,7 @@ class BlockletState extends BaseState {
299
300
  throw new Error(`Blocklet does not exist on update: ${did}`);
300
301
  }
301
302
 
302
- const formatted = formatBlocklet(cloneDeep(updates), 'onUpdate', this.config.dek);
303
+ const formatted = formatBlocklet(omit(cloneDeep(updates), ['vaults']), 'onUpdate', this.config.dek);
303
304
  const [, [updated]] = await this.update({ id: doc.id }, { $set: formatted });
304
305
 
305
306
  updated.status = getBlockletStatus(updated);
@@ -307,6 +308,18 @@ class BlockletState extends BaseState {
307
308
  return updated;
308
309
  }
309
310
 
311
+ async updateBlockletVaults(did, vaults) {
312
+ const doc = await this.getBlocklet(did);
313
+ if (!doc) {
314
+ throw new Error(`Blocklet does not exist on update vaults: ${did}`);
315
+ }
316
+
317
+ await verifyVault(vaults, doc.appDid, true);
318
+
319
+ const [, [updated]] = await this.update({ id: doc.id }, { $set: { vaults } });
320
+ return updated;
321
+ }
322
+
310
323
  async upgradeBlocklet({ meta, source, deployedFrom = '', children, manualChildPorts } = {}) {
311
324
  const doc = await this.getBlocklet(meta.did);
312
325
  if (!doc) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.39",
6
+ "version": "1.16.40-beta-20250227-092112-1815be0a",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,41 +19,41 @@
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.39",
23
- "@abtnode/auth": "1.16.39",
24
- "@abtnode/certificate-manager": "1.16.39",
25
- "@abtnode/constant": "1.16.39",
26
- "@abtnode/cron": "1.16.39",
27
- "@abtnode/docker-utils": "1.16.39",
28
- "@abtnode/logger": "1.16.39",
29
- "@abtnode/models": "1.16.39",
30
- "@abtnode/queue": "1.16.39",
31
- "@abtnode/rbac": "1.16.39",
32
- "@abtnode/router-provider": "1.16.39",
33
- "@abtnode/static-server": "1.16.39",
34
- "@abtnode/timemachine": "1.16.39",
35
- "@abtnode/util": "1.16.39",
36
- "@arcblock/did": "1.19.10",
37
- "@arcblock/did-auth": "1.19.10",
38
- "@arcblock/did-ext": "^1.19.10",
22
+ "@abtnode/analytics": "1.16.40-beta-20250227-092112-1815be0a",
23
+ "@abtnode/auth": "1.16.40-beta-20250227-092112-1815be0a",
24
+ "@abtnode/certificate-manager": "1.16.40-beta-20250227-092112-1815be0a",
25
+ "@abtnode/constant": "1.16.40-beta-20250227-092112-1815be0a",
26
+ "@abtnode/cron": "1.16.40-beta-20250227-092112-1815be0a",
27
+ "@abtnode/docker-utils": "1.16.40-beta-20250227-092112-1815be0a",
28
+ "@abtnode/logger": "1.16.40-beta-20250227-092112-1815be0a",
29
+ "@abtnode/models": "1.16.40-beta-20250227-092112-1815be0a",
30
+ "@abtnode/queue": "1.16.40-beta-20250227-092112-1815be0a",
31
+ "@abtnode/rbac": "1.16.40-beta-20250227-092112-1815be0a",
32
+ "@abtnode/router-provider": "1.16.40-beta-20250227-092112-1815be0a",
33
+ "@abtnode/static-server": "1.16.40-beta-20250227-092112-1815be0a",
34
+ "@abtnode/timemachine": "1.16.40-beta-20250227-092112-1815be0a",
35
+ "@abtnode/util": "1.16.40-beta-20250227-092112-1815be0a",
36
+ "@arcblock/did": "1.19.12",
37
+ "@arcblock/did-auth": "1.19.12",
38
+ "@arcblock/did-ext": "^1.19.12",
39
39
  "@arcblock/did-motif": "^1.1.13",
40
- "@arcblock/did-util": "1.19.10",
41
- "@arcblock/event-hub": "1.19.10",
42
- "@arcblock/jwt": "^1.19.10",
40
+ "@arcblock/did-util": "1.19.12",
41
+ "@arcblock/event-hub": "1.19.12",
42
+ "@arcblock/jwt": "^1.19.12",
43
43
  "@arcblock/pm2-events": "^0.0.5",
44
- "@arcblock/validator": "^1.19.10",
45
- "@arcblock/vc": "1.19.10",
46
- "@blocklet/constant": "1.16.39",
47
- "@blocklet/did-space-js": "^1.0.19",
48
- "@blocklet/env": "1.16.39",
49
- "@blocklet/meta": "1.16.39",
50
- "@blocklet/resolver": "1.16.39",
51
- "@blocklet/sdk": "1.16.39",
52
- "@blocklet/store": "1.16.39",
44
+ "@arcblock/validator": "^1.19.12",
45
+ "@arcblock/vc": "1.19.12",
46
+ "@blocklet/constant": "1.16.40-beta-20250227-092112-1815be0a",
47
+ "@blocklet/did-space-js": "^1.0.21",
48
+ "@blocklet/env": "1.16.40-beta-20250227-092112-1815be0a",
49
+ "@blocklet/meta": "1.16.40-beta-20250227-092112-1815be0a",
50
+ "@blocklet/resolver": "1.16.40-beta-20250227-092112-1815be0a",
51
+ "@blocklet/sdk": "1.16.40-beta-20250227-092112-1815be0a",
52
+ "@blocklet/store": "1.16.40-beta-20250227-092112-1815be0a",
53
53
  "@fidm/x509": "^1.2.1",
54
- "@ocap/mcrypto": "1.19.10",
55
- "@ocap/util": "1.19.10",
56
- "@ocap/wallet": "1.19.10",
54
+ "@ocap/mcrypto": "1.19.12",
55
+ "@ocap/util": "1.19.12",
56
+ "@ocap/wallet": "1.19.12",
57
57
  "@slack/webhook": "^5.0.4",
58
58
  "archiver": "^7.0.1",
59
59
  "axios": "^1.7.9",
@@ -110,5 +110,5 @@
110
110
  "jest": "^29.7.0",
111
111
  "unzipper": "^0.10.11"
112
112
  },
113
- "gitHead": "e3a614757b32dba71dcc187f20060932df31eab6"
113
+ "gitHead": "e33d791e24236a10ed3d196618aba989a0eee8ad"
114
114
  }