@abtnode/core 1.7.7 → 1.7.10
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/team.js +14 -4
- package/lib/blocklet/manager/disk.js +123 -19
- package/lib/blocklet/migration.js +8 -0
- package/lib/cert.js +14 -0
- package/lib/event.js +14 -0
- package/lib/index.js +7 -2
- package/lib/migrations/1.0.21-update-config.js +1 -1
- package/lib/migrations/1.0.22-max-memory.js +1 -1
- package/lib/migrations/1.0.25.js +1 -1
- package/lib/migrations/1.0.32-update-config.js +1 -1
- package/lib/migrations/1.6.21-rename-ip-echo-domain.js +1 -1
- package/lib/migrations/1.6.4-security.js +1 -1
- package/lib/migrations/README.md +1 -1
- package/lib/router/helper.js +11 -90
- package/lib/router/index.js +1 -1
- package/lib/router/manager.js +3 -3
- package/lib/states/blocklet.js +18 -1
- package/lib/team/manager.js +13 -0
- package/lib/util/blocklet.js +12 -8
- package/lib/util/get-domain-for-blocklet.js +1 -1
- package/lib/util/index.js +2 -7
- package/package.json +23 -24
- package/lib/util/service.js +0 -81
package/lib/api/team.js
CHANGED
|
@@ -104,6 +104,19 @@ class TeamAPI extends EventEmitter {
|
|
|
104
104
|
return state.getUser(user.did);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
async getOwner({ teamDid }) {
|
|
108
|
+
const owner = await this.teamManager.getOwner(teamDid);
|
|
109
|
+
|
|
110
|
+
if (!owner) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const state = await this.getUserState(teamDid);
|
|
115
|
+
|
|
116
|
+
const full = await state.getUser(owner.did);
|
|
117
|
+
return full || owner;
|
|
118
|
+
}
|
|
119
|
+
|
|
107
120
|
async updateUser({ teamDid, user }) {
|
|
108
121
|
const state = await this.getUserState(teamDid);
|
|
109
122
|
|
|
@@ -211,7 +224,7 @@ class TeamAPI extends EventEmitter {
|
|
|
211
224
|
|
|
212
225
|
// Invite member
|
|
213
226
|
|
|
214
|
-
async createInvitation({ teamDid, role, remark
|
|
227
|
+
async createInvitation({ teamDid, role, remark }, context) {
|
|
215
228
|
await this.teamManager.checkEnablePassportIssuance(teamDid);
|
|
216
229
|
|
|
217
230
|
if (!role) {
|
|
@@ -242,7 +255,6 @@ class TeamAPI extends EventEmitter {
|
|
|
242
255
|
expireDate,
|
|
243
256
|
inviter: user,
|
|
244
257
|
teamDid,
|
|
245
|
-
interfaceName,
|
|
246
258
|
});
|
|
247
259
|
|
|
248
260
|
logger.info('Create invite member', { role, user, inviteId });
|
|
@@ -254,7 +266,6 @@ class TeamAPI extends EventEmitter {
|
|
|
254
266
|
expireDate: new Date(expireDate).toString(),
|
|
255
267
|
inviter: user,
|
|
256
268
|
teamDid,
|
|
257
|
-
interfaceName,
|
|
258
269
|
};
|
|
259
270
|
}
|
|
260
271
|
|
|
@@ -271,7 +282,6 @@ class TeamAPI extends EventEmitter {
|
|
|
271
282
|
expireDate: new Date(d.expireDate).toString(),
|
|
272
283
|
inviter: d.inviter,
|
|
273
284
|
teamDid: d.teamDid,
|
|
274
|
-
interfaceName: d.interfaceName,
|
|
275
285
|
}));
|
|
276
286
|
}
|
|
277
287
|
|
|
@@ -104,6 +104,7 @@ const blockletPm2Events = require('./pm2-events');
|
|
|
104
104
|
const { getFactoryState } = require('../../util/chain');
|
|
105
105
|
const runMigrationScripts = require('../migration');
|
|
106
106
|
const hooks = require('../hooks');
|
|
107
|
+
const { formatName } = require('../../util/get-domain-for-blocklet');
|
|
107
108
|
|
|
108
109
|
const {
|
|
109
110
|
isInProgress,
|
|
@@ -113,6 +114,7 @@ const {
|
|
|
113
114
|
shouldUpdateBlockletStatus,
|
|
114
115
|
getBlockletMeta,
|
|
115
116
|
validateBlockletMeta,
|
|
117
|
+
validateOwner,
|
|
116
118
|
} = util;
|
|
117
119
|
|
|
118
120
|
const preDownloadLock = new Lock('pre-download-lock');
|
|
@@ -255,7 +257,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
255
257
|
}
|
|
256
258
|
|
|
257
259
|
const blocklet = await states.blocklet.getBlocklet(meta.did);
|
|
258
|
-
const isRunning = blocklet
|
|
260
|
+
const isRunning = blocklet ? blocklet.status === BlockletStatus.running : false;
|
|
259
261
|
|
|
260
262
|
return { meta, isFree, isInstalled: !!blocklet, isRunning };
|
|
261
263
|
}
|
|
@@ -279,9 +281,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
279
281
|
return this._installFromStore({ did, registry }, { ...context, blockletPurchaseVerified: true });
|
|
280
282
|
}
|
|
281
283
|
|
|
282
|
-
async start({ did, checkHealthImmediately = false,
|
|
284
|
+
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
283
285
|
logger.info('start blocklet', { did });
|
|
284
|
-
const blocklet = await this.ensureBlocklet(did);
|
|
286
|
+
const blocklet = await this.ensureBlocklet(did, e2eMode);
|
|
285
287
|
|
|
286
288
|
try {
|
|
287
289
|
if (!hasRunnableComponent(blocklet)) {
|
|
@@ -319,6 +321,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
319
321
|
}),
|
|
320
322
|
nodeEnvironments,
|
|
321
323
|
nodeInfo: await states.node.read(),
|
|
324
|
+
e2eMode,
|
|
322
325
|
});
|
|
323
326
|
|
|
324
327
|
// check blocklet healthy
|
|
@@ -481,6 +484,40 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
481
484
|
}
|
|
482
485
|
}
|
|
483
486
|
|
|
487
|
+
async reset({ did }, context = {}) {
|
|
488
|
+
logger.info('reset blocklet', { did });
|
|
489
|
+
|
|
490
|
+
const blocklet = await this.ensureBlocklet(did);
|
|
491
|
+
|
|
492
|
+
if (isInProgress(blocklet.status)) {
|
|
493
|
+
throw new Error('Cannot reset when blocklet is in progress');
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
await this.deleteProcess({ did }, context);
|
|
498
|
+
} catch {
|
|
499
|
+
// do nothing
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// Cleanup disk storage
|
|
503
|
+
const { name } = blocklet.meta;
|
|
504
|
+
const dataDir = path.join(this.dataDirs.data, name);
|
|
505
|
+
const logsDir = path.join(this.dataDirs.logs, name);
|
|
506
|
+
const cacheDir = path.join(this.dataDirs.cache, name);
|
|
507
|
+
fs.removeSync(cacheDir);
|
|
508
|
+
fs.removeSync(dataDir);
|
|
509
|
+
fs.removeSync(logsDir);
|
|
510
|
+
|
|
511
|
+
// Reset config in db
|
|
512
|
+
await this._delExtras(did);
|
|
513
|
+
await this._setConfigs(did);
|
|
514
|
+
await this.updateBlockletEnvironment(did);
|
|
515
|
+
await this.resetSiteByDid(did, context);
|
|
516
|
+
|
|
517
|
+
logger.info('blocklet reset', { did });
|
|
518
|
+
return blocklet;
|
|
519
|
+
}
|
|
520
|
+
|
|
484
521
|
async deleteComponent({ did, rootDid }, context) {
|
|
485
522
|
logger.info('delete blocklet component', { did, rootDid });
|
|
486
523
|
|
|
@@ -590,7 +627,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
590
627
|
}
|
|
591
628
|
|
|
592
629
|
// eslint-disable-next-line no-unused-vars
|
|
593
|
-
async config({ did, childDid, configs: newConfigs }, context) {
|
|
630
|
+
async config({ did, childDid, configs: newConfigs, skipHook }, context) {
|
|
594
631
|
logger.info('config blocklet', { did });
|
|
595
632
|
if (!Array.isArray(newConfigs)) {
|
|
596
633
|
throw new Error('configs list is not an array');
|
|
@@ -657,15 +694,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
657
694
|
blocklet.configObj[x.key] = x.value;
|
|
658
695
|
}
|
|
659
696
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
697
|
+
if (!skipHook) {
|
|
698
|
+
// FIXME: we should also call preConfig for child blocklets
|
|
699
|
+
await hooks.preConfig(blocklet.env.appId, {
|
|
700
|
+
appDir: blocklet.env.appDir,
|
|
701
|
+
hooks: Object.assign(blocklet.meta.hooks || {}, blocklet.meta.scripts || {}),
|
|
702
|
+
exitOnError: true,
|
|
703
|
+
env: { ...getRuntimeEnvironments(blocklet, nodeEnvironments), ...blocklet.configObj },
|
|
704
|
+
did,
|
|
705
|
+
context,
|
|
706
|
+
});
|
|
707
|
+
}
|
|
669
708
|
|
|
670
709
|
// update db
|
|
671
710
|
const configs = childDid
|
|
@@ -928,14 +967,22 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
928
967
|
* After the dev function finished, the caller should send a BlockletEvents.deployed event to the daemon
|
|
929
968
|
* @returns {Object} blocklet
|
|
930
969
|
*/
|
|
931
|
-
async dev(folder) {
|
|
932
|
-
logger.info('dev
|
|
970
|
+
async dev(folder, { rootDid, mountPoint } = {}) {
|
|
971
|
+
logger.info('dev component', { folder, rootDid, mountPoint });
|
|
933
972
|
|
|
934
973
|
const meta = getBlockletMeta(folder);
|
|
935
974
|
if (meta.group !== 'static' && (!meta.scripts || !meta.scripts.dev)) {
|
|
936
975
|
throw new Error('Incorrect blocklet manifest: missing `scripts.dev` field');
|
|
937
976
|
}
|
|
938
977
|
|
|
978
|
+
if (rootDid) {
|
|
979
|
+
return this._devComponent({ folder, meta, rootDid, mountPoint });
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
return this._devBlocklet({ folder, meta });
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
async _devBlocklet({ folder, meta }) {
|
|
939
986
|
const { did, version } = meta;
|
|
940
987
|
|
|
941
988
|
const exist = await states.blocklet.getBlocklet(did);
|
|
@@ -990,7 +1037,58 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
990
1037
|
return blocklet;
|
|
991
1038
|
}
|
|
992
1039
|
|
|
993
|
-
async
|
|
1040
|
+
async _devComponent({ folder, meta, rootDid, mountPoint }) {
|
|
1041
|
+
const { did, version } = meta;
|
|
1042
|
+
|
|
1043
|
+
const existRoot = await states.blocklet.getBlocklet(rootDid);
|
|
1044
|
+
if (!existRoot) {
|
|
1045
|
+
throw new Error('Root blocklet does not exist');
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
const exist = existRoot.children.find((x) => x.meta.did === meta.did);
|
|
1049
|
+
if (exist) {
|
|
1050
|
+
if (exist.mode === BLOCKLET_MODES.PRODUCTION) {
|
|
1051
|
+
throw new Error('The blocklet component of production mode already exists, please remove it before developing');
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
const status = fromBlockletStatus(exist.status);
|
|
1055
|
+
if (['starting', 'running'].includes(status)) {
|
|
1056
|
+
throw new Error(`The blocklet component is already on ${status}, please stop it before developing`);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
logger.info('remove blocklet component for dev', { did, version });
|
|
1060
|
+
|
|
1061
|
+
await this.deleteComponent({ did, rootDid });
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
const defaultPath = formatName(meta.name);
|
|
1065
|
+
const children = await parseChildren(existRoot.meta, {
|
|
1066
|
+
children: [
|
|
1067
|
+
{
|
|
1068
|
+
meta,
|
|
1069
|
+
mountPoint: mountPoint || `/${defaultPath}`,
|
|
1070
|
+
source: BlockletSource.local,
|
|
1071
|
+
deployedFrom: folder,
|
|
1072
|
+
status: BlockletStatus.installed,
|
|
1073
|
+
mode: BLOCKLET_MODES.DEVELOPMENT,
|
|
1074
|
+
},
|
|
1075
|
+
],
|
|
1076
|
+
dynamic: true,
|
|
1077
|
+
});
|
|
1078
|
+
await states.blocklet.addChildren(rootDid, children);
|
|
1079
|
+
|
|
1080
|
+
logger.info('add blocklet component for dev', { did, version, meta });
|
|
1081
|
+
|
|
1082
|
+
// Add environments
|
|
1083
|
+
await this._setConfigs(rootDid);
|
|
1084
|
+
await this.updateBlockletEnvironment(rootDid);
|
|
1085
|
+
|
|
1086
|
+
const rootBlocklet = await this.ensureBlocklet(rootDid);
|
|
1087
|
+
|
|
1088
|
+
return rootBlocklet;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
async ensureBlocklet(did, e2eMode = false) {
|
|
994
1092
|
if (!isValidDid(did)) {
|
|
995
1093
|
throw new Error(`Blocklet did is invalid: ${did}`);
|
|
996
1094
|
}
|
|
@@ -1008,6 +1106,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1008
1106
|
...getBlockletDirs(blocklet, {
|
|
1009
1107
|
dataDirs: this.dataDirs,
|
|
1010
1108
|
ensure: true,
|
|
1109
|
+
e2eMode,
|
|
1011
1110
|
}),
|
|
1012
1111
|
};
|
|
1013
1112
|
|
|
@@ -1051,9 +1150,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1051
1150
|
return blocklet;
|
|
1052
1151
|
}
|
|
1053
1152
|
|
|
1054
|
-
async setInitialized({ did }) {
|
|
1153
|
+
async setInitialized({ did, owner }) {
|
|
1154
|
+
if (!validateOwner(owner)) {
|
|
1155
|
+
throw new Error('Blocklet owner is invalid');
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1055
1158
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
1056
|
-
await states.blockletExtras.setSettings(blocklet.meta.did, { initialized: true });
|
|
1159
|
+
await states.blockletExtras.setSettings(blocklet.meta.did, { initialized: true, owner });
|
|
1160
|
+
logger.info('Blocklet initialized', { did, owner });
|
|
1057
1161
|
|
|
1058
1162
|
this.emit(BlockletEvents.updated, { meta: { did: blocklet.meta.did } });
|
|
1059
1163
|
|
|
@@ -1736,7 +1840,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1736
1840
|
meta,
|
|
1737
1841
|
mountPoint,
|
|
1738
1842
|
source: BlockletSource.upload,
|
|
1739
|
-
deployedFrom: `Upload by ${context.user.
|
|
1843
|
+
deployedFrom: `Upload by ${context.user.fullName}`,
|
|
1740
1844
|
sourceUrl: '',
|
|
1741
1845
|
dynamic: true,
|
|
1742
1846
|
};
|
|
@@ -21,6 +21,7 @@ async function runScripts({
|
|
|
21
21
|
printSuccess,
|
|
22
22
|
printError,
|
|
23
23
|
}) {
|
|
24
|
+
// 获取所有待执行的脚本
|
|
24
25
|
let scripts = [];
|
|
25
26
|
try {
|
|
26
27
|
scripts = await getScripts(scriptsDir);
|
|
@@ -37,13 +38,17 @@ async function runScripts({
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
printInfo('pending scripts', pendingScripts);
|
|
41
|
+
// 执行脚本前需要对数据库文件做一次备份
|
|
40
42
|
try {
|
|
41
43
|
await doBackup({ dbDir, backupDir, printInfo, printSuccess, printError });
|
|
42
44
|
} catch (err) {
|
|
43
45
|
printError(`Failed to backup state db due to ${err.message}, abort!`);
|
|
46
|
+
// 备份失败时,需要移除备份目录
|
|
47
|
+
fs.removeSync(backupDir);
|
|
44
48
|
throw err;
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
// 按照顺序依次执行 migration 脚本
|
|
47
52
|
for (let i = 0; i < pendingScripts.length; i++) {
|
|
48
53
|
const { script: scriptPath } = pendingScripts[i];
|
|
49
54
|
try {
|
|
@@ -59,7 +64,10 @@ async function runScripts({
|
|
|
59
64
|
|
|
60
65
|
try {
|
|
61
66
|
await doRestore({ dbDir, backupDir, printInfo, printSuccess, printError });
|
|
67
|
+
// 恢复备份成功时,需要移除备份目录
|
|
68
|
+
fs.removeSync(backupDir);
|
|
62
69
|
} catch (restoreErr) {
|
|
70
|
+
// 如果恢复备份失败,则保留备份目录,恢复数据
|
|
63
71
|
printError(`Failed to restore state db due to: ${restoreErr.message}`);
|
|
64
72
|
}
|
|
65
73
|
|
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,11 +25,14 @@ 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;
|
|
31
32
|
|
|
32
33
|
const events = new EventEmitter();
|
|
34
|
+
events.setMaxListeners(0);
|
|
35
|
+
|
|
33
36
|
// HACK: do not emit any events from CLI
|
|
34
37
|
if (isCLI() && process.env.NODE_ENV !== 'test') {
|
|
35
38
|
events.emit = (name) => logger.debug('stopped core state event in CLI', name);
|
|
@@ -123,6 +126,14 @@ module.exports = ({
|
|
|
123
126
|
await teamAPI.refreshBlockletInterfacePermissions(blocklet.meta);
|
|
124
127
|
} catch (error) {
|
|
125
128
|
logger.error('upgrade blocklet routing rules error', { event: name, error });
|
|
129
|
+
notificationState.create({
|
|
130
|
+
title: 'Blocklet URL Mapping Error',
|
|
131
|
+
// eslint-disable-next-line max-len
|
|
132
|
+
description: `Failed to upgrade URL mapping for blocklet ${blocklet.meta.name}@${blocklet.meta.version}, due to: ${error.message}`,
|
|
133
|
+
entityType: 'blocklet',
|
|
134
|
+
entityId: blocklet.meta.did,
|
|
135
|
+
severity: 'error',
|
|
136
|
+
});
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
try {
|
|
@@ -220,5 +231,8 @@ module.exports = ({
|
|
|
220
231
|
events.handleServerEvent = handleServerEvent;
|
|
221
232
|
events.handleBlockletEvent = handleBlockletEvent;
|
|
222
233
|
|
|
234
|
+
certManager.on('cert.issued', (data) => onEvent(EVENTS.CERT_ISSUED, data));
|
|
235
|
+
certManager.on('cert.error', (data) => onEvent(EVENTS.CERT_ERROR, data));
|
|
236
|
+
|
|
223
237
|
return events;
|
|
224
238
|
};
|
package/lib/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
fromBlockletSource,
|
|
11
11
|
toBlockletSource,
|
|
12
12
|
} = require('@blocklet/meta/lib/constants');
|
|
13
|
+
const { getServiceMetas } = require('@blocklet/meta/lib/service');
|
|
13
14
|
const { listProviders } = require('@abtnode/router-provider');
|
|
14
15
|
const { DEFAULT_CERTIFICATE_EMAIL, EVENTS } = require('@abtnode/constant');
|
|
15
16
|
|
|
@@ -29,7 +30,6 @@ const IP = require('./util/ip');
|
|
|
29
30
|
const DomainStatus = require('./util/domain-status');
|
|
30
31
|
const Upgrade = require('./util/upgrade');
|
|
31
32
|
const resetNode = require('./util/reset-node');
|
|
32
|
-
const { getServices } = require('./util/service');
|
|
33
33
|
const DiskMonitor = require('./util/disk-monitor');
|
|
34
34
|
const createQueue = require('./queue');
|
|
35
35
|
const createEvents = require('./event');
|
|
@@ -133,11 +133,13 @@ function ABTNode(options) {
|
|
|
133
133
|
registry: blockletRegistry,
|
|
134
134
|
daemon: options.daemon,
|
|
135
135
|
});
|
|
136
|
+
blockletManager.setMaxListeners(0);
|
|
136
137
|
|
|
137
138
|
const {
|
|
138
139
|
handleRouting,
|
|
139
140
|
getRoutingRulesByDid,
|
|
140
141
|
getSiteByDid,
|
|
142
|
+
resetSiteByDid,
|
|
141
143
|
updateNodeRouting,
|
|
142
144
|
takeRoutingSnapshot,
|
|
143
145
|
getRoutingSites,
|
|
@@ -159,6 +161,7 @@ function ABTNode(options) {
|
|
|
159
161
|
|
|
160
162
|
blockletManager.getRoutingRulesByDid = getRoutingRulesByDid;
|
|
161
163
|
blockletManager.getSiteByDid = getSiteByDid;
|
|
164
|
+
blockletManager.resetSiteByDid = resetSiteByDid;
|
|
162
165
|
|
|
163
166
|
// Generate an on node ready callback
|
|
164
167
|
const onStatesReady = createStateReadyQueue({ states, options, dataDirs });
|
|
@@ -216,6 +219,7 @@ function ABTNode(options) {
|
|
|
216
219
|
updateChildBlocklets: blockletManager.updateChildren.bind(blockletManager),
|
|
217
220
|
getLatestBlockletVersion: blockletManager.getLatestBlockletVersion.bind(blockletManager),
|
|
218
221
|
getBlockletMetaFromUrl: blockletManager.getMetaFromUrl.bind(blockletManager),
|
|
222
|
+
resetBlocklet: blockletManager.reset.bind(blockletManager),
|
|
219
223
|
|
|
220
224
|
deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
|
|
221
225
|
|
|
@@ -261,6 +265,7 @@ function ABTNode(options) {
|
|
|
261
265
|
getUsers: teamAPI.getUsers.bind(teamAPI),
|
|
262
266
|
getUsersCount: teamAPI.getUsersCount.bind(teamAPI),
|
|
263
267
|
getUser: teamAPI.getUser.bind(teamAPI),
|
|
268
|
+
getOwner: teamAPI.getOwner.bind(teamAPI),
|
|
264
269
|
getNodeUsers: () => teamAPI.getUsers({ teamDid: options.nodeDid }),
|
|
265
270
|
getNodeUser: (user) => teamAPI.getUser({ teamDid: options.nodeDid, user }),
|
|
266
271
|
addUser: teamAPI.addUser.bind(teamAPI),
|
|
@@ -372,7 +377,7 @@ function ABTNode(options) {
|
|
|
372
377
|
endSession: (params, context) => states.session.end(params.id, context),
|
|
373
378
|
|
|
374
379
|
// Services
|
|
375
|
-
getServices: (params, context) =>
|
|
380
|
+
getServices: (params, context) => getServiceMetas({ stringifySchema: true }, context),
|
|
376
381
|
|
|
377
382
|
// Utilities: moved here because some deps require native build
|
|
378
383
|
getSysInfo,
|
|
@@ -7,7 +7,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
|
|
|
7
7
|
printInfo('Try to update node config to 1.0.21...');
|
|
8
8
|
let changed = false;
|
|
9
9
|
|
|
10
|
-
const rawConfig = yaml.
|
|
10
|
+
const rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
11
11
|
const info = await states.node.read();
|
|
12
12
|
|
|
13
13
|
const updates = [
|
|
@@ -13,7 +13,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
|
|
|
13
13
|
printInfo('Try to update node config to 1.0.22...');
|
|
14
14
|
let changed = false;
|
|
15
15
|
|
|
16
|
-
const rawConfig = yaml.
|
|
16
|
+
const rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
17
17
|
const info = await states.node.read();
|
|
18
18
|
|
|
19
19
|
const updates = [
|
package/lib/migrations/1.0.25.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
|
|
|
10
10
|
printInfo('Try to update node config to 1.0.25...');
|
|
11
11
|
let changed = false;
|
|
12
12
|
|
|
13
|
-
const rawConfig = yaml.
|
|
13
|
+
const rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
14
14
|
const info = await states.node.read();
|
|
15
15
|
|
|
16
16
|
const updates = [
|
|
@@ -7,7 +7,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
|
|
|
7
7
|
printInfo('Try to update node config to 1.0.32...');
|
|
8
8
|
let changed = false;
|
|
9
9
|
|
|
10
|
-
const rawConfig = yaml.
|
|
10
|
+
const rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
11
11
|
const info = await states.node.read();
|
|
12
12
|
|
|
13
13
|
const updates = [{ key: 'routing.https', value: true }];
|
|
@@ -22,7 +22,7 @@ module.exports = async ({ states, printInfo, configFile }) => {
|
|
|
22
22
|
await states.node.updateNodeInfo(info);
|
|
23
23
|
|
|
24
24
|
if (process.env.NODE_ENV !== 'development') {
|
|
25
|
-
let rawConfig = yaml.
|
|
25
|
+
let rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
26
26
|
set(rawConfig, 'node.routing.ipWildcardDomain', info.routing.ipWildcardDomain);
|
|
27
27
|
set(rawConfig, 'node.routing.wildcardCertHost', DEFAULT_WILDCARD_CERT_HOST);
|
|
28
28
|
set(rawConfig, 'node.didDomain', DEFAULT_DID_DOMAIN);
|
|
@@ -19,7 +19,7 @@ module.exports = async ({ states, configFile, dataDir }) => {
|
|
|
19
19
|
try {
|
|
20
20
|
fs.writeFileSync(file, crypto.randomBytes(32), { encoding: 'binary', mode: '0600' });
|
|
21
21
|
|
|
22
|
-
const config = yaml.
|
|
22
|
+
const config = yaml.load(fs.readFileSync(configFile).toString(), { json: true });
|
|
23
23
|
config.node.sk = security.encrypt(config.node.sk, config.node.did, fs.readFileSync(file));
|
|
24
24
|
fs.writeFileSync(configFile, yaml.dump(config));
|
|
25
25
|
await states.node.updateNodeInfo({ sk: config.node.sk });
|
package/lib/migrations/README.md
CHANGED
|
@@ -41,7 +41,7 @@ module.exports = async ({ states, config, configFile, printInfo }) => {
|
|
|
41
41
|
printInfo('Try to update node config to 1.0.21...');
|
|
42
42
|
let changed = false;
|
|
43
43
|
|
|
44
|
-
const rawConfig = yaml.
|
|
44
|
+
const rawConfig = yaml.load(fs.readFileSync(configFile).toString());
|
|
45
45
|
const info = await states.node.read();
|
|
46
46
|
|
|
47
47
|
const updates = [
|
package/lib/router/helper.js
CHANGED
|
@@ -863,88 +863,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
863
863
|
return changes.some(Boolean);
|
|
864
864
|
};
|
|
865
865
|
|
|
866
|
-
/**
|
|
867
|
-
* Add system routing rules for blocklet in dashboard site
|
|
868
|
-
*
|
|
869
|
-
* @returns {boolean} if routing changed
|
|
870
|
-
* TODO: do we still need this?
|
|
871
|
-
*/
|
|
872
|
-
const _ensureBlockletRulesForDashboardSite = async (blocklet, sites, nodeInfo, context = {}) => {
|
|
873
|
-
// blocklet level duplication detection
|
|
874
|
-
const findRulesByInterface = (site, value) =>
|
|
875
|
-
site.rules.filter((x) => x.isProtected && x.to.did === blocklet.meta.did && get(x, 'to.interfaceName') === value);
|
|
876
|
-
|
|
877
|
-
const ipSite = sites.find((x) => x.domain === DOMAIN_FOR_IP_SITE);
|
|
878
|
-
if (!ipSite) {
|
|
879
|
-
logger.warn(`Routing rule for dashboard not found, abort on ensure rules for blocklet ${blocklet.meta.did}`);
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// If we have rule for legacy path prefix, just return
|
|
884
|
-
const pathPrefixLegacy = normalizePathPrefix(`/${nodeInfo.routing.adminPath}/${blocklet.meta.name}`);
|
|
885
|
-
if (hasRuleByPrefix(ipSite, pathPrefixLegacy)) {
|
|
886
|
-
return false;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
const removedRuleIds = [];
|
|
890
|
-
const changes = await Promise.all(
|
|
891
|
-
blocklet.meta.interfaces.map(async (x) => {
|
|
892
|
-
let changed = false; // if state db was mutated
|
|
893
|
-
let pathPrefix = '';
|
|
894
|
-
if (x.prefix === BLOCKLET_DYNAMIC_PATH_PREFIX) {
|
|
895
|
-
// pathPrefix for dynamic path: `/{adminPath}/{blockletName}/{interfaceName}`
|
|
896
|
-
pathPrefix = normalizePathPrefix(`/${pathPrefixLegacy}/${x.name}`);
|
|
897
|
-
} else {
|
|
898
|
-
// pathPrefix for fixed path: `/{interfacePrefix}`
|
|
899
|
-
pathPrefix = normalizePathPrefix(x.prefix);
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
// Remove if we have rule with same interface
|
|
903
|
-
const exists = findRulesByInterface(ipSite, x.name);
|
|
904
|
-
if (exists.length) {
|
|
905
|
-
// Note: we need to keep a list of removed rules since we might remove multiple rules in the loop
|
|
906
|
-
exists.forEach((e) => removedRuleIds.push(e.id));
|
|
907
|
-
await states.site.update(
|
|
908
|
-
{ _id: ipSite.id },
|
|
909
|
-
{ $set: { rules: ipSite.rules.filter((r) => removedRuleIds.includes(r.id) === false) } }
|
|
910
|
-
);
|
|
911
|
-
changed = true;
|
|
912
|
-
} else if (hasRuleByPrefix(ipSite, pathPrefix)) {
|
|
913
|
-
// Skip same pathPrefix rules
|
|
914
|
-
return changed;
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
// 不在 dashboard site 中添加 path 和 prefix 都是根路径(/) 的路由
|
|
918
|
-
if (x.path === '/' && x.prefix === '/') {
|
|
919
|
-
return changed;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
await routerManager.addRoutingRule(
|
|
923
|
-
{
|
|
924
|
-
id: ipSite.id,
|
|
925
|
-
rule: {
|
|
926
|
-
from: { pathPrefix },
|
|
927
|
-
to: {
|
|
928
|
-
type: ROUTING_RULE_TYPES.BLOCKLET,
|
|
929
|
-
port: findInterfacePortByName(blocklet, x.name),
|
|
930
|
-
did: blocklet.meta.did, // root blocklet did
|
|
931
|
-
interfaceName: x.name, // root blocklet interface
|
|
932
|
-
},
|
|
933
|
-
isProtected: true,
|
|
934
|
-
},
|
|
935
|
-
skipCheckDynamicBlacklist: true,
|
|
936
|
-
},
|
|
937
|
-
context
|
|
938
|
-
);
|
|
939
|
-
changed = true;
|
|
940
|
-
|
|
941
|
-
return changed;
|
|
942
|
-
})
|
|
943
|
-
);
|
|
944
|
-
|
|
945
|
-
return changes.some(Boolean);
|
|
946
|
-
};
|
|
947
|
-
|
|
948
866
|
const _removeBlockletSites = async (blocklet, nodeInfo, context = {}) => {
|
|
949
867
|
let changed = false;
|
|
950
868
|
|
|
@@ -980,14 +898,6 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
980
898
|
_ensureBlockletSites(blocklet, sites, nodeInfo, context),
|
|
981
899
|
];
|
|
982
900
|
|
|
983
|
-
if (nodeInfo.mode === NODE_MODES.DEBUG || ['e2e', 'test'].includes(process.env.NODE_ENV)) {
|
|
984
|
-
logger.info('Add blocklet endpoint in dashboard site', {
|
|
985
|
-
nodeMode: nodeInfo.mode,
|
|
986
|
-
NODE_ENV: process.env.NODE_ENV,
|
|
987
|
-
});
|
|
988
|
-
tasks.push(_ensureBlockletRulesForDashboardSite(blocklet, sites, nodeInfo, context));
|
|
989
|
-
}
|
|
990
|
-
|
|
991
901
|
const changes = await Promise.all(tasks);
|
|
992
902
|
|
|
993
903
|
return changes.some(Boolean);
|
|
@@ -1131,6 +1041,16 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1131
1041
|
return (sites || []).find((x) => x.domain === domain);
|
|
1132
1042
|
}
|
|
1133
1043
|
|
|
1044
|
+
async function resetSiteByDid(did, { refreshRouterProvider = true } = {}) {
|
|
1045
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
1046
|
+
await removeBlockletRouting(blocklet);
|
|
1047
|
+
await ensureBlockletRouting(blocklet);
|
|
1048
|
+
if (refreshRouterProvider) {
|
|
1049
|
+
const hash = await takeRoutingSnapshot({ message: `Reset blocklet ${did}`, dryRun: false });
|
|
1050
|
+
logger.info('reset blocklet routing rules', { did, hash });
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1134
1054
|
const providers = {}; // we need to keep reference for different router instances
|
|
1135
1055
|
const handleRouting = async (nodeInfo) => {
|
|
1136
1056
|
const providerName = get(nodeInfo, 'routing.provider', null);
|
|
@@ -1382,6 +1302,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1382
1302
|
handleRouting,
|
|
1383
1303
|
getRoutingRulesByDid,
|
|
1384
1304
|
getSiteByDid,
|
|
1305
|
+
resetSiteByDid,
|
|
1385
1306
|
updateNodeRouting,
|
|
1386
1307
|
takeRoutingSnapshot,
|
|
1387
1308
|
getRoutingSites,
|
package/lib/router/index.js
CHANGED
|
@@ -110,7 +110,7 @@ class Router {
|
|
|
110
110
|
await this.provider.update({
|
|
111
111
|
routingTable: this.routingTable,
|
|
112
112
|
certificates,
|
|
113
|
-
|
|
113
|
+
commonHeaders: headers,
|
|
114
114
|
services,
|
|
115
115
|
nodeInfo: pick(nodeInfo, ['name', 'version', 'port', 'mode', 'enableWelcomePage', 'routing']),
|
|
116
116
|
});
|
package/lib/router/manager.js
CHANGED
|
@@ -222,7 +222,7 @@ class RouterManager extends EventEmitter {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
// let custom domain in front of protected domain
|
|
225
|
-
const domainAliases = [{ value: domainAlias, isProtected: false }, ...dbSite.domainAliases];
|
|
225
|
+
const domainAliases = [{ value: domainAlias, isProtected: false }, ...(dbSite.domainAliases || [])];
|
|
226
226
|
|
|
227
227
|
const updateResult = await states.site.update({ _id: id }, { $set: { domainAliases } });
|
|
228
228
|
logger.debug('add domain alias update result', { id, updateResult, domainAlias });
|
|
@@ -420,7 +420,7 @@ class RouterManager extends EventEmitter {
|
|
|
420
420
|
}
|
|
421
421
|
|
|
422
422
|
async getMatchedCert(domain) {
|
|
423
|
-
const certs = await this.certManager.
|
|
423
|
+
const certs = await this.certManager.getAllNormal();
|
|
424
424
|
const matchedCert = certs.find((cert) => this.isCertMatchedDomain(cert, domain));
|
|
425
425
|
|
|
426
426
|
if (matchedCert) {
|
|
@@ -546,7 +546,7 @@ class RouterManager extends EventEmitter {
|
|
|
546
546
|
getRoutingParams: async () => ({
|
|
547
547
|
sites: await ensureLatestInfo(sites),
|
|
548
548
|
certificates,
|
|
549
|
-
|
|
549
|
+
commonHeaders: get(info, 'routing.headers', {}),
|
|
550
550
|
services: [], // TODO: do we need to add some item here?
|
|
551
551
|
nodeInfo: info,
|
|
552
552
|
}),
|
package/lib/states/blocklet.js
CHANGED
|
@@ -66,6 +66,16 @@ const formatBlocklet = (blocklet, phase, dek) => {
|
|
|
66
66
|
return blocklet;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
const fixChildren = (children) => {
|
|
70
|
+
if (!children) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
children.forEach((child) => {
|
|
75
|
+
child.mode = child.mode || BLOCKLET_MODES.PRODUCTION;
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
69
79
|
class BlockletState extends BaseState {
|
|
70
80
|
/**
|
|
71
81
|
* Creates an instance of BlockletState
|
|
@@ -163,6 +173,8 @@ class BlockletState extends BaseState {
|
|
|
163
173
|
defaultPort: getMaxPort(ports),
|
|
164
174
|
});
|
|
165
175
|
|
|
176
|
+
fixChildren(children);
|
|
177
|
+
|
|
166
178
|
// add to db
|
|
167
179
|
this.db.insert(
|
|
168
180
|
{
|
|
@@ -244,6 +256,8 @@ class BlockletState extends BaseState {
|
|
|
244
256
|
logger.info('Fill children ports when when upgrading blocklet', { name: doc.meta.name, did: doc.meta.did });
|
|
245
257
|
await this.fillChildrenPorts(children, { oldChildren: doc.children, defaultPort: getMaxPort(ports) });
|
|
246
258
|
|
|
259
|
+
fixChildren(children);
|
|
260
|
+
|
|
247
261
|
// add to db
|
|
248
262
|
const newDoc = await this.updateBlocklet(meta.did, {
|
|
249
263
|
meta: omit(sanitized, ['htmlAst']),
|
|
@@ -506,7 +520,7 @@ class BlockletState extends BaseState {
|
|
|
506
520
|
|
|
507
521
|
const newChildren = [...oldChildren];
|
|
508
522
|
for (const child of children) {
|
|
509
|
-
const { meta, mountPoint, sourceUrl = '', source = '', deployedFrom = '' } = child;
|
|
523
|
+
const { meta, mountPoint, sourceUrl = '', source = '', deployedFrom = '', mode } = child;
|
|
510
524
|
|
|
511
525
|
if (!mountPoint) {
|
|
512
526
|
throw new Error(`mountPoint is required when adding component ${getDisplayName(child, true)}`);
|
|
@@ -524,9 +538,12 @@ class BlockletState extends BaseState {
|
|
|
524
538
|
sourceUrl,
|
|
525
539
|
source,
|
|
526
540
|
deployedFrom,
|
|
541
|
+
mode,
|
|
527
542
|
dynamic: true,
|
|
528
543
|
status: BlockletStatus.added,
|
|
529
544
|
});
|
|
545
|
+
|
|
546
|
+
fixChildren(newChildren);
|
|
530
547
|
}
|
|
531
548
|
|
|
532
549
|
// use upgradeBlocklet to assign ports to children and write new data to db
|
package/lib/team/manager.js
CHANGED
|
@@ -267,6 +267,19 @@ class TeamManager extends EventEmitter {
|
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
async getOwner(did) {
|
|
271
|
+
let owner;
|
|
272
|
+
if (this.isNodeTeam(did)) {
|
|
273
|
+
const nodeInfo = await this.states.node.read();
|
|
274
|
+
owner = get(nodeInfo, 'nodeOwner');
|
|
275
|
+
} else {
|
|
276
|
+
const settings = await this.states.blockletExtras.getSettings(did);
|
|
277
|
+
owner = get(settings, 'owner');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return owner;
|
|
281
|
+
}
|
|
282
|
+
|
|
270
283
|
// =======
|
|
271
284
|
// Private
|
|
272
285
|
// =======
|
package/lib/util/blocklet.js
CHANGED
|
@@ -48,7 +48,6 @@ const { validate: validateEngine, get: getEngine } = require('../blocklet/manage
|
|
|
48
48
|
|
|
49
49
|
const isRequirementsSatisfied = require('./requirement');
|
|
50
50
|
const { getDidDomainForBlocklet } = require('./get-domain-for-blocklet');
|
|
51
|
-
const { getServices } = require('./service');
|
|
52
51
|
const {
|
|
53
52
|
isBeforeInstalled,
|
|
54
53
|
expandBundle,
|
|
@@ -104,7 +103,7 @@ const PRIVATE_NODE_ENVS = [
|
|
|
104
103
|
* appMain: app entry file or script (run appMain to start blocklet process)
|
|
105
104
|
* appCwd: cwd of appMain
|
|
106
105
|
*/
|
|
107
|
-
const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } = {}) => {
|
|
106
|
+
const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false, e2eMode = false } = {}) => {
|
|
108
107
|
if (!rootBlocklet) {
|
|
109
108
|
// eslint-disable-next-line no-param-reassign
|
|
110
109
|
rootBlocklet = blocklet;
|
|
@@ -126,8 +125,13 @@ const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } =
|
|
|
126
125
|
|
|
127
126
|
const { main, group } = blocklet.meta;
|
|
128
127
|
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
let startFromDevEntry = '';
|
|
129
|
+
if (blocklet.mode === BLOCKLET_MODES.DEVELOPMENT && blocklet.meta.scripts) {
|
|
130
|
+
startFromDevEntry = blocklet.meta.scripts.dev;
|
|
131
|
+
if (e2eMode && blocklet.meta.scripts.e2eDev) {
|
|
132
|
+
startFromDevEntry = blocklet.meta.scripts.e2eDev;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
131
135
|
|
|
132
136
|
if (!main && !startFromDevEntry && group !== BlockletGroup.gateway) {
|
|
133
137
|
throw new Error('Incorrect blocklet manifest: missing `main` field');
|
|
@@ -174,7 +178,7 @@ const getBlockletDirs = (blocklet, { rootBlocklet, dataDirs, ensure = false } =
|
|
|
174
178
|
let appMain = null;
|
|
175
179
|
let appCwd = null;
|
|
176
180
|
if (startFromDevEntry) {
|
|
177
|
-
appMain =
|
|
181
|
+
appMain = startFromDevEntry;
|
|
178
182
|
appCwd = appDir;
|
|
179
183
|
} else if (group === 'dapp') {
|
|
180
184
|
appMain = getBlockletEngine(blocklet.meta).script || BLOCKLET_ENTRY_FILE;
|
|
@@ -414,7 +418,7 @@ const getBlockletMetaFromUrl = async (url) => {
|
|
|
414
418
|
* Start all precesses of a blocklet
|
|
415
419
|
* @param {*} blocklet should contain env props
|
|
416
420
|
*/
|
|
417
|
-
const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironments, nodeInfo } = {}) => {
|
|
421
|
+
const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironments, nodeInfo, e2eMode } = {}) => {
|
|
418
422
|
if (!blocklet) {
|
|
419
423
|
throw new Error('blocklet should not be empty');
|
|
420
424
|
}
|
|
@@ -463,7 +467,7 @@ const startBlockletProcess = async (blocklet, { preStart = noop, nodeEnvironment
|
|
|
463
467
|
}
|
|
464
468
|
|
|
465
469
|
if (b.mode === BLOCKLET_MODES.DEVELOPMENT) {
|
|
466
|
-
options.env.NODE_ENV = 'development';
|
|
470
|
+
options.env.NODE_ENV = e2eMode ? 'e2e' : 'development';
|
|
467
471
|
options.env.BROWSER = 'none';
|
|
468
472
|
options.env.PORT = options.env[BLOCKLET_DEFAULT_PORT_NAME];
|
|
469
473
|
options.script = appMain;
|
|
@@ -1019,7 +1023,7 @@ const fixAndVerifyBlockletMeta = (meta, did) => {
|
|
|
1019
1023
|
}
|
|
1020
1024
|
|
|
1021
1025
|
// this step comes last because it has side effects: the meta is changed
|
|
1022
|
-
return fixAndValidateService(meta
|
|
1026
|
+
return fixAndValidateService(meta);
|
|
1023
1027
|
};
|
|
1024
1028
|
|
|
1025
1029
|
const getUpdateMetaList = (oldMetas = [], newMetas = []) => {
|
|
@@ -23,4 +23,4 @@ const getDidDomainForBlocklet = ({ name, daemonDid, didDomain }) => {
|
|
|
23
23
|
return `${prefix}-${daemonDid.toLowerCase()}.${didDomain}`;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
module.exports = { getIpDnsDomainForBlocklet, getDidDomainForBlocklet };
|
|
26
|
+
module.exports = { getIpDnsDomainForBlocklet, getDidDomainForBlocklet, formatName };
|
package/lib/util/index.js
CHANGED
|
@@ -35,7 +35,6 @@ const DEFAULT_WELLKNOWN_PORT = 8088;
|
|
|
35
35
|
|
|
36
36
|
const logger = require('@abtnode/logger')('@abtnode/core:util');
|
|
37
37
|
|
|
38
|
-
const { getServices } = require('./service');
|
|
39
38
|
const request = require('./request');
|
|
40
39
|
|
|
41
40
|
const validateOwner = (owner) => {
|
|
@@ -496,13 +495,9 @@ const lib = {
|
|
|
496
495
|
ensureDataDirs,
|
|
497
496
|
getDataDirs,
|
|
498
497
|
getBaseUrls,
|
|
499
|
-
getBlockletMeta:
|
|
500
|
-
parseBlockletMeta(dir, {
|
|
501
|
-
serviceMetas: getServices(),
|
|
502
|
-
...opts,
|
|
503
|
-
}),
|
|
498
|
+
getBlockletMeta: parseBlockletMeta,
|
|
504
499
|
validateBlockletMeta: (meta, opts = {}) => {
|
|
505
|
-
fixAndValidateService(meta
|
|
500
|
+
fixAndValidateService(meta);
|
|
506
501
|
return validateMeta(meta, opts);
|
|
507
502
|
},
|
|
508
503
|
getBlockletMetaByUrl,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.7.
|
|
6
|
+
"version": "1.7.10",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,32 +19,31 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/certificate-manager": "1.7.
|
|
23
|
-
"@abtnode/constant": "1.7.
|
|
24
|
-
"@abtnode/cron": "1.7.
|
|
25
|
-
"@abtnode/db": "1.7.
|
|
26
|
-
"@abtnode/logger": "1.7.
|
|
27
|
-
"@abtnode/queue": "1.7.
|
|
28
|
-
"@abtnode/rbac": "1.7.
|
|
29
|
-
"@abtnode/router-provider": "1.7.
|
|
30
|
-
"@abtnode/static-server": "1.7.
|
|
31
|
-
"@abtnode/timemachine": "1.7.
|
|
32
|
-
"@abtnode/util": "1.7.
|
|
33
|
-
"@arcblock/did": "^1.16.
|
|
34
|
-
"@arcblock/did-motif": "^1.1.
|
|
35
|
-
"@arcblock/event-hub": "1.16.
|
|
22
|
+
"@abtnode/certificate-manager": "1.7.10",
|
|
23
|
+
"@abtnode/constant": "1.7.10",
|
|
24
|
+
"@abtnode/cron": "1.7.10",
|
|
25
|
+
"@abtnode/db": "1.7.10",
|
|
26
|
+
"@abtnode/logger": "1.7.10",
|
|
27
|
+
"@abtnode/queue": "1.7.10",
|
|
28
|
+
"@abtnode/rbac": "1.7.10",
|
|
29
|
+
"@abtnode/router-provider": "1.7.10",
|
|
30
|
+
"@abtnode/static-server": "1.7.10",
|
|
31
|
+
"@abtnode/timemachine": "1.7.10",
|
|
32
|
+
"@abtnode/util": "1.7.10",
|
|
33
|
+
"@arcblock/did": "^1.16.5",
|
|
34
|
+
"@arcblock/did-motif": "^1.1.5",
|
|
35
|
+
"@arcblock/event-hub": "1.16.5",
|
|
36
36
|
"@arcblock/pm2-events": "^0.0.5",
|
|
37
|
-
"@arcblock/vc": "^1.16.
|
|
38
|
-
"@blocklet/meta": "1.7.
|
|
37
|
+
"@arcblock/vc": "^1.16.5",
|
|
38
|
+
"@blocklet/meta": "1.7.10",
|
|
39
39
|
"@fidm/x509": "^1.2.1",
|
|
40
40
|
"@nedb/core": "^1.2.2",
|
|
41
41
|
"@nedb/multi": "^1.2.2",
|
|
42
|
-
"@ocap/mcrypto": "^1.16.
|
|
43
|
-
"@ocap/util": "^1.16.
|
|
44
|
-
"@ocap/wallet": "^1.16.
|
|
42
|
+
"@ocap/mcrypto": "^1.16.5",
|
|
43
|
+
"@ocap/util": "^1.16.5",
|
|
44
|
+
"@ocap/wallet": "^1.16.5",
|
|
45
45
|
"@slack/webhook": "^5.0.3",
|
|
46
|
-
"
|
|
47
|
-
"axios": "^0.25.0",
|
|
46
|
+
"axios": "^0.26.1",
|
|
48
47
|
"axon": "^2.0.3",
|
|
49
48
|
"chalk": "^4.0.0",
|
|
50
49
|
"deep-diff": "^1.0.2",
|
|
@@ -56,7 +55,7 @@
|
|
|
56
55
|
"is-ip": "^3.1.0",
|
|
57
56
|
"is-url": "^1.2.4",
|
|
58
57
|
"joi": "^17.6.0",
|
|
59
|
-
"js-yaml": "^
|
|
58
|
+
"js-yaml": "^4.1.0",
|
|
60
59
|
"lodash": "^4.17.21",
|
|
61
60
|
"lru-cache": "^6.0.0",
|
|
62
61
|
"pm2": "^5.1.2",
|
|
@@ -78,5 +77,5 @@
|
|
|
78
77
|
"express": "^4.17.1",
|
|
79
78
|
"jest": "^27.4.5"
|
|
80
79
|
},
|
|
81
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "8eab10fd39b6183a2fa4d2706f52e8b2ecaa059a"
|
|
82
81
|
}
|
package/lib/util/service.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const cloneDeep = require('lodash/cloneDeep');
|
|
3
|
-
const Ajv = require('ajv').default;
|
|
4
|
-
|
|
5
|
-
const { NODE_SERVICES } = require('@abtnode/constant');
|
|
6
|
-
|
|
7
|
-
const ajv = new Ajv({
|
|
8
|
-
useDefaults: true,
|
|
9
|
-
removeAdditional: 'all',
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const SERVICES = {
|
|
13
|
-
AUTH: fs.readJSONSync(require.resolve('@abtnode/blocklet-services/configs/auth.json')),
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const getServices = ({ stringifySchema = false } = {}) => {
|
|
17
|
-
const list = Object.values(SERVICES).map((x) => {
|
|
18
|
-
const data = cloneDeep(x);
|
|
19
|
-
if (stringifySchema) {
|
|
20
|
-
data.schema = JSON.stringify(x.schema);
|
|
21
|
-
}
|
|
22
|
-
return data;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// backward compatible
|
|
26
|
-
const authService = cloneDeep(list.find((x) => x.name === NODE_SERVICES.AUTH));
|
|
27
|
-
authService.name = NODE_SERVICES.AUTH_SERVICE;
|
|
28
|
-
list.push(authService);
|
|
29
|
-
|
|
30
|
-
return list;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const getServiceMeta = (serviceName) => {
|
|
34
|
-
if (!serviceName) {
|
|
35
|
-
throw new Error('service name should not be empty');
|
|
36
|
-
}
|
|
37
|
-
const metas = getServices();
|
|
38
|
-
const meta = metas.find((x) => x.name === serviceName);
|
|
39
|
-
if (!meta) {
|
|
40
|
-
throw new Error(`service ${serviceName} does not exist`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return meta;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const getServiceConfig = (service, customConfig) => {
|
|
47
|
-
const serviceMeta = typeof service === 'string' ? getServiceMeta(service) : service;
|
|
48
|
-
|
|
49
|
-
const validate = ajv.compile(serviceMeta.schema.JSONSchema);
|
|
50
|
-
|
|
51
|
-
const data = cloneDeep(customConfig || {});
|
|
52
|
-
// this method may have side effect thar will fill default value to customConfig
|
|
53
|
-
validate(data || {});
|
|
54
|
-
|
|
55
|
-
return data;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const getDefaultServiceConfig = (service) => {
|
|
59
|
-
const serviceMeta = typeof service === 'string' ? getServiceMeta(service) : service;
|
|
60
|
-
|
|
61
|
-
// parse empty custom config to get default config
|
|
62
|
-
return getServiceConfig(serviceMeta, {});
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const findService = (services, name) => {
|
|
66
|
-
const names = [name];
|
|
67
|
-
|
|
68
|
-
// backward compatible
|
|
69
|
-
if (name === NODE_SERVICES.AUTH) {
|
|
70
|
-
names.push(NODE_SERVICES.AUTH_SERVICE);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return (services || []).find((x) => names.includes(x.name));
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
module.exports = {
|
|
77
|
-
getServices,
|
|
78
|
-
getServiceConfig,
|
|
79
|
-
getDefaultServiceConfig,
|
|
80
|
-
findService,
|
|
81
|
-
};
|