@abtnode/core 1.8.0 → 1.8.1
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/api/node.js +14 -1
- package/lib/blocklet/manager/disk.js +47 -8
- package/lib/cert.js +10 -5
- package/lib/event.js +8 -0
- package/lib/index.js +1 -0
- package/lib/router/helper.js +2 -1
- package/lib/router/manager.js +0 -34
- package/lib/states/audit-log.js +6 -1
- package/lib/states/session.js +7 -1
- package/lib/util/blocklet.js +0 -5
- package/lib/util/index.js +4 -1
- package/package.json +16 -16
package/lib/api/node.js
CHANGED
|
@@ -7,6 +7,7 @@ const isGitpod = require('@abtnode/util/lib/is-gitpod');
|
|
|
7
7
|
const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
8
8
|
const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
|
|
9
9
|
const { toDelegateAddress } = require('@arcblock/did-util');
|
|
10
|
+
const { STORE_DETAIL_PAGE_PATH_PREFIX } = require('@abtnode/constant');
|
|
10
11
|
|
|
11
12
|
const logger = require('@abtnode/logger')('@abtnode/core:api:node');
|
|
12
13
|
|
|
@@ -40,7 +41,19 @@ class NodeAPI {
|
|
|
40
41
|
// eslint-disable-next-line no-unused-vars
|
|
41
42
|
async addRegistry({ url }, context) {
|
|
42
43
|
logger.info('add registry', { url });
|
|
43
|
-
|
|
44
|
+
|
|
45
|
+
const urlObj = new URL(url);
|
|
46
|
+
let newUrl = urlObj.origin;
|
|
47
|
+
|
|
48
|
+
// if the pathname is store blocklet list or blocklet detail
|
|
49
|
+
if (urlObj.pathname?.includes(STORE_DETAIL_PAGE_PATH_PREFIX)) {
|
|
50
|
+
const lastIndex = urlObj.pathname.lastIndexOf(STORE_DETAIL_PAGE_PATH_PREFIX);
|
|
51
|
+
const pathnamePrefix = urlObj.pathname.substring(0, lastIndex);
|
|
52
|
+
newUrl = `${newUrl}${pathnamePrefix || ''}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const sanitized = sanitizeUrl(newUrl);
|
|
56
|
+
|
|
44
57
|
const info = await this.state.read();
|
|
45
58
|
const exist = info.blockletRegistryList.find((x) => x.url === sanitized);
|
|
46
59
|
if (exist) {
|
|
@@ -22,6 +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 handleInstanceInStore = require('@abtnode/util/lib/public-to-store');
|
|
25
26
|
const { VC_TYPE_BLOCKLET_PURCHASE } = require('@abtnode/constant');
|
|
26
27
|
|
|
27
28
|
const getBlockletEngine = require('@blocklet/meta/lib/engine');
|
|
@@ -216,6 +217,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
216
217
|
* @param {{
|
|
217
218
|
* url: string;
|
|
218
219
|
* sync: boolean = false;
|
|
220
|
+
* downloadToken: string;
|
|
219
221
|
* }} params
|
|
220
222
|
* @param {{
|
|
221
223
|
* [key: string]: any
|
|
@@ -223,9 +225,22 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
223
225
|
* @return {*}
|
|
224
226
|
* @memberof BlockletManager
|
|
225
227
|
*/
|
|
226
|
-
async install(params, context) {
|
|
228
|
+
async install(params, context = {}) {
|
|
227
229
|
logger.debug('install blocklet', { params, context });
|
|
228
230
|
|
|
231
|
+
if (params.downloadToken) {
|
|
232
|
+
const info = await states.node.read();
|
|
233
|
+
|
|
234
|
+
context.headers = Object.assign(context?.headers || {}, {
|
|
235
|
+
'x-server-did': info.did,
|
|
236
|
+
'x-download-token': params.downloadToken,
|
|
237
|
+
'x-server-publick-key': info.pk,
|
|
238
|
+
'x-server-signature': sign(info.did, info.sk, {
|
|
239
|
+
exp: (Date.now() + 5 * 60 * 1000) / 1000,
|
|
240
|
+
}),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
229
244
|
const source = getSourceFromInstallParams(params);
|
|
230
245
|
if (typeof context.startImmediately === 'undefined') {
|
|
231
246
|
context.startImmediately = !!params.startImmediately;
|
|
@@ -319,10 +334,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
319
334
|
}
|
|
320
335
|
}
|
|
321
336
|
|
|
337
|
+
const { inStore, registryUrl } = await parseSourceUrl(url);
|
|
338
|
+
|
|
322
339
|
const blocklet = await states.blocklet.getBlocklet(meta.did);
|
|
323
340
|
const isRunning = blocklet ? blocklet.status === BlockletStatus.running : false;
|
|
324
341
|
|
|
325
|
-
return { meta, isFree, isInstalled: !!blocklet, isRunning };
|
|
342
|
+
return { meta, isFree, isInstalled: !!blocklet, isRunning, inStore, registryUrl };
|
|
326
343
|
}
|
|
327
344
|
|
|
328
345
|
async installBlockletFromVc({ vcPresentation, challenge }, context) {
|
|
@@ -423,7 +440,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
423
440
|
|
|
424
441
|
await this.deleteProcess({ did });
|
|
425
442
|
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
426
|
-
this.emit(BlockletEvents.startFailed, res);
|
|
443
|
+
this.emit(BlockletEvents.startFailed, { ...res, error: { message: error.message } });
|
|
427
444
|
|
|
428
445
|
if (throwOnError) {
|
|
429
446
|
throw new Error(description);
|
|
@@ -601,7 +618,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
601
618
|
async deleteComponent({ did, rootDid, keepData, keepState }, context) {
|
|
602
619
|
logger.info('delete blocklet component', { did, rootDid, keepData });
|
|
603
620
|
|
|
604
|
-
const blocklet = await this.ensureBlocklet(rootDid);
|
|
621
|
+
const blocklet = await this.ensureBlocklet(rootDid, { validateEnv: false });
|
|
605
622
|
const child = blocklet.children.find((x) => x.meta.did === did);
|
|
606
623
|
if (!child) {
|
|
607
624
|
throw new Error('Component does not exist');
|
|
@@ -851,6 +868,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
851
868
|
return newState;
|
|
852
869
|
}
|
|
853
870
|
|
|
871
|
+
async configPublicToStore({ did, publicToStore = false }) {
|
|
872
|
+
const blocklet = await this.ensureBlocklet(did);
|
|
873
|
+
|
|
874
|
+
await handleInstanceInStore(blocklet, { publicToStore });
|
|
875
|
+
await states.blockletExtras.setSettings(did, { publicToStore });
|
|
876
|
+
|
|
877
|
+
const newState = await this.ensureBlocklet(did);
|
|
878
|
+
return newState;
|
|
879
|
+
}
|
|
880
|
+
|
|
854
881
|
/**
|
|
855
882
|
* upgrade blocklet from registry
|
|
856
883
|
*/
|
|
@@ -1495,7 +1522,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1495
1522
|
|
|
1496
1523
|
preDownloadLock.release();
|
|
1497
1524
|
|
|
1498
|
-
this.emit(BlockletEvents.downloadFailed, {
|
|
1525
|
+
this.emit(BlockletEvents.downloadFailed, {
|
|
1526
|
+
meta: { did },
|
|
1527
|
+
error: {
|
|
1528
|
+
message: err.message,
|
|
1529
|
+
},
|
|
1530
|
+
});
|
|
1499
1531
|
states.notification.create({
|
|
1500
1532
|
title: 'Blocklet Download Failed',
|
|
1501
1533
|
description: `Blocklet ${name}@${version} download failed with error: ${err.message}`,
|
|
@@ -1786,10 +1818,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1786
1818
|
throw new Error('Root blocklet does not exist');
|
|
1787
1819
|
}
|
|
1788
1820
|
|
|
1821
|
+
const { inStore } = await parseSourceUrl(url);
|
|
1822
|
+
|
|
1789
1823
|
const meta = await getBlockletMetaFromUrl(url);
|
|
1790
1824
|
|
|
1791
|
-
// 如果是一个付费的blocklet
|
|
1792
|
-
if (!isFreeBlocklet(meta)) {
|
|
1825
|
+
// 如果是一个付费的blocklet,并且url来源为Store, 需要携带token才能下载成功
|
|
1826
|
+
if (!isFreeBlocklet(meta) && inStore) {
|
|
1793
1827
|
const info = await states.node.read();
|
|
1794
1828
|
|
|
1795
1829
|
// eslint-disable-next-line no-param-reassign
|
|
@@ -2625,7 +2659,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2625
2659
|
logger.error('failed to install blocklet', { name, did, version, error: err });
|
|
2626
2660
|
try {
|
|
2627
2661
|
await this._rollback('install', did, oldBlocklet);
|
|
2628
|
-
this.emit(BlockletEvents.installFailed, {
|
|
2662
|
+
this.emit(BlockletEvents.installFailed, {
|
|
2663
|
+
meta: { did },
|
|
2664
|
+
error: {
|
|
2665
|
+
message: err.message,
|
|
2666
|
+
},
|
|
2667
|
+
});
|
|
2629
2668
|
states.notification.create({
|
|
2630
2669
|
title: 'Blocklet Install Failed',
|
|
2631
2670
|
description: `Blocklet ${meta.name}@${meta.version} install failed with error: ${err.message}`,
|
package/lib/cert.js
CHANGED
|
@@ -103,14 +103,16 @@ class Cert extends EventEmitter {
|
|
|
103
103
|
|
|
104
104
|
async add(data) {
|
|
105
105
|
if (!data.certificate || !data.privateKey) {
|
|
106
|
-
throw new Error('certificate and privateKey
|
|
106
|
+
throw new Error('certificate and privateKey are required');
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
Cert.fixCertificate(data);
|
|
110
110
|
|
|
111
|
-
await this.manager.add(data);
|
|
112
|
-
logger.info('add certificate result', { name:
|
|
113
|
-
this.emit('cert.added',
|
|
111
|
+
const result = await this.manager.add(data);
|
|
112
|
+
logger.info('add certificate result', { name: result.name });
|
|
113
|
+
this.emit('cert.added', result);
|
|
114
|
+
|
|
115
|
+
return result;
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
async issue({ domain }) {
|
|
@@ -120,7 +122,10 @@ class Cert extends EventEmitter {
|
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
async upsertByDomain(data) {
|
|
123
|
-
|
|
125
|
+
const result = await this.manager.upsertByDomain(data);
|
|
126
|
+
this.emit('cert.updated', result);
|
|
127
|
+
|
|
128
|
+
return result;
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
async update(data) {
|
package/lib/event.js
CHANGED
|
@@ -5,6 +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('@abtnode/util/lib/public-to-store');
|
|
8
9
|
|
|
9
10
|
const eventHub =
|
|
10
11
|
process.env.NODE_ENV === 'test' ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
|
|
@@ -160,6 +161,13 @@ module.exports = ({
|
|
|
160
161
|
await handleBlockletUpgrade(eventName, payload);
|
|
161
162
|
} else if ([BlockletEvents.removed].includes(eventName)) {
|
|
162
163
|
await handleBlockletRemove(eventName, payload);
|
|
164
|
+
} else if ([BlockletEvents.started].includes(eventName)) {
|
|
165
|
+
try {
|
|
166
|
+
const blocklet = await blockletManager.ensureBlocklet(payload.meta.did);
|
|
167
|
+
await handleInstanceInStore(blocklet);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
logger.error('handleInstanceInStore failed', { error });
|
|
170
|
+
}
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
if (payload.blocklet && !payload.meta) {
|
package/lib/index.js
CHANGED
|
@@ -226,6 +226,7 @@ function ABTNode(options) {
|
|
|
226
226
|
getLatestBlockletVersion: blockletManager.getLatestBlockletVersion.bind(blockletManager),
|
|
227
227
|
getBlockletMetaFromUrl: blockletManager.getMetaFromUrl.bind(blockletManager),
|
|
228
228
|
resetBlocklet: blockletManager.reset.bind(blockletManager),
|
|
229
|
+
configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
|
|
229
230
|
|
|
230
231
|
deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
|
|
231
232
|
|
package/lib/router/helper.js
CHANGED
|
@@ -434,7 +434,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
434
434
|
isProtected: true,
|
|
435
435
|
});
|
|
436
436
|
|
|
437
|
-
logger.info('dashboard certificate updated');
|
|
437
|
+
logger.info('dashboard certificate updated', { domain });
|
|
438
438
|
} catch (error) {
|
|
439
439
|
logger.error('update dashboard certificate failed', { error });
|
|
440
440
|
throw error;
|
|
@@ -1103,6 +1103,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1103
1103
|
certManager.on('cert.added', () => providers[providerName].reload());
|
|
1104
1104
|
certManager.on('cert.removed', () => providers[providerName].reload());
|
|
1105
1105
|
certManager.on('cert.issued', () => providers[providerName].reload());
|
|
1106
|
+
certManager.on('cert.updated', () => providers[providerName].reload());
|
|
1106
1107
|
|
|
1107
1108
|
await providers[providerName].start();
|
|
1108
1109
|
}
|
package/lib/router/manager.js
CHANGED
|
@@ -8,7 +8,6 @@ const path = require('path');
|
|
|
8
8
|
const os = require('os');
|
|
9
9
|
const fse = require('fs-extra');
|
|
10
10
|
const get = require('lodash/get');
|
|
11
|
-
const { Certificate, PrivateKey } = require('@fidm/x509');
|
|
12
11
|
const { EventEmitter } = require('events');
|
|
13
12
|
const uuid = require('uuid');
|
|
14
13
|
const isUrl = require('is-url');
|
|
@@ -564,39 +563,6 @@ class RouterManager extends EventEmitter {
|
|
|
564
563
|
}
|
|
565
564
|
}
|
|
566
565
|
|
|
567
|
-
validateCertificate(cert, domain) {
|
|
568
|
-
const certificate = Certificate.fromPEM(cert.certificate);
|
|
569
|
-
const privateKey = PrivateKey.fromPEM(cert.privateKey);
|
|
570
|
-
|
|
571
|
-
const data = Buffer.allocUnsafe(100);
|
|
572
|
-
const signature = privateKey.sign(data, 'sha512');
|
|
573
|
-
if (!certificate.publicKey.verify(data, signature, 'sha512')) {
|
|
574
|
-
throw new Error('Invalid certificate: signature verify failed');
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const certDomain = get(certificate, 'subject.commonName', '');
|
|
578
|
-
if (domain && domain !== certDomain) {
|
|
579
|
-
throw new Error('Invalid certificate: domain does not match');
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
const validFrom = get(certificate, 'validFrom', '');
|
|
583
|
-
if (!validFrom || new Date(validFrom).getTime() > Date.now()) {
|
|
584
|
-
throw new Error('Invalid certificate: not in valid period');
|
|
585
|
-
}
|
|
586
|
-
const validTo = get(certificate, 'validTo', '');
|
|
587
|
-
if (!validTo || new Date(validTo).getTime() < Date.now()) {
|
|
588
|
-
throw new Error('Invalid certificate: not in valid period');
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return certificate;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
fixCertificate(entity) {
|
|
595
|
-
// Hack: this logic exists because gql does not allow line breaks in arg values
|
|
596
|
-
entity.privateKey = entity.privateKey.split('|').join('\n');
|
|
597
|
-
entity.certificate = entity.certificate.split('|').join('\n');
|
|
598
|
-
}
|
|
599
|
-
|
|
600
566
|
fixRootBlockletRule(rule) {
|
|
601
567
|
if (!rule.id) {
|
|
602
568
|
rule.id = uuid.v4();
|
package/lib/states/audit-log.js
CHANGED
|
@@ -114,7 +114,11 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
114
114
|
return `upgraded blocklet ${getBlockletInfo(result, info)} to v${result.meta.version}`;
|
|
115
115
|
case 'updateChildBlocklets':
|
|
116
116
|
return `upgraded components for blocklet ${getBlockletInfo(result, info)}`;
|
|
117
|
-
|
|
117
|
+
case 'configPublicToStore':
|
|
118
|
+
if (args.publicToStore) {
|
|
119
|
+
return `set publicToStore to true for blocklet ${getBlockletInfo(result, info)}`;
|
|
120
|
+
}
|
|
121
|
+
return `set publicToStore to false for blocklet ${getBlockletInfo(result, info)}`;
|
|
118
122
|
// store
|
|
119
123
|
case 'addBlockletStore':
|
|
120
124
|
return `added blocklet store ${args.url}`;
|
|
@@ -237,6 +241,7 @@ const getLogCategory = (action) => {
|
|
|
237
241
|
case 'configBlocklet':
|
|
238
242
|
case 'upgradeBlocklet':
|
|
239
243
|
case 'updateChildBlocklets':
|
|
244
|
+
case 'configPublicToStore':
|
|
240
245
|
return 'blocklet';
|
|
241
246
|
|
|
242
247
|
// store
|
package/lib/states/session.js
CHANGED
|
@@ -10,7 +10,13 @@ class SessionState extends BaseState {
|
|
|
10
10
|
|
|
11
11
|
this.db.ensureIndex({ fieldName: 'createdAt' }, (error) => {
|
|
12
12
|
if (error) {
|
|
13
|
-
logger.error('ensure index failed', { error });
|
|
13
|
+
logger.error('ensure createdAt index failed', { error });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
this.db.ensureIndex({ fieldName: 'expireDate', expireAfterSeconds: 0 }, (error) => {
|
|
18
|
+
if (error) {
|
|
19
|
+
logger.error('ensure expireDate index failed', { error });
|
|
14
20
|
}
|
|
15
21
|
});
|
|
16
22
|
}
|
package/lib/util/blocklet.js
CHANGED
|
@@ -934,11 +934,6 @@ const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings })
|
|
|
934
934
|
|
|
935
935
|
const fillAppDirs = async (dir, level = 'root') => {
|
|
936
936
|
if (level === 'version') {
|
|
937
|
-
if (!fs.existsSync(path.join(dir, 'blocklet.yml'))) {
|
|
938
|
-
logger.error('blocklet.yml does not exist in blocklet bundle dir', { dir });
|
|
939
|
-
return;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
937
|
appDirs.push({
|
|
943
938
|
key: path.relative(installDir, dir),
|
|
944
939
|
dir,
|
package/lib/util/index.js
CHANGED
|
@@ -398,7 +398,10 @@ const validateUrl = async (url, expectedHttpResTypes = ['application/json', 'tex
|
|
|
398
398
|
throw new Error(`Cannot get content-type from ${url}: ${err.message}`);
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
-
if (
|
|
401
|
+
if (
|
|
402
|
+
res.headers['content-type'] &&
|
|
403
|
+
expectedHttpResTypes.some((x) => res.headers['content-type'].includes(x)) === false
|
|
404
|
+
) {
|
|
402
405
|
throw new Error(`Unexpected content-type from ${url}: ${res.headers['content-type']}`);
|
|
403
406
|
}
|
|
404
407
|
|
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.1",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,17 +19,17 @@
|
|
|
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.
|
|
22
|
+
"@abtnode/certificate-manager": "1.8.1",
|
|
23
|
+
"@abtnode/constant": "1.8.1",
|
|
24
|
+
"@abtnode/cron": "1.8.1",
|
|
25
|
+
"@abtnode/db": "1.8.1",
|
|
26
|
+
"@abtnode/logger": "1.8.1",
|
|
27
|
+
"@abtnode/queue": "1.8.1",
|
|
28
|
+
"@abtnode/rbac": "1.8.1",
|
|
29
|
+
"@abtnode/router-provider": "1.8.1",
|
|
30
|
+
"@abtnode/static-server": "1.8.1",
|
|
31
|
+
"@abtnode/timemachine": "1.8.1",
|
|
32
|
+
"@abtnode/util": "1.8.1",
|
|
33
33
|
"@arcblock/did": "1.17.0",
|
|
34
34
|
"@arcblock/did-motif": "^1.1.10",
|
|
35
35
|
"@arcblock/did-util": "1.17.0",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@arcblock/jwt": "^1.17.0",
|
|
38
38
|
"@arcblock/pm2-events": "^0.0.5",
|
|
39
39
|
"@arcblock/vc": "1.17.0",
|
|
40
|
-
"@blocklet/meta": "1.8.
|
|
40
|
+
"@blocklet/meta": "1.8.1",
|
|
41
41
|
"@fidm/x509": "^1.2.1",
|
|
42
|
-
"@nedb/core": "^1.
|
|
43
|
-
"@nedb/multi": "^1.
|
|
42
|
+
"@nedb/core": "^1.3.1",
|
|
43
|
+
"@nedb/multi": "^1.3.1",
|
|
44
44
|
"@ocap/mcrypto": "1.17.0",
|
|
45
45
|
"@ocap/util": "1.17.0",
|
|
46
46
|
"@ocap/wallet": "1.17.0",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"express": "^4.17.1",
|
|
82
82
|
"jest": "^27.4.5"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "c970b8a386bebd7fe6dbc8b8eedf8bd8328b4bb5"
|
|
85
85
|
}
|