@abtnode/blocklet-services 1.16.11-next-a232f5fb → 1.16.11-next-3d2b39f7

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/api/index.js CHANGED
@@ -13,7 +13,7 @@ const minimatch = require('minimatch');
13
13
 
14
14
  const { getAccessLogStream } = require('@abtnode/logger');
15
15
  const { WELLKNOWN_SERVICE_PATH_PREFIX, NODE_SERVICES_PREFIX, EVENTS } = require('@abtnode/constant');
16
- const { BlockletEvents } = require('@blocklet/constant');
16
+ const { BlockletEvents, BlockletInternalEvents } = require('@blocklet/constant');
17
17
  const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
18
18
  const createInvite = require('@abtnode/auth/lib/invitation');
19
19
  const eventHub =
@@ -145,6 +145,13 @@ module.exports = function createServer(node, serverOptions = {}) {
145
145
  cache.del(cache.keyFns.node());
146
146
  });
147
147
 
148
+ [BlockletInternalEvents.componentsUpdated, BlockletInternalEvents.appConfigChanged].forEach((name) => {
149
+ eventHub.on(name, (data) => {
150
+ const { appDid } = data;
151
+ notificationService.sendToApp.exec({ event: name, appDid, data });
152
+ });
153
+ });
154
+
148
155
  // Http server
149
156
  const server = express();
150
157
 
@@ -1,24 +1,31 @@
1
1
  const { BlockletStatus } = require('@blocklet/constant');
2
2
  const getBlockletMaintenanceTemplate = require('@abtnode/router-templates/lib/blocklet-maintenance');
3
+ const { findComponentByIdV2 } = require('@blocklet/meta/lib/util');
3
4
 
4
5
  const { shouldGotoStartPage, getRedirectUrl } = require('../util');
5
6
 
