@abtnode/core 1.16.19-beta-340de95d → 1.16.19-beta-7b2db880
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 +44 -15
- package/lib/blocklet/storage/backup/spaces.js +9 -6
- package/lib/event/auto-backup-handler.js +2 -1
- package/lib/event/index.js +14 -8
- package/lib/index.js +8 -0
- package/lib/migrations/index.js +1 -105
- package/lib/router/helper.js +5 -0
- package/lib/router/index.js +13 -12
- package/lib/states/audit-log.js +4 -5
- package/lib/states/node.js +0 -8
- package/lib/states/runtime-insight.js +1 -1
- package/lib/states/traffic-insight.js +1 -1
- package/lib/states/user.js +1 -1
- package/lib/util/blocklet.js +14 -0
- package/lib/util/log.js +3 -2
- package/lib/validators/user.js +1 -1
- package/package.json +22 -22
|
@@ -27,6 +27,8 @@ const {
|
|
|
27
27
|
MONITOR_RECORD_INTERVAL_SEC,
|
|
28
28
|
INSTALL_ACTIONS,
|
|
29
29
|
BACKUPS,
|
|
30
|
+
DEFAULT_DID_DOMAIN,
|
|
31
|
+
FEDERATED,
|
|
30
32
|
} = require('@abtnode/constant');
|
|
31
33
|
|
|
32
34
|
const getBlockletEngine = require('@blocklet/meta/lib/engine');
|
|
@@ -91,6 +93,7 @@ const pLimit = require('p-limit');
|
|
|
91
93
|
const pRetry = require('p-retry');
|
|
92
94
|
|
|
93
95
|
const isFunction = require('lodash/isFunction');
|
|
96
|
+
const { encode } = require('@abtnode/util/lib/base32');
|
|
94
97
|
const { consumeServerlessNFT, consumeLauncherSession } = require('../../util/launcher');
|
|
95
98
|
const util = require('../../util');
|
|
96
99
|
const {
|
|
@@ -191,7 +194,6 @@ const { callFederated } = require('../../util/federated');
|
|
|
191
194
|
const { formatEnvironments, getBlockletMeta, validateOwner, isCLI } = util;
|
|
192
195
|
|
|
193
196
|
const statusLock = new Lock('blocklet-status-lock');
|
|
194
|
-
const limitSync = pLimit(1);
|
|
195
197
|
|
|
196
198
|
const getHooksOutputFiles = (blocklet) => ({
|
|
197
199
|
output: blocklet.mode === BLOCKLET_MODES.DEVELOPMENT ? '' : path.join(blocklet.env.logsDir, 'output.log'),
|
|
@@ -2330,10 +2332,23 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2330
2332
|
*/
|
|
2331
2333
|
async _onBackupToSpaces({ did, context, backupState }) {
|
|
2332
2334
|
const {
|
|
2333
|
-
referrer,
|
|
2334
2335
|
user: { did: userDid, locale },
|
|
2335
2336
|
} = context;
|
|
2336
2337
|
|
|
2338
|
+
let { referrer } = context;
|
|
2339
|
+
if (isEmpty(referrer)) {
|
|
2340
|
+
// fixes: https://github.com/ArcBlock/did-spaces/issues/908, referrer 在某些情况下会不存在
|
|
2341
|
+
/**
|
|
2342
|
+
* @type {import('@abtnode/client').NodeState}
|
|
2343
|
+
*/
|
|
2344
|
+
const node = await states.node.read();
|
|
2345
|
+
referrer = joinUrl(
|
|
2346
|
+
`https://${encode(node.did)}.${DEFAULT_DID_DOMAIN}`,
|
|
2347
|
+
node.routing.adminPath,
|
|
2348
|
+
`/blocklets/${did}/storage`
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2337
2352
|
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2338
2353
|
const {
|
|
2339
2354
|
appDid,
|
|
@@ -3403,9 +3418,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3403
3418
|
const { did } = data;
|
|
3404
3419
|
const assetState = await util.getNFTState(data.controller.chainHost, data.controller.nftId);
|
|
3405
3420
|
const isExpired = isNFTExpired(assetState);
|
|
3406
|
-
const blocklet = await states.blocklet.getBlocklet(did);
|
|
3407
3421
|
|
|
3408
|
-
if (isExpired
|
|
3422
|
+
if (isExpired) {
|
|
3409
3423
|
const expiredAt = getNftExpirationDate(assetState);
|
|
3410
3424
|
logger.info('the blocklet already expired and will be stopped', {
|
|
3411
3425
|
blockletDid: did,
|
|
@@ -3413,7 +3427,13 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3413
3427
|
expiredAt,
|
|
3414
3428
|
});
|
|
3415
3429
|
|
|
3416
|
-
|
|
3430
|
+
// 如果 Blocklet 没停止, 先停止
|
|
3431
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
3432
|
+
if (blocklet.status !== BlockletStatus.stopped) {
|
|
3433
|
+
await this.stop({ did });
|
|
3434
|
+
logger.info('the expired blocklet is stopped', { did, blockletDid: did });
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3417
3437
|
await states.blockletExtras.updateByDid(did, {
|
|
3418
3438
|
controller: {
|
|
3419
3439
|
...data.controller,
|
|
@@ -3424,11 +3444,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3424
3444
|
},
|
|
3425
3445
|
});
|
|
3426
3446
|
logger.info('the expired blocklet is stopped', { did });
|
|
3427
|
-
|
|
3428
|
-
// 为了减小服务器压力,每次删除一个 blocklet 后,休息 10s
|
|
3429
|
-
if (process.env.NODE_ENV !== 'test') {
|
|
3430
|
-
await sleep(10 * 1000);
|
|
3431
|
-
}
|
|
3432
3447
|
}
|
|
3433
3448
|
} catch (error) {
|
|
3434
3449
|
logger.error('stop expired blocklet failed', {
|
|
@@ -3893,6 +3908,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
3893
3908
|
},
|
|
3894
3909
|
masterAppUrl: masterSite.appUrl,
|
|
3895
3910
|
});
|
|
3911
|
+
const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
|
|
3896
3912
|
|
|
3897
3913
|
const disbandQueue = federated.sites
|
|
3898
3914
|
.filter((item) => item.appPid !== did)
|
|
@@ -4101,6 +4117,7 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4101
4117
|
|
|
4102
4118
|
const nodeInfo = await states.node.read();
|
|
4103
4119
|
const { permanentWallet } = getBlockletInfo(blocklet, nodeInfo.sk);
|
|
4120
|
+
const limitSync = pLimit(FEDERATED.SYNC_LIMIT);
|
|
4104
4121
|
|
|
4105
4122
|
const waitingList = federated.sites
|
|
4106
4123
|
.filter((item) => {
|
|
@@ -4115,22 +4132,34 @@ class FederatedBlockletManager extends DiskBlockletManager {
|
|
|
4115
4132
|
}
|
|
4116
4133
|
return false;
|
|
4117
4134
|
})
|
|
4118
|
-
.map((item) => {
|
|
4119
|
-
|
|
4135
|
+
.map(async (item) => {
|
|
4136
|
+
const resultItem = await limitSync(async () => {
|
|
4120
4137
|
try {
|
|
4121
4138
|
// NOTICE: 即使通知某个站点失败了,也不影响其他站点接收同步结果
|
|
4122
|
-
await callFederated({
|
|
4139
|
+
const result = await callFederated({
|
|
4123
4140
|
action: 'sync',
|
|
4124
4141
|
permanentWallet,
|
|
4125
4142
|
site: item,
|
|
4126
4143
|
data: safeData,
|
|
4127
4144
|
});
|
|
4145
|
+
return result;
|
|
4128
4146
|
} catch (error) {
|
|
4129
|
-
logger.warn('Failed to sync federated sites', {
|
|
4147
|
+
logger.warn('Failed to sync federated sites', {
|
|
4148
|
+
error,
|
|
4149
|
+
action: 'sync',
|
|
4150
|
+
site: item,
|
|
4151
|
+
data: safeData,
|
|
4152
|
+
});
|
|
4153
|
+
return null;
|
|
4130
4154
|
}
|
|
4131
4155
|
});
|
|
4156
|
+
return {
|
|
4157
|
+
site: item,
|
|
4158
|
+
result: resultItem,
|
|
4159
|
+
};
|
|
4132
4160
|
});
|
|
4133
|
-
await Promise.all(waitingList);
|
|
4161
|
+
const resultList = await Promise.all(waitingList);
|
|
4162
|
+
return resultList;
|
|
4134
4163
|
}
|
|
4135
4164
|
|
|
4136
4165
|
async loginFederated({ did, site, data }) {
|
|
@@ -40,6 +40,12 @@ const { RoutingRuleBackup } = require('./routing-rule');
|
|
|
40
40
|
const { translate } = require('../../../locales');
|
|
41
41
|
const { getFolderSize } = require('../utils/disk');
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @param {{ appDid: string, appPid: string }} params
|
|
45
|
+
* @returns {{ appDid: string, meta: { did: string } }}
|
|
46
|
+
*/
|
|
47
|
+
const getAppId = (params) => ({ appDid: params.appDid, meta: { did: params.appPid } });
|
|
48
|
+
|
|
43
49
|
class SpacesBackup extends BaseBackup {
|
|
44
50
|
/**
|
|
45
51
|
*
|
|
@@ -168,8 +174,7 @@ class SpacesBackup extends BaseBackup {
|
|
|
168
174
|
|
|
169
175
|
async export() {
|
|
170
176
|
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
171
|
-
|
|
172
|
-
meta: { did: this.input.appPid },
|
|
177
|
+
...getAppId(this.input),
|
|
173
178
|
message: 'Preparing data for backup...',
|
|
174
179
|
progress: 15,
|
|
175
180
|
completed: false,
|
|
@@ -182,8 +187,7 @@ class SpacesBackup extends BaseBackup {
|
|
|
182
187
|
this.syncObjects = await this.collectSyncObjects(this.dataBackup, this.storages);
|
|
183
188
|
|
|
184
189
|
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
185
|
-
|
|
186
|
-
meta: { did: this.input.appPid },
|
|
190
|
+
...getAppId(this.input),
|
|
187
191
|
message: 'Data ready, start backup...',
|
|
188
192
|
progress: 20,
|
|
189
193
|
completed: false,
|
|
@@ -272,8 +276,7 @@ class SpacesBackup extends BaseBackup {
|
|
|
272
276
|
message: progressMessage,
|
|
273
277
|
});
|
|
274
278
|
this.input.event.emit(BlockletEvents.backupProgress, {
|
|
275
|
-
|
|
276
|
-
meta: { did: this.input.appDid },
|
|
279
|
+
...getAppId(this.input),
|
|
277
280
|
message: progressMessage,
|
|
278
281
|
// 0.8 是因为上传文件到 spaces 占进度的 80%,+ 20 是因为需要累加之前的进度
|
|
279
282
|
progress,
|
|
@@ -36,7 +36,8 @@ const debouncedFuncs = {};
|
|
|
36
36
|
*/
|
|
37
37
|
function autoBackupHandlerFactory(id, fn) {
|
|
38
38
|
if (!debouncedFuncs[id]) {
|
|
39
|
-
|
|
39
|
+
// 自动备份立即执行的间隔时间暂定为 1 min
|
|
40
|
+
debouncedFuncs[id] = debounce(fn, 1000 * 60);
|
|
40
41
|
}
|
|
41
42
|
return debouncedFuncs[id];
|
|
42
43
|
}
|
package/lib/event/index.js
CHANGED
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
BlockletEvents,
|
|
11
11
|
BlockletInternalEvents,
|
|
12
12
|
} = require('@blocklet/constant');
|
|
13
|
-
const { EVENTS } = require('@abtnode/constant');
|
|
13
|
+
const { EVENTS, BACKUPS } = require('@abtnode/constant');
|
|
14
14
|
const { NodeMonitSender } = require('../monitor/node-monit-sender');
|
|
15
15
|
const handleInstanceInStore = require('../util/public-to-store');
|
|
16
16
|
const { isCLI } = require('../util');
|
|
@@ -27,7 +27,8 @@ const routingSnapshotPrefix = (blocklet) => (blocklet.mode === BLOCKLET_MODES.DE
|
|
|
27
27
|
/**
|
|
28
28
|
*
|
|
29
29
|
* @param {{
|
|
30
|
-
* blockletManager: import('../blocklet/manager/disk')
|
|
30
|
+
* blockletManager: import('../blocklet/manager/disk'),
|
|
31
|
+
* node: import('../index')
|
|
31
32
|
* }} param0
|
|
32
33
|
* @returns
|
|
33
34
|
*/
|
|
@@ -107,6 +108,10 @@ module.exports = ({
|
|
|
107
108
|
safeData = wipeSensitiveData(cloneDeep(data));
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
if (get(safeData, 'blocklet.meta.did', '')) {
|
|
112
|
+
safeData.blocklet = wipeSensitiveData(cloneDeep(safeData.blocklet));
|
|
113
|
+
}
|
|
114
|
+
|
|
110
115
|
logger.debug('proxy event to event hub', { name });
|
|
111
116
|
eventHub.broadcast(name, safeData);
|
|
112
117
|
events.emit(name, safeData);
|
|
@@ -317,12 +322,13 @@ module.exports = ({
|
|
|
317
322
|
strategy: payload.backup.strategy,
|
|
318
323
|
};
|
|
319
324
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
325
|
+
if (payload.backup.strategy === BACKUPS.STRATEGY.MANUAL) {
|
|
326
|
+
await node.createAuditLog({
|
|
327
|
+
action: 'backupToSpaces',
|
|
328
|
+
args,
|
|
329
|
+
context: payload?.context ?? {},
|
|
330
|
+
});
|
|
331
|
+
}
|
|
326
332
|
|
|
327
333
|
if (payload?.progress !== 100) {
|
|
328
334
|
await node.createNotification({
|
package/lib/index.js
CHANGED
|
@@ -86,7 +86,9 @@ function ABTNode(options) {
|
|
|
86
86
|
model: states.job,
|
|
87
87
|
name: 'jobs',
|
|
88
88
|
onJob: async (job) => {
|
|
89
|
+
// eslint-disable-next-line no-use-before-define
|
|
89
90
|
if (typeof blockletManager.onJob === 'function') {
|
|
91
|
+
// eslint-disable-next-line no-use-before-define
|
|
90
92
|
await blockletManager.onJob(job);
|
|
91
93
|
}
|
|
92
94
|
},
|
|
@@ -102,7 +104,9 @@ function ABTNode(options) {
|
|
|
102
104
|
model: states.job,
|
|
103
105
|
name: 'install_queue',
|
|
104
106
|
onJob: async (job) => {
|
|
107
|
+
// eslint-disable-next-line no-use-before-define
|
|
105
108
|
if (typeof blockletManager.onJob === 'function') {
|
|
109
|
+
// eslint-disable-next-line no-use-before-define
|
|
106
110
|
await blockletManager.onJob(job);
|
|
107
111
|
}
|
|
108
112
|
},
|
|
@@ -120,7 +124,9 @@ function ABTNode(options) {
|
|
|
120
124
|
model: states.job,
|
|
121
125
|
name: 'backup_queue',
|
|
122
126
|
onJob: async (job) => {
|
|
127
|
+
// eslint-disable-next-line no-use-before-define
|
|
123
128
|
if (typeof blockletManager.onJob === 'function') {
|
|
129
|
+
// eslint-disable-next-line no-use-before-define
|
|
124
130
|
await blockletManager.onJob(job);
|
|
125
131
|
}
|
|
126
132
|
},
|
|
@@ -140,7 +146,9 @@ function ABTNode(options) {
|
|
|
140
146
|
name: 'restore_queue',
|
|
141
147
|
model: states.job,
|
|
142
148
|
onJob: async (job) => {
|
|
149
|
+
// eslint-disable-next-line no-use-before-define
|
|
143
150
|
if (typeof blockletManager.onJob === 'function') {
|
|
151
|
+
// eslint-disable-next-line no-use-before-define
|
|
144
152
|
await blockletManager.onJob(job);
|
|
145
153
|
}
|
|
146
154
|
},
|
package/lib/migrations/index.js
CHANGED
|
@@ -5,50 +5,13 @@ const path = require('path');
|
|
|
5
5
|
const semver = require('semver');
|
|
6
6
|
const uniqBy = require('lodash/uniqBy');
|
|
7
7
|
const logger = require('@abtnode/logger')('@abtnode/core:migration');
|
|
8
|
-
const {
|
|
9
|
-
doSchemaMigration,
|
|
10
|
-
doDataMigration,
|
|
11
|
-
getBlockletModels,
|
|
12
|
-
getServerModels,
|
|
13
|
-
getServiceModels,
|
|
14
|
-
getCertificateManagerModels,
|
|
15
|
-
createSequelize,
|
|
16
|
-
} = require('@abtnode/models');
|
|
8
|
+
const { doSchemaMigration, createSequelize } = require('@abtnode/models');
|
|
17
9
|
const { getDbFilePath } = require('../util');
|
|
18
10
|
|
|
19
11
|
const BACKUP_FILE_DB = 'server.db';
|
|
20
12
|
const BACKUP_FILE_CONFIG = 'config.yml';
|
|
21
13
|
|
|
22
14
|
const MODULES = ['certificate-manager'];
|
|
23
|
-
const MAPPINGS = {
|
|
24
|
-
server: {
|
|
25
|
-
access_key: 'AccessKey',
|
|
26
|
-
'audit-log': 'AuditLog',
|
|
27
|
-
blocklet: 'Blocklet',
|
|
28
|
-
blocklet_extras: 'BlockletExtra',
|
|
29
|
-
cache: 'Cache',
|
|
30
|
-
migration: 'Migration',
|
|
31
|
-
node: 'Server',
|
|
32
|
-
notification: 'Notification',
|
|
33
|
-
routing_rule: 'Site',
|
|
34
|
-
session: 'Session',
|
|
35
|
-
user: 'User',
|
|
36
|
-
webhook: 'WebHook',
|
|
37
|
-
},
|
|
38
|
-
blocklet: {
|
|
39
|
-
user: 'User',
|
|
40
|
-
session: 'Session',
|
|
41
|
-
rbac: 'Rbac',
|
|
42
|
-
},
|
|
43
|
-
service: {
|
|
44
|
-
message: 'Message',
|
|
45
|
-
},
|
|
46
|
-
'certificate-manager': {
|
|
47
|
-
account: 'Account',
|
|
48
|
-
certificate: 'Certificate',
|
|
49
|
-
'http-challenge': 'HttpChallenge',
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
15
|
|
|
53
16
|
const getMigrationScripts = (scriptsDir) => {
|
|
54
17
|
const files = fs.readdirSync(scriptsDir);
|
|
@@ -243,72 +206,6 @@ const runSchemaMigrations = async ({
|
|
|
243
206
|
}
|
|
244
207
|
};
|
|
245
208
|
|
|
246
|
-
const runDataMigrations = async ({
|
|
247
|
-
dataDir,
|
|
248
|
-
blocklets = [],
|
|
249
|
-
printInfo = console.info, // eslint-disable-line
|
|
250
|
-
printSuccess = console.info, // eslint-disable-line
|
|
251
|
-
printError = console.error,
|
|
252
|
-
}) => {
|
|
253
|
-
// migrate server data
|
|
254
|
-
await doDataMigration({
|
|
255
|
-
srcDir: path.join(dataDir, 'core'),
|
|
256
|
-
dbFile: path.join(dataDir, 'core/server.db'),
|
|
257
|
-
mapping: MAPPINGS.server,
|
|
258
|
-
models: getServerModels(),
|
|
259
|
-
printInfo,
|
|
260
|
-
printError,
|
|
261
|
-
printSuccess,
|
|
262
|
-
});
|
|
263
|
-
printSuccess('Server data successfully migrated');
|
|
264
|
-
|
|
265
|
-
// migrate service data
|
|
266
|
-
await doDataMigration({
|
|
267
|
-
srcDir: path.join(dataDir, 'services'),
|
|
268
|
-
dbFile: path.join(dataDir, 'services/service.db'),
|
|
269
|
-
models: getServiceModels(),
|
|
270
|
-
mapping: MAPPINGS.service,
|
|
271
|
-
printInfo,
|
|
272
|
-
printError,
|
|
273
|
-
printSuccess,
|
|
274
|
-
});
|
|
275
|
-
printSuccess('Service data successfully migrated');
|
|
276
|
-
|
|
277
|
-
// migrate blocklet data
|
|
278
|
-
for (let i = 0; i < blocklets.length; i++) {
|
|
279
|
-
const blocklet = blocklets[i];
|
|
280
|
-
const env = blocklet.environments.find((x) => x.key === 'BLOCKLET_DATA_DIR');
|
|
281
|
-
if (env) {
|
|
282
|
-
await doDataMigration({
|
|
283
|
-
srcDir: path.join(env.value),
|
|
284
|
-
dbFile: path.join(env.value, 'blocklet.db'),
|
|
285
|
-
models: getBlockletModels(),
|
|
286
|
-
mapping: MAPPINGS.blocklet,
|
|
287
|
-
printInfo,
|
|
288
|
-
printError,
|
|
289
|
-
printSuccess,
|
|
290
|
-
});
|
|
291
|
-
printSuccess(`Blocklet data successfully migrated: ${blocklet.appPid}`);
|
|
292
|
-
} else {
|
|
293
|
-
printInfo(`Skip migrate data for blocklet: ${blocklet.appPid}`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// migrate certificate manager schema
|
|
298
|
-
for (let i = 0; i < MODULES.length; i++) {
|
|
299
|
-
await doDataMigration({
|
|
300
|
-
srcDir: path.join(dataDir, `modules/${MODULES[i]}/db`),
|
|
301
|
-
dbFile: path.join(dataDir, `modules/${MODULES[i]}/module.db`),
|
|
302
|
-
models: getCertificateManagerModels(),
|
|
303
|
-
mapping: MAPPINGS[MODULES[i]],
|
|
304
|
-
printInfo,
|
|
305
|
-
printError,
|
|
306
|
-
printSuccess,
|
|
307
|
-
});
|
|
308
|
-
printSuccess(`${MODULES[i]} data successfully migrated`);
|
|
309
|
-
}
|
|
310
|
-
};
|
|
311
|
-
|
|
312
209
|
const closeDatabaseConnections = ({
|
|
313
210
|
dataDir,
|
|
314
211
|
blocklets = [],
|
|
@@ -340,7 +237,6 @@ module.exports = {
|
|
|
340
237
|
getMigrationScripts,
|
|
341
238
|
runMigrationScripts,
|
|
342
239
|
runSchemaMigrations,
|
|
343
|
-
runDataMigrations,
|
|
344
240
|
closeDatabaseConnections,
|
|
345
241
|
doBackup,
|
|
346
242
|
doRestore,
|
package/lib/router/helper.js
CHANGED
|
@@ -949,6 +949,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
if (updatedResult.length) {
|
|
952
|
+
// eslint-disable-next-line no-use-before-define
|
|
952
953
|
const hash = await takeRoutingSnapshot({ message: 'ensure dashboard routing rules', dryRun: false }, context);
|
|
953
954
|
logger.info('take routing snapshot on ensure dashboard routing rules', { updatedResult, hash });
|
|
954
955
|
return true;
|
|
@@ -1168,6 +1169,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1168
1169
|
|
|
1169
1170
|
const clearBlockletRoutingCache = async (blocklet) => {
|
|
1170
1171
|
const info = await nodeState.read();
|
|
1172
|
+
// eslint-disable-next-line no-use-before-define
|
|
1171
1173
|
const provider = providers[info.routing.provider];
|
|
1172
1174
|
if (provider) {
|
|
1173
1175
|
await provider.clearCache(blocklet.appPid);
|
|
@@ -1214,6 +1216,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1214
1216
|
await removeBlockletRouting(blocklet);
|
|
1215
1217
|
await ensureBlockletRouting(blocklet);
|
|
1216
1218
|
if (refreshRouterProvider) {
|
|
1219
|
+
// eslint-disable-next-line no-use-before-define
|
|
1217
1220
|
const hash = await takeRoutingSnapshot({ message: `Reset blocklet ${did}`, dryRun: false });
|
|
1218
1221
|
logger.info('reset blocklet routing rules', { did, hash });
|
|
1219
1222
|
}
|
|
@@ -1301,6 +1304,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1301
1304
|
|
|
1302
1305
|
const analyzeRouterLog = async () => {
|
|
1303
1306
|
const info = await nodeState.read();
|
|
1307
|
+
// eslint-disable-next-line no-use-before-define
|
|
1304
1308
|
const sites = await getRoutingSites({});
|
|
1305
1309
|
const providerName = get(info, 'routing.provider', null);
|
|
1306
1310
|
if (!providerName || !providers[providerName]) {
|
|
@@ -1404,6 +1408,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1404
1408
|
|
|
1405
1409
|
// We need to take snapshot after system rules ensured
|
|
1406
1410
|
if (ensureBlockletResults.filter(Boolean).length) {
|
|
1411
|
+
// eslint-disable-next-line no-use-before-define
|
|
1407
1412
|
await takeRoutingSnapshot({ message: `Switch routing engine to ${newProvider}`, dryRun: false }, context);
|
|
1408
1413
|
logger.info(`take routing snapshot on switch engine: ${newProvider}`, { ensureBlockletResults });
|
|
1409
1414
|
}
|
package/lib/router/index.js
CHANGED
|
@@ -19,6 +19,18 @@ const { isGatewayCacheEnabled, isBlockletSite } = require('../util');
|
|
|
19
19
|
|
|
20
20
|
const isServiceFeDevelopment = process.env.ABT_NODE_SERVICE_FE_PORT;
|
|
21
21
|
|
|
22
|
+
const mergeAllowedOrigins = (domain, allowedOrigins) => {
|
|
23
|
+
const origins = Array.isArray(allowedOrigins) ? allowedOrigins : [domain];
|
|
24
|
+
if (origins.includes(domain) === false) {
|
|
25
|
+
origins.push(domain);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// skip site if domain is BLOCKLET_SITE_GROUP
|
|
29
|
+
const res = origins.filter((x) => !x.endsWith(BLOCKLET_SITE_GROUP_SUFFIX));
|
|
30
|
+
|
|
31
|
+
return res;
|
|
32
|
+
};
|
|
33
|
+
|
|
22
34
|
const expandSites = (sites = []) => {
|
|
23
35
|
const result = [];
|
|
24
36
|
|
|
@@ -51,19 +63,8 @@ const expandSites = (sites = []) => {
|
|
|
51
63
|
return result;
|
|
52
64
|
};
|
|
53
65
|
|
|
54
|
-
const mergeAllowedOrigins = (domain, allowedOrigins) => {
|
|
55
|
-
const origins = Array.isArray(allowedOrigins) ? allowedOrigins : [domain];
|
|
56
|
-
if (origins.includes(domain) === false) {
|
|
57
|
-
origins.push(domain);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// skip site if domain is BLOCKLET_SITE_GROUP
|
|
61
|
-
const res = origins.filter((x) => !x.endsWith(BLOCKLET_SITE_GROUP_SUFFIX));
|
|
62
|
-
|
|
63
|
-
return res;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
66
|
const getRoutingTable = ({ sites, nodeInfo }) => {
|
|
67
|
+
// eslint-disable-next-line no-use-before-define
|
|
67
68
|
let routingTable = Router.formatSites(sites);
|
|
68
69
|
routingTable = expandSites(routingTable);
|
|
69
70
|
|
package/lib/states/audit-log.js
CHANGED
|
@@ -5,7 +5,7 @@ const get = require('lodash/get');
|
|
|
5
5
|
const uniq = require('lodash/uniq');
|
|
6
6
|
const joinUrl = require('url-join');
|
|
7
7
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
8
|
-
const { BLOCKLET_SITE_GROUP_SUFFIX, NODE_SERVICES
|
|
8
|
+
const { BLOCKLET_SITE_GROUP_SUFFIX, NODE_SERVICES } = require('@abtnode/constant');
|
|
9
9
|
const logger = require('@abtnode/logger')('@abtnode/core:states:audit-log');
|
|
10
10
|
|
|
11
11
|
const BaseState = require('./base');
|
|
@@ -140,10 +140,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
140
140
|
// @see: core/state/lib/event.js#311
|
|
141
141
|
case 'backupToSpaces':
|
|
142
142
|
if (args?.success) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
return `Automatic backup application to ${args.url} successfully:\n- Backup files have been stored [here](${args.backupUrl})`;
|
|
143
|
+
// @note: 目前只需要给出手动备份的审计日志,自动备份的审计日志不再显示出来
|
|
144
|
+
return `Manual backup application to ${args.url} successfully:\n- Backup files have been stored [here](${args.backupUrl})`;
|
|
147
145
|
}
|
|
148
146
|
return `Backup application to ${args.url} failed:\n- Reason: <span style='color:red'>${args.errorMessage}</span>`;
|
|
149
147
|
case 'configPublicToStore':
|
|
@@ -200,6 +198,7 @@ const getLogContent = async (action, args, context, result, info, node) => {
|
|
|
200
198
|
const syncData = {
|
|
201
199
|
users: args.users,
|
|
202
200
|
sites: args.sites,
|
|
201
|
+
userSessions: args.userSessions,
|
|
203
202
|
};
|
|
204
203
|
return `sync federated: site ${getSiteInfo(args.callerSite)} sync data:
|
|
205
204
|
\`\`\`json
|
package/lib/states/node.js
CHANGED
|
@@ -284,14 +284,6 @@ class NodeState extends BaseState {
|
|
|
284
284
|
}));
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
// deprecated
|
|
288
|
-
async increaseCustomBlockletNumber() {
|
|
289
|
-
const { customBlockletNumber = 0 } = await this.read();
|
|
290
|
-
const num = customBlockletNumber + 1;
|
|
291
|
-
await this.update({ $set: { customBlockletNumber: num } });
|
|
292
|
-
return num;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
287
|
async updateGateway(gateway) {
|
|
296
288
|
const { routing } = await this.read();
|
|
297
289
|
routing.requestLimit = gateway.requestLimit;
|
package/lib/states/user.js
CHANGED
|
@@ -371,7 +371,7 @@ class User extends ExtendBase {
|
|
|
371
371
|
}
|
|
372
372
|
// update user, connectedAccount, passport
|
|
373
373
|
updates.connectedAccounts = updateConnectedAccount(exist.connectedAccounts, user.connectedAccount);
|
|
374
|
-
updated = await this.updateUser(
|
|
374
|
+
updated = await this.updateUser(exist.did, updates);
|
|
375
375
|
} else {
|
|
376
376
|
// create user, connectedAccount, passport
|
|
377
377
|
updates.did = user.did;
|
package/lib/util/blocklet.js
CHANGED
|
@@ -158,6 +158,7 @@ const getComponentDirs = (component, { dataDirs, ensure = false, ancestors = []
|
|
|
158
158
|
if (component.source === BlockletSource.local) {
|
|
159
159
|
appDir = component.deployedFrom;
|
|
160
160
|
} else {
|
|
161
|
+
// eslint-disable-next-line no-use-before-define
|
|
161
162
|
appDir = getBundleDir(dataDirs.blocklets, component.meta);
|
|
162
163
|
}
|
|
163
164
|
|
|
@@ -523,6 +524,7 @@ const startBlockletProcess = async (
|
|
|
523
524
|
return;
|
|
524
525
|
}
|
|
525
526
|
|
|
527
|
+
// eslint-disable-next-line no-use-before-define
|
|
526
528
|
if (shouldSkipComponent(b.meta.did, componentDids)) {
|
|
527
529
|
logger.info('skip start process not selected', { processId });
|
|
528
530
|
return;
|
|
@@ -616,6 +618,7 @@ const startBlockletProcess = async (
|
|
|
616
618
|
|
|
617
619
|
await pm2.startAsync(options);
|
|
618
620
|
|
|
621
|
+
// eslint-disable-next-line no-use-before-define
|
|
619
622
|
const status = await getProcessState(processId);
|
|
620
623
|
if (status === BlockletStatus.error) {
|
|
621
624
|
throw new Error(`${processId} is not running within 3 seconds`);
|
|
@@ -636,6 +639,7 @@ const startBlockletProcess = async (
|
|
|
636
639
|
* @param {*} blocklet should contain env props
|
|
637
640
|
*/
|
|
638
641
|
const stopBlockletProcess = (blocklet, { preStop = noop, skippedProcessIds = [], componentDids } = {}) => {
|
|
642
|
+
// eslint-disable-next-line no-use-before-define
|
|
639
643
|
return deleteBlockletProcess(blocklet, { preDelete: preStop, skippedProcessIds, componentDids });
|
|
640
644
|
};
|
|
641
645
|
|
|
@@ -657,6 +661,7 @@ const deleteBlockletProcess = async (blocklet, { preDelete = noop, skippedProces
|
|
|
657
661
|
return;
|
|
658
662
|
}
|
|
659
663
|
|
|
664
|
+
// eslint-disable-next-line no-use-before-define
|
|
660
665
|
if (shouldSkipComponent(b.meta?.did, componentDids)) {
|
|
661
666
|
logger.info(`skip delete process not selected: ${b.meta.did}`, { processId: b.env.processId });
|
|
662
667
|
return;
|
|
@@ -667,6 +672,7 @@ const deleteBlockletProcess = async (blocklet, { preDelete = noop, skippedProces
|
|
|
667
672
|
}
|
|
668
673
|
|
|
669
674
|
await preDelete(b, { ancestors });
|
|
675
|
+
// eslint-disable-next-line no-use-before-define
|
|
670
676
|
await deleteProcess(b.env.processId);
|
|
671
677
|
},
|
|
672
678
|
{ parallel: true }
|
|
@@ -685,11 +691,13 @@ const reloadBlockletProcess = (blocklet, { componentDids } = {}) =>
|
|
|
685
691
|
return;
|
|
686
692
|
}
|
|
687
693
|
|
|
694
|
+
// eslint-disable-next-line no-use-before-define
|
|
688
695
|
if (shouldSkipComponent(b.meta.did, componentDids)) {
|
|
689
696
|
logger.info('skip reload process', { processId: b.env.processId });
|
|
690
697
|
return;
|
|
691
698
|
}
|
|
692
699
|
|
|
700
|
+
// eslint-disable-next-line no-use-before-define
|
|
693
701
|
await reloadProcess(b.env.processId);
|
|
694
702
|
logger.info('done reload process', { processId: b.env.processId });
|
|
695
703
|
},
|
|
@@ -701,6 +709,7 @@ const reloadBlockletProcess = (blocklet, { componentDids } = {}) =>
|
|
|
701
709
|
* @returns {BlockletStatus}
|
|
702
710
|
*/
|
|
703
711
|
const getProcessState = async (processId) => {
|
|
712
|
+
// eslint-disable-next-line no-use-before-define
|
|
704
713
|
const info = await getProcessInfo(processId);
|
|
705
714
|
if (!statusMap[info.pm2_env.status]) {
|
|
706
715
|
logger.error('Cannot find the blocklet status for pm2 status mapping', {
|
|
@@ -773,6 +782,7 @@ const checkBlockletProcessHealthy = async (blocklet, { minConsecutiveTime, timeo
|
|
|
773
782
|
return;
|
|
774
783
|
}
|
|
775
784
|
|
|
785
|
+
// eslint-disable-next-line no-use-before-define
|
|
776
786
|
if (shouldSkipComponent(b.meta.did, componentDids)) {
|
|
777
787
|
logger.info('skip check component healthy', { processId: b.env.processId });
|
|
778
788
|
return;
|
|
@@ -781,6 +791,7 @@ const checkBlockletProcessHealthy = async (blocklet, { minConsecutiveTime, timeo
|
|
|
781
791
|
const logToTerminal = [blocklet.mode, b.mode].includes(BLOCKLET_MODES.DEVELOPMENT);
|
|
782
792
|
|
|
783
793
|
const startedAt = Date.now();
|
|
794
|
+
// eslint-disable-next-line no-use-before-define
|
|
784
795
|
await _checkProcessHealthy(b, { minConsecutiveTime, timeout, logToTerminal });
|
|
785
796
|
logger.info('done check component healthy', { processId: b.env.processId, time: Date.now() - startedAt });
|
|
786
797
|
},
|
|
@@ -1334,6 +1345,7 @@ const getConfigFromPreferences = (blocklet) => {
|
|
|
1334
1345
|
|
|
1335
1346
|
const getBlockletURLForLauncher = ({ blocklet, nodeInfo }) => {
|
|
1336
1347
|
const didDomain = getDidDomainForBlocklet({
|
|
1348
|
+
// eslint-disable-next-line no-use-before-define
|
|
1337
1349
|
did: getSlpDid(nodeInfo.did, blocklet.appPid),
|
|
1338
1350
|
didDomain: nodeInfo.slpDomain,
|
|
1339
1351
|
});
|
|
@@ -1676,11 +1688,13 @@ const getBlockletDidDomainList = (blocklet, nodeInfo) => {
|
|
|
1676
1688
|
domainAliases.push({ value: domain, isProtected: true });
|
|
1677
1689
|
});
|
|
1678
1690
|
|
|
1691
|
+
// eslint-disable-next-line no-use-before-define
|
|
1679
1692
|
const enableSlpDomain = shouldEnableSlpDomain({
|
|
1680
1693
|
mode: nodeInfo.mode,
|
|
1681
1694
|
launcher: nodeInfo.launcher,
|
|
1682
1695
|
});
|
|
1683
1696
|
if (enableSlpDomain) {
|
|
1697
|
+
// eslint-disable-next-line no-use-before-define
|
|
1684
1698
|
const slpDid = getSlpDid(nodeInfo.did, blocklet.appPid);
|
|
1685
1699
|
const domain = getDidDomainForBlocklet({ did: slpDid, didDomain: nodeInfo.slpDomain });
|
|
1686
1700
|
|
package/lib/util/log.js
CHANGED
|
@@ -141,11 +141,12 @@ const getLogFiles = async ({ name, node }) => {
|
|
|
141
141
|
if (name === 'blocklet-services') {
|
|
142
142
|
const logDir = path.join(node.dataDirs.logs, '_abtnode');
|
|
143
143
|
const info = path.join(logDir, 'service.log');
|
|
144
|
+
const error = path.join(logDir, 'service-error.log');
|
|
144
145
|
const access = path.join(logDir, 'service.access.log');
|
|
145
146
|
const stdout = path.join(logDir, 'service.stdout.log');
|
|
146
147
|
const stderr = path.join(logDir, 'service.stderr.log');
|
|
147
|
-
createFile({ info, access, stdout, stderr });
|
|
148
|
-
return { info, access, stdout, stderr };
|
|
148
|
+
createFile({ error, info, access, stdout, stderr });
|
|
149
|
+
return { error, info, access, stdout, stderr };
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
if (name.indexOf('blocklet-') === 0) {
|
package/lib/validators/user.js
CHANGED
|
@@ -35,7 +35,7 @@ const loginSchema = Joi.object({
|
|
|
35
35
|
remark: Joi.string().empty(''),
|
|
36
36
|
lastLoginIp: Joi.string().empty(''),
|
|
37
37
|
passport: passportSchema.optional(),
|
|
38
|
-
sourceAppPid: Joi.
|
|
38
|
+
sourceAppPid: Joi.DID().trim().empty(null),
|
|
39
39
|
connectedAccount: Joi.alternatives()
|
|
40
40
|
.try(connectedAccountSchema.required(), Joi.array().items(connectedAccountSchema).min(1).sparse(true))
|
|
41
41
|
.required(),
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.19-beta-
|
|
6
|
+
"version": "1.16.19-beta-7b2db880",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.19-beta-
|
|
23
|
-
"@abtnode/auth": "1.16.19-beta-
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.19-beta-
|
|
25
|
-
"@abtnode/constant": "1.16.19-beta-
|
|
26
|
-
"@abtnode/cron": "1.16.19-beta-
|
|
27
|
-
"@abtnode/logger": "1.16.19-beta-
|
|
28
|
-
"@abtnode/models": "1.16.19-beta-
|
|
29
|
-
"@abtnode/queue": "1.16.19-beta-
|
|
30
|
-
"@abtnode/rbac": "1.16.19-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.16.19-beta-
|
|
32
|
-
"@abtnode/static-server": "1.16.19-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.16.19-beta-
|
|
34
|
-
"@abtnode/util": "1.16.19-beta-
|
|
22
|
+
"@abtnode/analytics": "1.16.19-beta-7b2db880",
|
|
23
|
+
"@abtnode/auth": "1.16.19-beta-7b2db880",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.19-beta-7b2db880",
|
|
25
|
+
"@abtnode/constant": "1.16.19-beta-7b2db880",
|
|
26
|
+
"@abtnode/cron": "1.16.19-beta-7b2db880",
|
|
27
|
+
"@abtnode/logger": "1.16.19-beta-7b2db880",
|
|
28
|
+
"@abtnode/models": "1.16.19-beta-7b2db880",
|
|
29
|
+
"@abtnode/queue": "1.16.19-beta-7b2db880",
|
|
30
|
+
"@abtnode/rbac": "1.16.19-beta-7b2db880",
|
|
31
|
+
"@abtnode/router-provider": "1.16.19-beta-7b2db880",
|
|
32
|
+
"@abtnode/static-server": "1.16.19-beta-7b2db880",
|
|
33
|
+
"@abtnode/timemachine": "1.16.19-beta-7b2db880",
|
|
34
|
+
"@abtnode/util": "1.16.19-beta-7b2db880",
|
|
35
35
|
"@arcblock/did": "1.18.95",
|
|
36
36
|
"@arcblock/did-auth": "1.18.95",
|
|
37
37
|
"@arcblock/did-ext": "^1.18.95",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
43
|
"@arcblock/validator": "^1.18.95",
|
|
44
44
|
"@arcblock/vc": "1.18.95",
|
|
45
|
-
"@blocklet/constant": "1.16.19-beta-
|
|
46
|
-
"@blocklet/env": "1.16.19-beta-
|
|
47
|
-
"@blocklet/meta": "1.16.19-beta-
|
|
48
|
-
"@blocklet/resolver": "1.16.19-beta-
|
|
49
|
-
"@blocklet/sdk": "1.16.19-beta-
|
|
50
|
-
"@did-space/client": "^0.3.
|
|
45
|
+
"@blocklet/constant": "1.16.19-beta-7b2db880",
|
|
46
|
+
"@blocklet/env": "1.16.19-beta-7b2db880",
|
|
47
|
+
"@blocklet/meta": "1.16.19-beta-7b2db880",
|
|
48
|
+
"@blocklet/resolver": "1.16.19-beta-7b2db880",
|
|
49
|
+
"@blocklet/sdk": "1.16.19-beta-7b2db880",
|
|
50
|
+
"@did-space/client": "^0.3.28",
|
|
51
51
|
"@fidm/x509": "^1.2.1",
|
|
52
52
|
"@ocap/mcrypto": "1.18.95",
|
|
53
53
|
"@ocap/util": "1.18.95",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"p-retry": "4.6.1",
|
|
81
81
|
"read-last-lines": "^1.8.0",
|
|
82
82
|
"semver": "^7.3.8",
|
|
83
|
-
"sequelize": "^6.
|
|
83
|
+
"sequelize": "^6.35.0",
|
|
84
84
|
"shelljs": "^0.8.5",
|
|
85
85
|
"ssri": "^8.0.1",
|
|
86
86
|
"stream-throttle": "^0.1.3",
|
|
@@ -101,5 +101,5 @@
|
|
|
101
101
|
"jest": "^27.5.1",
|
|
102
102
|
"unzipper": "^0.10.11"
|
|
103
103
|
},
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "598b576b97dd7accbfa1bb509b75e423ad27e5e2"
|
|
105
105
|
}
|