@abtnode/core 1.8.2 → 1.8.5
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 +124 -45
- package/lib/event.js +48 -4
- package/lib/index.js +16 -16
- package/lib/states/audit-log.js +25 -6
- package/lib/states/blocklet.js +16 -0
- package/lib/states/node.js +8 -0
- package/lib/util/blocklet.js +13 -2
- package/lib/util/public-to-store.js +85 -0
- package/lib/validators/router.js +1 -1
- package/lib/webhook/index.js +7 -2
- package/lib/webhook/sender/index.js +5 -0
- package/lib/webhook/sender/slack/index.js +1 -1
- package/lib/webhook/sender/wallet/index.js +45 -0
- package/package.json +25 -24
|
@@ -22,8 +22,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
|
|
|
22
22
|
const downloadFile = require('@abtnode/util/lib/download-file');
|
|
23
23
|
const Lock = require('@abtnode/util/lib/lock');
|
|
24
24
|
const { getVcFromPresentation } = require('@abtnode/util/lib/vc');
|
|
25
|
-
const
|
|
26
|
-
const { VC_TYPE_BLOCKLET_PURCHASE } = require('@abtnode/constant');
|
|
25
|
+
const { VC_TYPE_BLOCKLET_PURCHASE, WHO_CAN_ACCESS } = require('@abtnode/constant');
|
|
27
26
|
|
|
28
27
|
const getBlockletEngine = require('@blocklet/meta/lib/engine');
|
|
29
28
|
const {
|
|
@@ -116,6 +115,7 @@ const { getFactoryState } = require('../../util/chain');
|
|
|
116
115
|
const runMigrationScripts = require('../migration');
|
|
117
116
|
const hooks = require('../hooks');
|
|
118
117
|
const { formatName } = require('../../util/get-domain-for-blocklet');
|
|
118
|
+
const handleInstanceInStore = require('../../util/public-to-store');
|
|
119
119
|
|
|
120
120
|
const {
|
|
121
121
|
isInProgress,
|
|
@@ -128,7 +128,7 @@ const {
|
|
|
128
128
|
validateOwner,
|
|
129
129
|
} = util;
|
|
130
130
|
|
|
131
|
-
const
|
|
131
|
+
const statusLock = new Lock('blocklet-status-lock');
|
|
132
132
|
|
|
133
133
|
const asyncFs = fs.promises;
|
|
134
134
|
|
|
@@ -234,7 +234,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
234
234
|
context.headers = Object.assign(context?.headers || {}, {
|
|
235
235
|
'x-server-did': info.did,
|
|
236
236
|
'x-download-token': params.downloadToken,
|
|
237
|
+
// FIXME: 先保证兼容性,后续删除
|
|
237
238
|
'x-server-publick-key': info.pk,
|
|
239
|
+
'x-server-public-key': info.pk,
|
|
238
240
|
'x-server-signature': sign(info.did, info.sk, {
|
|
239
241
|
exp: (Date.now() + 5 * 60 * 1000) / 1000,
|
|
240
242
|
}),
|
|
@@ -427,6 +429,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
427
429
|
|
|
428
430
|
return blocklet;
|
|
429
431
|
} catch (err) {
|
|
432
|
+
const status = await states.blocklet.getBlockletStatus(did);
|
|
433
|
+
if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
|
|
434
|
+
logger.info('Failed to start blocklet maybe due to manually stopped');
|
|
435
|
+
return states.blocklet.getBlocklet(did);
|
|
436
|
+
}
|
|
437
|
+
|
|
430
438
|
const error = Array.isArray(err) ? err[0] : err;
|
|
431
439
|
logger.error('Failed to start blocklet', { error, did, name: blocklet.meta.name });
|
|
432
440
|
const description = `Start blocklet ${blocklet.meta.name} failed with error: ${error.message}`;
|
|
@@ -677,26 +685,38 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
677
685
|
return newBlocklet;
|
|
678
686
|
}
|
|
679
687
|
|
|
680
|
-
async cancelDownload({ did }, context) {
|
|
681
|
-
await preDownloadLock.acquire();
|
|
688
|
+
async cancelDownload({ did: inputDid }, context) {
|
|
682
689
|
try {
|
|
683
|
-
|
|
690
|
+
await statusLock.acquire();
|
|
691
|
+
const blocklet = await states.blocklet.getBlocklet(inputDid);
|
|
684
692
|
if (!blocklet) {
|
|
685
|
-
throw new Error('Can not cancel download for non-exist blocklet in database.', {
|
|
693
|
+
throw new Error('Can not cancel download for non-exist blocklet in database.', { inputDid });
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const { name, did, version } = blocklet.meta;
|
|
697
|
+
|
|
698
|
+
if (![BlockletStatus.downloading, BlockletStatus.waiting].includes(blocklet.status)) {
|
|
699
|
+
throw new Error(`Can not cancel blocklet that status is ${fromBlockletStatus(blocklet.status)}`);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
const job = await this.installQueue.get(did);
|
|
703
|
+
if (job) {
|
|
704
|
+
const { postAction, oldBlocklet } = job;
|
|
705
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
686
706
|
}
|
|
687
707
|
|
|
688
708
|
if (blocklet.status === BlockletStatus.downloading) {
|
|
689
709
|
await this._cancelDownload(blocklet.meta, context);
|
|
690
710
|
} else if (blocklet.status === BlockletStatus.waiting) {
|
|
691
711
|
await this._cancelWaiting(blocklet.meta, context);
|
|
692
|
-
} else {
|
|
693
|
-
throw new Error(`Can not cancel blocklet that status is ${fromBlockletStatus(blocklet.status)}`);
|
|
694
712
|
}
|
|
695
713
|
|
|
696
|
-
|
|
714
|
+
logger.info('cancel download blocklet', { did, name, version, status: fromBlockletStatus(blocklet.status) });
|
|
715
|
+
|
|
716
|
+
statusLock.release();
|
|
697
717
|
return blocklet;
|
|
698
718
|
} catch (error) {
|
|
699
|
-
|
|
719
|
+
statusLock.release();
|
|
700
720
|
throw error;
|
|
701
721
|
}
|
|
702
722
|
}
|
|
@@ -880,6 +900,25 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
880
900
|
return newState;
|
|
881
901
|
}
|
|
882
902
|
|
|
903
|
+
async updateWhoCanAccess({ did, whoCanAccess }) {
|
|
904
|
+
if (!(await this.hasBlocklet({ did }))) {
|
|
905
|
+
throw new Error('The blocklet does not exist');
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (!Object.values(WHO_CAN_ACCESS).includes(whoCanAccess)) {
|
|
909
|
+
logger.error(`The value of whoCanAccess is invalid: ${whoCanAccess}`);
|
|
910
|
+
throw new Error('the value is invalid');
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
await states.blockletExtras.setSettings(did, { whoCanAccess });
|
|
914
|
+
|
|
915
|
+
const blocklet = await this.ensureBlocklet(did);
|
|
916
|
+
|
|
917
|
+
this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
|
|
918
|
+
|
|
919
|
+
return blocklet;
|
|
920
|
+
}
|
|
921
|
+
|
|
883
922
|
/**
|
|
884
923
|
* upgrade blocklet from registry
|
|
885
924
|
*/
|
|
@@ -1495,39 +1534,45 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1495
1534
|
const { meta } = blocklet;
|
|
1496
1535
|
const { name, did, version } = meta;
|
|
1497
1536
|
|
|
1537
|
+
// check status
|
|
1498
1538
|
try {
|
|
1499
|
-
await
|
|
1539
|
+
await statusLock.acquire();
|
|
1500
1540
|
|
|
1501
1541
|
const b0 = await states.blocklet.getBlocklet(did);
|
|
1502
|
-
if (!b0 || ![BlockletStatus.waiting
|
|
1542
|
+
if (!b0 || ![BlockletStatus.waiting].includes(b0.status)) {
|
|
1503
1543
|
if (!b0) {
|
|
1504
|
-
|
|
1544
|
+
throw new Error('blocklet does not exist before downloading');
|
|
1505
1545
|
} else {
|
|
1506
|
-
|
|
1507
|
-
name,
|
|
1508
|
-
did,
|
|
1509
|
-
status: fromBlockletStatus(b0.status),
|
|
1510
|
-
});
|
|
1546
|
+
throw new Error(`blocklet status is invalid before downloading: ${fromBlockletStatus(b0.status)}`);
|
|
1511
1547
|
}
|
|
1512
|
-
preDownloadLock.release();
|
|
1513
|
-
await this._rollback(postAction, did, oldBlocklet);
|
|
1514
|
-
return;
|
|
1515
1548
|
}
|
|
1549
|
+
statusLock.release();
|
|
1550
|
+
} catch (error) {
|
|
1551
|
+
statusLock.release();
|
|
1552
|
+
logger.error('Check blocklet status failed before downloading', {
|
|
1553
|
+
name,
|
|
1554
|
+
did,
|
|
1555
|
+
error,
|
|
1556
|
+
});
|
|
1557
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1516
1560
|
|
|
1517
|
-
|
|
1518
|
-
|
|
1561
|
+
// download bundle
|
|
1562
|
+
try {
|
|
1519
1563
|
const { isCancelled } = await this._downloadBlocklet(blocklet, oldBlocklet, context);
|
|
1520
1564
|
|
|
1521
1565
|
if (isCancelled) {
|
|
1522
|
-
logger.info('Download was canceled
|
|
1523
|
-
|
|
1566
|
+
logger.info('Download was canceled', { name, did, version });
|
|
1567
|
+
|
|
1568
|
+
if ((await states.blocklet.getBlockletStatus(did)) === BlockletStatus.downloading) {
|
|
1569
|
+
await this._rollback(postAction, did, oldBlocklet);
|
|
1570
|
+
}
|
|
1524
1571
|
return;
|
|
1525
1572
|
}
|
|
1526
1573
|
} catch (err) {
|
|
1527
1574
|
logger.error('Download blocklet tarball failed', { name, did, version });
|
|
1528
1575
|
|
|
1529
|
-
preDownloadLock.release();
|
|
1530
|
-
|
|
1531
1576
|
this.emit(BlockletEvents.downloadFailed, {
|
|
1532
1577
|
meta: { did },
|
|
1533
1578
|
error: {
|
|
@@ -1555,6 +1600,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1555
1600
|
return;
|
|
1556
1601
|
}
|
|
1557
1602
|
|
|
1603
|
+
// update status
|
|
1604
|
+
try {
|
|
1605
|
+
await statusLock.acquire();
|
|
1606
|
+
|
|
1607
|
+
if ((await states.blocklet.getBlockletStatus(did)) !== BlockletStatus.downloading) {
|
|
1608
|
+
throw new Error('blocklet status changed durning download');
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (postAction === 'install') {
|
|
1612
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing);
|
|
1613
|
+
this.emit(BlockletEvents.statusChange, state);
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
if (['upgrade', 'downgrade'].includes(postAction)) {
|
|
1617
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading);
|
|
1618
|
+
this.emit(BlockletEvents.statusChange, state);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
statusLock.release();
|
|
1622
|
+
} catch (error) {
|
|
1623
|
+
logger.error(error.message);
|
|
1624
|
+
statusLock.release();
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// install
|
|
1558
1628
|
try {
|
|
1559
1629
|
// install blocklet
|
|
1560
1630
|
if (postAction === 'install') {
|
|
@@ -1578,9 +1648,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1578
1648
|
const { did, version } = meta;
|
|
1579
1649
|
logger.info('do install blocklet', { did, version });
|
|
1580
1650
|
|
|
1581
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing);
|
|
1582
|
-
this.emit(BlockletEvents.statusChange, state);
|
|
1583
|
-
|
|
1584
1651
|
try {
|
|
1585
1652
|
const installedBlocklet = await this._installBlocklet({
|
|
1586
1653
|
did,
|
|
@@ -1608,9 +1675,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1608
1675
|
const { version, did } = newBlocklet.meta;
|
|
1609
1676
|
logger.info(`do ${action} blocklet`, { did, version });
|
|
1610
1677
|
|
|
1611
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading);
|
|
1612
|
-
this.emit(BlockletEvents.statusChange, state);
|
|
1613
|
-
|
|
1614
1678
|
try {
|
|
1615
1679
|
await this._upgradeBlocklet({
|
|
1616
1680
|
newBlocklet,
|
|
@@ -1642,6 +1706,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1642
1706
|
const res = await this.status(did, { forceSync: true });
|
|
1643
1707
|
this.emit(BlockletEvents.started, res);
|
|
1644
1708
|
} catch (error) {
|
|
1709
|
+
const status = await states.blocklet.getBlockletStatus(did);
|
|
1710
|
+
if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
|
|
1711
|
+
logger.info(`Check blocklet healthy failing because blocklet is ${fromBlockletStatus(status)}`);
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1645
1715
|
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
1646
1716
|
|
|
1647
1717
|
await this.deleteProcess({ did }, context);
|
|
@@ -1838,7 +1908,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1838
1908
|
headers: {
|
|
1839
1909
|
'x-server-did': info.did,
|
|
1840
1910
|
'x-download-token': downloadToken,
|
|
1911
|
+
// FIXME: 先保证兼容性,后续删除
|
|
1841
1912
|
'x-server-publick-key': info.pk,
|
|
1913
|
+
'x-server-public-key': info.pk,
|
|
1842
1914
|
'x-server-signature': sign(info.did, info.sk, {
|
|
1843
1915
|
exp: (Date.now() + 5 * 60 * 1000) / 1000,
|
|
1844
1916
|
}),
|
|
@@ -2406,7 +2478,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2406
2478
|
headers: {
|
|
2407
2479
|
'x-server-did': info.did,
|
|
2408
2480
|
'x-download-token': blocklet?.tokens?.paidBlockletDownloadToken,
|
|
2481
|
+
// FIXME: 先保证兼容性,后续删除
|
|
2409
2482
|
'x-server-publick-key': info.pk,
|
|
2483
|
+
'x-server-public-key': info.pk,
|
|
2410
2484
|
'x-server-signature': sign(info.did, info.sk, {
|
|
2411
2485
|
exp: (Date.now() + 5 * 60 * 1000) / 1000,
|
|
2412
2486
|
}),
|
|
@@ -2440,7 +2514,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2440
2514
|
ticket.on('failed', async (err) => {
|
|
2441
2515
|
logger.error('queue failed', { entity: 'blocklet', action, did, version, name, error: err });
|
|
2442
2516
|
await this._rollback(action, did, oldBlocklet);
|
|
2443
|
-
|
|
2517
|
+
const eventNames = {
|
|
2518
|
+
upgrade: BlockletEvents.upgradeFailed,
|
|
2519
|
+
downgrade: BlockletEvents.downgradeFailed,
|
|
2520
|
+
};
|
|
2521
|
+
this.emit(eventNames[action], { blocklet: oldBlocklet, context });
|
|
2444
2522
|
states.notification.create({
|
|
2445
2523
|
title: `Blocklet ${capitalize(action)} Failed`,
|
|
2446
2524
|
description: `Blocklet ${name}@${version} ${action} failed with error: ${err.message || 'queue exception'}`,
|
|
@@ -2811,7 +2889,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2811
2889
|
} catch (err) {
|
|
2812
2890
|
const b = await this._rollback(action, did, oldBlocklet);
|
|
2813
2891
|
logger.error(`failed to ${action} blocklet`, { did, version, name, error: err });
|
|
2892
|
+
|
|
2814
2893
|
this.emit(BlockletEvents.updated, b);
|
|
2894
|
+
|
|
2895
|
+
const eventNames = {
|
|
2896
|
+
upgrade: BlockletEvents.upgradeFailed,
|
|
2897
|
+
downgrade: BlockletEvents.downgradeFailed,
|
|
2898
|
+
};
|
|
2899
|
+
this.emit(eventNames[action], { blocklet: oldBlocklet, context });
|
|
2900
|
+
|
|
2815
2901
|
states.notification.create({
|
|
2816
2902
|
title: `Blocklet ${capitalize(action)} Failed`,
|
|
2817
2903
|
description: `Blocklet ${name}@${version} ${action} failed with error: ${err.message}`,
|
|
@@ -3120,26 +3206,19 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3120
3206
|
|
|
3121
3207
|
// eslint-disable-next-line no-unused-vars
|
|
3122
3208
|
async _cancelDownload(blockletMeta, context) {
|
|
3123
|
-
const { did
|
|
3209
|
+
const { did } = blockletMeta;
|
|
3124
3210
|
|
|
3125
3211
|
if (this.downloadCtrls[did]) {
|
|
3126
3212
|
for (const cancelCtrl of this.downloadCtrls[did].values()) {
|
|
3127
3213
|
cancelCtrl.cancel();
|
|
3128
3214
|
}
|
|
3129
|
-
logger.info('cancel download blocklet', { did, name, version });
|
|
3130
3215
|
}
|
|
3131
3216
|
}
|
|
3132
3217
|
|
|
3133
3218
|
// eslint-disable-next-line no-unused-vars
|
|
3134
3219
|
async _cancelWaiting(blockletMeta, context) {
|
|
3135
|
-
const { did
|
|
3136
|
-
|
|
3137
|
-
const {
|
|
3138
|
-
job: { postAction, oldBlocklet },
|
|
3139
|
-
} = await this.installQueue.cancel(did);
|
|
3140
|
-
await this._rollback(postAction, did, oldBlocklet);
|
|
3141
|
-
|
|
3142
|
-
logger.info('cancel waiting blocklet', { did, name, version });
|
|
3220
|
+
const { did } = blockletMeta;
|
|
3221
|
+
return this.installQueue.cancel(did);
|
|
3143
3222
|
}
|
|
3144
3223
|
|
|
3145
3224
|
/**
|
package/lib/event.js
CHANGED
|
@@ -5,7 +5,7 @@ const { wipeSensitiveData } = require('@blocklet/meta/lib/util');
|
|
|
5
5
|
const logger = require('@abtnode/logger')('@abtnode/core:event');
|
|
6
6
|
const { BLOCKLET_MODES, BlockletStatus, BlockletSource, BlockletEvents } = require('@blocklet/meta/lib/constants');
|
|
7
7
|
const { EVENTS } = require('@abtnode/constant');
|
|
8
|
-
const handleInstanceInStore = require('
|
|
8
|
+
const handleInstanceInStore = require('./util/public-to-store');
|
|
9
9
|
|
|
10
10
|
const eventHub =
|
|
11
11
|
process.env.NODE_ENV === 'test' ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
|
|
@@ -27,6 +27,7 @@ module.exports = ({
|
|
|
27
27
|
domainStatus,
|
|
28
28
|
teamAPI,
|
|
29
29
|
certManager,
|
|
30
|
+
node,
|
|
30
31
|
}) => {
|
|
31
32
|
const notificationState = states.notification;
|
|
32
33
|
const nodeState = states.node;
|
|
@@ -155,22 +156,65 @@ module.exports = ({
|
|
|
155
156
|
};
|
|
156
157
|
|
|
157
158
|
const handleBlockletEvent = async (eventName, payload) => {
|
|
159
|
+
const blocklet = payload.blocklet || payload;
|
|
160
|
+
|
|
158
161
|
if ([BlockletEvents.deployed, BlockletEvents.installed].includes(eventName)) {
|
|
159
162
|
await handleBlockletAdd(eventName, payload);
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
await node.createAuditLog({
|
|
166
|
+
action: 'installBlocklet',
|
|
167
|
+
args: {
|
|
168
|
+
did: blocklet.meta.did,
|
|
169
|
+
},
|
|
170
|
+
context: payload.context || {},
|
|
171
|
+
result: blocklet,
|
|
172
|
+
});
|
|
173
|
+
} catch (error) {
|
|
174
|
+
logger.error('Failed to createAuditLog for installBlocklet', { error });
|
|
175
|
+
}
|
|
160
176
|
} else if ([BlockletEvents.upgraded, BlockletEvents.downgraded].includes(eventName)) {
|
|
161
177
|
await handleBlockletUpgrade(eventName, payload);
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
await node.createAuditLog({
|
|
181
|
+
action: 'upgradeBlocklet',
|
|
182
|
+
args: {
|
|
183
|
+
did: blocklet.meta.did,
|
|
184
|
+
},
|
|
185
|
+
context: payload.context || {},
|
|
186
|
+
result: blocklet,
|
|
187
|
+
});
|
|
188
|
+
} catch (error) {
|
|
189
|
+
logger.error('Failed to createAuditLog for upgradeBlocklet', { error });
|
|
190
|
+
}
|
|
162
191
|
} else if ([BlockletEvents.removed].includes(eventName)) {
|
|
163
192
|
await handleBlockletRemove(eventName, payload);
|
|
164
193
|
} else if ([BlockletEvents.started].includes(eventName)) {
|
|
165
194
|
try {
|
|
166
|
-
const
|
|
167
|
-
const { publicToStore } = blocklet.settings;
|
|
195
|
+
const { publicToStore } = blocklet.settings || {};
|
|
168
196
|
// 如果一个 blocklet 没有设置 publicToStore,启动成功后不应给 store 发请求
|
|
169
197
|
if (publicToStore) {
|
|
170
198
|
await handleInstanceInStore(blocklet, { publicToStore });
|
|
171
199
|
}
|
|
172
200
|
} catch (error) {
|
|
173
|
-
logger.error('
|
|
201
|
+
logger.error('handleInstanceInStore failed', { error });
|
|
202
|
+
}
|
|
203
|
+
} else if ([BlockletEvents.upgradeFailed, BlockletEvents.downgradeFailed].includes(eventName)) {
|
|
204
|
+
try {
|
|
205
|
+
await node.createAuditLog({
|
|
206
|
+
action: 'upgradeBlocklet',
|
|
207
|
+
args: {
|
|
208
|
+
did: blocklet.meta.did,
|
|
209
|
+
},
|
|
210
|
+
context: payload.context || {},
|
|
211
|
+
result: {
|
|
212
|
+
...blocklet,
|
|
213
|
+
resultStatus: 'failed',
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
} catch (error) {
|
|
217
|
+
logger.error('Failed to createAuditLog for upgradeBlocklet failed', { error });
|
|
174
218
|
}
|
|
175
219
|
}
|
|
176
220
|
|
package/lib/index.js
CHANGED
|
@@ -174,19 +174,6 @@ function ABTNode(options) {
|
|
|
174
174
|
onStatesReady(createStateReadyHandler(routingSnapshot));
|
|
175
175
|
const domainStatus = new DomainStatus(routerManager);
|
|
176
176
|
|
|
177
|
-
const events = createEvents({
|
|
178
|
-
blockletManager,
|
|
179
|
-
blockletRegistry,
|
|
180
|
-
ensureBlockletRouting,
|
|
181
|
-
ensureBlockletRoutingForUpgrade,
|
|
182
|
-
removeBlockletRouting,
|
|
183
|
-
takeRoutingSnapshot,
|
|
184
|
-
handleRouting,
|
|
185
|
-
domainStatus,
|
|
186
|
-
teamAPI,
|
|
187
|
-
certManager,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
177
|
const isInitialized = async () => {
|
|
191
178
|
const state = await states.node.read();
|
|
192
179
|
return states.node.isInitialized(state);
|
|
@@ -226,9 +213,9 @@ function ABTNode(options) {
|
|
|
226
213
|
getLatestBlockletVersion: blockletManager.getLatestBlockletVersion.bind(blockletManager),
|
|
227
214
|
getBlockletMetaFromUrl: blockletManager.getMetaFromUrl.bind(blockletManager),
|
|
228
215
|
resetBlocklet: blockletManager.reset.bind(blockletManager),
|
|
229
|
-
configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
|
|
230
|
-
|
|
231
216
|
deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
|
|
217
|
+
configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
|
|
218
|
+
updateWhoCanAccess: blockletManager.updateWhoCanAccess.bind(blockletManager),
|
|
232
219
|
|
|
233
220
|
// For diagnose purpose
|
|
234
221
|
syncBlockletStatus: blockletManager.status.bind(blockletManager),
|
|
@@ -319,7 +306,6 @@ function ABTNode(options) {
|
|
|
319
306
|
processPassportIssuance: teamAPI.processPassportIssuance.bind(teamAPI),
|
|
320
307
|
configTrustedPassports: teamAPI.configTrustedPassports.bind(teamAPI),
|
|
321
308
|
configPassportIssuance: teamAPI.configPassportIssuance.bind(teamAPI),
|
|
322
|
-
configWhoCanAccess: teamAPI.configWhoCanAccess.bind(teamAPI),
|
|
323
309
|
|
|
324
310
|
// Challenge
|
|
325
311
|
generateChallenge: states.challenge.generate.bind(states.challenge),
|
|
@@ -405,6 +391,20 @@ function ABTNode(options) {
|
|
|
405
391
|
getRouterProvider,
|
|
406
392
|
};
|
|
407
393
|
|
|
394
|
+
const events = createEvents({
|
|
395
|
+
blockletManager,
|
|
396
|
+
blockletRegistry,
|
|
397
|
+
ensureBlockletRouting,
|
|
398
|
+
ensureBlockletRoutingForUpgrade,
|
|
399
|
+
removeBlockletRouting,
|
|
400
|
+
takeRoutingSnapshot,
|
|
401
|
+
handleRouting,
|
|
402
|
+
domainStatus,
|
|
403
|
+
teamAPI,
|
|
404
|
+
certManager,
|
|
405
|
+
node: instance,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
408
|
const webhook = WebHook({ events, dataDirs, instance });
|
|
409
409
|
|
|
410
410
|
const initCron = () => {
|
package/lib/states/audit-log.js
CHANGED
|
@@ -111,6 +111,9 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
111
111
|
case 'configBlocklet':
|
|
112
112
|
return `updated following config for blocklet ${getBlockletInfo(result, info)}:\n${args.configs.map(x => `- ${x.key}: ${x.value}\n`)}`; // prettier-ignore
|
|
113
113
|
case 'upgradeBlocklet':
|
|
114
|
+
if (result.resultStatus === 'failed') {
|
|
115
|
+
return `upgrade blocklet failed: ${getBlockletInfo(result, info)}`;
|
|
116
|
+
}
|
|
114
117
|
return `upgraded blocklet ${getBlockletInfo(result, info)} to v${result.meta.version}`;
|
|
115
118
|
case 'updateChildBlocklets':
|
|
116
119
|
return `upgraded components for blocklet ${getBlockletInfo(result, info)}`;
|
|
@@ -141,7 +144,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
141
144
|
return `switched passport to ${args.passport.name} for ${team}`;
|
|
142
145
|
case 'login':
|
|
143
146
|
return `${user} logged in to ${team} with passport ${args.passport.name}`;
|
|
144
|
-
case '
|
|
147
|
+
case 'updateWhoCanAccess':
|
|
145
148
|
return `updated access control policy to **${args.value}** for ${team} when ${args.reason}`;
|
|
146
149
|
case 'configPassportIssuance':
|
|
147
150
|
return `${args.enabled ? 'enabled' : 'disabled'} passport issuance for ${team}`;
|
|
@@ -214,12 +217,22 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
214
217
|
return `added extra domain **${args.domainAlias}** to ${site}`; // prettier-ignore
|
|
215
218
|
case 'deleteDomainAlias':
|
|
216
219
|
return `removed extra domain **${args.domainAlias}** from ${site}`; // prettier-ignore
|
|
220
|
+
case 'updateRoutingSite':
|
|
221
|
+
return `updated site from ${site}`; // prettier-ignore
|
|
222
|
+
case 'addRoutingRule':
|
|
223
|
+
return `added routing rule **${args.rule?.from?.pathPrefix}** from ${site}`; // prettier-ignore
|
|
224
|
+
case 'updateRoutingRule':
|
|
225
|
+
return `updated routing rule **${args.rule?.from?.pathPrefix}** from ${site}`; // prettier-ignore
|
|
226
|
+
case 'deleteRoutingRule':
|
|
227
|
+
return `deleted routing rule from ${site}`; // prettier-ignore
|
|
217
228
|
case 'updateGateway': {
|
|
218
229
|
let message = args.requestLimit.enabled ? `status: enabled, rate: ${args.requestLimit.rate}` : 'status: disabled';
|
|
219
230
|
message = `update gateway. ${message}`;
|
|
220
231
|
|
|
221
232
|
return message;
|
|
222
233
|
}
|
|
234
|
+
case 'createTransferInvitation':
|
|
235
|
+
return `created a transfer node invitation(${result.inviteId})`;
|
|
223
236
|
|
|
224
237
|
default:
|
|
225
238
|
return action;
|
|
@@ -271,6 +284,7 @@ const getLogCategory = (action) => {
|
|
|
271
284
|
case 'updatePermissionsForRole':
|
|
272
285
|
case 'configTrustedPassports':
|
|
273
286
|
case 'delegateTransferNFT':
|
|
287
|
+
case 'createTransferInvitation':
|
|
274
288
|
return 'team';
|
|
275
289
|
|
|
276
290
|
// accessKeys
|
|
@@ -312,16 +326,21 @@ const getScope = (args = {}) => {
|
|
|
312
326
|
return args.teamDid;
|
|
313
327
|
}
|
|
314
328
|
|
|
329
|
+
// this param usually means mutating an blockle application
|
|
330
|
+
if (args.did) {
|
|
331
|
+
// this param usually means mutating a nested child component
|
|
332
|
+
if (Array.isArray(args.did)) {
|
|
333
|
+
return args.did[0];
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return args.did;
|
|
337
|
+
}
|
|
338
|
+
|
|
315
339
|
// this param usually means mutating a child component
|
|
316
340
|
if (args.rootDid) {
|
|
317
341
|
return args.rootDid;
|
|
318
342
|
}
|
|
319
343
|
|
|
320
|
-
// this param usually means mutating a nested child component
|
|
321
|
-
if (Array.isArray(args.did)) {
|
|
322
|
-
return args.did[0];
|
|
323
|
-
}
|
|
324
|
-
|
|
325
344
|
return null;
|
|
326
345
|
};
|
|
327
346
|
|
package/lib/states/blocklet.js
CHANGED
|
@@ -102,6 +102,22 @@ class BlockletState extends BaseState {
|
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
async getBlockletStatus(did) {
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
if (!did) {
|
|
108
|
+
resolve(null);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.db.findOne({ $or: [{ 'meta.did': did }, { appDid: did }] }, { status: 1 }, (err, doc) => {
|
|
112
|
+
if (err) {
|
|
113
|
+
return reject(err);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return resolve(doc ? doc.status : null);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
hasBlocklet(did) {
|
|
106
122
|
return new Promise((resolve, reject) => {
|
|
107
123
|
if (!did) {
|
package/lib/states/node.js
CHANGED
|
@@ -283,6 +283,14 @@ class NodeState extends BaseState {
|
|
|
283
283
|
return this.updateNodeInfo({ previousMode: '', mode: info.previousMode });
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
+
async setMode(mode) {
|
|
287
|
+
if (Object.values(NODE_MODES).includes(mode) === false) {
|
|
288
|
+
throw new Error(`Can not update server to unsupported mode: ${mode}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return this.updateNodeInfo({ previousMode: '', mode });
|
|
292
|
+
}
|
|
293
|
+
|
|
286
294
|
async getEnvironments() {
|
|
287
295
|
return this.read().then((info) => ({
|
|
288
296
|
ABT_NODE: info.version,
|
package/lib/util/blocklet.js
CHANGED
|
@@ -312,6 +312,7 @@ const getComponentSystemEnvironments = (blocklet) => {
|
|
|
312
312
|
|
|
313
313
|
return {
|
|
314
314
|
BLOCKLET_REAL_DID: blocklet.env.id,
|
|
315
|
+
BLOCKLET_REAL_NAME: blocklet.env.name,
|
|
315
316
|
BLOCKLET_DATA_DIR: blocklet.env.dataDir,
|
|
316
317
|
BLOCKLET_LOG_DIR: blocklet.env.logsDir,
|
|
317
318
|
BLOCKLET_CACHE_DIR: blocklet.env.cacheDir,
|
|
@@ -337,11 +338,21 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
|
|
|
337
338
|
}
|
|
338
339
|
: {};
|
|
339
340
|
|
|
341
|
+
const root = (ancestors || [])[0] || blocklet;
|
|
342
|
+
const ports = {};
|
|
343
|
+
forEachBlockletSync(root, (x) => {
|
|
344
|
+
const webInterface = findWebInterface(x);
|
|
345
|
+
if (webInterface && x.environmentObj[webInterface.port]) {
|
|
346
|
+
ports[x.environmentObj.BLOCKLET_REAL_NAME] = x.environmentObj[webInterface.port];
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
340
350
|
return {
|
|
341
351
|
...blocklet.configObj,
|
|
342
352
|
...getSharedConfigObj(blocklet, ancestors),
|
|
343
353
|
...blocklet.environmentObj,
|
|
344
354
|
...devEnvironments,
|
|
355
|
+
BLOCKLET_WEB_PORTS: JSON.stringify(ports),
|
|
345
356
|
...nodeEnvironments,
|
|
346
357
|
...safeNodeEnvironments,
|
|
347
358
|
};
|
|
@@ -415,7 +426,7 @@ const getBlockletMetaFromUrls = async (urls) => {
|
|
|
415
426
|
const meta = await any(urls.map(getBlockletMetaFromUrl));
|
|
416
427
|
return meta;
|
|
417
428
|
} catch (err) {
|
|
418
|
-
logger.error('failed get blocklet meta', { urls });
|
|
429
|
+
logger.error('failed get blocklet meta', { urls, error: err });
|
|
419
430
|
throw new Error('Failed get blocklet meta');
|
|
420
431
|
}
|
|
421
432
|
};
|
|
@@ -729,7 +740,7 @@ const parseChildrenFromMeta = async (src, context = {}) => {
|
|
|
729
740
|
try {
|
|
730
741
|
m = await getBlockletMetaFromUrls(urls);
|
|
731
742
|
} catch {
|
|
732
|
-
throw new Error(
|
|
743
|
+
throw new Error(`Failed get component meta: ${config.title || config.name}`);
|
|
733
744
|
}
|
|
734
745
|
|
|
735
746
|
validateBlockletMeta(m, { ensureDist: true });
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const { sign } = require('@arcblock/jwt');
|
|
2
|
+
const { BlockletSource } = require('@blocklet/meta/lib/constants');
|
|
3
|
+
const { WHO_CAN_ACCESS } = require('@abtnode/constant');
|
|
4
|
+
const logger = require('@abtnode/logger')('@abtnode/util:public-to-store');
|
|
5
|
+
|
|
6
|
+
const getWallet = require('@abtnode/util/lib/get-app-wallet');
|
|
7
|
+
const axios = require('@abtnode/util/lib/axios');
|
|
8
|
+
|
|
9
|
+
const getAppToken = (blocklet) =>
|
|
10
|
+
sign(blocklet.environmentObj?.BLOCKLET_APP_ID, blocklet.environmentObj?.BLOCKLET_APP_SK);
|
|
11
|
+
|
|
12
|
+
const getAppId = (blocklet) => blocklet.environmentObj?.BLOCKLET_APP_ID;
|
|
13
|
+
|
|
14
|
+
const getAppSK = (blocklet) => blocklet.environmentObj?.BLOCKLET_APP_SK;
|
|
15
|
+
|
|
16
|
+
const getBlockletDid = (blocklet) => blocklet.meta?.bundleDid;
|
|
17
|
+
|
|
18
|
+
const getAppUrl = (blocklet) => blocklet.environmentObj?.BLOCKLET_APP_URL;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* verify manages the permissions of blocklet public instance
|
|
22
|
+
* @param {*} blocklet
|
|
23
|
+
* @returns bool
|
|
24
|
+
*/
|
|
25
|
+
const verifyPublicInstance = (blocklet) => {
|
|
26
|
+
const { whoCanAccess = WHO_CAN_ACCESS.ALL } = blocklet.settings;
|
|
27
|
+
return blocklet.source === BlockletSource.registry && whoCanAccess === WHO_CAN_ACCESS.ALL;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param {*} blocklet
|
|
33
|
+
* @param {*} {userDid publicToStore}
|
|
34
|
+
* @returns bool
|
|
35
|
+
*/
|
|
36
|
+
async function handleInstanceInStore(blocklet, { userDid = null, publicToStore = false } = {}) {
|
|
37
|
+
if (!blocklet) {
|
|
38
|
+
logger.error('blocklet argument is required');
|
|
39
|
+
throw new Error('blocklet argument is required');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ownerDid = userDid || blocklet.settings?.owner?.did;
|
|
43
|
+
if (!ownerDid) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!verifyPublicInstance(blocklet)) {
|
|
48
|
+
logger.error('no permission to set publicInstance');
|
|
49
|
+
throw new Error('no permission to set publicInstance');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const appToken = getAppToken(blocklet);
|
|
53
|
+
const blockletDid = getBlockletDid(blocklet);
|
|
54
|
+
const appId = getAppId(blocklet);
|
|
55
|
+
const appSK = getAppSK(blocklet);
|
|
56
|
+
const wallet = getWallet(appSK);
|
|
57
|
+
const body = {
|
|
58
|
+
appToken,
|
|
59
|
+
appId,
|
|
60
|
+
appPK: wallet.publicKey,
|
|
61
|
+
ownerDid,
|
|
62
|
+
appUrl: getAppUrl(blocklet),
|
|
63
|
+
blockletDid,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const api = axios.create({ baseURL: blocklet.deployedFrom, timeout: 1000 * 10 });
|
|
67
|
+
if (!publicToStore) {
|
|
68
|
+
try {
|
|
69
|
+
await api.delete(`/api/blocklet-instances/${appId}`, { data: body });
|
|
70
|
+
} catch (error) {
|
|
71
|
+
logger.error('failed to delete blocklet instance', { error });
|
|
72
|
+
throw new Error('failed to delete blocklet instance');
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
try {
|
|
76
|
+
await api.put(`/api/blocklet-instances/${appId}`, body);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
logger.error('failed to update blocklet instance', { error });
|
|
79
|
+
throw new Error('failed to delete blocklet instance');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = handleInstanceInStore;
|
package/lib/validators/router.js
CHANGED
package/lib/webhook/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const { evaluateURLs } = require('@abtnode/util/lib/url-evaluation');
|
|
|
4
4
|
const checkURLAccessible = require('@abtnode/util/lib/url-evaluation/check-accessible-node');
|
|
5
5
|
const { EVENTS } = require('@abtnode/constant');
|
|
6
6
|
const WebHookSender = require('./sender');
|
|
7
|
+
const WalletSender = require('./sender/wallet');
|
|
7
8
|
const createQueue = require('../queue');
|
|
8
9
|
const IP = require('../util/ip');
|
|
9
10
|
const states = require('../states');
|
|
@@ -72,6 +73,11 @@ module.exports = ({ events, dataDirs, instance }) => {
|
|
|
72
73
|
const baseUrls = await getBaseUrls(instance, [external, internal]);
|
|
73
74
|
const senderFns = {};
|
|
74
75
|
|
|
76
|
+
// Always send message to wallet
|
|
77
|
+
webhookList.push({
|
|
78
|
+
type: WalletSender.type,
|
|
79
|
+
});
|
|
80
|
+
|
|
75
81
|
if (webhookList.length) {
|
|
76
82
|
for (let i = 0; i < webhookList.length; i++) {
|
|
77
83
|
const item = webhookList[i];
|
|
@@ -79,8 +85,7 @@ module.exports = ({ events, dataDirs, instance }) => {
|
|
|
79
85
|
const senderInstance = WebHookSender.getMessageSender(item.type);
|
|
80
86
|
senderFns[item.type] = senderInstance.send.bind(senderInstance);
|
|
81
87
|
}
|
|
82
|
-
const {
|
|
83
|
-
const options = { ...message, nodeInfo: `*${name}*` };
|
|
88
|
+
const options = { ...message, nodeInfo, node: instance };
|
|
84
89
|
if (item.type === 'slack') {
|
|
85
90
|
// eslint-disable-next-line
|
|
86
91
|
options.urlInfo = await getSlackUrlInfo(message.action, baseUrls);
|
|
@@ -3,6 +3,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:sender');
|
|
|
3
3
|
|
|
4
4
|
const Slack = require('./slack');
|
|
5
5
|
const Api = require('./api');
|
|
6
|
+
const Wallet = require('./wallet');
|
|
6
7
|
|
|
7
8
|
const SenderMap = new Map([
|
|
8
9
|
[Slack.type, Slack],
|
|
@@ -12,6 +13,10 @@ const SenderMap = new Map([
|
|
|
12
13
|
const getSenderNames = () => [...SenderMap.keys()];
|
|
13
14
|
|
|
14
15
|
const getSender = (name) => {
|
|
16
|
+
if (name === Wallet.type) {
|
|
17
|
+
return Wallet;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
if (!SenderMap.has(name)) {
|
|
16
21
|
logger.error(`getSender:sender name [${name}] does not exist`);
|
|
17
22
|
return null;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const logger = require('@abtnode/logger')('@abtnode/core:sender:api');
|
|
2
|
+
const { sendToUser } = require('@blocklet/sdk/lib/util/send-notification');
|
|
3
|
+
const { ROLES, PASSPORT_STATUS } = require('@abtnode/constant');
|
|
4
|
+
const BaseSender = require('../base');
|
|
5
|
+
|
|
6
|
+
class WalletSender extends BaseSender {
|
|
7
|
+
async send(params, data = {}) {
|
|
8
|
+
const { title, description, nodeInfo, node } = data;
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const sender = {
|
|
12
|
+
appDid: nodeInfo.did,
|
|
13
|
+
appSk: nodeInfo.sk,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const message = {
|
|
17
|
+
title,
|
|
18
|
+
body: description,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const { users } = await node.getUsers({ teamDid: nodeInfo.did, paging: { pageSize: 100 } });
|
|
22
|
+
const adminUsers = users
|
|
23
|
+
.filter(
|
|
24
|
+
(x) =>
|
|
25
|
+
x.approved &&
|
|
26
|
+
(x.passports || []).some(
|
|
27
|
+
(y) => [ROLES.OWNER, ROLES.ADMIN].includes(y.name) && y.status === PASSPORT_STATUS.VALID
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
.map((x) => x.did);
|
|
31
|
+
|
|
32
|
+
if (!adminUsers.length) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
await sendToUser(adminUsers, message, sender, process.env.ABT_NODE_SERVICE_PORT);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error('failed to push notification to wallet', { error });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
WalletSender.type = 'wallet';
|
|
44
|
+
|
|
45
|
+
module.exports = WalletSender;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.8.
|
|
6
|
+
"version": "1.8.5",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,31 +19,32 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.8.
|
|
23
|
-
"@abtnode/constant": "1.8.
|
|
24
|
-
"@abtnode/cron": "1.8.
|
|
25
|
-
"@abtnode/db": "1.8.
|
|
26
|
-
"@abtnode/logger": "1.8.
|
|
27
|
-
"@abtnode/queue": "1.8.
|
|
28
|
-
"@abtnode/rbac": "1.8.
|
|
29
|
-
"@abtnode/router-provider": "1.8.
|
|
30
|
-
"@abtnode/static-server": "1.8.
|
|
31
|
-
"@abtnode/timemachine": "1.8.
|
|
32
|
-
"@abtnode/util": "1.8.
|
|
33
|
-
"@arcblock/did": "1.17.
|
|
22
|
+
"@abtnode/certificate-manager": "1.8.5",
|
|
23
|
+
"@abtnode/constant": "1.8.5",
|
|
24
|
+
"@abtnode/cron": "1.8.5",
|
|
25
|
+
"@abtnode/db": "1.8.5",
|
|
26
|
+
"@abtnode/logger": "1.8.5",
|
|
27
|
+
"@abtnode/queue": "1.8.5",
|
|
28
|
+
"@abtnode/rbac": "1.8.5",
|
|
29
|
+
"@abtnode/router-provider": "1.8.5",
|
|
30
|
+
"@abtnode/static-server": "1.8.5",
|
|
31
|
+
"@abtnode/timemachine": "1.8.5",
|
|
32
|
+
"@abtnode/util": "1.8.5",
|
|
33
|
+
"@arcblock/did": "1.17.6",
|
|
34
34
|
"@arcblock/did-motif": "^1.1.10",
|
|
35
|
-
"@arcblock/did-util": "1.17.
|
|
36
|
-
"@arcblock/event-hub": "1.17.
|
|
37
|
-
"@arcblock/jwt": "^1.17.
|
|
35
|
+
"@arcblock/did-util": "1.17.6",
|
|
36
|
+
"@arcblock/event-hub": "1.17.6",
|
|
37
|
+
"@arcblock/jwt": "^1.17.6",
|
|
38
38
|
"@arcblock/pm2-events": "^0.0.5",
|
|
39
|
-
"@arcblock/vc": "1.17.
|
|
40
|
-
"@blocklet/meta": "1.8.
|
|
39
|
+
"@arcblock/vc": "1.17.6",
|
|
40
|
+
"@blocklet/meta": "1.8.5",
|
|
41
|
+
"@blocklet/sdk": "1.8.5",
|
|
41
42
|
"@fidm/x509": "^1.2.1",
|
|
42
|
-
"@nedb/core": "^1.3.
|
|
43
|
-
"@nedb/multi": "^1.3.
|
|
44
|
-
"@ocap/mcrypto": "1.17.
|
|
45
|
-
"@ocap/util": "1.17.
|
|
46
|
-
"@ocap/wallet": "1.17.
|
|
43
|
+
"@nedb/core": "^1.3.2",
|
|
44
|
+
"@nedb/multi": "^1.3.2",
|
|
45
|
+
"@ocap/mcrypto": "1.17.6",
|
|
46
|
+
"@ocap/util": "1.17.6",
|
|
47
|
+
"@ocap/wallet": "1.17.6",
|
|
47
48
|
"@slack/webhook": "^5.0.3",
|
|
48
49
|
"axios": "^0.27.2",
|
|
49
50
|
"axon": "^2.0.3",
|
|
@@ -81,5 +82,5 @@
|
|
|
81
82
|
"express": "^4.17.1",
|
|
82
83
|
"jest": "^27.4.5"
|
|
83
84
|
},
|
|
84
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "58da88581cdf1dd45fd50e56db08a055be82626e"
|
|
85
86
|
}
|