@abtnode/core 1.16.44-beta-20250529-223630-10e16ac8 → 1.16.44-beta-20250603-231026-30a9d27f
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/lib/blocklet/manager/disk.js +24 -10
- package/lib/blocklet/migration-dist/migration.cjs +4 -1
- package/lib/blocklet/webhook/index.js +46 -1
- package/lib/blocklet/webhook/queues.js +57 -17
- package/lib/blocklet/webhook/util.js +7 -0
- package/lib/event/index.js +7 -1
- package/lib/index.js +3 -0
- package/lib/router/manager.js +92 -5
- package/lib/router/monitor.js +2 -1
- package/lib/states/audit-log.js +3 -0
- package/lib/util/domain-status.js +8 -71
- package/package.json +37 -37
|
@@ -26,6 +26,7 @@ const { sendToUser } = require('@blocklet/sdk/lib/util/send-notification');
|
|
|
26
26
|
const { getDidDomainForBlocklet } = require('@abtnode/util/lib/get-domain-for-blocklet');
|
|
27
27
|
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
|
|
28
28
|
const promiseSpawn = require('@abtnode/util/lib/promise-spawn');
|
|
29
|
+
const { sanitizeTag } = require('@abtnode/util/lib/sanitize');
|
|
29
30
|
|
|
30
31
|
const {
|
|
31
32
|
BLOCKLET_INSTALL_TYPE,
|
|
@@ -237,7 +238,6 @@ const ensureBlockletRunning = require('./ensure-blocklet-running');
|
|
|
237
238
|
const { transformNotification } = require('../../util/notification');
|
|
238
239
|
const { generateUserUpdateData } = require('../../util/user');
|
|
239
240
|
const { blockletThemeSchema } = require('../../validators/theme');
|
|
240
|
-
const checkDNS = require('../../util/check-dns.js');
|
|
241
241
|
const { removeDockerNetwork } = require('../../util/docker/docker-network.js');
|
|
242
242
|
const parseDockerName = require('../../util/docker/parse-docker-name.js');
|
|
243
243
|
|
|
@@ -341,6 +341,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
341
341
|
nodeAPI,
|
|
342
342
|
teamAPI,
|
|
343
343
|
certManager,
|
|
344
|
+
routerManager,
|
|
344
345
|
}) {
|
|
345
346
|
super();
|
|
346
347
|
|
|
@@ -358,6 +359,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
358
359
|
this.resendNotificationQueue = resendNotificationQueue;
|
|
359
360
|
this.teamManager = teamManager;
|
|
360
361
|
this.certManager = certManager;
|
|
362
|
+
this.routerManager = routerManager;
|
|
361
363
|
/**
|
|
362
364
|
* @type {import('../../api/node')}
|
|
363
365
|
*/
|
|
@@ -443,7 +445,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
443
445
|
title,
|
|
444
446
|
description,
|
|
445
447
|
action: `/blocklets/${did}/overview`,
|
|
446
|
-
blockletDashboardAction:
|
|
448
|
+
blockletDashboardAction: `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/blocklets`,
|
|
447
449
|
entityType: 'blocklet',
|
|
448
450
|
entityId: did,
|
|
449
451
|
severity,
|
|
@@ -1482,7 +1484,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1482
1484
|
entityId: newBlocklet.meta.did,
|
|
1483
1485
|
severity: 'success',
|
|
1484
1486
|
action: `/blocklets/${newBlocklet.meta.did}/components`,
|
|
1485
|
-
blockletDashboardAction:
|
|
1487
|
+
blockletDashboardAction: `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/components`,
|
|
1486
1488
|
});
|
|
1487
1489
|
|
|
1488
1490
|
this.emit(BlockletEvents.componentRemoved, {
|
|
@@ -1664,6 +1666,12 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1664
1666
|
throw new Error('configs list is not an array');
|
|
1665
1667
|
}
|
|
1666
1668
|
|
|
1669
|
+
// 对用户输入的配置进行 XSS 清理
|
|
1670
|
+
const sanitizedConfigs = newConfigs.map((c) => ({
|
|
1671
|
+
...c,
|
|
1672
|
+
value: sanitizeTag(c.value),
|
|
1673
|
+
}));
|
|
1674
|
+
|
|
1667
1675
|
const tmpDids = Array.isArray(did) ? did : [did];
|
|
1668
1676
|
const [rootDid, childDid] = tmpDids;
|
|
1669
1677
|
const rootMetaDid = await states.blocklet.getBlockletMetaDid(rootDid);
|
|
@@ -1682,7 +1690,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1682
1690
|
|
|
1683
1691
|
const configObj = {};
|
|
1684
1692
|
const ignoredKeys = [];
|
|
1685
|
-
for (const x of
|
|
1693
|
+
for (const x of sanitizedConfigs) {
|
|
1686
1694
|
if (['CHAIN_TYPE', 'BLOCKLET_APP_CHAIN_TYPE'].includes(x.key)) {
|
|
1687
1695
|
throw new Error(`${x.key} should not be changed`);
|
|
1688
1696
|
} else if (x.custom === true) {
|
|
@@ -1715,7 +1723,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1715
1723
|
configObj[x.key] = x.value;
|
|
1716
1724
|
}
|
|
1717
1725
|
|
|
1718
|
-
const finalConfigs =
|
|
1726
|
+
const finalConfigs = sanitizedConfigs.filter((x) => !ignoredKeys.includes(x.key));
|
|
1719
1727
|
const willAppSkChange = isRotatingAppSk(finalConfigs, blocklet.configs, blocklet.externalSk);
|
|
1720
1728
|
|
|
1721
1729
|
// NOTICE: cannot use appDid as did param because appDid will become old appDid in alsoKnownAs and cannot get blocklet by the old appDid
|
|
@@ -2348,12 +2356,18 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2348
2356
|
|
|
2349
2357
|
await Promise.all(
|
|
2350
2358
|
customAliases.map(async (alias) => {
|
|
2351
|
-
const dns = await
|
|
2359
|
+
const dns = await this.routerManager.checkDomainDNS(alias.value, cnameDomain?.value);
|
|
2352
2360
|
logger.info('dns info', { dns });
|
|
2353
2361
|
if (!dns.isDnsResolved || !dns.isCnameMatch) {
|
|
2354
2362
|
return;
|
|
2355
2363
|
}
|
|
2356
2364
|
|
|
2365
|
+
const foundCert = await this.routerManager.getHttpsCert({ domain: alias.value });
|
|
2366
|
+
logger.info('cron check dns global certificate', { foundCert: !!foundCert, domain: alias.value });
|
|
2367
|
+
if (foundCert) {
|
|
2368
|
+
return;
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2357
2371
|
if (!alias.certificateId) {
|
|
2358
2372
|
logger.info('cron check dns no certificate');
|
|
2359
2373
|
await issueCert(alias);
|
|
@@ -3513,7 +3527,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3513
3527
|
};
|
|
3514
3528
|
|
|
3515
3529
|
const action = `/blocklets/${did}/components?checkUpdate=1`;
|
|
3516
|
-
const blockletDashboardAction =
|
|
3530
|
+
const blockletDashboardAction = `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/components?checkUpdate=1`;
|
|
3517
3531
|
const users = await this.teamManager.getOwnerAndAdminUsers(did, 1);
|
|
3518
3532
|
const nodeInfo = await states.node.read();
|
|
3519
3533
|
const { wallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
@@ -4067,7 +4081,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4067
4081
|
deployedFrom || fromBlockletSource(source)
|
|
4068
4082
|
})`,
|
|
4069
4083
|
action: `/blocklets/${did}/overview`,
|
|
4070
|
-
blockletDashboardAction:
|
|
4084
|
+
blockletDashboardAction: `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/blocklets`,
|
|
4071
4085
|
entityType: 'blocklet',
|
|
4072
4086
|
entityId: did,
|
|
4073
4087
|
severity: 'success',
|
|
@@ -4308,7 +4322,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4308
4322
|
componentDids
|
|
4309
4323
|
)} is ${actionName} successfully for ${title}`,
|
|
4310
4324
|
action: `/blocklets/${did}/overview`,
|
|
4311
|
-
blockletDashboardAction:
|
|
4325
|
+
blockletDashboardAction: `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/blocklets`,
|
|
4312
4326
|
entityType: 'blocklet',
|
|
4313
4327
|
entityId: did,
|
|
4314
4328
|
severity: 'success',
|
|
@@ -5162,7 +5176,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
5162
5176
|
async getDomainDNS({ teamDid, domain }) {
|
|
5163
5177
|
const blocklet = await this.getBlocklet(teamDid);
|
|
5164
5178
|
const cnameDomain = (get(blocklet, 'site.domainAliases') || []).find((item) => isDidDomain(item.value));
|
|
5165
|
-
return
|
|
5179
|
+
return this.routerManager.checkDomainDNS(domain, cnameDomain?.value);
|
|
5166
5180
|
}
|
|
5167
5181
|
}
|
|
5168
5182
|
|
|
@@ -287,6 +287,8 @@ const EVENTS = {
|
|
|
287
287
|
RELOAD_GATEWAY: 'gateway.reload',
|
|
288
288
|
NOTIFICATION_CREATE_QUEUED: 'notification.create.queued',
|
|
289
289
|
UPDATE_DOMAIN_ALIAS: 'router.domain.alias.updated',
|
|
290
|
+
|
|
291
|
+
WEBHOOK_ATTEMPT: 'webhook.attempt',
|
|
290
292
|
};
|
|
291
293
|
|
|
292
294
|
const WHO_CAN_ACCESS = Object.freeze({
|
|
@@ -752,6 +754,7 @@ module.exports = Object.freeze({
|
|
|
752
754
|
// FIXME: 梁柱, 下面两个 get 接口, 可以不开放但是前端需要根据情况取消获取这两个接口的调用
|
|
753
755
|
getBlockletRuntimeHistory: true,
|
|
754
756
|
checkDomains: true,
|
|
757
|
+
isDidDomain: true,
|
|
755
758
|
},
|
|
756
759
|
// 这些接口可以跳过 ACCESS VERIFY
|
|
757
760
|
SKIP_ACCESS_VERIFY_METHODS: {
|
|
@@ -38885,7 +38888,7 @@ module.exports = require("zlib");
|
|
|
38885
38888
|
/***/ ((module) => {
|
|
38886
38889
|
|
|
38887
38890
|
"use strict";
|
|
38888
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.43","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.43","@abtnode/auth":"1.16.43","@abtnode/certificate-manager":"1.16.43","@abtnode/client":"1.16.43","@abtnode/constant":"1.16.43","@abtnode/cron":"1.16.43","@abtnode/docker-utils":"1.16.43","@abtnode/logger":"1.16.43","@abtnode/models":"1.16.43","@abtnode/queue":"1.16.43","@abtnode/rbac":"1.16.43","@abtnode/router-provider":"1.16.43","@abtnode/static-server":"1.16.43","@abtnode/timemachine":"1.16.43","@abtnode/util":"1.16.43","@arcblock/did":"1.20.
|
|
38891
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.43","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.43","@abtnode/auth":"1.16.43","@abtnode/certificate-manager":"1.16.43","@abtnode/client":"1.16.43","@abtnode/constant":"1.16.43","@abtnode/cron":"1.16.43","@abtnode/docker-utils":"1.16.43","@abtnode/logger":"1.16.43","@abtnode/models":"1.16.43","@abtnode/queue":"1.16.43","@abtnode/rbac":"1.16.43","@abtnode/router-provider":"1.16.43","@abtnode/static-server":"1.16.43","@abtnode/timemachine":"1.16.43","@abtnode/util":"1.16.43","@arcblock/did":"1.20.12","@arcblock/did-auth":"1.20.12","@arcblock/did-ext":"1.20.12","@arcblock/did-motif":"^1.1.13","@arcblock/did-util":"1.20.12","@arcblock/event-hub":"1.20.12","@arcblock/jwt":"1.20.12","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.20.12","@arcblock/vc":"1.20.12","@blocklet/constant":"1.16.43","@blocklet/did-space-js":"^1.0.57","@blocklet/env":"1.16.43","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.43","@blocklet/resolver":"1.16.43","@blocklet/sdk":"1.16.43","@blocklet/store":"1.16.43","@blocklet/theme":"^2.13.61","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.20.12","@ocap/util":"1.20.12","@ocap/wallet":"1.20.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","dayjs":"^1.11.13","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","p-wait-for":"^3.2.0","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","slugify":"^1.6.6","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"}');
|
|
38889
38892
|
|
|
38890
38893
|
/***/ }),
|
|
38891
38894
|
|
|
@@ -2,7 +2,9 @@ const pick = require('lodash/pick');
|
|
|
2
2
|
const pickBy = require('lodash/pickBy');
|
|
3
3
|
const get = require('lodash/get');
|
|
4
4
|
const { EventEmitter } = require('events');
|
|
5
|
-
const {
|
|
5
|
+
const { EVENTS } = require('@abtnode/constant');
|
|
6
|
+
const { API_VERSION, STATUS } = require('./util');
|
|
7
|
+
const endpointQueueInit = require('./queues');
|
|
6
8
|
|
|
7
9
|
const DEFAULT_PAGE = 1;
|
|
8
10
|
const DEFAULT_PAGE_SIZE = 10;
|
|
@@ -25,6 +27,9 @@ class WebhooksAPI extends EventEmitter {
|
|
|
25
27
|
|
|
26
28
|
this.cache = new Map();
|
|
27
29
|
this.TTL = 5 * 60 * 1000;
|
|
30
|
+
|
|
31
|
+
const { webhookEndpointQueue } = endpointQueueInit.init({ states, teamManager });
|
|
32
|
+
this.webhookEndpointQueue = webhookEndpointQueue;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
async getUserInfo(userDid, teamDid, serverDid) {
|
|
@@ -161,6 +166,46 @@ class WebhooksAPI extends EventEmitter {
|
|
|
161
166
|
const list = await webhookAttemptState.list(page, pageSize, where);
|
|
162
167
|
return list;
|
|
163
168
|
}
|
|
169
|
+
|
|
170
|
+
async retryWebhookAttempt({ eventId, webhookId, attemptId, teamDid }, context) {
|
|
171
|
+
const { webhookAttemptState } = await this.teamManager.getWebhookState(teamDid);
|
|
172
|
+
|
|
173
|
+
const result = await webhookAttemptState.insert({
|
|
174
|
+
eventId,
|
|
175
|
+
webhookId,
|
|
176
|
+
status: STATUS.PENDING,
|
|
177
|
+
retryCount: 1,
|
|
178
|
+
responseStatus: 200,
|
|
179
|
+
responseBody: {},
|
|
180
|
+
triggeredBy: getUserDid(context),
|
|
181
|
+
triggeredFrom: attemptId,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const emitResult = async () => {
|
|
185
|
+
return {
|
|
186
|
+
teamDid,
|
|
187
|
+
...(await webhookAttemptState.findOne({ eventId, webhookId, id: result.id })),
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
this.webhookEndpointQueue.push({
|
|
192
|
+
eventId,
|
|
193
|
+
webhookId,
|
|
194
|
+
appDid: teamDid,
|
|
195
|
+
attemptId: result.id,
|
|
196
|
+
triggeredBy: getUserDid(context),
|
|
197
|
+
triggeredFrom: attemptId,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
this.webhookEndpointQueue.on('finished', async () => {
|
|
201
|
+
this.emit(EVENTS.WEBHOOK_ATTEMPT, { ...(await emitResult()) });
|
|
202
|
+
});
|
|
203
|
+
this.webhookEndpointQueue.on('failed', async () => {
|
|
204
|
+
this.emit(EVENTS.WEBHOOK_ATTEMPT, { ...(await emitResult()) });
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
164
209
|
}
|
|
165
210
|
|
|
166
211
|
module.exports = WebhooksAPI;
|
|
@@ -3,13 +3,19 @@ const axios = require('@abtnode/util/lib/axios');
|
|
|
3
3
|
const { Op } = require('sequelize');
|
|
4
4
|
|
|
5
5
|
const createQueue = require('../../util/queue');
|
|
6
|
-
const { getWebhookJobId } = require('./util');
|
|
6
|
+
const { getWebhookJobId, STATUS } = require('./util');
|
|
7
7
|
|
|
8
8
|
const MAX_RETRY_COUNT = 2; // 重试一次
|
|
9
9
|
const AXIOS_TIMEOUT = 1000 * 60 * 3;
|
|
10
10
|
|
|
11
11
|
const createWebhookEndpointQueue = ({ states, teamManager }) => {
|
|
12
12
|
// https://stripe.com/docs/webhooks
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {*} job eventId: event.id, webhookId: webhook.id, appDid: job.appDid, attemptId?:string
|
|
16
|
+
*
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
13
19
|
const handleWebhookEndpoint = async (job) => {
|
|
14
20
|
logger.info('handle webhook endpoint', job);
|
|
15
21
|
|
|
@@ -48,14 +54,31 @@ const createWebhookEndpointQueue = ({ states, teamManager }) => {
|
|
|
48
54
|
// verify similar to component call, but supports external urls
|
|
49
55
|
const response = await axios.post(webhook.url, event.request, { timeout: AXIOS_TIMEOUT });
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
if (job.attemptId) {
|
|
58
|
+
await webhookAttemptState.update(
|
|
59
|
+
{ id: job.attemptId },
|
|
60
|
+
{
|
|
61
|
+
status: STATUS.SUCCEEDED,
|
|
62
|
+
responseStatus: response.status,
|
|
63
|
+
responseBody: response.data || {},
|
|
64
|
+
retryCount,
|
|
65
|
+
triggeredBy: job.triggeredBy,
|
|
66
|
+
triggeredFrom: job.triggeredFrom,
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
} else {
|
|
70
|
+
await webhookAttemptState.insert({
|
|
71
|
+
eventId: event.id,
|
|
72
|
+
webhookId: webhook.id,
|
|
73
|
+
status: STATUS.SUCCEEDED,
|
|
74
|
+
responseStatus: response.status,
|
|
75
|
+
responseBody: response.data || {},
|
|
76
|
+
retryCount,
|
|
77
|
+
triggeredBy: job.triggeredBy,
|
|
78
|
+
triggeredFrom: job.triggeredFrom,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
59
82
|
logger.info('WebhookAttempt created successfully', { eventId: event.id, webhookId: webhook.id });
|
|
60
83
|
|
|
61
84
|
const newPendingCount = Math.max(0, event.pendingWebhooks - 1);
|
|
@@ -66,14 +89,31 @@ const createWebhookEndpointQueue = ({ states, teamManager }) => {
|
|
|
66
89
|
} catch (err) {
|
|
67
90
|
logger.warn('webhook attempt error', { ...job, retryCount, message: err.message });
|
|
68
91
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
92
|
+
if (job.attemptId) {
|
|
93
|
+
await webhookAttemptState.update(
|
|
94
|
+
{ id: job.attemptId },
|
|
95
|
+
{
|
|
96
|
+
status: STATUS.FAILED,
|
|
97
|
+
responseStatus: err.response?.status || 500,
|
|
98
|
+
responseBody: err.response?.data || {},
|
|
99
|
+
retryCount,
|
|
100
|
+
triggeredBy: job.triggeredBy,
|
|
101
|
+
triggeredFrom: job.triggeredFrom,
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
} else {
|
|
105
|
+
await webhookAttemptState.insert({
|
|
106
|
+
eventId: event.id,
|
|
107
|
+
webhookId: webhook.id,
|
|
108
|
+
status: STATUS.FAILED,
|
|
109
|
+
responseStatus: err.response?.status || 500,
|
|
110
|
+
responseBody: err.response?.data || {},
|
|
111
|
+
retryCount,
|
|
112
|
+
triggeredBy: job.triggeredBy,
|
|
113
|
+
triggeredFrom: job.triggeredFrom,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
77
117
|
logger.info('Failed WebhookAttempt created', { eventId: event.id, webhookId: webhook.id });
|
|
78
118
|
|
|
79
119
|
// reschedule next attempt
|
|
@@ -6,7 +6,14 @@ const getWebhookJobId = (eventId, webhookId) => {
|
|
|
6
6
|
return md5([eventId, webhookId].join('-'));
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
const STATUS = {
|
|
10
|
+
SUCCEEDED: 'succeeded',
|
|
11
|
+
FAILED: 'failed',
|
|
12
|
+
PENDING: 'pending',
|
|
13
|
+
};
|
|
14
|
+
|
|
9
15
|
module.exports = {
|
|
10
16
|
API_VERSION,
|
|
17
|
+
STATUS,
|
|
11
18
|
getWebhookJobId,
|
|
12
19
|
};
|
package/lib/event/index.js
CHANGED
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
DEFAULT_DID_DOMAIN,
|
|
20
20
|
WELLKNOWN_BLOCKLET_ADMIN_PATH,
|
|
21
21
|
TEST_STORE_URL,
|
|
22
|
+
WELLKNOWN_SERVICE_PATH_PREFIX,
|
|
22
23
|
} = require('@abtnode/constant');
|
|
23
24
|
const { joinURL } = require('ufo');
|
|
24
25
|
const { encode } = require('@abtnode/util/lib/base32');
|
|
@@ -65,6 +66,7 @@ module.exports = ({
|
|
|
65
66
|
node,
|
|
66
67
|
nodeRuntimeMonitor,
|
|
67
68
|
daemon,
|
|
69
|
+
webhookManager,
|
|
68
70
|
}) => {
|
|
69
71
|
const nodeState = states.node;
|
|
70
72
|
const nodeMonitSender = new NodeMonitSender({ node });
|
|
@@ -561,6 +563,10 @@ module.exports = ({
|
|
|
561
563
|
eventHub.broadcast(name, data);
|
|
562
564
|
});
|
|
563
565
|
|
|
566
|
+
listen(webhookManager, EVENTS.WEBHOOK_ATTEMPT, (name, data) => {
|
|
567
|
+
onEvent(name, data, true);
|
|
568
|
+
});
|
|
569
|
+
|
|
564
570
|
listen(nodeState, BlockletEvents.purchaseChange, onEvent);
|
|
565
571
|
nodeState.on(EVENTS.ROUTING_UPDATED, (nodeInfo) => onEvent(EVENTS.ROUTING_UPDATED, { routing: nodeInfo.routing }));
|
|
566
572
|
nodeState.once(EVENTS.NODE_ADDED_OWNER, () => downloadAddedBlocklet());
|
|
@@ -706,7 +712,7 @@ module.exports = ({
|
|
|
706
712
|
actions: [
|
|
707
713
|
{
|
|
708
714
|
name: translation.viewYourAccount,
|
|
709
|
-
link: joinURL(origin,
|
|
715
|
+
link: joinURL(origin, `${WELLKNOWN_SERVICE_PATH_PREFIX}/user/settings`),
|
|
710
716
|
},
|
|
711
717
|
],
|
|
712
718
|
};
|
package/lib/index.js
CHANGED
|
@@ -280,6 +280,7 @@ function ABTNode(options) {
|
|
|
280
280
|
nodeAPI,
|
|
281
281
|
teamAPI,
|
|
282
282
|
certManager,
|
|
283
|
+
routerManager,
|
|
283
284
|
});
|
|
284
285
|
blockletManager.setMaxListeners(0);
|
|
285
286
|
const securityAPI = new SecurityAPI({ teamManager, blockletManager });
|
|
@@ -752,6 +753,7 @@ function ABTNode(options) {
|
|
|
752
753
|
getWebhookEndpoints: webhookAPI.getWebhookEndpoints.bind(webhookAPI),
|
|
753
754
|
getWebhookEndpoint: webhookAPI.getWebhookEndpoint.bind(webhookAPI),
|
|
754
755
|
getWebhookAttempts: webhookAPI.getWebhookAttempts.bind(webhookAPI),
|
|
756
|
+
retryWebhookAttempt: webhookAPI.retryWebhookAttempt.bind(webhookAPI),
|
|
755
757
|
|
|
756
758
|
// passport
|
|
757
759
|
createPassportLog: passportAPI.createPassportLog.bind(passportAPI),
|
|
@@ -798,6 +800,7 @@ function ABTNode(options) {
|
|
|
798
800
|
nodeRuntimeMonitor: nodeAPI.runtimeMonitor,
|
|
799
801
|
daemon: options.daemon,
|
|
800
802
|
handleBlockletWafChange,
|
|
803
|
+
webhookManager: webhookAPI,
|
|
801
804
|
});
|
|
802
805
|
|
|
803
806
|
const webhook = WebHook({ events, dataDirs, instance, teamManager });
|
package/lib/router/manager.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Router manager is the business logic layer of router related, includes:
|
|
5
5
|
* RoutingRuleState, HttpsCertState
|
|
6
6
|
*/
|
|
7
|
+
const https = require('https');
|
|
7
8
|
const path = require('path');
|
|
8
9
|
const os = require('os');
|
|
9
10
|
const dns = require('dns');
|
|
@@ -22,7 +23,7 @@ const { getProvider } = require('@abtnode/router-provider');
|
|
|
22
23
|
const checkDomainMatch = require('@abtnode/util/lib/check-domain-match');
|
|
23
24
|
const { isDidDomain, isCustomDomain } = require('@abtnode/util/lib/url-evaluation');
|
|
24
25
|
const { isTopLevelDomain } = require('@abtnode/util/lib/domain');
|
|
25
|
-
const { EVENTS } = require('@abtnode/constant');
|
|
26
|
+
const { EVENTS, WELLKNOWN_PING_PREFIX } = require('@abtnode/constant');
|
|
26
27
|
const {
|
|
27
28
|
DOMAIN_FOR_IP_SITE,
|
|
28
29
|
DOMAIN_FOR_DEFAULT_SITE,
|
|
@@ -342,12 +343,41 @@ class RouterManager extends EventEmitter {
|
|
|
342
343
|
|
|
343
344
|
if (issueCert) {
|
|
344
345
|
const didDomain = doc.domainAliases.find((x) => isDidDomain(x.value));
|
|
345
|
-
const dnsValue = await
|
|
346
|
-
|
|
346
|
+
const [dnsValue, cert] = await Promise.all([
|
|
347
|
+
this.checkDomainDNS(domain, didDomain?.value),
|
|
348
|
+
this.getHttpsCert({ domain }),
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
// 自定义域名如果 DNS 未解析成功 或 CNAME 不匹配 或 已配置证书,则不自动颁发证书
|
|
352
|
+
const shouldSkipCertIssue =
|
|
353
|
+
isCustomDomain(domain) && (!dnsValue.isDnsResolved || !dnsValue.isCnameMatch || !!cert);
|
|
354
|
+
|
|
355
|
+
if (shouldSkipCertIssue) {
|
|
356
|
+
const reasonFn = () => {
|
|
357
|
+
if (cert) {
|
|
358
|
+
return 'cert already exists';
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (!dnsValue.isDnsResolved) {
|
|
362
|
+
return 'DNS not resolved';
|
|
363
|
+
}
|
|
347
364
|
|
|
348
|
-
|
|
365
|
+
if (!dnsValue.isCnameMatch) {
|
|
366
|
+
return 'CNAME not match';
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return 'unknown reason';
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
logger.info('skip cert issue for domain alias', {
|
|
373
|
+
cert,
|
|
374
|
+
domain,
|
|
375
|
+
dnsValue,
|
|
376
|
+
reason: reasonFn(),
|
|
377
|
+
});
|
|
378
|
+
} else {
|
|
349
379
|
this.certManager
|
|
350
|
-
.issue({ domain, did, siteId: id, inBlockletSetup }, { delay:
|
|
380
|
+
.issue({ domain, did, siteId: id, inBlockletSetup }, { delay: 3000 })
|
|
351
381
|
.then(() => {
|
|
352
382
|
logger.info('issue cert for domain alias', { domain, did });
|
|
353
383
|
})
|
|
@@ -635,6 +665,63 @@ class RouterManager extends EventEmitter {
|
|
|
635
665
|
return null;
|
|
636
666
|
}
|
|
637
667
|
|
|
668
|
+
checkDomainDNS(domain, cnameDomain) {
|
|
669
|
+
try {
|
|
670
|
+
if (isCustomDomain(domain)) {
|
|
671
|
+
return checkDNS(domain, cnameDomain);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return Promise.resolve({
|
|
675
|
+
isDnsResolved: true,
|
|
676
|
+
hasCname: true,
|
|
677
|
+
cnameRecords: [cnameDomain],
|
|
678
|
+
isCnameMatch: true,
|
|
679
|
+
});
|
|
680
|
+
} catch (error) {
|
|
681
|
+
logger.error('check domain dns error', error?.message);
|
|
682
|
+
return Promise.resolve({
|
|
683
|
+
isDnsResolved: false,
|
|
684
|
+
hasCname: false,
|
|
685
|
+
cnameRecords: [],
|
|
686
|
+
isCnameMatch: false,
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
async getHttpsCert({ domain }) {
|
|
692
|
+
const matchedCert = await this.getMatchedCert(domain);
|
|
693
|
+
|
|
694
|
+
if (matchedCert) {
|
|
695
|
+
return matchedCert;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return new Promise((resolve) => {
|
|
699
|
+
const req = https.request(
|
|
700
|
+
{ host: domain, path: WELLKNOWN_PING_PREFIX, method: 'GET', timeout: 1000 * 10 },
|
|
701
|
+
(res) => {
|
|
702
|
+
try {
|
|
703
|
+
const data = res.socket.getPeerCertificate();
|
|
704
|
+
const cert = {
|
|
705
|
+
issuer: {
|
|
706
|
+
countryName: data.issuer.C,
|
|
707
|
+
organizationName: data.issuer.O,
|
|
708
|
+
commonName: data.issuer.CN,
|
|
709
|
+
},
|
|
710
|
+
validFrom: data.valid_from,
|
|
711
|
+
validTo: data.valid_to,
|
|
712
|
+
};
|
|
713
|
+
resolve(cert);
|
|
714
|
+
} catch {
|
|
715
|
+
resolve(null);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
);
|
|
719
|
+
|
|
720
|
+
req.on('error', () => resolve(null));
|
|
721
|
+
req.end();
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
|
|
638
725
|
isCertMatchedDomain(cert, domain = '') {
|
|
639
726
|
return [cert.domain, ...(cert.sans || [])].some((d) => checkDomainMatch(d, domain));
|
|
640
727
|
}
|
package/lib/router/monitor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
|
|
1
2
|
const { createLogWatcher } = require('./watcher');
|
|
2
3
|
|
|
3
4
|
// Function to parse the log entry and extract relevant information
|
|
@@ -36,7 +37,7 @@ function parseLogEntry(line, check = true) {
|
|
|
36
37
|
logEntry.status <= 599 &&
|
|
37
38
|
logEntry.request.includes('/.well-known/did.json') === false &&
|
|
38
39
|
logEntry.request.includes('/websocket') === false &&
|
|
39
|
-
logEntry.request.includes(
|
|
40
|
+
logEntry.request.includes(`${WELLKNOWN_SERVICE_PATH_PREFIX}/health`) === false
|
|
40
41
|
) {
|
|
41
42
|
console.warn(`5xx request detected: ${logEntry.host}`, line);
|
|
42
43
|
return logEntry;
|
package/lib/states/audit-log.js
CHANGED
|
@@ -515,6 +515,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
515
515
|
return `Delete Blocklet Webhook(${result.id})`;
|
|
516
516
|
case 'ensureBlockletRunning':
|
|
517
517
|
return `${result.title}:\n* ${result.description}`;
|
|
518
|
+
case 'retryWebhookAttempt':
|
|
519
|
+
return `Retry Webhook Attempt(${args.attemptId})`;
|
|
518
520
|
|
|
519
521
|
case 'addUploadEndpoint':
|
|
520
522
|
return `Create Upload Endpoint(${args.url})`;
|
|
@@ -657,6 +659,7 @@ const getLogCategory = (action) => {
|
|
|
657
659
|
case 'createWebhookEndpoint':
|
|
658
660
|
case 'updateWebhookEndpoint':
|
|
659
661
|
case 'deleteWebhookEndpoint':
|
|
662
|
+
case 'retryWebhookAttempt':
|
|
660
663
|
return 'integrations';
|
|
661
664
|
|
|
662
665
|
// server
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
const https = require('https');
|
|
2
1
|
const { EventEmitter } = require('events');
|
|
3
2
|
const logger = require('@abtnode/logger')('@abtnode/domain-status');
|
|
4
|
-
const { EVENTS
|
|
3
|
+
const { EVENTS } = require('@abtnode/constant');
|
|
5
4
|
const { BlockletEvents } = require('@blocklet/constant');
|
|
6
|
-
const {
|
|
5
|
+
const { isDidDomain } = require('@abtnode/util/lib/url-evaluation');
|
|
7
6
|
const { checkDomainDNS } = require('./index');
|
|
8
|
-
const checkDNS = require('./check-dns');
|
|
9
7
|
|
|
10
8
|
const dnsStatusStore = Object.create(null);
|
|
11
9
|
|
|
@@ -48,71 +46,6 @@ class DomainStatus extends EventEmitter {
|
|
|
48
46
|
this.states = states;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
async getHttpsCert(domain) {
|
|
52
|
-
const matchedCert = await this.routerManager.getMatchedCert(domain);
|
|
53
|
-
|
|
54
|
-
if (matchedCert) {
|
|
55
|
-
return matchedCert;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return new Promise((resolve) => {
|
|
59
|
-
const req = https.request(
|
|
60
|
-
{
|
|
61
|
-
host: domain,
|
|
62
|
-
path: WELLKNOWN_PING_PREFIX,
|
|
63
|
-
method: 'GET',
|
|
64
|
-
timeout: 1000 * 10,
|
|
65
|
-
},
|
|
66
|
-
(res) => {
|
|
67
|
-
try {
|
|
68
|
-
const data = res.socket.getPeerCertificate();
|
|
69
|
-
const cert = {
|
|
70
|
-
issuer: {
|
|
71
|
-
countryName: data.issuer.C,
|
|
72
|
-
organizationName: data.issuer.O,
|
|
73
|
-
commonName: data.issuer.CN,
|
|
74
|
-
},
|
|
75
|
-
validFrom: data.valid_from,
|
|
76
|
-
validTo: data.valid_to,
|
|
77
|
-
};
|
|
78
|
-
resolve(cert);
|
|
79
|
-
} catch {
|
|
80
|
-
resolve(null);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
req.on('error', () => {
|
|
86
|
-
resolve(null);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
req.end();
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
checkDomainDNS(domain, cnameDomain) {
|
|
94
|
-
try {
|
|
95
|
-
if (isCustomDomain(domain)) {
|
|
96
|
-
return checkDNS(domain, cnameDomain);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return Promise.resolve({
|
|
100
|
-
isDnsResolved: true,
|
|
101
|
-
hasCname: true,
|
|
102
|
-
cnameRecords: [cnameDomain],
|
|
103
|
-
isCnameMatch: true,
|
|
104
|
-
});
|
|
105
|
-
} catch (error) {
|
|
106
|
-
logger.error('check domain dns error', error?.message);
|
|
107
|
-
return Promise.resolve({
|
|
108
|
-
isDnsResolved: false,
|
|
109
|
-
hasCname: false,
|
|
110
|
-
cnameRecords: [],
|
|
111
|
-
isCnameMatch: false,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
49
|
async checkDomainsStatus({ domains, did } = {}) {
|
|
117
50
|
if (did) {
|
|
118
51
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -122,8 +55,12 @@ class DomainStatus extends EventEmitter {
|
|
|
122
55
|
const cnameDomain = domains.find((x) => isDidDomain(x));
|
|
123
56
|
|
|
124
57
|
(domains || []).forEach((domain) => {
|
|
125
|
-
Promise.all([
|
|
126
|
-
.
|
|
58
|
+
Promise.all([
|
|
59
|
+
this.routerManager.getHttpsCert({ domain }),
|
|
60
|
+
this.routerManager.checkDomainDNS(domain, cnameDomain),
|
|
61
|
+
checkDomainDnsWrapper(domain),
|
|
62
|
+
])
|
|
63
|
+
.then(([matchedCert, dnsResolve, dns]) => {
|
|
127
64
|
const eventData = {
|
|
128
65
|
domain,
|
|
129
66
|
matchedCert,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.44-beta-
|
|
6
|
+
"version": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,44 +19,44 @@
|
|
|
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.44-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.44-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.44-beta-
|
|
25
|
-
"@abtnode/client": "1.16.44-beta-
|
|
26
|
-
"@abtnode/constant": "1.16.44-beta-
|
|
27
|
-
"@abtnode/cron": "1.16.44-beta-
|
|
28
|
-
"@abtnode/docker-utils": "1.16.44-beta-
|
|
29
|
-
"@abtnode/logger": "1.16.44-beta-
|
|
30
|
-
"@abtnode/models": "1.16.44-beta-
|
|
31
|
-
"@abtnode/queue": "1.16.44-beta-
|
|
32
|
-
"@abtnode/rbac": "1.16.44-beta-
|
|
33
|
-
"@abtnode/router-provider": "1.16.44-beta-
|
|
34
|
-
"@abtnode/static-server": "1.16.44-beta-
|
|
35
|
-
"@abtnode/timemachine": "1.16.44-beta-
|
|
36
|
-
"@abtnode/util": "1.16.44-beta-
|
|
37
|
-
"@arcblock/did": "1.20.
|
|
38
|
-
"@arcblock/did-auth": "1.20.
|
|
39
|
-
"@arcblock/did-ext": "1.20.
|
|
22
|
+
"@abtnode/analytics": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
23
|
+
"@abtnode/auth": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
25
|
+
"@abtnode/client": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
26
|
+
"@abtnode/constant": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
27
|
+
"@abtnode/cron": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
28
|
+
"@abtnode/docker-utils": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
29
|
+
"@abtnode/logger": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
30
|
+
"@abtnode/models": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
31
|
+
"@abtnode/queue": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
32
|
+
"@abtnode/rbac": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
33
|
+
"@abtnode/router-provider": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
34
|
+
"@abtnode/static-server": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
35
|
+
"@abtnode/timemachine": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
36
|
+
"@abtnode/util": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
37
|
+
"@arcblock/did": "1.20.12",
|
|
38
|
+
"@arcblock/did-auth": "1.20.12",
|
|
39
|
+
"@arcblock/did-ext": "1.20.12",
|
|
40
40
|
"@arcblock/did-motif": "^1.1.13",
|
|
41
|
-
"@arcblock/did-util": "1.20.
|
|
42
|
-
"@arcblock/event-hub": "1.20.
|
|
43
|
-
"@arcblock/jwt": "1.20.
|
|
41
|
+
"@arcblock/did-util": "1.20.12",
|
|
42
|
+
"@arcblock/event-hub": "1.20.12",
|
|
43
|
+
"@arcblock/jwt": "1.20.12",
|
|
44
44
|
"@arcblock/pm2-events": "^0.0.5",
|
|
45
|
-
"@arcblock/validator": "1.20.
|
|
46
|
-
"@arcblock/vc": "1.20.
|
|
47
|
-
"@blocklet/constant": "1.16.44-beta-
|
|
48
|
-
"@blocklet/did-space-js": "^1.0.
|
|
49
|
-
"@blocklet/env": "1.16.44-beta-
|
|
50
|
-
"@blocklet/error": "^0.2.
|
|
51
|
-
"@blocklet/meta": "1.16.44-beta-
|
|
52
|
-
"@blocklet/resolver": "1.16.44-beta-
|
|
53
|
-
"@blocklet/sdk": "1.16.44-beta-
|
|
54
|
-
"@blocklet/store": "1.16.44-beta-
|
|
55
|
-
"@blocklet/theme": "^2.13.
|
|
45
|
+
"@arcblock/validator": "1.20.12",
|
|
46
|
+
"@arcblock/vc": "1.20.12",
|
|
47
|
+
"@blocklet/constant": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
48
|
+
"@blocklet/did-space-js": "^1.0.57",
|
|
49
|
+
"@blocklet/env": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
50
|
+
"@blocklet/error": "^0.2.5",
|
|
51
|
+
"@blocklet/meta": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
52
|
+
"@blocklet/resolver": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
53
|
+
"@blocklet/sdk": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
54
|
+
"@blocklet/store": "1.16.44-beta-20250603-231026-30a9d27f",
|
|
55
|
+
"@blocklet/theme": "^2.13.61",
|
|
56
56
|
"@fidm/x509": "^1.2.1",
|
|
57
|
-
"@ocap/mcrypto": "1.20.
|
|
58
|
-
"@ocap/util": "1.20.
|
|
59
|
-
"@ocap/wallet": "1.20.
|
|
57
|
+
"@ocap/mcrypto": "1.20.12",
|
|
58
|
+
"@ocap/util": "1.20.12",
|
|
59
|
+
"@ocap/wallet": "1.20.12",
|
|
60
60
|
"@slack/webhook": "^5.0.4",
|
|
61
61
|
"archiver": "^7.0.1",
|
|
62
62
|
"axios": "^1.7.9",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"jest": "^29.7.0",
|
|
117
117
|
"unzipper": "^0.10.11"
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "c76d07121652516f178de4188d8694fc130767b8"
|
|
120
120
|
}
|