@abtnode/core 1.8.66 → 1.8.67-beta-794a8082
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 +79 -48
- package/lib/blocklet/manager/helper/install-from-backup.js +4 -4
- package/lib/blocklet/storage/backup/spaces.js +3 -3
- package/lib/blocklet/storage/restore/blocklets.js +5 -2
- package/lib/blocklet/storage/restore/spaces.js +5 -5
- package/lib/event.js +2 -2
- package/lib/index.js +0 -1
- package/lib/router/helper.js +7 -5
- package/lib/router/index.js +31 -0
- package/lib/router/manager.js +1 -1
- package/lib/states/audit-log.js +5 -3
- package/lib/states/node.js +5 -2
- package/lib/util/blocklet.js +46 -10
- package/lib/util/index.js +24 -0
- package/lib/validators/node.js +1 -0
- package/package.json +26 -27
|
@@ -15,20 +15,18 @@ const { isNFTExpired, getNftExpirationDate } = require('@abtnode/util/lib/nft');
|
|
|
15
15
|
const didDocument = require('@abtnode/util/lib/did-document');
|
|
16
16
|
const { sign } = require('@arcblock/jwt');
|
|
17
17
|
const { isValid: isValidDid } = require('@arcblock/did');
|
|
18
|
-
const { verifyPresentation } = require('@arcblock/vc');
|
|
19
18
|
const { toSvg: createDidLogo } =
|
|
20
19
|
process.env.NODE_ENV !== 'test' ? require('@arcblock/did-motif') : require('@arcblock/did-motif/dist/did-motif.cjs');
|
|
21
20
|
const getBlockletInfo = require('@blocklet/meta/lib/info');
|
|
22
21
|
const sleep = require('@abtnode/util/lib/sleep');
|
|
23
22
|
|
|
24
23
|
const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
|
|
25
|
-
const { getVcFromPresentation } = require('@abtnode/util/lib/vc');
|
|
26
24
|
const {
|
|
27
|
-
VC_TYPE_BLOCKLET_PURCHASE,
|
|
28
25
|
WHO_CAN_ACCESS,
|
|
29
26
|
SERVER_ROLES,
|
|
30
27
|
WHO_CAN_ACCESS_PREFIX_ROLES,
|
|
31
28
|
BLOCKLET_INSTALL_TYPE,
|
|
29
|
+
NODE_MODES,
|
|
32
30
|
} = require('@abtnode/constant');
|
|
33
31
|
|
|
34
32
|
const getBlockletEngine = require('@blocklet/meta/lib/engine');
|
|
@@ -49,7 +47,7 @@ const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-
|
|
|
49
47
|
const toBlockletDid = require('@blocklet/meta/lib/did');
|
|
50
48
|
const { validateMeta } = require('@blocklet/meta/lib/validate');
|
|
51
49
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
52
|
-
const { titleSchema,
|
|
50
|
+
const { titleSchema, updateMountPointSchema, environmentNameSchema } = require('@blocklet/meta/lib/schema');
|
|
53
51
|
const hasReservedKey = require('@blocklet/meta/lib/has-reserved-key');
|
|
54
52
|
const Lock = require('@abtnode/util/lib/lock');
|
|
55
53
|
|
|
@@ -111,6 +109,8 @@ const {
|
|
|
111
109
|
validateAppConfig,
|
|
112
110
|
checkDuplicateAppSk,
|
|
113
111
|
checkDuplicateMountPoint,
|
|
112
|
+
validateStore,
|
|
113
|
+
validateInServerless,
|
|
114
114
|
} = require('../../util/blocklet');
|
|
115
115
|
const StoreUtil = require('../../util/store');
|
|
116
116
|
const states = require('../../states');
|
|
@@ -242,6 +242,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
242
242
|
* did: string;
|
|
243
243
|
* title: string;
|
|
244
244
|
* description: string;
|
|
245
|
+
* storeUrl: string;
|
|
246
|
+
* appSk: string;
|
|
245
247
|
* sync: boolean = false; // download synchronously, not use queue
|
|
246
248
|
* delay: number; // push download task to queue after a delay
|
|
247
249
|
* downloadTokenList: Array<{did: string, token: string}>;
|
|
@@ -278,28 +280,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
278
280
|
context.startImmediately = !!params.startImmediately;
|
|
279
281
|
}
|
|
280
282
|
|
|
283
|
+
const { appSk } = params;
|
|
284
|
+
|
|
281
285
|
if (type === BLOCKLET_INSTALL_TYPE.URL) {
|
|
282
286
|
const { url, controller, sync, delay } = params;
|
|
283
|
-
return this._installFromUrl({ url, controller, sync, delay }, context);
|
|
287
|
+
return this._installFromUrl({ url, controller, sync, delay, appSk }, context);
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
if (type === BLOCKLET_INSTALL_TYPE.UPLOAD) {
|
|
287
291
|
const { file, did, diffVersion, deleteSet } = params;
|
|
288
|
-
return this._installFromUpload({ file, did, diffVersion, deleteSet,
|
|
292
|
+
return this._installFromUpload({ file, did, diffVersion, deleteSet, appSk }, context);
|
|
289
293
|
}
|
|
290
294
|
|
|
291
295
|
if (type === BLOCKLET_INSTALL_TYPE.STORE) {
|
|
292
296
|
const { did, controller, sync, delay, storeUrl } = params;
|
|
293
|
-
return this._installFromStore({ did, controller, sync, delay, storeUrl }, context);
|
|
297
|
+
return this._installFromStore({ did, controller, sync, delay, storeUrl, appSk }, context);
|
|
294
298
|
}
|
|
295
299
|
|
|
296
300
|
if (type === BLOCKLET_INSTALL_TYPE.CREATE) {
|
|
297
|
-
|
|
301
|
+
const { title, description } = params;
|
|
302
|
+
return this._installFromCreate({ title, description, appSk }, context);
|
|
298
303
|
}
|
|
299
304
|
|
|
300
305
|
if (type === BLOCKLET_INSTALL_TYPE.RESTORE) {
|
|
301
|
-
const { url
|
|
302
|
-
return this._installFromBackup({ url,
|
|
306
|
+
const { url } = params;
|
|
307
|
+
return this._installFromBackup({ url, appSk }, context);
|
|
303
308
|
}
|
|
304
309
|
|
|
305
310
|
// should not be here
|
|
@@ -343,10 +348,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
343
348
|
},
|
|
344
349
|
context = {}
|
|
345
350
|
) {
|
|
346
|
-
const mountPoint = await
|
|
351
|
+
const mountPoint = await updateMountPointSchema.validateAsync(tmpMountPoint);
|
|
347
352
|
logger.debug('start install component', { rootDid, mountPoint, url });
|
|
348
353
|
|
|
349
354
|
if (file) {
|
|
355
|
+
// TODO: 如何触发这种场景?
|
|
356
|
+
const info = await states.node.read();
|
|
357
|
+
if (info.mode === NODE_MODES.SERVERLESS) {
|
|
358
|
+
throw new Error("Can't install component in serverless-mode server via upload");
|
|
359
|
+
}
|
|
360
|
+
|
|
350
361
|
return this._installComponentFromUpload({
|
|
351
362
|
rootDid,
|
|
352
363
|
mountPoint,
|
|
@@ -360,6 +371,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
360
371
|
}
|
|
361
372
|
|
|
362
373
|
if (url) {
|
|
374
|
+
const info = await states.node.read();
|
|
375
|
+
if (info.mode === NODE_MODES.SERVERLESS) {
|
|
376
|
+
validateStore(info, url);
|
|
377
|
+
}
|
|
378
|
+
|
|
363
379
|
return this._installComponentFromUrl({
|
|
364
380
|
rootDid,
|
|
365
381
|
mountPoint,
|
|
@@ -431,25 +447,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
431
447
|
return { isInstalled: !!blocklet, isRunning, blockletDid, isExternal };
|
|
432
448
|
}
|
|
433
449
|
|
|
434
|
-
async installBlockletFromVc({ vcPresentation, challenge }, context) {
|
|
435
|
-
logger.info('Install from vc');
|
|
436
|
-
const vc = getVcFromPresentation(vcPresentation);
|
|
437
|
-
|
|
438
|
-
// FIXME: 这里的 trustedIssuers 相当于相信任何 VC,需要想更安全的方法
|
|
439
|
-
verifyPresentation({ presentation: vcPresentation, trustedIssuers: [get(vc, 'issuer.id')], challenge });
|
|
440
|
-
|
|
441
|
-
if (!vc.type.includes(VC_TYPE_BLOCKLET_PURCHASE)) {
|
|
442
|
-
throw new Error(`Expect ${VC_TYPE_BLOCKLET_PURCHASE} VC type`);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const blockletUrl = get(vc, 'credentialSubject.purchased.blocklet.url');
|
|
446
|
-
const urlObject = new URL(blockletUrl);
|
|
447
|
-
const did = get(vc, 'credentialSubject.purchased.blocklet.id');
|
|
448
|
-
const registry = urlObject.origin;
|
|
449
|
-
|
|
450
|
-
return this._installFromStore({ did, registry }, context);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
450
|
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
454
451
|
logger.info('start blocklet', { did });
|
|
455
452
|
// should check blocklet integrity
|
|
@@ -631,7 +628,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
631
628
|
// FIXME: 需要改成队列执行,本次失败,下次还需要重试,页面刷新后也能知道最新的状态
|
|
632
629
|
await this._installFromBackup({
|
|
633
630
|
url: `file://${spacesRestore.blockletRestoreDir}`,
|
|
634
|
-
|
|
631
|
+
appSk: spacesRestore.blockletWallet.secretKey,
|
|
635
632
|
moveDir: true,
|
|
636
633
|
});
|
|
637
634
|
}
|
|
@@ -1004,7 +1001,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1004
1001
|
}
|
|
1005
1002
|
|
|
1006
1003
|
// eslint-disable-next-line no-unused-vars
|
|
1007
|
-
async config({ did, configs: newConfigs, skipHook }, context) {
|
|
1004
|
+
async config({ did, configs: newConfigs, skipHook, skipDidDocument }, context) {
|
|
1008
1005
|
if (!Array.isArray(newConfigs)) {
|
|
1009
1006
|
throw new Error('configs list is not an array');
|
|
1010
1007
|
}
|
|
@@ -1064,7 +1061,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1064
1061
|
[BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK, BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_WALLET_TYPE].includes(item.key)
|
|
1065
1062
|
);
|
|
1066
1063
|
|
|
1067
|
-
if (isSkOrWalletTypeChanged) {
|
|
1064
|
+
if (isSkOrWalletTypeChanged && !skipDidDocument) {
|
|
1068
1065
|
await this._updateDidDocument(blocklet);
|
|
1069
1066
|
}
|
|
1070
1067
|
|
|
@@ -1198,7 +1195,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1198
1195
|
}
|
|
1199
1196
|
|
|
1200
1197
|
async updateComponentMountPoint({ did, rootDid: inputRootDid, mountPoint: tmpMountPoint }, context) {
|
|
1201
|
-
const mountPoint = await
|
|
1198
|
+
const mountPoint = await updateMountPointSchema.validateAsync(tmpMountPoint);
|
|
1202
1199
|
|
|
1203
1200
|
const blocklet = await states.blocklet.getBlocklet(inputRootDid);
|
|
1204
1201
|
|
|
@@ -1679,13 +1676,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1679
1676
|
* /blocklet.json
|
|
1680
1677
|
* /blocklet_extras.json
|
|
1681
1678
|
* @see Blocklet 端到端备份方案的设计与实现(一期) https://team.arcblock.io/comment/discussions/e62084d5-fafa-489e-91d5-defcd6e93223
|
|
1682
|
-
* @param {{ url: string,
|
|
1679
|
+
* @param {{ url: string, appSk: string, moveDir: boolean}} [{ url }={}]
|
|
1683
1680
|
* @param {Record<string, string>} [context={}]
|
|
1684
1681
|
* @return {Promise<any>}
|
|
1685
1682
|
* @memberof BlockletManager
|
|
1686
1683
|
*/
|
|
1687
|
-
async _installFromBackup({ url,
|
|
1688
|
-
return installFromBackup({ url,
|
|
1684
|
+
async _installFromBackup({ url, appSk, moveDir } = {}, context = {}) {
|
|
1685
|
+
return installFromBackup({ url, appSk, moveDir, context, manager: this, states });
|
|
1689
1686
|
}
|
|
1690
1687
|
|
|
1691
1688
|
async ensureBlocklet(did, opts = {}) {
|
|
@@ -2084,17 +2081,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2084
2081
|
*
|
|
2085
2082
|
* @param {{
|
|
2086
2083
|
* did: string;
|
|
2087
|
-
* registry: string;
|
|
2088
2084
|
* sync: boolean;
|
|
2089
2085
|
* delay: number;
|
|
2090
2086
|
* controller: Controller;
|
|
2087
|
+
* appSk: string;
|
|
2088
|
+
* storeUrl: string;
|
|
2091
2089
|
* }} params
|
|
2092
2090
|
* @param {*} context
|
|
2093
2091
|
* @return {*}
|
|
2094
2092
|
* @memberof BlockletManager
|
|
2095
2093
|
*/
|
|
2096
2094
|
async _installFromStore(params, context) {
|
|
2097
|
-
const { did, storeUrl, sync, delay, controller } = params;
|
|
2095
|
+
const { did, storeUrl, sync, delay, controller, appSk } = params;
|
|
2098
2096
|
|
|
2099
2097
|
logger.debug('start install blocklet', { did });
|
|
2100
2098
|
if (!isValidDid(did)) {
|
|
@@ -2138,6 +2136,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2138
2136
|
sync,
|
|
2139
2137
|
delay,
|
|
2140
2138
|
controller,
|
|
2139
|
+
appSk,
|
|
2141
2140
|
context,
|
|
2142
2141
|
});
|
|
2143
2142
|
}
|
|
@@ -2154,13 +2153,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2154
2153
|
* sync: boolean;
|
|
2155
2154
|
* delay: number;
|
|
2156
2155
|
* controller: Controller;
|
|
2156
|
+
* appSk: string;
|
|
2157
2157
|
* }} params
|
|
2158
2158
|
* @param {{}} context
|
|
2159
2159
|
* @return {*}
|
|
2160
2160
|
* @memberof BlockletManager
|
|
2161
2161
|
*/
|
|
2162
2162
|
async _installFromUrl(params, context) {
|
|
2163
|
-
const { url, sync, delay, controller } = params;
|
|
2163
|
+
const { url, sync, delay, controller, appSk } = params;
|
|
2164
2164
|
|
|
2165
2165
|
logger.debug('start install blocklet', { url });
|
|
2166
2166
|
|
|
@@ -2174,13 +2174,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2174
2174
|
|
|
2175
2175
|
// install from store if url is a store url
|
|
2176
2176
|
const { inStore, registryUrl, blockletDid: bundleDid } = await StoreUtil.parseSourceUrl(url, controller);
|
|
2177
|
+
|
|
2178
|
+
const nodeInfo = await states.node.read();
|
|
2179
|
+
|
|
2180
|
+
await validateStore(nodeInfo, registryUrl);
|
|
2181
|
+
|
|
2177
2182
|
if (inStore) {
|
|
2178
2183
|
const exist = await states.blocklet.getBlocklet(blockletDid);
|
|
2179
2184
|
if (exist) {
|
|
2180
2185
|
return this.upgrade({ did: blockletDid, storeUrl: registryUrl, sync, delay }, context);
|
|
2181
2186
|
}
|
|
2182
2187
|
|
|
2183
|
-
return this._installFromStore({ did: bundleDid, storeUrl: registryUrl, controller, sync, delay }, context);
|
|
2188
|
+
return this._installFromStore({ did: bundleDid, storeUrl: registryUrl, controller, sync, delay, appSk }, context);
|
|
2184
2189
|
}
|
|
2185
2190
|
|
|
2186
2191
|
const meta = ensureMeta(bundleMeta, { name: blockletName, did: blockletDid });
|
|
@@ -2206,6 +2211,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2206
2211
|
sync,
|
|
2207
2212
|
delay,
|
|
2208
2213
|
controller,
|
|
2214
|
+
appSk,
|
|
2209
2215
|
context,
|
|
2210
2216
|
});
|
|
2211
2217
|
}
|
|
@@ -2310,7 +2316,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2310
2316
|
);
|
|
2311
2317
|
}
|
|
2312
2318
|
|
|
2313
|
-
async _installFromCreate({ title, description }, context = {}) {
|
|
2319
|
+
async _installFromCreate({ title, description, appSk }, context = {}) {
|
|
2314
2320
|
logger.debug('create blocklet', { title, description });
|
|
2315
2321
|
|
|
2316
2322
|
await joi.string().label('title').max(20).required().validateAsync(title);
|
|
@@ -2338,11 +2344,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2338
2344
|
};
|
|
2339
2345
|
const meta = validateMeta(rawMeta);
|
|
2340
2346
|
|
|
2341
|
-
await states.blocklet.addBlocklet({
|
|
2342
|
-
meta,
|
|
2343
|
-
source: BlockletSource.custom,
|
|
2344
|
-
});
|
|
2347
|
+
await states.blocklet.addBlocklet({ meta, source: BlockletSource.custom });
|
|
2345
2348
|
await this._setConfigsFromMeta(did);
|
|
2349
|
+
await this._setAppSk(did, appSk);
|
|
2346
2350
|
|
|
2347
2351
|
// check duplicate appSk
|
|
2348
2352
|
await checkDuplicateAppSk({ did, states });
|
|
@@ -2382,7 +2386,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2382
2386
|
return { cwd, tarFile };
|
|
2383
2387
|
}
|
|
2384
2388
|
|
|
2385
|
-
async _installFromUpload({ file, did, diffVersion, deleteSet,
|
|
2389
|
+
async _installFromUpload({ file, did, diffVersion, deleteSet, appSk }, context) {
|
|
2386
2390
|
logger.info('install blocklet', { from: 'upload file' });
|
|
2387
2391
|
const { tarFile } = await this._downloadFromUpload(file);
|
|
2388
2392
|
|
|
@@ -2480,6 +2484,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2480
2484
|
const oldState = { extraState: oldExtraState };
|
|
2481
2485
|
try {
|
|
2482
2486
|
await this._setConfigsFromMeta(meta.did);
|
|
2487
|
+
await this._setAppSk(appSk);
|
|
2483
2488
|
await validateBlocklet(blocklet);
|
|
2484
2489
|
|
|
2485
2490
|
// check duplicate appSk
|
|
@@ -2776,6 +2781,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2776
2781
|
* meta: {}; // blocklet meta
|
|
2777
2782
|
* source: number; // example: BlockletSource.registry,
|
|
2778
2783
|
* deployedFrom: string;
|
|
2784
|
+
* appSk: string;
|
|
2779
2785
|
* context: {}
|
|
2780
2786
|
* sync: boolean = false;
|
|
2781
2787
|
* delay: number;
|
|
@@ -2785,10 +2791,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2785
2791
|
* @memberof BlockletManager
|
|
2786
2792
|
*/
|
|
2787
2793
|
async _install(params) {
|
|
2788
|
-
const { meta, source, deployedFrom, context, sync, delay, controller } = params;
|
|
2794
|
+
const { meta, source, deployedFrom, context, sync, delay, controller, appSk } = params;
|
|
2789
2795
|
|
|
2790
2796
|
validateBlockletMeta(meta, { ensureDist: true });
|
|
2791
2797
|
|
|
2798
|
+
const info = await states.node.read();
|
|
2799
|
+
if (info.mode === NODE_MODES.SERVERLESS) {
|
|
2800
|
+
validateInServerless({ blockletMeta: meta });
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2792
2803
|
const { name, did, version } = meta;
|
|
2793
2804
|
|
|
2794
2805
|
const oldExtraState = await states.blockletExtras.findOne({ did: meta.did });
|
|
@@ -2808,6 +2819,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2808
2819
|
await states.blockletExtras.addMeta({ did, meta: { did, name }, controller });
|
|
2809
2820
|
|
|
2810
2821
|
await this._setConfigsFromMeta(did);
|
|
2822
|
+
await this._setAppSk(did, appSk);
|
|
2811
2823
|
|
|
2812
2824
|
// check duplicate appSk
|
|
2813
2825
|
await checkDuplicateAppSk({ did, states });
|
|
@@ -3405,12 +3417,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
3405
3417
|
}
|
|
3406
3418
|
}
|
|
3407
3419
|
|
|
3420
|
+
async _setAppSk(did, appSk, context) {
|
|
3421
|
+
if (process.env.NODE_ENV === 'production' && !appSk) {
|
|
3422
|
+
throw new Error(`appSk for blocklet ${did} is required`);
|
|
3423
|
+
}
|
|
3424
|
+
|
|
3425
|
+
if (appSk) {
|
|
3426
|
+
await this.config(
|
|
3427
|
+
{
|
|
3428
|
+
did,
|
|
3429
|
+
configs: [{ key: 'BLOCKLET_APP_SK', value: appSk, secure: true }],
|
|
3430
|
+
skipHook: true,
|
|
3431
|
+
skipDidDocument: true,
|
|
3432
|
+
},
|
|
3433
|
+
context
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3408
3438
|
async _findNextCustomBlockletName(leftTimes = 10) {
|
|
3409
3439
|
if (leftTimes <= 0) {
|
|
3410
3440
|
throw new Error('Generate custom blocklet did too many times');
|
|
3411
3441
|
}
|
|
3412
3442
|
const number = await states.node.increaseCustomBlockletNumber();
|
|
3413
3443
|
const name = `custom-${number}`;
|
|
3444
|
+
// MEMO: 空壳 APP可以保留原有的 did 生成逻辑
|
|
3414
3445
|
const did = toBlockletDid(name);
|
|
3415
3446
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
3416
3447
|
if (blocklet) {
|
|
@@ -19,7 +19,7 @@ const { validateBlocklet, checkDuplicateAppSk, getAppDirs } = require('../../../
|
|
|
19
19
|
* }} param0
|
|
20
20
|
* @returns
|
|
21
21
|
*/
|
|
22
|
-
module.exports = async ({ url,
|
|
22
|
+
module.exports = async ({ url, appSk, moveDir, context = {}, states, manager } = {}) => {
|
|
23
23
|
// TODO: support more url schema feature (http, did-spaces)
|
|
24
24
|
if (!url.startsWith('file://')) {
|
|
25
25
|
throw new Error('url must starts with file://');
|
|
@@ -71,17 +71,17 @@ module.exports = async ({ url, blockletSecretKey, moveDir, context = {}, states,
|
|
|
71
71
|
throw new Error('blocklet is already exist');
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
if (
|
|
74
|
+
if (appSk) {
|
|
75
75
|
extra.configs = extra.configs || [];
|
|
76
76
|
const skConfig = extra.configs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK);
|
|
77
77
|
if (skConfig) {
|
|
78
|
-
skConfig.value =
|
|
78
|
+
skConfig.value = appSk;
|
|
79
79
|
skConfig.secure = true;
|
|
80
80
|
skConfig.shared = false;
|
|
81
81
|
} else {
|
|
82
82
|
extra.configs.push({
|
|
83
83
|
key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK,
|
|
84
|
-
value:
|
|
84
|
+
value: appSk,
|
|
85
85
|
secure: true,
|
|
86
86
|
shared: false,
|
|
87
87
|
});
|
|
@@ -150,10 +150,10 @@ class SpacesBackup {
|
|
|
150
150
|
const { errorCount } = await spaceClient.send(
|
|
151
151
|
new SyncFolderPushCommand({
|
|
152
152
|
source: join(this.blockletBackupDir, '/'),
|
|
153
|
-
target: join('.did-objects', this.blocklet.appDid),
|
|
153
|
+
target: join('.did-objects', this.blocklet.appDid, '/'),
|
|
154
154
|
debug: true,
|
|
155
|
-
concurrency:
|
|
156
|
-
retryCount:
|
|
155
|
+
concurrency: 32,
|
|
156
|
+
retryCount: 10,
|
|
157
157
|
filter: (object) => {
|
|
158
158
|
return object.name !== '.DS_Store';
|
|
159
159
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { existsSync, remove } = require('fs-extra');
|
|
1
|
+
const { existsSync, remove, ensureDirSync } = require('fs-extra');
|
|
2
2
|
const { join } = require('path');
|
|
3
3
|
const fg = require('fast-glob');
|
|
4
4
|
const { BaseRestore } = require('./base');
|
|
@@ -10,8 +10,11 @@ class BlockletsRestore extends BaseRestore {
|
|
|
10
10
|
async import() {
|
|
11
11
|
const blockletsDir = join(this.blockletRestoreDir, this.filename);
|
|
12
12
|
|
|
13
|
+
// blockletsDir 可以不存在, 因为还原的 blocklet 可能所有的组件都是来自 store 的
|
|
13
14
|
if (!existsSync(blockletsDir)) {
|
|
14
|
-
|
|
15
|
+
// FIXME: 如果文件夹不存在,需要创建文件夹,因为 installFromBackup 未做容错处理
|
|
16
|
+
ensureDirSync(blockletsDir);
|
|
17
|
+
return;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
const paths = await fg('**/*.zip', {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {{
|
|
3
3
|
* endpoint: string;
|
|
4
|
-
*
|
|
4
|
+
* appSk: string;
|
|
5
5
|
* }} SpaceRestoreInput
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -98,7 +98,7 @@ class SpacesRestore {
|
|
|
98
98
|
|
|
99
99
|
async getBlockletWallet() {
|
|
100
100
|
// @FIXME: blocklet 钱包类型如何得知呢?
|
|
101
|
-
const wallet = fromSecretKey(this.input.
|
|
101
|
+
const wallet = fromSecretKey(this.input.appSk, WalletType({ role: types.RoleType.ROLE_APPLICATION }));
|
|
102
102
|
|
|
103
103
|
return wallet;
|
|
104
104
|
}
|
|
@@ -115,10 +115,10 @@ class SpacesRestore {
|
|
|
115
115
|
const { errorCount } = await spaceClient.send(
|
|
116
116
|
new SyncFolderPullCommand({
|
|
117
117
|
source: join('.did-objects', this.blockletWallet.address, '/'),
|
|
118
|
-
target: this.blockletRestoreDir,
|
|
118
|
+
target: join(this.blockletRestoreDir, '/'),
|
|
119
119
|
debug: true,
|
|
120
|
-
concurrency:
|
|
121
|
-
retryCount:
|
|
120
|
+
concurrency: 32,
|
|
121
|
+
retryCount: 10,
|
|
122
122
|
})
|
|
123
123
|
);
|
|
124
124
|
|
package/lib/event.js
CHANGED
|
@@ -81,7 +81,7 @@ module.exports = ({
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
const
|
|
84
|
+
const handleBlockletInstall = async (name, { blocklet, context }) => {
|
|
85
85
|
try {
|
|
86
86
|
const changed = await ensureBlockletRouting(blocklet, context);
|
|
87
87
|
if (changed) {
|
|
@@ -173,7 +173,7 @@ module.exports = ({
|
|
|
173
173
|
const blocklet = payload.blocklet || payload;
|
|
174
174
|
|
|
175
175
|
if ([BlockletEvents.installed].includes(eventName)) {
|
|
176
|
-
await
|
|
176
|
+
await handleBlockletInstall(eventName, payload);
|
|
177
177
|
|
|
178
178
|
try {
|
|
179
179
|
await node.createAuditLog({
|
package/lib/index.js
CHANGED
|
@@ -192,7 +192,6 @@ function ABTNode(options) {
|
|
|
192
192
|
|
|
193
193
|
// Blocklet manager
|
|
194
194
|
installBlocklet: blockletManager.install.bind(blockletManager),
|
|
195
|
-
installBlockletFromVc: blockletManager.installBlockletFromVc.bind(blockletManager),
|
|
196
195
|
installComponent: blockletManager.installComponent.bind(blockletManager),
|
|
197
196
|
startBlocklet: blockletManager.start.bind(blockletManager),
|
|
198
197
|
stopBlocklet: blockletManager.stop.bind(blockletManager),
|
package/lib/router/helper.js
CHANGED
|
@@ -26,7 +26,6 @@ const {
|
|
|
26
26
|
NAME_FOR_WELLKNOWN_SITE,
|
|
27
27
|
DEFAULT_HTTP_PORT,
|
|
28
28
|
DEFAULT_HTTPS_PORT,
|
|
29
|
-
NODE_MODES,
|
|
30
29
|
ROUTING_RULE_TYPES,
|
|
31
30
|
CERTIFICATE_EXPIRES_OFFSET,
|
|
32
31
|
DEFAULT_SERVICE_PATH,
|
|
@@ -56,6 +55,7 @@ const {
|
|
|
56
55
|
findInterfacePortByName,
|
|
57
56
|
getWellknownSitePort,
|
|
58
57
|
getServerDidDomain,
|
|
58
|
+
isGatewayCacheEnabled,
|
|
59
59
|
} = require('../util');
|
|
60
60
|
const { getIpDnsDomainForBlocklet, getDidDomainForBlocklet } = require('../util/get-domain-for-blocklet');
|
|
61
61
|
const { getFromCache: getAccessibleExternalNodeIp } = require('../util/get-accessible-external-node-ip');
|
|
@@ -382,7 +382,7 @@ const ensureBlockletCache = async (sites = [], blocklets) => {
|
|
|
382
382
|
const clone = cloneDeep(rule);
|
|
383
383
|
clone.from.pathPrefix = joinUrl(rule.from.pathPrefix, cachePrefix);
|
|
384
384
|
clone.to.cacheGroup = 'blockletProxy';
|
|
385
|
-
clone.to.
|
|
385
|
+
clone.to.targetPrefix = cachePrefix;
|
|
386
386
|
clone.dynamic = true; // mark as dynamic to avoid redundant generated rules
|
|
387
387
|
cacheRules.push(clone);
|
|
388
388
|
});
|
|
@@ -518,7 +518,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
518
518
|
|
|
519
519
|
const ensureDomainCert = async (domain, url) => {
|
|
520
520
|
const cert = await certManager.getByDomain(domain);
|
|
521
|
-
if (!cert) {
|
|
521
|
+
if (!cert || get(cert, 'meta.validTo') <= Date.now()) {
|
|
522
522
|
await downloadCert({
|
|
523
523
|
domain,
|
|
524
524
|
url,
|
|
@@ -1115,7 +1115,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1115
1115
|
configDir: path.join(dataDirs.router, providerName),
|
|
1116
1116
|
httpPort: nodeInfo.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1117
1117
|
httpsPort: nodeInfo.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1118
|
-
|
|
1118
|
+
cacheEnabled: isGatewayCacheEnabled(nodeInfo),
|
|
1119
1119
|
}),
|
|
1120
1120
|
getRoutingParams: async () => {
|
|
1121
1121
|
try {
|
|
@@ -1220,7 +1220,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1220
1220
|
configDir: path.join(dataDirs.router, info.routing.provider),
|
|
1221
1221
|
httpPort: info.routing.httpPort || DEFAULT_HTTP_PORT,
|
|
1222
1222
|
httpsPort: info.routing.httpsPort || DEFAULT_HTTPS_PORT,
|
|
1223
|
-
|
|
1223
|
+
cacheEnabled: isGatewayCacheEnabled(info),
|
|
1224
1224
|
});
|
|
1225
1225
|
await providerInstance.stop();
|
|
1226
1226
|
logger.info('original router stopped:', { provider: info.routing.provider });
|
|
@@ -1408,6 +1408,8 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1408
1408
|
deleteRoutingRule,
|
|
1409
1409
|
addDomainAlias,
|
|
1410
1410
|
deleteDomainAlias,
|
|
1411
|
+
|
|
1412
|
+
isGatewayCacheEnabled,
|
|
1411
1413
|
};
|
|
1412
1414
|
};
|
|
1413
1415
|
|
package/lib/router/index.js
CHANGED
|
@@ -11,8 +11,11 @@ const {
|
|
|
11
11
|
GATEWAY_REQ_LIMIT,
|
|
12
12
|
} = require('@abtnode/constant');
|
|
13
13
|
const { BLOCKLET_UI_INTERFACES, BLOCKLET_MODES } = require('@blocklet/constant');
|
|
14
|
+
|
|
14
15
|
const logger = require('@abtnode/logger')('@abtnode/core:router');
|
|
15
16
|
|
|
17
|
+
const { isGatewayCacheEnabled } = require('../util');
|
|
18
|
+
|
|
16
19
|
const expandSites = (sites = []) => {
|
|
17
20
|
const result = [];
|
|
18
21
|
|
|
@@ -117,6 +120,7 @@ class Router {
|
|
|
117
120
|
services,
|
|
118
121
|
nodeInfo: pick(nodeInfo, ['name', 'version', 'port', 'mode', 'enableWelcomePage', 'routing']),
|
|
119
122
|
requestLimit,
|
|
123
|
+
cacheEnabled: isGatewayCacheEnabled(nodeInfo),
|
|
120
124
|
});
|
|
121
125
|
}
|
|
122
126
|
|
|
@@ -183,6 +187,10 @@ Router.formatSites = (sites = []) => {
|
|
|
183
187
|
result.forEach((site) => {
|
|
184
188
|
if (Array.isArray(site.rules) && site.rules.length > 0) {
|
|
185
189
|
const rules = cloneDeep(site.rules);
|
|
190
|
+
|
|
191
|
+
let hasRootPathBlockletRule = false;
|
|
192
|
+
let tmpBlockletRule;
|
|
193
|
+
|
|
186
194
|
rules.forEach((rule) => {
|
|
187
195
|
if ([ROUTING_RULE_TYPES.BLOCKLET].includes(rule.to.type) === false) {
|
|
188
196
|
return;
|
|
@@ -197,6 +205,11 @@ Router.formatSites = (sites = []) => {
|
|
|
197
205
|
}
|
|
198
206
|
|
|
199
207
|
if (daemonRule) {
|
|
208
|
+
if (rule.from.pathPrefix === '/') {
|
|
209
|
+
hasRootPathBlockletRule = true;
|
|
210
|
+
}
|
|
211
|
+
tmpBlockletRule = rule;
|
|
212
|
+
|
|
200
213
|
// Serve meta js: both prefix and suffix do not contain trailing slash
|
|
201
214
|
// NOTICE: 这里隐含了一个约定
|
|
202
215
|
// 如果安装的 blockletA 和 blockletB 都需要 __blocklet__.js
|
|
@@ -244,6 +257,24 @@ Router.formatSites = (sites = []) => {
|
|
|
244
257
|
});
|
|
245
258
|
}
|
|
246
259
|
});
|
|
260
|
+
|
|
261
|
+
// ensure /__blocklet__.js should be proxy to daemon
|
|
262
|
+
if (daemonRule && !hasRootPathBlockletRule && tmpBlockletRule) {
|
|
263
|
+
site.rules.push({
|
|
264
|
+
from: {
|
|
265
|
+
pathPrefix: '/',
|
|
266
|
+
groupPathPrefix: '/',
|
|
267
|
+
pathSuffix: '/__blocklet__.js',
|
|
268
|
+
},
|
|
269
|
+
to: {
|
|
270
|
+
type: ROUTING_RULE_TYPES.DAEMON,
|
|
271
|
+
port: daemonRule.to.port,
|
|
272
|
+
did: tmpBlockletRule.to.did,
|
|
273
|
+
componentId: tmpBlockletRule.to.did,
|
|
274
|
+
cacheGroup: site.mode === BLOCKLET_MODES.PRODUCTION ? 'blockletJs' : '',
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
247
278
|
}
|
|
248
279
|
});
|
|
249
280
|
|
package/lib/router/manager.js
CHANGED
|
@@ -559,8 +559,8 @@ class RouterManager extends EventEmitter {
|
|
|
559
559
|
await tempRouter.validateConfig();
|
|
560
560
|
await fse.remove(tmpDir);
|
|
561
561
|
} catch (error) {
|
|
562
|
+
// 如果出错,保留 Nginx 配置文件,方便定位问题
|
|
562
563
|
logger.error('validate router config failed', { error, action, data });
|
|
563
|
-
await fse.remove(tmpDir);
|
|
564
564
|
throw error;
|
|
565
565
|
}
|
|
566
566
|
}
|
package/lib/states/audit-log.js
CHANGED
|
@@ -239,9 +239,11 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
239
239
|
case 'deleteRoutingRule':
|
|
240
240
|
return `deleted routing rule from ${site}`; // prettier-ignore
|
|
241
241
|
case 'updateGateway': {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
242
|
+
const changes = [
|
|
243
|
+
args.requestLimit.enabled ? `rate limit: enabled, rate: ${args.requestLimit.rate}` : 'rate limit: disabled',
|
|
244
|
+
args.cacheEnabled ? `global cache: enabled, rate: ${args.cacheEnabled}` : 'global cache: disabled',
|
|
245
|
+
];
|
|
246
|
+
const message = `update gateway: ${changes.join('; ')}`;
|
|
245
247
|
return message;
|
|
246
248
|
}
|
|
247
249
|
case 'createTransferInvitation':
|
package/lib/states/node.js
CHANGED
|
@@ -124,7 +124,7 @@ class NodeState extends BaseState {
|
|
|
124
124
|
routing,
|
|
125
125
|
docker,
|
|
126
126
|
mode,
|
|
127
|
-
enableWelcomePage:
|
|
127
|
+
enableWelcomePage: mode !== NODE_MODES.SERVERLESS,
|
|
128
128
|
runtimeConfig,
|
|
129
129
|
ownerNft,
|
|
130
130
|
diskAlertThreshold: DISK_ALERT_THRESHOLD_PERCENT,
|
|
@@ -310,7 +310,10 @@ class NodeState extends BaseState {
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
async updateGateway(gateway) {
|
|
313
|
-
const [, nodeInfo] = await this.update(
|
|
313
|
+
const [, nodeInfo] = await this.update(
|
|
314
|
+
{},
|
|
315
|
+
{ $set: { 'routing.requestLimit': gateway.requestLimit, 'routing.cacheEnabled': gateway.cacheEnabled } }
|
|
316
|
+
);
|
|
314
317
|
|
|
315
318
|
this.emit(EVENTS.RELOAD_GATEWAY, nodeInfo);
|
|
316
319
|
|
package/lib/util/blocklet.js
CHANGED
|
@@ -31,7 +31,12 @@ const getFolderSize = require('@abtnode/util/lib/get-folder-size');
|
|
|
31
31
|
const normalizePathPrefix = require('@abtnode/util/lib/normalize-path-prefix');
|
|
32
32
|
const hashFiles = require('@abtnode/util/lib/hash-files');
|
|
33
33
|
const isPathPrefixEqual = require('@abtnode/util/lib/is-path-prefix-equal');
|
|
34
|
-
const {
|
|
34
|
+
const {
|
|
35
|
+
BLOCKLET_MAX_MEM_LIMIT_IN_MB,
|
|
36
|
+
BLOCKLET_STORE,
|
|
37
|
+
BLOCKLET_INSTALL_TYPE,
|
|
38
|
+
BLOCKLET_STORE_DEV,
|
|
39
|
+
} = require('@abtnode/constant');
|
|
35
40
|
const formatBackSlash = require('@abtnode/util/lib/format-back-slash');
|
|
36
41
|
|
|
37
42
|
const SCRIPT_ENGINES_WHITE_LIST = ['npm', 'npx', 'pnpm', 'yarn'];
|
|
@@ -89,6 +94,7 @@ const {
|
|
|
89
94
|
validateBlockletMeta,
|
|
90
95
|
prettyURL,
|
|
91
96
|
getNFTState,
|
|
97
|
+
templateReplace,
|
|
92
98
|
} = require('./index');
|
|
93
99
|
|
|
94
100
|
const getComponentConfig = (meta) => meta.components || meta.children;
|
|
@@ -235,12 +241,12 @@ const getComponentDirs = (
|
|
|
235
241
|
const fillBlockletConfigs = (blocklet, configs) => {
|
|
236
242
|
blocklet.configs = configs || [];
|
|
237
243
|
blocklet.configObj = blocklet.configs.reduce((acc, x) => {
|
|
238
|
-
acc[x.key] = x.value;
|
|
244
|
+
acc[x.key] = templateReplace(x.value, blocklet);
|
|
239
245
|
return acc;
|
|
240
246
|
}, {});
|
|
241
247
|
blocklet.environments = blocklet.environments || [];
|
|
242
248
|
blocklet.environmentObj = blocklet.environments.reduce((acc, x) => {
|
|
243
|
-
acc[x.key] = x.value;
|
|
249
|
+
acc[x.key] = templateReplace(x.value, blocklet);
|
|
244
250
|
return acc;
|
|
245
251
|
}, {});
|
|
246
252
|
};
|
|
@@ -835,7 +841,7 @@ const parseChildrenFromMeta = async (src, context = {}) => {
|
|
|
835
841
|
};
|
|
836
842
|
|
|
837
843
|
const validateBlocklet = (blocklet) =>
|
|
838
|
-
forEachBlocklet(blocklet, (b) => {
|
|
844
|
+
forEachBlocklet(blocklet, async (b) => {
|
|
839
845
|
isRequirementsSatisfied(b.meta.requirements);
|
|
840
846
|
validateEngine(getBlockletEngineNameByPlatform(b.meta));
|
|
841
847
|
});
|
|
@@ -1400,12 +1406,14 @@ const getBlocklet = async ({
|
|
|
1400
1406
|
|
|
1401
1407
|
blocklet.settings.storeList = blocklet.settings.storeList || [];
|
|
1402
1408
|
|
|
1403
|
-
|
|
1404
|
-
blocklet.settings.storeList.
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
+
[BLOCKLET_STORE_DEV, BLOCKLET_STORE].forEach((store) => {
|
|
1410
|
+
if (!blocklet.settings.storeList.find((x) => x.url === store.url)) {
|
|
1411
|
+
blocklet.settings.storeList.unshift({
|
|
1412
|
+
...store,
|
|
1413
|
+
protected: true,
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
});
|
|
1409
1417
|
|
|
1410
1418
|
// app site
|
|
1411
1419
|
blocklet.site = await states.site.findOneByBlocklet(blocklet.meta.did);
|
|
@@ -1690,6 +1698,32 @@ const checkDuplicateMountPoint = (blocklet, mountPoint) => {
|
|
|
1690
1698
|
}
|
|
1691
1699
|
};
|
|
1692
1700
|
|
|
1701
|
+
const validateStore = (nodeInfo, storeUrl) => {
|
|
1702
|
+
if (nodeInfo.mode !== 'serverless') {
|
|
1703
|
+
return;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
const inStoreList = nodeInfo.blockletRegistryList.find((item) => {
|
|
1707
|
+
const itemURLObj = new URL(item.url);
|
|
1708
|
+
const storeUrlObj = new URL(storeUrl);
|
|
1709
|
+
|
|
1710
|
+
return itemURLObj.host === storeUrlObj.host;
|
|
1711
|
+
});
|
|
1712
|
+
|
|
1713
|
+
if (!inStoreList) {
|
|
1714
|
+
throw new Error('Must be installed from the compliant blocklet store list');
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
|
|
1718
|
+
const validateInServerless = ({ blockletMeta }) => {
|
|
1719
|
+
const { interfaces } = blockletMeta;
|
|
1720
|
+
const externalPortInterfaces = (interfaces || []).filter((item) => !!item.port?.external);
|
|
1721
|
+
|
|
1722
|
+
if (externalPortInterfaces.length > 0) {
|
|
1723
|
+
throw new Error('Blocklets with exposed ports cannot be installed');
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1693
1727
|
module.exports = {
|
|
1694
1728
|
consumeServerlessNFT,
|
|
1695
1729
|
forEachBlocklet,
|
|
@@ -1737,4 +1771,6 @@ module.exports = {
|
|
|
1737
1771
|
validateAppConfig,
|
|
1738
1772
|
checkDuplicateAppSk,
|
|
1739
1773
|
checkDuplicateMountPoint,
|
|
1774
|
+
validateStore,
|
|
1775
|
+
validateInServerless,
|
|
1740
1776
|
};
|
package/lib/util/index.js
CHANGED
|
@@ -27,6 +27,7 @@ const {
|
|
|
27
27
|
DEFAULT_HTTP_PORT,
|
|
28
28
|
DEFAULT_HTTPS_PORT,
|
|
29
29
|
SLOT_FOR_IP_DNS_SITE,
|
|
30
|
+
NODE_MODES,
|
|
30
31
|
} = require('@abtnode/constant');
|
|
31
32
|
|
|
32
33
|
const DEFAULT_WELLKNOWN_PORT = 8088;
|
|
@@ -452,6 +453,27 @@ const prettyURL = (url, isHttps = true) => {
|
|
|
452
453
|
return isHttps ? `https://${url}` : `http://${url}`;
|
|
453
454
|
};
|
|
454
455
|
|
|
456
|
+
const templateReplace = (str, vars = {}) => {
|
|
457
|
+
if (typeof str === 'string') {
|
|
458
|
+
return str.replace(/{([.\w]+)}/g, (m, key) => get(vars, key));
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return str;
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
const isGatewayCacheEnabled = (info) => {
|
|
465
|
+
if (info.mode === NODE_MODES.DEBUG) {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const cacheEnabled = get(info, 'routing.cacheEnabled');
|
|
470
|
+
if (typeof cacheEnabled === 'boolean') {
|
|
471
|
+
return cacheEnabled;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return true;
|
|
475
|
+
};
|
|
476
|
+
|
|
455
477
|
const lib = {
|
|
456
478
|
validateOwner,
|
|
457
479
|
getProviderFromNodeInfo,
|
|
@@ -489,6 +511,8 @@ const lib = {
|
|
|
489
511
|
getNFTState,
|
|
490
512
|
getServerDidDomain,
|
|
491
513
|
prettyURL,
|
|
514
|
+
templateReplace,
|
|
515
|
+
isGatewayCacheEnabled,
|
|
492
516
|
};
|
|
493
517
|
|
|
494
518
|
module.exports = lib;
|
package/lib/validators/node.js
CHANGED
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.67-beta-794a8082",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,33 +19,33 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/auth": "1.8.
|
|
23
|
-
"@abtnode/certificate-manager": "1.8.
|
|
24
|
-
"@abtnode/constant": "1.8.
|
|
25
|
-
"@abtnode/cron": "1.8.
|
|
26
|
-
"@abtnode/db": "1.8.
|
|
27
|
-
"@abtnode/logger": "1.8.
|
|
28
|
-
"@abtnode/queue": "1.8.
|
|
29
|
-
"@abtnode/rbac": "1.8.
|
|
30
|
-
"@abtnode/router-provider": "1.8.
|
|
31
|
-
"@abtnode/static-server": "1.8.
|
|
32
|
-
"@abtnode/timemachine": "1.8.
|
|
33
|
-
"@abtnode/util": "1.8.
|
|
34
|
-
"@arcblock/did": "1.18.
|
|
22
|
+
"@abtnode/auth": "1.8.67-beta-794a8082",
|
|
23
|
+
"@abtnode/certificate-manager": "1.8.67-beta-794a8082",
|
|
24
|
+
"@abtnode/constant": "1.8.67-beta-794a8082",
|
|
25
|
+
"@abtnode/cron": "1.8.67-beta-794a8082",
|
|
26
|
+
"@abtnode/db": "1.8.67-beta-794a8082",
|
|
27
|
+
"@abtnode/logger": "1.8.67-beta-794a8082",
|
|
28
|
+
"@abtnode/queue": "1.8.67-beta-794a8082",
|
|
29
|
+
"@abtnode/rbac": "1.8.67-beta-794a8082",
|
|
30
|
+
"@abtnode/router-provider": "1.8.67-beta-794a8082",
|
|
31
|
+
"@abtnode/static-server": "1.8.67-beta-794a8082",
|
|
32
|
+
"@abtnode/timemachine": "1.8.67-beta-794a8082",
|
|
33
|
+
"@abtnode/util": "1.8.67-beta-794a8082",
|
|
34
|
+
"@arcblock/did": "1.18.54",
|
|
35
35
|
"@arcblock/did-motif": "^1.1.10",
|
|
36
|
-
"@arcblock/did-util": "1.18.
|
|
37
|
-
"@arcblock/event-hub": "1.18.
|
|
38
|
-
"@arcblock/jwt": "^1.18.
|
|
36
|
+
"@arcblock/did-util": "1.18.54",
|
|
37
|
+
"@arcblock/event-hub": "1.18.54",
|
|
38
|
+
"@arcblock/jwt": "^1.18.54",
|
|
39
39
|
"@arcblock/pm2-events": "^0.0.5",
|
|
40
|
-
"@arcblock/vc": "1.18.
|
|
41
|
-
"@blocklet/constant": "1.8.
|
|
42
|
-
"@blocklet/meta": "1.8.
|
|
43
|
-
"@blocklet/sdk": "1.8.
|
|
44
|
-
"@did-space/client": "^0.1.
|
|
40
|
+
"@arcblock/vc": "1.18.54",
|
|
41
|
+
"@blocklet/constant": "1.8.67-beta-794a8082",
|
|
42
|
+
"@blocklet/meta": "1.8.67-beta-794a8082",
|
|
43
|
+
"@blocklet/sdk": "1.8.67-beta-794a8082",
|
|
44
|
+
"@did-space/client": "^0.1.76",
|
|
45
45
|
"@fidm/x509": "^1.2.1",
|
|
46
|
-
"@ocap/mcrypto": "1.18.
|
|
47
|
-
"@ocap/util": "1.18.
|
|
48
|
-
"@ocap/wallet": "1.18.
|
|
46
|
+
"@ocap/mcrypto": "1.18.54",
|
|
47
|
+
"@ocap/util": "1.18.54",
|
|
48
|
+
"@ocap/wallet": "1.18.54",
|
|
49
49
|
"@slack/webhook": "^5.0.4",
|
|
50
50
|
"archiver": "^5.3.1",
|
|
51
51
|
"axios": "^0.27.2",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
"pm2": "^5.2.0",
|
|
73
73
|
"semver": "^7.3.8",
|
|
74
74
|
"shelljs": "^0.8.5",
|
|
75
|
-
"slugify": "^1.6.5",
|
|
76
75
|
"ssri": "^8.0.1",
|
|
77
76
|
"stream-throttle": "^0.1.3",
|
|
78
77
|
"stream-to-promise": "^3.0.0",
|
|
@@ -90,5 +89,5 @@
|
|
|
90
89
|
"express": "^4.18.2",
|
|
91
90
|
"jest": "^27.5.1"
|
|
92
91
|
},
|
|
93
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "f4ad32bea4d80b12971fb6bef941bdbe2af6a834"
|
|
94
93
|
}
|