6
7
  const checkRunning = async (req, res, next) => {
7
- const blocklet = await req.getBlocklet();
8
+ const app = await req.getBlocklet();
9
+ const componentId = req.getBlockletComponentId();
10
+ let component = findComponentByIdV2(app, componentId);
11
+
12
+ // for backward compatibility
13
+ component = component || app;
14
+
8
15
  if (
9
16
  ![
10
17
  BlockletStatus.running,
11
18
  // Waiting, Downloading should be allowed because blocklet is currently being upgrading
12
19
  BlockletStatus.waiting,
13
20
  BlockletStatus.downloading,
14
- ].includes(blocklet.status)
21
+ ].includes(component.status)
15
22
  ) {
16
- if (shouldGotoStartPage(req, blocklet)) {
23
+ if (shouldGotoStartPage(req, component)) {
17
24
  // FIXME: @wangshijun how to validate this token or generate token here?
18
25
  if (req.query.setupToken) {
19
26
  res.cookie('login_token', req.query.setupToken, { maxAge: 24 * 60 * 60 * 1000 });
20
27
  }
21
- if (blocklet.settings.initialized) {
28
+ if (app.settings.initialized) {
22
29
  res.redirect(getRedirectUrl({ req, pagePath: '/start' }));
23
30
  } else {
24
31
  res.redirect(getRedirectUrl({ req, pagePath: '/setup' }));
@@ -32,11 +39,18 @@ const checkRunning = async (req, res, next) => {
32
39
  if (req.accepts(['html', 'json']) === 'json') {
33
40
  res.json({ code: 'error', error: 'blocklet is under maintenance' });
34
41
  } else {
35
- res.send(getBlockletMaintenanceTemplate(blocklet, nodeInfo));
42
+ res.send(getBlockletMaintenanceTemplate(app, nodeInfo, component));
36
43
  }
37
44
  return;
38
45
  }
39
46
 
47
+ const url = new URL(`http://localhost${req.url}`);
48
+ if (url.searchParams.get('__start__')) {
49
+ url.searchParams.delete('__start__');
50
+ res.redirect(`${url.pathname}${url.search}`);
51
+ return;
52
+ }
53
+
40
54
  next();
41
55
  };
42
56
 
@@ -21,7 +21,12 @@ const {
21
21
  cacheError,
22
22
  } = require('@abtnode/util/lib/logo-middleware');
23
23
  const formatName = require('@abtnode/util/lib/format-name');
24
- const { fixBlockletStatus, wipeSensitiveData, findComponentById } = require('@blocklet/meta/lib/util');
24
+ const {
25
+ fixBlockletStatus,
26
+ wipeSensitiveData,
27
+ findComponentByIdV2,
28
+ forEachComponentV2Sync,
29
+ } = require('@blocklet/meta/lib/util');
25
30
  const { WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX, ROLES } = require('@abtnode/constant');
26
31
  const logger = require('@abtnode/logger')(require('../../package.json').name);
27
32
 
@@ -88,7 +93,7 @@ module.exports = {
88
93
  onGetBlocklet: async ({ req }) => {
89
94
  const blocklet = await req.getBlocklet();
90
95
  const dids = req.url.split('?')[0].replace(`${prefix}/blocklet/logo-bundle`, '').split('/').filter(Boolean);
91
- const component = findComponentById(blocklet, [blocklet.meta.did].concat(dids));
96
+ const component = findComponentByIdV2(blocklet, [blocklet.meta.did].concat(dids));
92
97
  return component;
93
98
  },
94
99
  }),
@@ -318,10 +323,43 @@ module.exports = {
318
323
  server.get(`${prefix}/health`, async (req, res) => {
319
324
  const blocklet = await req.getBlocklet();
320
325
 
326
+ if (!blocklet) {
327
+ return res.status(404).json({ message: 'blocklet not found' });
328
+ }
329
+
321
330
  if (blocklet.status !== BlockletStatus.running) {
322
331
  return res.status(503).json({ message: 'not running' });
323
332
  }
324
333
 
334
+ const components = {};
335
+ forEachComponentV2Sync(blocklet, (component) => {
336
+ components[component.meta.did] = {
337
+ running: component.status === BlockletStatus.running,
338
+ };
339
+ });
340
+
341
+ return res.json({ message: 'ok', components });
342
+ });
343
+
344
+ server.get(`${prefix}/health/:componentId`, async (req, res) => {
345
+ const { componentId } = req.params;
346
+
347
+ const blocklet = await req.getBlocklet();
348
+
349
+ if (!blocklet) {
350
+ return res.status(404).json({ message: 'blocklet not found' });
351
+ }
352
+
353
+ const component = findComponentByIdV2(blocklet, componentId);
354
+
355
+ if (!component) {
356
+ return res.status(404).json({ message: 'component not found' });
357
+ }
358
+
359
+ if (component.status !== BlockletStatus.running) {
360
+ return res.status(503).json({ message: 'not running' });
361
+ }
362
+
325
363
  return res.json({ message: 'ok' });
326
364
  });
327
365
 
@@ -10,7 +10,7 @@ const states = require('../../state');
10
10
  const { PREFIXES } = require('../../util/constants');
11
11
 
12
12
  const { sendToAppChannel } = require('../../socket/channel/app');
13
- const { sendToDid } = require('../../socket/channel/did');
13
+ const { sendToUserDid, sendToAppDid } = require('../../socket/channel/did');
14
14
  const getHooksByChannel = require('../../socket/channel/hooks');
15
15
  const { getTokenInfo } = require('../../socket/util');
16
16
 
@@ -113,7 +113,7 @@ const init = ({ node }) => {
113
113
 
114
114
  const onSendToUser = async (req, res) => {
115
115
  try {
116
- await sendToDid({ ...req.body.data, node, wsServer });
116
+ await sendToUserDid({ ...req.body.data, node, wsServer });
117
117
  res.status(200).send('');
118
118
  } catch (error) {
119
119
  logger.error('Send message to user channel failed', { error });
@@ -144,7 +144,11 @@ const init = ({ node }) => {
144
144
  app.post(`${prefix}/api/sendToUser`, onSendToUser);
145
145
  });
146
146
  },
147
- exec: (data) => sendToDid({ ...data, node, wsServer }),
147
+ exec: (data) => sendToUserDid({ ...data, node, wsServer }),
148
+ },
149
+
150
+ sendToApp: {
151
+ exec: ({ event, appDid, data }) => sendToAppDid({ event, appDid, data, node, wsServer }),
148
152
  },
149
153
 
150
154
  sendToAppChannel: {
@@ -6,16 +6,17 @@ const {
6
6
  } = require('@blocklet/sdk/lib/validators/notification');
7
7
  const { NODE_MODES } = require('@abtnode/constant');
8
8
  const { getWalletDid } = require('@blocklet/sdk/lib/did');
9
+ const JWT = require('@arcblock/jwt');
9
10
  const pMap = require('p-map');
10
11
 
11
12
  // eslint-disable-next-line global-require
12
13
  const logger = require('@abtnode/logger')(`${require('../../../package.json').name}:notification`);
13
- const { ensureSenderApp, parseNotification, broadcast, EVENTS } = require('../util');
14
+ const { ensureSenderApp, getSenderServer, parseNotification, broadcast, EVENTS } = require('../util');
14
15
  const states = require('../../state');
15
16
  const { validateEmail, sendEmail } = require('../../libs/email');
16
17
 
17
18
  /**
18
- *
19
+ * app send notification to user
19
20
  * @param {{
20
21
  * {{
21
22
  * did: String
@@ -29,7 +30,7 @@ const { validateEmail, sendEmail } = require('../../libs/email');
29
30
  * }}
30
31
  * @returns
31
32
  */
32
- const sendToDid = async ({ sender, receiver: rawDid, notification, options, node, wsServer }) => {
33
+ const sendToUserDid = async ({ sender, receiver: rawDid, notification, options, node, wsServer }) => {
33
34
  const { keepForOfflineUser = true } = options || {};
34
35
  const receiver = Array.isArray(rawDid) ? rawDid : [rawDid];
35
36
 
@@ -72,7 +73,7 @@ const sendToDid = async ({ sender, receiver: rawDid, notification, options, node
72
73
  throw new Error('Invalid receiver');
73
74
  }
74
75
 
75
- const nodeInfo = await node.getNodeInfo();
76
+ const nodeInfo = await node.getNodeInfo({ useCache: true });
76
77
 
77
78
  if (nodeInfo.mode !== NODE_MODES.DEBUG) {
78
79
  await validateNotification(notification);
@@ -107,6 +108,24 @@ const sendToDid = async ({ sender, receiver: rawDid, notification, options, node
107
108
  });
108
109
  };
109
110
 
111
+ // server send notification to app
112
+ const sendToAppDid = async ({ event, appDid, data, node, wsServer }) => {
113
+ const senderInfo = await getSenderServer({ node });
114
+
115
+ const notification = {
116
+ data,
117
+ };
118
+
119
+ notification.sender = {
120
+ did: senderInfo.wallet.address,
121
+ pk: senderInfo.wallet.publicKey,
122
+ token: JWT.sign(senderInfo.wallet.address, senderInfo.wallet.secretKey),
123
+ name: senderInfo.name,
124
+ };
125
+
126
+ wsServer.broadcast(appDid, event, notification, { noCluster: true });
127
+ };
128
+
110
129
  const sendCachedMessages = async (wsServer, did) => {
111
130
  try {
112
131
  const messages = await states.message.find({ did });
@@ -145,9 +164,9 @@ const onMessage = async ({ channel: from, event = EVENTS.MESSAGE, payload: messa
145
164
  // validate receiver
146
165
  const { receiver, ...data } = message;
147
166
 
148
- const blocklet = await node.getBlocklet({ did: receiver.did, attachConfig: false });
167
+ const blocklet = await node.getBlocklet({ did: receiver.did, attachConfig: false, useCache: true });
149
168
  if (!blocklet) {
150
- const nodeInfo = await node.getNodeInfo();
169
+ const nodeInfo = await node.getNodeInfo({ useCache: true });
151
170
 
152
171
  // only throw error if receiver is a blocklet (not server)
153
172
  if (nodeInfo.did !== receiver.did) {
@@ -187,4 +206,4 @@ const onAuthenticate = async ({ channel, did, payload }) => {
187
206
  }
188
207
  };
189
208
 
190
- module.exports = { onAuthenticate, onJoin, onMessage, sendToDid };
209
+ module.exports = { onAuthenticate, onJoin, onMessage, sendToUserDid, sendToAppDid };
@@ -66,6 +66,12 @@ const ensureSenderApp = async ({ sender, node, nodeInfo }) => {
66
66
  return appInfo;
67
67
  };
68
68
 
69
+ const getSenderServer = async ({ node }) => {
70
+ const nodeInfo = await node.getNodeInfo({ useCache: true });
71
+ const senderInfo = await getApplicationInfo({ node, nodeInfo, teamDid: nodeInfo.did });
72
+ return senderInfo;
73
+ };
74
+
69
75
  const getTokenInfo = (decoded) => ({
70
76
  did: decoded.iss.replace(/^did:abt:/, ''),
71
77
  });
@@ -78,6 +84,7 @@ module.exports = {
78
84
  parseNotification,
79
85
  broadcast,
80
86
  ensureSenderApp,
87
+ getSenderServer,
81
88
  getTokenInfo,
82
89
  EVENTS,
83
90
  };
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "/.blocklet/proxy/blocklet-service/static/css/main.632501d5.css",
4
- "main.js": "/.blocklet/proxy/blocklet-service/static/js/main.941e7207.js",
4
+ "main.js": "/.blocklet/proxy/blocklet-service/static/js/main.748b0f19.js",
5
5
  "static/js/716.b48e64d9.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/716.b48e64d9.chunk.js",
6
6
  "static/js/359.d6450ee2.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/359.d6450ee2.chunk.js",
7
7
  "static/js/255.279b1bca.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/255.279b1bca.chunk.js",
8
8
  "static/js/371.f67a06b4.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/371.f67a06b4.chunk.js",
9
- "static/js/737.5fbeda50.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/737.5fbeda50.chunk.js",
9
+ "static/js/737.ef64812c.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/737.ef64812c.chunk.js",
10
10
  "static/js/158.ca656ebd.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/158.ca656ebd.chunk.js",
11
11
  "static/js/868.ac8df3a0.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/868.ac8df3a0.chunk.js",
12
12
  "static/js/547.03d5d719.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/547.03d5d719.chunk.js",
13
- "static/js/343.7deaa08f.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/343.7deaa08f.chunk.js",
13
+ "static/js/343.da2b2075.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/343.da2b2075.chunk.js",
14
14
  "static/js/682.a8bf723a.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/682.a8bf723a.chunk.js",
15
15
  "static/js/711.56427a24.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/711.56427a24.chunk.js",
16
16
  "static/js/437.075e8453.chunk.js": "/.blocklet/proxy/blocklet-service/static/js/437.075e8453.chunk.js",
@@ -45,16 +45,16 @@
45
45
  "router-template-styles/styles.css": "/.blocklet/proxy/blocklet-service/router-template-styles/styles.css",
46
46
  "index.html": "/.blocklet/proxy/blocklet-service/index.html",
47
47
  "main.632501d5.css.map": "/.blocklet/proxy/blocklet-service/static/css/main.632501d5.css.map",
48
- "main.941e7207.js.map": "/.blocklet/proxy/blocklet-service/static/js/main.941e7207.js.map",
48
+ "main.748b0f19.js.map": "/.blocklet/proxy/blocklet-service/static/js/main.748b0f19.js.map",
49
49
  "716.b48e64d9.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/716.b48e64d9.chunk.js.map",
50
50
  "359.d6450ee2.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/359.d6450ee2.chunk.js.map",
51
51
  "255.279b1bca.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/255.279b1bca.chunk.js.map",
52
52
  "371.f67a06b4.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/371.f67a06b4.chunk.js.map",
53
- "737.5fbeda50.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/737.5fbeda50.chunk.js.map",
53
+ "737.ef64812c.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/737.ef64812c.chunk.js.map",
54
54
  "158.ca656ebd.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/158.ca656ebd.chunk.js.map",
55
55
  "868.ac8df3a0.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/868.ac8df3a0.chunk.js.map",
56
56
  "547.03d5d719.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/547.03d5d719.chunk.js.map",
57
- "343.7deaa08f.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/343.7deaa08f.chunk.js.map",
57
+ "343.da2b2075.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/343.da2b2075.chunk.js.map",
58
58
  "682.a8bf723a.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/682.a8bf723a.chunk.js.map",
59
59
  "711.56427a24.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/711.56427a24.chunk.js.map",
60
60
  "437.075e8453.chunk.js.map": "/.blocklet/proxy/blocklet-service/static/js/437.075e8453.chunk.js.map",
@@ -70,6 +70,6 @@
70
70
  },
71
71
  "entrypoints": [
72
72
  "static/css/main.632501d5.css",
73
- "static/js/main.941e7207.js"
73
+ "static/js/main.748b0f19.js"
74
74
  ]
75
75
  }
package/build/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#000000"/><title>Blocklet Service</title><script src=".well-known/service/api/env"></script><script src="/__blocklet__.js"></script><script defer="defer" src="/.blocklet/proxy/blocklet-service/static/js/main.941e7207.js"></script><link href="/.blocklet/proxy/blocklet-service/static/css/main.632501d5.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#000000"/><title>Blocklet Service</title><script src=".well-known/service/api/env"></script><script src="/__blocklet__.js"></script><script defer="defer" src="/.blocklet/proxy/blocklet-service/static/js/main.748b0f19.js"></script><link href="/.blocklet/proxy/blocklet-service/static/css/main.632501d5.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>