@abtnode/core 1.7.9 → 1.7.12
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 +7 -1
- package/lib/api/team.js +2 -2
- package/lib/blocklet/manager/disk.js +153 -91
- package/lib/blocklet/registry.js +6 -2
- package/lib/cert.js +14 -0
- package/lib/event.js +9 -0
- package/lib/index.js +41 -9
- package/lib/migrations/1.7.12-blocklet-meta.js +51 -0
- package/lib/router/index.js +8 -1
- package/lib/router/manager.js +3 -3
- package/lib/states/README.md +31 -1
- package/lib/states/audit-log.js +382 -0
- package/lib/states/blocklet.js +9 -7
- package/lib/states/index.js +3 -0
- package/lib/states/node.js +8 -0
- package/lib/util/blocklet.js +103 -45
- package/lib/util/index.js +37 -7
- package/lib/util/ip.js +6 -0
- package/lib/util/rpc.js +16 -0
- package/lib/util/ua.js +54 -0
- package/lib/util/upgrade.js +3 -15
- package/lib/validators/node.js +13 -0
- package/package.json +21 -21
- package/lib/util/service.js +0 -81
package/lib/api/node.js
CHANGED
|
@@ -10,7 +10,7 @@ const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
|
|
|
10
10
|
const logger = require('@abtnode/logger')('@abtnode/core:api:node');
|
|
11
11
|
|
|
12
12
|
const IP = require('../util/ip');
|
|
13
|
-
const { validateNodeInfo } = require('../validators/node');
|
|
13
|
+
const { validateNodeInfo, validateUpdateGateway } = require('../validators/node');
|
|
14
14
|
const BlockletRegistry = require('../blocklet/registry');
|
|
15
15
|
const { getAll } = require('../blocklet/manager/engine');
|
|
16
16
|
|
|
@@ -154,6 +154,12 @@ class NodeAPI {
|
|
|
154
154
|
|
|
155
155
|
return res;
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
async updateGateway(entity, context) {
|
|
159
|
+
const data = await validateUpdateGateway(entity, context);
|
|
160
|
+
|
|
161
|
+
return this.state.updateGateway(data);
|
|
162
|
+
}
|
|
157
163
|
}
|
|
158
164
|
|
|
159
165
|
module.exports = NodeAPI;
|
package/lib/api/team.js
CHANGED
|
@@ -54,9 +54,9 @@ class TeamAPI extends EventEmitter {
|
|
|
54
54
|
if (teamDid === nodeInfo.did && nodeInfo.nodeOwner && user.did !== nodeInfo.nodeOwner.did) {
|
|
55
55
|
await this.notification.create({
|
|
56
56
|
title: 'New member join',
|
|
57
|
-
description: `User with Name (${user.fullName}) and DID (${user.did}) has joined this
|
|
57
|
+
description: `User with Name (${user.fullName}) and DID (${user.did}) has joined this server`,
|
|
58
58
|
entityType: 'node',
|
|
59
|
-
action: '/
|
|
59
|
+
action: '/team/members',
|
|
60
60
|
entityId: user.did,
|
|
61
61
|
severity: 'success',
|
|
62
62
|
});
|
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
isDeletableBlocklet,
|
|
32
32
|
getRequiredMissingConfigs,
|
|
33
33
|
hasRunnableComponent,
|
|
34
|
+
forEachBlocklet,
|
|
34
35
|
} = require('@blocklet/meta/lib/util');
|
|
35
36
|
const validateBlockletEntry = require('@blocklet/meta/lib/entry');
|
|
36
37
|
const toBlockletDid = require('@blocklet/meta/lib/did');
|
|
@@ -63,7 +64,6 @@ const {
|
|
|
63
64
|
getFromCache: getAccessibleExternalNodeIp,
|
|
64
65
|
} = require('../../util/get-accessible-external-node-ip');
|
|
65
66
|
const {
|
|
66
|
-
forEachBlocklet,
|
|
67
67
|
getBlockletDirs,
|
|
68
68
|
getBlockletMetaFromUrl,
|
|
69
69
|
fillBlockletConfigs,
|
|
@@ -88,12 +88,15 @@ const {
|
|
|
88
88
|
getUpdateMetaList,
|
|
89
89
|
getRuntimeEnvironments,
|
|
90
90
|
getSourceFromInstallParams,
|
|
91
|
+
parseChildrenFromMeta,
|
|
91
92
|
parseChildren,
|
|
92
93
|
checkDuplicateComponents,
|
|
93
94
|
getDiffFiles,
|
|
94
95
|
getBundleDir,
|
|
95
96
|
needBlockletDownload,
|
|
96
97
|
verifyPurchase,
|
|
98
|
+
findAvailableDid,
|
|
99
|
+
ensureMeta,
|
|
97
100
|
} = require('../../util/blocklet');
|
|
98
101
|
const { parseSourceUrl } = require('../../util/registry');
|
|
99
102
|
const states = require('../../states');
|
|
@@ -217,11 +220,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
217
220
|
*
|
|
218
221
|
* InstallFromUpload
|
|
219
222
|
* @param {Object} file
|
|
220
|
-
* @param {String} did for diff upload
|
|
223
|
+
* @param {String} did for diff upload or custom component did
|
|
221
224
|
* @param {String} diffVersion for diff upload
|
|
222
225
|
* @param {Array} deleteSet for diff upload
|
|
226
|
+
*
|
|
227
|
+
* Custom info
|
|
228
|
+
* @param {String} title custom component title
|
|
229
|
+
* @param {String} name custom component name
|
|
223
230
|
*/
|
|
224
|
-
async installComponent({ rootDid, mountPoint, url, file, did, diffVersion, deleteSet }, context = {}) {
|
|
231
|
+
async installComponent({ rootDid, mountPoint, url, file, did, diffVersion, deleteSet, title, name }, context = {}) {
|
|
225
232
|
logger.debug('start install component', { rootDid, mountPoint, url });
|
|
226
233
|
|
|
227
234
|
if (file) {
|
|
@@ -229,7 +236,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
if (url) {
|
|
232
|
-
return this._installComponentFromUrl({ rootDid, mountPoint, url, context });
|
|
239
|
+
return this._installComponentFromUrl({ rootDid, mountPoint, url, context, title, did, name });
|
|
233
240
|
}
|
|
234
241
|
|
|
235
242
|
// should not be here
|
|
@@ -283,7 +290,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
283
290
|
|
|
284
291
|
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
285
292
|
logger.info('start blocklet', { did });
|
|
286
|
-
const blocklet = await this.ensureBlocklet(did, e2eMode);
|
|
293
|
+
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
287
294
|
|
|
288
295
|
try {
|
|
289
296
|
if (!hasRunnableComponent(blocklet)) {
|
|
@@ -452,7 +459,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
452
459
|
logger.info('delete blocklet', { did, keepData });
|
|
453
460
|
|
|
454
461
|
try {
|
|
455
|
-
const blocklet = await this.ensureBlocklet(did);
|
|
462
|
+
const blocklet = await this.ensureBlocklet(did, { validateEnv: false });
|
|
456
463
|
if (isDeletableBlocklet(blocklet) === false) {
|
|
457
464
|
throw new Error('Blocklet is protected from accidental deletion');
|
|
458
465
|
}
|
|
@@ -521,14 +528,33 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
521
528
|
async deleteComponent({ did, rootDid }, context) {
|
|
522
529
|
logger.info('delete blocklet component', { did, rootDid });
|
|
523
530
|
|
|
531
|
+
const blocklet = await this.ensureBlocklet(rootDid);
|
|
524
532
|
const doc = await states.blocklet.getBlocklet(rootDid);
|
|
525
533
|
|
|
534
|
+
const child = doc.children.find((x) => x.meta.did === did);
|
|
535
|
+
|
|
536
|
+
if (!child) {
|
|
537
|
+
throw new Error('Component does not exist');
|
|
538
|
+
}
|
|
539
|
+
|
|
526
540
|
doc.children = doc.children.filter((x) => x.meta.did !== did);
|
|
527
541
|
const children = (await this._getDynamicChildrenFromSettings(rootDid)).filter((x) => x.meta.did !== did);
|
|
542
|
+
children.push({
|
|
543
|
+
meta: pick(child.meta, ['did', 'name', 'bundleDid', 'bundleName', 'version', 'title', 'description']),
|
|
544
|
+
mountPoint: child.mountPoint,
|
|
545
|
+
status: BlockletStatus.deleted,
|
|
546
|
+
deletedAt: new Date(),
|
|
547
|
+
});
|
|
528
548
|
|
|
529
549
|
await states.blocklet.updateBlocklet(rootDid, doc);
|
|
530
550
|
states.blockletExtras.setSettings(rootDid, { children });
|
|
531
551
|
|
|
552
|
+
// delete storage
|
|
553
|
+
const childBlocklet = blocklet.children.find((x) => x.meta.did === did);
|
|
554
|
+
const { cacheDir, logsDir } = childBlocklet.env;
|
|
555
|
+
fs.removeSync(cacheDir);
|
|
556
|
+
fs.removeSync(logsDir);
|
|
557
|
+
|
|
532
558
|
const newBlocklet = await this.ensureBlocklet(rootDid);
|
|
533
559
|
this.emit(BlockletEvents.upgraded, { blocklet: newBlocklet, context }); // trigger router refresh
|
|
534
560
|
return newBlocklet;
|
|
@@ -627,7 +653,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
627
653
|
}
|
|
628
654
|
|
|
629
655
|
// eslint-disable-next-line no-unused-vars
|
|
630
|
-
async config({ did, childDid, configs: newConfigs }, context) {
|
|
656
|
+
async config({ did, childDid, configs: newConfigs, skipHook }, context) {
|
|
631
657
|
logger.info('config blocklet', { did });
|
|
632
658
|
if (!Array.isArray(newConfigs)) {
|
|
633
659
|
throw new Error('configs list is not an array');
|
|
@@ -694,15 +720,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
694
720
|
blocklet.configObj[x.key] = x.value;
|
|
695
721
|
}
|
|
696
722
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
723
|
+
if (!skipHook) {
|
|
724
|
+
// FIXME: we should also call preConfig for child blocklets
|
|
725
|
+
await hooks.preConfig(blocklet.env.appId, {
|
|
726
|
+
appDir: blocklet.env.appDir,
|
|
727
|
+
hooks: Object.assign(blocklet.meta.hooks || {}, blocklet.meta.scripts || {}),
|
|
728
|
+
exitOnError: true,
|
|
729
|
+
env: { ...getRuntimeEnvironments(blocklet, nodeEnvironments), ...blocklet.configObj },
|
|
730
|
+
did,
|
|
731
|
+
context,
|
|
732
|
+
});
|
|
733
|
+
}
|
|
706
734
|
|
|
707
735
|
// update db
|
|
708
736
|
const configs = childDid
|
|
@@ -736,9 +764,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
736
764
|
|
|
737
765
|
const upgradeFromRegistry = registryUrl || blocklet.deployedFrom;
|
|
738
766
|
|
|
739
|
-
const
|
|
767
|
+
const newVersionMeta = await this.registry.getBlockletMeta(
|
|
740
768
|
{
|
|
741
|
-
did,
|
|
769
|
+
did: blocklet.meta.bundleDid,
|
|
742
770
|
registryUrl: upgradeFromRegistry,
|
|
743
771
|
},
|
|
744
772
|
context
|
|
@@ -765,7 +793,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
765
793
|
}
|
|
766
794
|
|
|
767
795
|
const currentDeveloperSignature = getSignature(blocklet.meta.signatures);
|
|
768
|
-
const newVersionDeveloperSignature = getSignature(
|
|
796
|
+
const newVersionDeveloperSignature = getSignature(newVersionMeta.signatures, blocklet.meta.signatures);
|
|
769
797
|
|
|
770
798
|
if (!newVersionDeveloperSignature) {
|
|
771
799
|
throw new Error('Invalid upgrade blocklet signature');
|
|
@@ -781,15 +809,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
781
809
|
throw new Error('Invalid developer signature');
|
|
782
810
|
}
|
|
783
811
|
|
|
784
|
-
if (blocklet.meta.version ===
|
|
812
|
+
if (blocklet.meta.version === newVersionMeta.version) {
|
|
785
813
|
throw new Error('Upgrade/downgrade blocklet to same version is noop');
|
|
786
814
|
}
|
|
787
815
|
|
|
788
|
-
const action = semver.gt(blocklet.meta.version,
|
|
816
|
+
const action = semver.gt(blocklet.meta.version, newVersionMeta.version) ? 'downgrade' : 'upgrade';
|
|
789
817
|
logger.info(`${action} blocklet`, { did });
|
|
790
818
|
|
|
791
819
|
return this._upgrade({
|
|
792
|
-
meta:
|
|
820
|
+
meta: newVersionMeta,
|
|
793
821
|
source: BlockletSource.registry,
|
|
794
822
|
deployedFrom: upgradeFromRegistry,
|
|
795
823
|
context,
|
|
@@ -857,16 +885,19 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
857
885
|
|
|
858
886
|
async checkChildrenForUpdates({ did }) {
|
|
859
887
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
860
|
-
const newStaticChildren = await
|
|
888
|
+
const newStaticChildren = await parseChildrenFromMeta(blocklet.meta);
|
|
861
889
|
|
|
862
|
-
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(did);
|
|
890
|
+
const oldDynamicChildren = await this._getDynamicChildrenFromSettings(did, { skipDeleted: true });
|
|
863
891
|
const noneSourceUrlChildren = oldDynamicChildren.filter((x) => !x.sourceUrl);
|
|
864
892
|
const dynamicConfig = oldDynamicChildren
|
|
865
893
|
.filter((x) => x.sourceUrl)
|
|
866
894
|
.map((x) => ({ resolved: x.sourceUrl, name: x.meta.name, mountPoint: x.mountPoint }));
|
|
867
|
-
const newDynamicChildren = [
|
|
895
|
+
const newDynamicChildren = [
|
|
896
|
+
...noneSourceUrlChildren,
|
|
897
|
+
...(await parseChildrenFromMeta(dynamicConfig, { dynamic: true })),
|
|
898
|
+
];
|
|
868
899
|
|
|
869
|
-
checkDuplicateComponents(newDynamicChildren, newStaticChildren);
|
|
900
|
+
checkDuplicateComponents([...newDynamicChildren, ...newStaticChildren]);
|
|
870
901
|
|
|
871
902
|
const updateList = getUpdateMetaList(
|
|
872
903
|
[...blocklet.children.map((x) => x.meta), ...oldDynamicChildren.map((x) => x.meta)],
|
|
@@ -1011,7 +1042,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1011
1042
|
|
|
1012
1043
|
const children = await this._getChildren(meta);
|
|
1013
1044
|
const added = await states.blocklet.addBlocklet({
|
|
1014
|
-
did,
|
|
1015
1045
|
meta,
|
|
1016
1046
|
source: BlockletSource.local,
|
|
1017
1047
|
deployedFrom: folder,
|
|
@@ -1060,19 +1090,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1060
1090
|
}
|
|
1061
1091
|
|
|
1062
1092
|
const defaultPath = formatName(meta.name);
|
|
1063
|
-
const children = await parseChildren(
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
dynamic: true,
|
|
1075
|
-
});
|
|
1093
|
+
const children = await parseChildren([
|
|
1094
|
+
{
|
|
1095
|
+
meta: ensureMeta(meta),
|
|
1096
|
+
mountPoint: mountPoint || `/${defaultPath}`,
|
|
1097
|
+
source: BlockletSource.local,
|
|
1098
|
+
deployedFrom: folder,
|
|
1099
|
+
status: BlockletStatus.installed,
|
|
1100
|
+
mode: BLOCKLET_MODES.DEVELOPMENT,
|
|
1101
|
+
dynamic: true,
|
|
1102
|
+
},
|
|
1103
|
+
]);
|
|
1076
1104
|
await states.blocklet.addChildren(rootDid, children);
|
|
1077
1105
|
|
|
1078
1106
|
logger.info('add blocklet component for dev', { did, version, meta });
|
|
@@ -1086,7 +1114,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1086
1114
|
return rootBlocklet;
|
|
1087
1115
|
}
|
|
1088
1116
|
|
|
1089
|
-
async ensureBlocklet(did, e2eMode = false) {
|
|
1117
|
+
async ensureBlocklet(did, { e2eMode = false, validateEnv = true } = {}) {
|
|
1090
1118
|
if (!isValidDid(did)) {
|
|
1091
1119
|
throw new Error(`Blocklet did is invalid: ${did}`);
|
|
1092
1120
|
}
|
|
@@ -1096,6 +1124,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1096
1124
|
throw new Error(`Can not find blocklet in database by did ${did}`);
|
|
1097
1125
|
}
|
|
1098
1126
|
|
|
1127
|
+
// env
|
|
1099
1128
|
blocklet.env = {
|
|
1100
1129
|
appId: blocklet.meta.name,
|
|
1101
1130
|
// dataDir is /dataDir.data/blocklet.meta.name
|
|
@@ -1105,18 +1134,23 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1105
1134
|
dataDirs: this.dataDirs,
|
|
1106
1135
|
ensure: true,
|
|
1107
1136
|
e2eMode,
|
|
1137
|
+
validate: validateEnv,
|
|
1108
1138
|
}),
|
|
1109
1139
|
};
|
|
1110
1140
|
|
|
1141
|
+
// configs
|
|
1111
1142
|
const configs = await states.blockletExtras.getConfigs(blocklet.meta.did);
|
|
1112
1143
|
fillBlockletConfigs(blocklet, configs);
|
|
1113
1144
|
|
|
1114
|
-
//
|
|
1145
|
+
// settings
|
|
1115
1146
|
const settings = await states.blockletExtras.getSettings(blocklet.meta.did);
|
|
1116
1147
|
blocklet.trustedPassports = get(settings, 'trustedPassports') || [];
|
|
1117
1148
|
blocklet.enablePassportIssuance = get(settings, 'enablePassportIssuance', true);
|
|
1118
1149
|
blocklet.settings = settings || {};
|
|
1119
1150
|
|
|
1151
|
+
// site
|
|
1152
|
+
blocklet.site = await this.getSiteByDid(blocklet.meta.did);
|
|
1153
|
+
|
|
1120
1154
|
// handle child env
|
|
1121
1155
|
for (const child of blocklet.children) {
|
|
1122
1156
|
const {
|
|
@@ -1126,11 +1160,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1126
1160
|
meta: { name },
|
|
1127
1161
|
} = blocklet;
|
|
1128
1162
|
|
|
1163
|
+
// child env
|
|
1129
1164
|
child.env = {
|
|
1130
1165
|
appId: `${encodeURIComponent(name)}/${encodeURIComponent(childName)}`,
|
|
1131
|
-
// dataDir is /dataDir.data/blocklet.meta.name/child.meta.name
|
|
1132
|
-
// cacheDir is /dataDirs.cache/blocklet.meta.name/child.meta.name
|
|
1133
|
-
// logDir is /dataDirs.log/blocklet.meta.name
|
|
1134
1166
|
...getBlockletDirs(child, {
|
|
1135
1167
|
dataDirs: this.dataDirs,
|
|
1136
1168
|
ensure: true,
|
|
@@ -1138,13 +1170,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1138
1170
|
}),
|
|
1139
1171
|
};
|
|
1140
1172
|
|
|
1173
|
+
// child configs
|
|
1141
1174
|
const childConfigs = await states.blockletExtras.getChildConfigs(blocklet.meta.did, childDid);
|
|
1142
1175
|
fillBlockletConfigs(child, childConfigs, blocklet);
|
|
1143
1176
|
}
|
|
1144
1177
|
|
|
1145
|
-
// site
|
|
1146
|
-
blocklet.site = await this.getSiteByDid(blocklet.meta.did);
|
|
1147
|
-
|
|
1148
1178
|
return blocklet;
|
|
1149
1179
|
}
|
|
1150
1180
|
|
|
@@ -1581,7 +1611,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1581
1611
|
});
|
|
1582
1612
|
}
|
|
1583
1613
|
|
|
1584
|
-
async _installComponentFromUrl({ rootDid, mountPoint, url, context }) {
|
|
1614
|
+
async _installComponentFromUrl({ rootDid, mountPoint, url, context, title, name: inputName, did: inputDid }) {
|
|
1585
1615
|
const blocklet = await states.blocklet.getBlocklet(rootDid);
|
|
1586
1616
|
if (!blocklet) {
|
|
1587
1617
|
throw new Error('Root blocklet does not exist');
|
|
@@ -1599,18 +1629,31 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1599
1629
|
|
|
1600
1630
|
verifyPurchase(meta, context);
|
|
1601
1631
|
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1632
|
+
if (title) {
|
|
1633
|
+
meta.title = await titleSchema.validateAsync(title);
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
let name = inputName;
|
|
1637
|
+
let did = inputDid;
|
|
1638
|
+
if (!inputName && !inputDid) {
|
|
1639
|
+
const found = findAvailableDid(meta, [
|
|
1640
|
+
...blocklet.children.map((x) => x.meta),
|
|
1641
|
+
...(await states.blockletExtras.getSettings(rootDid, 'children', [])).map((x) => x.meta),
|
|
1642
|
+
]);
|
|
1643
|
+
name = found.name;
|
|
1644
|
+
did = found.did;
|
|
1645
|
+
}
|
|
1612
1646
|
|
|
1613
|
-
|
|
1647
|
+
const newChildren = await parseChildren([
|
|
1648
|
+
{
|
|
1649
|
+
meta: ensureMeta(meta, { did, name }),
|
|
1650
|
+
mountPoint,
|
|
1651
|
+
sourceUrl: url,
|
|
1652
|
+
dynamic: true,
|
|
1653
|
+
},
|
|
1654
|
+
]);
|
|
1655
|
+
|
|
1656
|
+
checkDuplicateComponents([...blocklet.children, ...newChildren]);
|
|
1614
1657
|
|
|
1615
1658
|
// add component to db
|
|
1616
1659
|
await states.blocklet.addChildren(rootDid, newChildren);
|
|
@@ -1654,7 +1697,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1654
1697
|
const meta = validateMeta(rawMeta);
|
|
1655
1698
|
|
|
1656
1699
|
await states.blocklet.addBlocklet({
|
|
1657
|
-
did: meta.did,
|
|
1658
1700
|
meta,
|
|
1659
1701
|
source: BlockletSource.custom,
|
|
1660
1702
|
});
|
|
@@ -1721,7 +1763,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1721
1763
|
|
|
1722
1764
|
const { meta } = await this._resolveDiffDownload(cwd, tarFile, deleteSet, oldBlocklet.meta);
|
|
1723
1765
|
const newBlocklet = await states.blocklet.getBlocklet(did);
|
|
1724
|
-
newBlocklet.meta = meta;
|
|
1766
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
1725
1767
|
newBlocklet.source = BlockletSource.upload;
|
|
1726
1768
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
1727
1769
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -1747,7 +1789,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1747
1789
|
}
|
|
1748
1790
|
|
|
1749
1791
|
const newBlocklet = await states.blocklet.getBlocklet(meta.did);
|
|
1750
|
-
newBlocklet.meta = meta;
|
|
1792
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
1751
1793
|
newBlocklet.source = BlockletSource.upload;
|
|
1752
1794
|
newBlocklet.deployedFrom = `Upload by ${context.user.fullName}`;
|
|
1753
1795
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -1765,7 +1807,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1765
1807
|
// full deploy - install
|
|
1766
1808
|
const children = await this._getChildren(meta);
|
|
1767
1809
|
const blocklet = await states.blocklet.addBlocklet({
|
|
1768
|
-
did: meta.did,
|
|
1769
1810
|
meta,
|
|
1770
1811
|
source: BlockletSource.upload,
|
|
1771
1812
|
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
@@ -1832,28 +1873,26 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1832
1873
|
}
|
|
1833
1874
|
|
|
1834
1875
|
const newBlocklet = await states.blocklet.getBlocklet(rootDid);
|
|
1835
|
-
|
|
1876
|
+
|
|
1877
|
+
if (newBlocklet.children.some((x) => !x.dynamic && x.meta.did === meta.did)) {
|
|
1878
|
+
throw new Error('Cannot add duplicate component defined in app meta');
|
|
1879
|
+
}
|
|
1836
1880
|
|
|
1837
1881
|
const newChild = {
|
|
1838
|
-
meta,
|
|
1882
|
+
meta: ensureMeta(meta),
|
|
1839
1883
|
mountPoint,
|
|
1840
1884
|
source: BlockletSource.upload,
|
|
1841
1885
|
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
1842
1886
|
sourceUrl: '',
|
|
1843
1887
|
dynamic: true,
|
|
1844
1888
|
};
|
|
1845
|
-
const index =
|
|
1889
|
+
const index = newBlocklet.children.findIndex((child) => child.meta.did === meta.did);
|
|
1846
1890
|
if (index >= 0) {
|
|
1847
|
-
|
|
1891
|
+
newBlocklet.children.splice(index, 1, newChild);
|
|
1848
1892
|
} else {
|
|
1849
|
-
|
|
1893
|
+
newBlocklet.children.push(newChild);
|
|
1850
1894
|
}
|
|
1851
1895
|
|
|
1852
|
-
const staticChildren = newBlocklet.children.filter((x) => !x.dynamic);
|
|
1853
|
-
checkDuplicateComponents(dynamicChildren, staticChildren);
|
|
1854
|
-
|
|
1855
|
-
newBlocklet.children = [...staticChildren, ...dynamicChildren.map((x) => ({ ...x, dynamic: true }))];
|
|
1856
|
-
|
|
1857
1896
|
await validateBlocklet(newBlocklet);
|
|
1858
1897
|
|
|
1859
1898
|
return this._upgradeBlocklet({
|
|
@@ -1900,13 +1939,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1900
1939
|
throw new Error('the blocklet is not installed');
|
|
1901
1940
|
}
|
|
1902
1941
|
|
|
1942
|
+
const { bundleDid } = blocklet.meta;
|
|
1943
|
+
|
|
1903
1944
|
let versions = this.cachedBlockletVersions.get(did);
|
|
1904
1945
|
|
|
1905
1946
|
if (!versions) {
|
|
1906
1947
|
const { blockletRegistryList } = await states.node.read();
|
|
1907
1948
|
const tasks = blockletRegistryList.map((registry) =>
|
|
1908
1949
|
this.registry
|
|
1909
|
-
.getBlockletMeta({ did, registryUrl: registry.url })
|
|
1950
|
+
.getBlockletMeta({ did: bundleDid, registryUrl: registry.url })
|
|
1910
1951
|
.then((item) => ({ did, version: item.version, registryUrl: registry.url }))
|
|
1911
1952
|
.catch((error) => {
|
|
1912
1953
|
if (error.response && error.response.status === 404) {
|
|
@@ -1980,19 +2021,24 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1980
2021
|
}
|
|
1981
2022
|
|
|
1982
2023
|
async _getChildren(meta) {
|
|
1983
|
-
const staticChildren = await
|
|
1984
|
-
const dynamicChildren = await parseChildren(
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
2024
|
+
const staticChildren = await parseChildrenFromMeta(meta);
|
|
2025
|
+
const dynamicChildren = await parseChildren(
|
|
2026
|
+
await this._getDynamicChildrenFromSettings(meta.did, { skipDeleted: true }),
|
|
2027
|
+
meta,
|
|
2028
|
+
{
|
|
2029
|
+
dynamic: true,
|
|
2030
|
+
}
|
|
2031
|
+
);
|
|
2032
|
+
checkDuplicateComponents([...dynamicChildren, ...staticChildren]);
|
|
1989
2033
|
|
|
1990
2034
|
return [...staticChildren, ...dynamicChildren];
|
|
1991
2035
|
}
|
|
1992
2036
|
|
|
1993
|
-
async _getDynamicChildrenFromSettings(did) {
|
|
2037
|
+
async _getDynamicChildrenFromSettings(did, { skipDeleted } = {}) {
|
|
1994
2038
|
const children = await states.blockletExtras.getSettings(did, 'children', []);
|
|
1995
|
-
return children
|
|
2039
|
+
return children
|
|
2040
|
+
.map((x) => ({ ...x, dynamic: true }))
|
|
2041
|
+
.filter((x) => (skipDeleted ? x.status !== BlockletStatus.deleted : true));
|
|
1996
2042
|
}
|
|
1997
2043
|
|
|
1998
2044
|
async _install({ meta, source, deployedFrom, context, sync }) {
|
|
@@ -2003,7 +2049,6 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2003
2049
|
const children = await this._getChildren(meta);
|
|
2004
2050
|
try {
|
|
2005
2051
|
const blocklet = await states.blocklet.addBlocklet({
|
|
2006
|
-
did: meta.did,
|
|
2007
2052
|
meta,
|
|
2008
2053
|
source,
|
|
2009
2054
|
deployedFrom,
|
|
@@ -2089,11 +2134,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2089
2134
|
|
|
2090
2135
|
// NOTE: 目前的版本移除了降级通道,所以不需要考虑降级通道的情况
|
|
2091
2136
|
const action = semver.gt(oldBlocklet.meta.version, version) ? 'downgrade' : 'upgrade';
|
|
2092
|
-
logger.info(`${action} blocklet`, { did, version });
|
|
2137
|
+
logger.info(`${action} blocklet`, { did, name, version });
|
|
2093
2138
|
|
|
2094
2139
|
const newBlocklet = await states.blocklet.setBlockletStatus(did, BlockletStatus.waiting);
|
|
2095
2140
|
|
|
2096
|
-
newBlocklet.meta = meta;
|
|
2141
|
+
newBlocklet.meta = ensureMeta(meta);
|
|
2097
2142
|
newBlocklet.source = source;
|
|
2098
2143
|
newBlocklet.deployedFrom = deployedFrom;
|
|
2099
2144
|
newBlocklet.children = await this._getChildren(meta);
|
|
@@ -2324,6 +2369,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2324
2369
|
|
|
2325
2370
|
this.emit(BlockletEvents.installed, { blocklet, context });
|
|
2326
2371
|
|
|
2372
|
+
// Update dynamic component meta in blocklet settings
|
|
2373
|
+
await this._ensureDynamicChildrenInSettings(blocklet);
|
|
2374
|
+
|
|
2327
2375
|
states.notification.create({
|
|
2328
2376
|
title: 'Blocklet Installed',
|
|
2329
2377
|
description: `Blocklet ${meta.name}@${meta.version} is installed successfully. (Source: ${
|
|
@@ -2473,10 +2521,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2473
2521
|
}
|
|
2474
2522
|
|
|
2475
2523
|
// Update dynamic component meta in blocklet settings
|
|
2476
|
-
|
|
2477
|
-
.filter((x) => x.dynamic)
|
|
2478
|
-
.map((x) => pick(x, ['meta', 'mountPoint', 'sourceUrl', 'source']));
|
|
2479
|
-
await states.blockletExtras.setSettings(did, { children: dynamicChildren });
|
|
2524
|
+
await this._ensureDynamicChildrenInSettings(blocklet);
|
|
2480
2525
|
|
|
2481
2526
|
return blocklet;
|
|
2482
2527
|
} catch (err) {
|
|
@@ -2494,6 +2539,23 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2494
2539
|
}
|
|
2495
2540
|
}
|
|
2496
2541
|
|
|
2542
|
+
// Update dynamic component meta in blocklet settings
|
|
2543
|
+
async _ensureDynamicChildrenInSettings(blocklet) {
|
|
2544
|
+
const { did } = blocklet.meta;
|
|
2545
|
+
const dynamicChildren = blocklet.children
|
|
2546
|
+
.filter((x) => x.dynamic)
|
|
2547
|
+
.map((x) => pick(x, ['meta', 'mountPoint', 'sourceUrl', 'source']));
|
|
2548
|
+
|
|
2549
|
+
// deleted blocklet
|
|
2550
|
+
let deletes = await states.blockletExtras.getSettings(did, 'children', []);
|
|
2551
|
+
deletes = deletes.filter(
|
|
2552
|
+
(x) => x.status === BlockletStatus.deleted && !blocklet.children.some((y) => y.meta.did === x.meta.did)
|
|
2553
|
+
);
|
|
2554
|
+
dynamicChildren.push(...deletes);
|
|
2555
|
+
|
|
2556
|
+
await states.blockletExtras.setSettings(did, { children: dynamicChildren });
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2497
2559
|
/**
|
|
2498
2560
|
* for download: cwd, tarball, did
|
|
2499
2561
|
* for verify: verify, integrity
|
|
@@ -2617,7 +2679,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2617
2679
|
* @return {object} { isCancelled: Boolean }
|
|
2618
2680
|
*/
|
|
2619
2681
|
async _downloadBundle(meta, rootDid, url) {
|
|
2620
|
-
const { name, did, version, dist = {} } = meta;
|
|
2682
|
+
const { bundleName: name, bundleDid: did, version, dist = {} } = meta;
|
|
2621
2683
|
const { tarball, integrity } = dist;
|
|
2622
2684
|
|
|
2623
2685
|
const lockName = `download-${did}-${version}`;
|
package/lib/blocklet/registry.js
CHANGED
|
@@ -11,7 +11,7 @@ const request = require('../util/request');
|
|
|
11
11
|
|
|
12
12
|
const states = require('../states');
|
|
13
13
|
const isRequirementsSatisfied = require('../util/requirement');
|
|
14
|
-
const {
|
|
14
|
+
const { fixAndVerifyMetaFromStore } = require('../util/blocklet');
|
|
15
15
|
const { translate } = require('../locales');
|
|
16
16
|
const { validateRegistryURL, getRegistryMeta } = require('../util/registry');
|
|
17
17
|
|
|
@@ -68,7 +68,11 @@ class BlockletRegistry {
|
|
|
68
68
|
|
|
69
69
|
const { data } = await request.get(url);
|
|
70
70
|
try {
|
|
71
|
-
|
|
71
|
+
if (data.did !== did) {
|
|
72
|
+
throw new Error('Invalid blocklet meta: did does not match');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return fixAndVerifyMetaFromStore(data);
|
|
72
76
|
} catch (err) {
|
|
73
77
|
logger.error('failed to get blocklet meta', { did, data, error: err });
|
|
74
78
|
throw err;
|
package/lib/cert.js
CHANGED
|
@@ -37,6 +37,16 @@ const onCertIssued = (cert) => {
|
|
|
37
37
|
});
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
const onCertIssueFailed = (cert) => {
|
|
41
|
+
states.notification.create({
|
|
42
|
+
title: 'Certificate Issue Failed',
|
|
43
|
+
description: `Failed to issue certificate for ${cert.domain}`,
|
|
44
|
+
severity: 'error',
|
|
45
|
+
entityType: 'certificate',
|
|
46
|
+
entityId: cert.id,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
40
50
|
const getDomainFromInput = (input) => {
|
|
41
51
|
if (Object.prototype.toString.call(input) === '[object Object]') {
|
|
42
52
|
return input.domain;
|
|
@@ -58,6 +68,10 @@ class Cert extends EventEmitter {
|
|
|
58
68
|
|
|
59
69
|
this.manager.on('cert.expired', onCertExpired);
|
|
60
70
|
this.manager.on('cert.about_to_expire', onCertAboutExpire);
|
|
71
|
+
this.manager.on('cert.error', (cert) => {
|
|
72
|
+
this.emit('cert.error', cert);
|
|
73
|
+
onCertIssueFailed(cert);
|
|
74
|
+
});
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
start() {
|
package/lib/event.js
CHANGED
|
@@ -25,6 +25,7 @@ module.exports = ({
|
|
|
25
25
|
handleRouting,
|
|
26
26
|
domainStatus,
|
|
27
27
|
teamAPI,
|
|
28
|
+
certManager,
|
|
28
29
|
}) => {
|
|
29
30
|
const notificationState = states.notification;
|
|
30
31
|
const nodeState = states.node;
|
|
@@ -209,6 +210,11 @@ module.exports = ({
|
|
|
209
210
|
}
|
|
210
211
|
});
|
|
211
212
|
nodeState.on(EVENTS.NODE_UPGRADE_PROGRESS, (session) => onEvent(EVENTS.NODE_UPGRADE_PROGRESS, session));
|
|
213
|
+
nodeState.on(EVENTS.RELOAD_GATEWAY, (nodeInfo) => {
|
|
214
|
+
handleRouting(nodeInfo).catch((err) => {
|
|
215
|
+
logger.error('Handle routing failed on node.updated', { error: err });
|
|
216
|
+
});
|
|
217
|
+
});
|
|
212
218
|
|
|
213
219
|
domainStatus.on(EVENTS.DOMAIN_STATUS, (data) => {
|
|
214
220
|
if (data) {
|
|
@@ -230,5 +236,8 @@ module.exports = ({
|
|
|
230
236
|
events.handleServerEvent = handleServerEvent;
|
|
231
237
|
events.handleBlockletEvent = handleBlockletEvent;
|
|
232
238
|
|
|
239
|
+
certManager.on('cert.issued', (data) => onEvent(EVENTS.CERT_ISSUED, data));
|
|
240
|
+
certManager.on('cert.error', (data) => onEvent(EVENTS.CERT_ERROR, data));
|
|
241
|
+
|
|
233
242
|
return events;
|
|
234
243
|
};
|