@abtnode/core 1.16.24-beta-30f58f8d → 1.16.24-beta-c8847287

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.
@@ -220,6 +220,40 @@ const pm2StatusMap = {
220
220
  */
221
221
  const getBlockletEngineNameByPlatform = (blockletMeta) => getBlockletEngine(blockletMeta).interpreter;
222
222
 
223
+ const getWalletAppNotification = async (blocklet, tempBlockletInfo) => {
224
+ let blockletInfo = tempBlockletInfo;
225
+ if (!blockletInfo) {
226
+ const nodeInfo = await states.node.read();
227
+ blockletInfo = getBlockletInfo(blocklet, nodeInfo.sk);
228
+ }
229
+
230
+ return {
231
+ actions: [
232
+ {
233
+ name: 'Visit',
234
+ link: blockletInfo.appUrl,
235
+ },
236
+ ],
237
+ attachments: [
238
+ {
239
+ type: 'dapp',
240
+ data: {
241
+ url: blockletInfo.appUrl,
242
+ appDID: blocklet.appPid,
243
+ logo:
244
+ blocklet.environmentObj.BLOCKLET_APP_LOGO ||
245
+ joinUrl(
246
+ blockletInfo.appUrl,
247
+ normalizePathPrefix(joinUrl(WELLKNOWN_SERVICE_PATH_PREFIX, '/blocklet/logo')) || '/'
248
+ ),
249
+ title: blockletInfo.name,
250
+ desc: blockletInfo.description,
251
+ },
252
+ },
253
+ ],
254
+ };
255
+ };
256
+
223
257
  class DiskBlockletManager extends BaseBlockletManager {
224
258
  constructor({
225
259
  dataDirs,
@@ -1434,6 +1468,45 @@ class DiskBlockletManager extends BaseBlockletManager {
1434
1468
 
1435
1469
  this.configSynchronizer.syncComponentConfig(childDid, rootDid, { serverSk });
1436
1470
  }
1471
+
1472
+ try {
1473
+ const observableConfigs = [
1474
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_URL,
1475
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_NAME,
1476
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_DESCRIPTION,
1477
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_LOGO,
1478
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_LOGO_SQUARE,
1479
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_LOGO_RECT,
1480
+ BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_LOGO_FAVICON,
1481
+ ];
1482
+
1483
+ const shouldSendWalletNotification = observableConfigs.some((x) => newConfigs.some((y) => y.key === x));
1484
+ const receiverUsers = await this.teamManager.getOwnerAndAdminUsers(newState.appPid, 1);
1485
+ const receiver = receiverUsers.map((x) => x.did);
1486
+
1487
+ if (shouldSendWalletNotification && receiver) {
1488
+ const nodeInfo = await states.node.read();
1489
+ const blockletInfo = getBlockletInfo(newState, nodeInfo.sk);
1490
+ const walletExtra = await getWalletAppNotification(newState, blockletInfo);
1491
+
1492
+ const notification = {
1493
+ receiver,
1494
+ teamDid: newState.appPid,
1495
+ title: 'Blocklet Config Changed',
1496
+ description: `Blocklet ${blockletInfo.name} config changed`,
1497
+ action: `/blocklets/${did}/overview`,
1498
+ entityType: 'blocklet',
1499
+ entityId: newState.appPid,
1500
+ severity: 'success',
1501
+ blockletUrl: blockletInfo.appUrl,
1502
+ extra: { wallet: walletExtra },
1503
+ };
1504
+
1505
+ await this.teamManager.createNotification(notification);
1506
+ }
1507
+ } catch (error) {
1508
+ logger.error('Failed to send wallet notification after updated config', { did, error });
1509
+ }
1437
1510
  }
1438
1511
 
1439
1512
  return newState;
@@ -3221,16 +3294,25 @@ class DiskBlockletManager extends BaseBlockletManager {
3221
3294
  }
3222
3295
 
3223
3296
  if (createNotification) {
3224
- this._createNotification(did, {
3225
- title: 'Blocklet Installed',
3226
- description: `Blocklet ${meta.title} is installed successfully. (Source: ${
3227
- deployedFrom || fromBlockletSource(source)
3228
- })`,
3229
- action: `/blocklets/${did}/overview`,
3230
- entityType: 'blocklet',
3231
- entityId: did,
3232
- severity: 'success',
3233
- });
3297
+ // 发送通知不阻塞后续安装流程
3298
+ try {
3299
+ const walletExtra = await getWalletAppNotification(blocklet);
3300
+
3301
+ this._createNotification(did, {
3302
+ title: 'Blocklet Installed',
3303
+ description: `Blocklet ${meta.title} is installed successfully. (Source: ${
3304
+ deployedFrom || fromBlockletSource(source)
3305
+ })`,
3306
+ action: `/blocklets/${did}/overview`,
3307
+ entityType: 'blocklet',
3308
+ entityId: did,
3309
+ severity: 'success',
3310
+ receiver: blocklet?.controller?.nftOwner,
3311
+ extra: { wallet: walletExtra },
3312
+ });
3313
+ } catch (error) {
3314
+ logger.error('create installed notification failed', { error, did });
3315
+ }
3234
3316
  }
3235
3317
 
3236
3318
  await this._rollbackCache.remove({ did: blocklet.meta.did });
@@ -3730,13 +3812,15 @@ class DiskBlockletManager extends BaseBlockletManager {
3730
3812
  }${WELLKNOWN_BLOCKLET_ADMIN_PATH}`;
3731
3813
  }
3732
3814
  } catch (error) {
3733
- logger.error('[_createNotification] get blocklet url failed', { error });
3815
+ logger.error('[_createNotification] get blocklet url failed', { did, error });
3734
3816
  }
3735
3817
 
3736
3818
  // if blocklet is external, no need to create notification in server
3737
3819
  const extra = await states.blockletExtras.getMeta(did);
3738
3820
  const isExternal = !!extra?.controller;
3739
- if (!isExternal) {
3821
+
3822
+ // 如果指定了 receiver, 或者是内部 blocklet, 则创建 notification
3823
+ if (notification.receiver || !isExternal) {
3740
3824
  await states.notification.create({ ...notification, blockletUrl });
3741
3825
  }
3742
3826
  await this.teamManager.createNotification({
@@ -3746,7 +3830,7 @@ class DiskBlockletManager extends BaseBlockletManager {
3746
3830
  blockletUrl,
3747
3831
  });
3748
3832
  } catch (error) {
3749
- logger.error('create notification failed', { error });
3833
+ logger.error('create notification failed', { did, error });
3750
3834
  }
3751
3835
  }
3752
3836
 
@@ -113,7 +113,6 @@ const installComponentFromUrl = async ({
113
113
  if (onlyRequired) {
114
114
  newChildren = filterRequiredComponents(newChild, newChildren);
115
115
  }
116
-
117
116
  blocklet.children.push(...newChildren);
118
117
 
119
118
  checkVersionCompatibility(blocklet.children);
@@ -13,6 +13,7 @@ const {
13
13
  BLOCKLET_CONFIGURABLE_KEY,
14
14
  } = require('@blocklet/constant');
15
15
  const { EVENTS, BACKUPS } = require('@abtnode/constant');
16
+
16
17
  const { NodeMonitSender } = require('../monitor/node-monit-sender');
17
18
  const handleInstanceInStore = require('../util/public-to-store');
18
19
  const { isCLI } = require('../util');
@@ -145,6 +146,7 @@ module.exports = ({
145
146
  }
146
147
 
147
148
  await teamAPI.refreshBlockletInterfacePermissions(blocklet.meta);
149
+ logger.info('refreshed blocklet interface permissions after installed', { did: blocklet.meta.did });
148
150
  } catch (error) {
149
151
  logger.error('create.url.mapping.error', { event: name, error });
150
152
  notificationState.create({
@@ -154,7 +154,7 @@ class BlockletRuntimeMonitor extends EventEmitter {
154
154
 
155
155
  async monitAll() {
156
156
  if (this.inProgress) {
157
- this.logger.error('monitoring is in progress');
157
+ this.logger.debug('monitoring is in progress');
158
158
  return;
159
159
  }
160
160
 
@@ -105,7 +105,7 @@ class NodeRuntimeMonitor extends EventEmitter {
105
105
 
106
106
  async monit() {
107
107
  if (this.inProgress) {
108
- this.logger.error('monitoring is in progress');
108
+ this.logger.debug('monitoring is in progress');
109
109
  return;
110
110
  }
111
111
 
@@ -137,11 +137,11 @@ class TeamManager extends EventEmitter {
137
137
  return this.getState(teamDid, 'notification');
138
138
  }
139
139
 
140
- async createNotification({ teamDid, ...payload }) {
140
+ async createNotification({ teamDid, receiver, ...payload }) {
141
141
  const notification = await this.getState(teamDid, 'notification');
142
142
  const doc = await notification.create({ ...payload, teamDid });
143
143
  const metaDid = await this.states.blocklet.getBlockletMetaDid(teamDid);
144
- this.emit(EVENTS.NOTIFICATION_BLOCKLET_CREATE, { meta: { did: metaDid }, ...payload, ...doc, teamDid });
144
+ this.emit(EVENTS.NOTIFICATION_BLOCKLET_CREATE, { meta: { did: metaDid }, ...payload, ...doc, teamDid, receiver });
145
145
  }
146
146
 
147
147
  async getProjectState(teamDid) {
@@ -8,7 +8,40 @@ const { filterDuplicateComponents, parseComponents } = require('./blocklet');
8
8
  async function getDynamicComponents({ url }) {
9
9
  const rawMeta = await axios.get(url).then((res) => res.data);
10
10
  const { dynamicComponents } = await parseComponents({ meta: rawMeta });
11
- return filterDuplicateComponents(dynamicComponents);
11
+
12
+ const components = filterDuplicateComponents(dynamicComponents);
13
+
14
+ const requiredComponents = {};
15
+ rawMeta.components?.forEach((component) => {
16
+ if (component.required) {
17
+ requiredComponents[component.source?.name || component.name] = true;
18
+ }
19
+ });
20
+
21
+ const subRequiredComponents = {};
22
+ components.forEach((component) => {
23
+ component.required = !!requiredComponents[component.meta?.name || component.meta?.did];
24
+ if (component.required && component.meta?.components) {
25
+ component.meta.components.forEach((subComponent) => {
26
+ if (subComponent.required) {
27
+ if (subComponent.source?.name) {
28
+ subRequiredComponents[subComponent.source?.name] = true;
29
+ }
30
+ subRequiredComponents[subComponent.name] = true;
31
+ }
32
+ });
33
+ }
34
+ });
35
+ components.forEach((component) => {
36
+ if (subRequiredComponents[component.meta?.name || component.meta?.did]) {
37
+ component.required = true;
38
+ }
39
+ });
40
+
41
+ // eslint-disable-next-line no-nested-ternary
42
+ components.sort((a, b) => (a.required === b.required ? 0 : a.required ? -1 : 1));
43
+
44
+ return components;
12
45
  }
13
46
 
14
47
  module.exports = getDynamicComponents;
@@ -1,8 +1,9 @@
1
1
  const logger = require('@abtnode/logger')('@abtnode/core:webhook:index');
2
-
3
2
  const { evaluateURLs } = require('@abtnode/util/lib/url-evaluation');
4
3
  const checkURLAccessible = require('@abtnode/util/lib/url-evaluation/check-accessible-node');
5
4
  const { EVENTS } = require('@abtnode/constant');
5
+ const isEmpty = require('lodash/isEmpty');
6
+
6
7
  const WebHookSender = require('./sender');
7
8
  const WalletSender = require('./sender/wallet');
8
9
  const createQueue = require('../util/queue');
@@ -78,7 +79,7 @@ module.exports = ({ events, dataDirs, instance }) => {
78
79
  const webhookState = states.webhook;
79
80
  const notification = states.notification; // eslint-disable-line
80
81
 
81
- const sendMessage = async (message) => {
82
+ const sendMessage = async ({ extra, ...message } = {}) => {
82
83
  try {
83
84
  const webhookList = await webhookState.list();
84
85
  const nodeInfo = await nodeState.read();
@@ -98,7 +99,7 @@ module.exports = ({ events, dataDirs, instance }) => {
98
99
  const senderInstance = WebHookSender.getMessageSender(item.type);
99
100
  senderFns[item.type] = senderInstance.send.bind(senderInstance);
100
101
  }
101
- const options = { ...message, nodeInfo, node: instance };
102
+ let options = { ...message, nodeInfo, node: instance };
102
103
  if (item.type === 'slack') {
103
104
  // eslint-disable-next-line
104
105
  options.urlInfo = await getSlackUrlInfo({
@@ -106,7 +107,10 @@ module.exports = ({ events, dataDirs, instance }) => {
106
107
  path: message.action,
107
108
  serverUrls: baseUrls,
108
109
  });
110
+ } else if (item.type === WalletSender.type && !isEmpty(extra?.wallet)) {
111
+ options = { ...options, ...extra.wallet };
109
112
  }
113
+
110
114
  try {
111
115
  // eslint-disable-next-line
112
116
  await senderFns[item.type](item.params, options);
@@ -135,9 +139,9 @@ module.exports = ({ events, dataDirs, instance }) => {
135
139
 
136
140
  [EVENTS.NOTIFICATION_CREATE, EVENTS.NOTIFICATION_BLOCKLET_CREATE].forEach((event) => {
137
141
  events.on(event, (data) => {
138
- const { title, description, severity, action, entityType, blockletUrl, entityId } = data;
139
- if (!reduceQueue({ title, description, entityType, entityId, severity })) {
140
- queue.push({ title, description, status: severity, action, entityType, blockletUrl });
142
+ const { title, description, severity, action, entityType, blockletUrl, entityId, extra, receiver } = data;
143
+ if (!reduceQueue({ title, description, entityType, entityId, severity, extra })) {
144
+ queue.push({ title, description, status: severity, action, entityType, blockletUrl, extra, receiver });
141
145
  }
142
146
  });
143
147
  });
@@ -5,7 +5,7 @@ const BaseSender = require('../base');
5
5
 
6
6
  class WalletSender extends BaseSender {
7
7
  async send(params, data = {}) {
8
- const { title, description, nodeInfo, node } = data;
8
+ const { title, description, nodeInfo, node, receiver, actions, attachments } = data;
9
9
 
10
10
  try {
11
11
  const sender = {
@@ -17,28 +17,37 @@ class WalletSender extends BaseSender {
17
17
  const message = {
18
18
  title,
19
19
  body: description,
20
+ actions,
21
+ attachments,
20
22
  };
21
23
 
22
- const { users } = await node.getUsers({
23
- teamDid: nodeInfo.did,
24
- paging: { pageSize: 100 },
25
- query: { includePassports: true },
26
- });
27
- const adminUsers = users
28
- .filter(
29
- (x) =>
30
- x.approved &&
31
- (x.passports || []).some(
32
- (y) => [ROLES.OWNER, ROLES.ADMIN].includes(y.name) && y.status === PASSPORT_STATUS.VALID
33
- )
34
- )
35
- .map((x) => x.did);
36
-
37
- if (!adminUsers.length) {
24
+ let to = [];
25
+
26
+ if (receiver) {
27
+ to = Array.isArray(receiver) ? receiver : [receiver];
28
+ } else {
29
+ const { users } = await node.getUsers({
30
+ teamDid: nodeInfo.did,
31
+ paging: { pageSize: 100 },
32
+ query: { includePassports: true },
33
+ });
34
+
35
+ to = users
36
+ .filter(
37
+ (x) =>
38
+ x.approved &&
39
+ (x.passports || []).some(
40
+ (y) => [ROLES.OWNER, ROLES.ADMIN].includes(y.name) && y.status === PASSPORT_STATUS.VALID
41
+ )
42
+ )
43
+ .map((x) => x.did);
44
+ }
45
+
46
+ if (!to.length) {
38
47
  return;
39
48
  }
40
49
 
41
- await sendToUser(adminUsers, message, sender, process.env.ABT_NODE_SERVICE_PORT);
50
+ await sendToUser(to, message, sender, process.env.ABT_NODE_SERVICE_PORT);
42
51
  } catch (error) {
43
52
  delete error.request;
44
53
  delete error.response;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.24-beta-30f58f8d",
6
+ "version": "1.16.24-beta-c8847287",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,19 +19,19 @@
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.24-beta-30f58f8d",
23
- "@abtnode/auth": "1.16.24-beta-30f58f8d",
24
- "@abtnode/certificate-manager": "1.16.24-beta-30f58f8d",
25
- "@abtnode/constant": "1.16.24-beta-30f58f8d",
26
- "@abtnode/cron": "1.16.24-beta-30f58f8d",
27
- "@abtnode/logger": "1.16.24-beta-30f58f8d",
28
- "@abtnode/models": "1.16.24-beta-30f58f8d",
29
- "@abtnode/queue": "1.16.24-beta-30f58f8d",
30
- "@abtnode/rbac": "1.16.24-beta-30f58f8d",
31
- "@abtnode/router-provider": "1.16.24-beta-30f58f8d",
32
- "@abtnode/static-server": "1.16.24-beta-30f58f8d",
33
- "@abtnode/timemachine": "1.16.24-beta-30f58f8d",
34
- "@abtnode/util": "1.16.24-beta-30f58f8d",
22
+ "@abtnode/analytics": "1.16.24-beta-c8847287",
23
+ "@abtnode/auth": "1.16.24-beta-c8847287",
24
+ "@abtnode/certificate-manager": "1.16.24-beta-c8847287",
25
+ "@abtnode/constant": "1.16.24-beta-c8847287",
26
+ "@abtnode/cron": "1.16.24-beta-c8847287",
27
+ "@abtnode/logger": "1.16.24-beta-c8847287",
28
+ "@abtnode/models": "1.16.24-beta-c8847287",
29
+ "@abtnode/queue": "1.16.24-beta-c8847287",
30
+ "@abtnode/rbac": "1.16.24-beta-c8847287",
31
+ "@abtnode/router-provider": "1.16.24-beta-c8847287",
32
+ "@abtnode/static-server": "1.16.24-beta-c8847287",
33
+ "@abtnode/timemachine": "1.16.24-beta-c8847287",
34
+ "@abtnode/util": "1.16.24-beta-c8847287",
35
35
  "@arcblock/did": "1.18.110",
36
36
  "@arcblock/did-auth": "1.18.110",
37
37
  "@arcblock/did-ext": "^1.18.110",
@@ -42,11 +42,11 @@
42
42
  "@arcblock/pm2-events": "^0.0.5",
43
43
  "@arcblock/validator": "^1.18.110",
44
44
  "@arcblock/vc": "1.18.110",
45
- "@blocklet/constant": "1.16.24-beta-30f58f8d",
46
- "@blocklet/env": "1.16.24-beta-30f58f8d",
47
- "@blocklet/meta": "1.16.24-beta-30f58f8d",
48
- "@blocklet/resolver": "1.16.24-beta-30f58f8d",
49
- "@blocklet/sdk": "1.16.24-beta-30f58f8d",
45
+ "@blocklet/constant": "1.16.24-beta-c8847287",
46
+ "@blocklet/env": "1.16.24-beta-c8847287",
47
+ "@blocklet/meta": "1.16.24-beta-c8847287",
48
+ "@blocklet/resolver": "1.16.24-beta-c8847287",
49
+ "@blocklet/sdk": "1.16.24-beta-c8847287",
50
50
  "@did-space/client": "^0.3.64",
51
51
  "@fidm/x509": "^1.2.1",
52
52
  "@ocap/mcrypto": "1.18.110",
@@ -102,5 +102,5 @@
102
102
  "jest": "^29.7.0",
103
103
  "unzipper": "^0.10.11"
104
104
  },
105
- "gitHead": "95f8e79898d7901f0665f3883e3c014c36f16668"
105
+ "gitHead": "463311bdbd2cf425eb5c1fcf94e821053de1f7b1"
106
106
  }