@abtnode/core 1.16.8-beta-186fd5aa → 1.16.8-next-c66e39c7
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 +42 -62
- package/lib/blocklet/manager/disk.js +2 -8
- package/lib/blocklet/manager/helper/migrate-application-to-struct-v2.js +5 -5
- package/lib/blocklet/storage/backup/blocklet-extras.js +2 -2
- package/lib/blocklet/storage/backup/blocklet.js +2 -2
- package/lib/index.js +17 -16
- package/lib/migrations/1.16.8-component-title.js +1 -1
- package/lib/migrations/1.6.9-update-node-info-and-certificate.js +1 -1
- package/lib/migrations/index.js +190 -40
- package/lib/monitor/node-runtime-monitor.js +2 -29
- package/lib/router/helper.js +6 -6
- package/lib/router/manager.js +35 -36
- package/lib/states/access-key.js +3 -20
- package/lib/states/audit-log.js +7 -8
- package/lib/states/backup.js +11 -59
- package/lib/states/base.js +13 -5
- package/lib/states/blocklet-extras.js +11 -8
- package/lib/states/blocklet.js +148 -222
- package/lib/states/cache.js +3 -21
- package/lib/states/connect-account.js +8 -0
- package/lib/states/index.js +28 -18
- package/lib/states/job.js +8 -0
- package/lib/states/migration.js +3 -4
- package/lib/states/node.js +104 -145
- package/lib/states/notification.js +18 -40
- package/lib/states/passport.js +8 -0
- package/lib/states/session.js +28 -44
- package/lib/states/site.js +32 -39
- package/lib/states/user.js +169 -378
- package/lib/states/webhook.js +5 -7
- package/lib/team/manager.js +108 -116
- package/lib/util/blocklet.js +0 -1
- package/lib/util/index.js +3 -0
- package/lib/util/queue.js +14 -20
- package/lib/util/ready.js +1 -1
- package/lib/webhook/index.js +6 -4
- package/package.json +19 -18
- package/lib/states/challenge.js +0 -58
package/lib/migrations/index.js
CHANGED
|
@@ -1,13 +1,55 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
1
2
|
/* eslint-disable no-await-in-loop */
|
|
2
3
|
const fs = require('fs');
|
|
3
4
|
const path = require('path');
|
|
4
5
|
const semver = require('semver');
|
|
5
6
|
const uniqBy = require('lodash/uniqBy');
|
|
6
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');
|
|
17
|
+
const { getDbFilePath } = require('../util');
|
|
7
18
|
|
|
8
|
-
const
|
|
19
|
+
const BACKUP_FILE_DB = 'server.db';
|
|
9
20
|
const BACKUP_FILE_CONFIG = 'config.yml';
|
|
10
21
|
|
|
22
|
+
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
|
+
|
|
11
53
|
const getMigrationScripts = (scriptsDir) => {
|
|
12
54
|
const files = fs.readdirSync(scriptsDir);
|
|
13
55
|
const scripts = files
|
|
@@ -36,23 +78,17 @@ const getMigrationScripts = (scriptsDir) => {
|
|
|
36
78
|
return sorted;
|
|
37
79
|
};
|
|
38
80
|
|
|
39
|
-
|
|
40
|
-
const doBackup = async ({ states, dataDir, configFile, printInfo, printSuccess }) => {
|
|
81
|
+
const doBackup = async ({ dataDir, configFile, printInfo, printSuccess }) => {
|
|
41
82
|
printInfo('Backing up state db and config before migration...');
|
|
42
|
-
const data = {};
|
|
43
|
-
const keys = Object.keys(states);
|
|
44
|
-
for (let i = 0; i < keys.length; i++) {
|
|
45
|
-
const key = keys[i];
|
|
46
|
-
const state = states[key];
|
|
47
|
-
data[key] = await state.asyncDB.find({});
|
|
48
|
-
}
|
|
49
83
|
|
|
50
84
|
const backupDir = path.join(dataDir, 'migration', Date.now().toString());
|
|
51
85
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
52
86
|
|
|
53
|
-
const
|
|
54
|
-
fs.
|
|
55
|
-
|
|
87
|
+
const dbFile = path.join(dataDir, 'core/server.db');
|
|
88
|
+
if (fs.existsSync(dbFile)) {
|
|
89
|
+
fs.copyFileSync(dbFile, path.join(backupDir, BACKUP_FILE_DB));
|
|
90
|
+
}
|
|
91
|
+
if (fs.existsSync(configFile)) {
|
|
56
92
|
fs.copyFileSync(configFile, path.join(backupDir, BACKUP_FILE_CONFIG));
|
|
57
93
|
}
|
|
58
94
|
|
|
@@ -60,47 +96,28 @@ const doBackup = async ({ states, dataDir, configFile, printInfo, printSuccess }
|
|
|
60
96
|
return backupDir;
|
|
61
97
|
};
|
|
62
98
|
|
|
63
|
-
|
|
64
|
-
const doRestore = async ({ states, configFile, backupPath, printInfo, printSuccess }) => {
|
|
99
|
+
const doRestore = async ({ dataDir, configFile, backupPath, printInfo, printSuccess }) => {
|
|
65
100
|
printInfo('Restoring when migration failed...');
|
|
66
101
|
|
|
67
|
-
const
|
|
102
|
+
const dbBackup = path.join(backupPath, BACKUP_FILE_DB);
|
|
68
103
|
const configBackup = path.join(backupPath, BACKUP_FILE_CONFIG);
|
|
69
104
|
|
|
70
105
|
// Validate backup
|
|
71
106
|
if (fs.existsSync(backupPath) === false) {
|
|
72
107
|
throw new Error(`Backup folder does not exist: ${backupPath}`);
|
|
73
108
|
}
|
|
74
|
-
if (fs.existsSync(
|
|
75
|
-
throw new Error(`Backup file for state does not exist: ${
|
|
109
|
+
if (fs.existsSync(dbBackup) === false) {
|
|
110
|
+
throw new Error(`Backup file for state does not exist: ${dbBackup}`);
|
|
76
111
|
}
|
|
77
112
|
if (configFile && fs.existsSync(configBackup) === false) {
|
|
78
113
|
throw new Error(`Backup file for config does not exist: ${configBackup}`);
|
|
79
114
|
}
|
|
80
115
|
|
|
81
116
|
// Restore state db
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
backup = JSON.parse(fs.readFileSync(stateBackup));
|
|
85
|
-
} catch (err) {
|
|
86
|
-
throw new Error(`Failed to read and parse backup file: ${stateBackup}, ${err.message}`);
|
|
87
|
-
}
|
|
88
|
-
const keys = Object.keys(states);
|
|
89
|
-
for (let i = 0; i < keys.length; i++) {
|
|
90
|
-
const key = keys[i];
|
|
91
|
-
const state = states[key];
|
|
92
|
-
if (Array.isArray(backup[key])) {
|
|
93
|
-
await state.asyncDB.remove({}, { multi: true });
|
|
94
|
-
await state.asyncDB.insert(backup[key]);
|
|
95
|
-
} else {
|
|
96
|
-
throw new Error(`Invalid backup for state ${key}`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
117
|
+
fs.copyFileSync(dbBackup, path.join(dataDir, 'core/server.db'));
|
|
99
118
|
|
|
100
119
|
// Restore config
|
|
101
|
-
|
|
102
|
-
fs.copyFileSync(configBackup, configFile);
|
|
103
|
-
}
|
|
120
|
+
fs.copyFileSync(configBackup, configFile);
|
|
104
121
|
|
|
105
122
|
printSuccess('State db and config was successfully restored!');
|
|
106
123
|
};
|
|
@@ -154,7 +171,7 @@ const runMigrationScripts = async ({
|
|
|
154
171
|
|
|
155
172
|
let backupPath = null;
|
|
156
173
|
try {
|
|
157
|
-
backupPath = await doBackup({
|
|
174
|
+
backupPath = await doBackup({ dataDir, configFile, printInfo, printSuccess });
|
|
158
175
|
} catch (err) {
|
|
159
176
|
printError(`Failed to backup state db due to ${err.message}, abort!`);
|
|
160
177
|
return false;
|
|
@@ -177,7 +194,7 @@ const runMigrationScripts = async ({
|
|
|
177
194
|
printError(`Failed to execute migration script: ${script}, error: ${err.message}`);
|
|
178
195
|
|
|
179
196
|
try {
|
|
180
|
-
await doRestore({
|
|
197
|
+
await doRestore({ configFile, dataDir, printInfo, printSuccess, backupPath });
|
|
181
198
|
} catch (err2) {
|
|
182
199
|
printError(`Failed to restore state db due to: ${err2.message}`);
|
|
183
200
|
}
|
|
@@ -189,9 +206,142 @@ const runMigrationScripts = async ({
|
|
|
189
206
|
return true;
|
|
190
207
|
};
|
|
191
208
|
|
|
209
|
+
const runSchemaMigrations = async ({
|
|
210
|
+
dataDir,
|
|
211
|
+
blocklets = [],
|
|
212
|
+
printInfo = console.info, // eslint-disable-line
|
|
213
|
+
printSuccess = console.info, // eslint-disable-line
|
|
214
|
+
}) => {
|
|
215
|
+
// migrate server schema
|
|
216
|
+
let filePath = getDbFilePath(path.join(dataDir, 'core/server.db'));
|
|
217
|
+
await doSchemaMigration(filePath, 'server');
|
|
218
|
+
printSuccess(`Server schema successfully migrated: ${filePath}`);
|
|
219
|
+
|
|
220
|
+
// migrate service schema
|
|
221
|
+
filePath = getDbFilePath(path.join(dataDir, 'services/service.db'));
|
|
222
|
+
await doSchemaMigration(filePath, 'service');
|
|
223
|
+
printSuccess(`Service schema successfully migrated: ${filePath}`);
|
|
224
|
+
|
|
225
|
+
// migrate blocklet schema
|
|
226
|
+
for (let i = 0; i < blocklets.length; i++) {
|
|
227
|
+
const blocklet = blocklets[i];
|
|
228
|
+
const env = blocklet.environments.find((x) => x.key === 'BLOCKLET_DATA_DIR');
|
|
229
|
+
if (env) {
|
|
230
|
+
filePath = getDbFilePath(path.join(env.value, 'blocklet.db'));
|
|
231
|
+
await doSchemaMigration(filePath, 'blocklet');
|
|
232
|
+
printSuccess(`Blocklet schema successfully migrated: ${blocklet.appPid}: ${filePath}`);
|
|
233
|
+
} else {
|
|
234
|
+
printInfo(`Skip migrate schema for blocklet: ${blocklet.appPid}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// migrate certificate manager schema
|
|
239
|
+
for (let i = 0; i < MODULES.length; i++) {
|
|
240
|
+
filePath = getDbFilePath(path.join(dataDir, `modules/${MODULES[i]}/module.db`));
|
|
241
|
+
await doSchemaMigration(filePath, MODULES[i]);
|
|
242
|
+
printSuccess(`${MODULES[i]} schema successfully migrated: ${filePath}`);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
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
|
+
const closeDatabaseConnections = async ({
|
|
313
|
+
dataDir,
|
|
314
|
+
blocklets = [],
|
|
315
|
+
printInfo = console.info, // eslint-disable-line
|
|
316
|
+
}) => {
|
|
317
|
+
const dataFiles = [
|
|
318
|
+
getDbFilePath(path.join(dataDir, 'core/server.db')),
|
|
319
|
+
getDbFilePath(path.join(dataDir, 'services/service.db')),
|
|
320
|
+
];
|
|
321
|
+
for (let i = 0; i < blocklets.length; i++) {
|
|
322
|
+
const blocklet = blocklets[i];
|
|
323
|
+
const env = blocklet.environments.find((x) => x.key === 'BLOCKLET_DATA_DIR');
|
|
324
|
+
if (env) {
|
|
325
|
+
dataFiles.push(getDbFilePath(path.join(env.value, 'blocklet.db')));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
for (let i = 0; i < MODULES.length; i++) {
|
|
329
|
+
dataFiles.push(getDbFilePath(path.join(dataDir, `modules/${MODULES[i]}/module.db`)));
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const connections = dataFiles.map((x) => createSequelize(x));
|
|
333
|
+
connections.forEach((x) => {
|
|
334
|
+
x.close();
|
|
335
|
+
printInfo(`Closed database connection: ${x}`);
|
|
336
|
+
});
|
|
337
|
+
};
|
|
338
|
+
|
|
192
339
|
module.exports = {
|
|
193
340
|
getMigrationScripts,
|
|
194
341
|
runMigrationScripts,
|
|
342
|
+
runSchemaMigrations,
|
|
343
|
+
runDataMigrations,
|
|
344
|
+
closeDatabaseConnections,
|
|
195
345
|
doBackup,
|
|
196
346
|
doRestore,
|
|
197
347
|
};
|
|
@@ -2,7 +2,7 @@ const EventEmitter = require('events');
|
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const cloneDeep = require('lodash/cloneDeep');
|
|
4
4
|
|
|
5
|
-
const { PROCESS_NAME_DAEMON,
|
|
5
|
+
const { PROCESS_NAME_DAEMON, PROCESS_NAME_SERVICE, EVENTS } = require('@abtnode/constant');
|
|
6
6
|
const defaultLogger = require('@abtnode/logger')('@abtnode/util:node-runtime-info');
|
|
7
7
|
const pm2 = require('@abtnode/util/lib/async-pm2');
|
|
8
8
|
|
|
@@ -45,7 +45,6 @@ const getProcessInfo = (processId, { returnList } = {}) =>
|
|
|
45
45
|
// mem: number;
|
|
46
46
|
// daemonMem: number;
|
|
47
47
|
// serviceMem: number;
|
|
48
|
-
// dbMem: number;
|
|
49
48
|
// };
|
|
50
49
|
|
|
51
50
|
// type History = Array<NodeHistoryItem>;
|
|
@@ -57,7 +56,6 @@ const getProcessInfo = (processId, { returnList } = {}) =>
|
|
|
57
56
|
// disks: [];
|
|
58
57
|
// daemon: RuntimeInfo
|
|
59
58
|
// service: ServiceRuntimeInfo
|
|
60
|
-
// db: RuntimeInfo
|
|
61
59
|
|
|
62
60
|
// type MonitorData = {
|
|
63
61
|
// realtime: Realtime;
|
|
@@ -72,7 +70,6 @@ const DEFAULT_DATA = {
|
|
|
72
70
|
disks: [],
|
|
73
71
|
daemon: {},
|
|
74
72
|
service: {},
|
|
75
|
-
db: {},
|
|
76
73
|
},
|
|
77
74
|
history: [],
|
|
78
75
|
};
|
|
@@ -123,13 +120,8 @@ class NodeRuntimeMonitor extends EventEmitter {
|
|
|
123
120
|
this.logger.error(`failed to get daemon info: ${error.message}`);
|
|
124
121
|
})
|
|
125
122
|
: Promise.resolve(),
|
|
126
|
-
process.env.NODE_ENV !== 'development'
|
|
127
|
-
? getProcessInfo(PROCESS_NAME_PROXY).catch((error) => {
|
|
128
|
-
this.logger.error(`failed to get db info: ${error.message}`);
|
|
129
|
-
})
|
|
130
|
-
: Promise.resolve(),
|
|
131
123
|
])
|
|
132
|
-
.then(([{ value: sysInfo }, { value: serviceInfos }, { value: daemonInfo }
|
|
124
|
+
.then(([{ value: sysInfo }, { value: serviceInfos }, { value: daemonInfo }]) => {
|
|
133
125
|
this.inProgress = false;
|
|
134
126
|
|
|
135
127
|
const historyItem = {
|
|
@@ -138,7 +130,6 @@ class NodeRuntimeMonitor extends EventEmitter {
|
|
|
138
130
|
mem: 0,
|
|
139
131
|
daemonMem: 0,
|
|
140
132
|
serviceMem: 0,
|
|
141
|
-
dbMem: 0,
|
|
142
133
|
};
|
|
143
134
|
|
|
144
135
|
if (sysInfo) {
|
|
@@ -186,24 +177,6 @@ class NodeRuntimeMonitor extends EventEmitter {
|
|
|
186
177
|
this.data.realtime.daemon = {};
|
|
187
178
|
}
|
|
188
179
|
|
|
189
|
-
if (dbInfo) {
|
|
190
|
-
const proc = dbInfo;
|
|
191
|
-
|
|
192
|
-
const runtimeInfo = {
|
|
193
|
-
pid: proc.pid,
|
|
194
|
-
uptime: proc.pm2_env ? +new Date() - Number(proc.pm2_env.pm_uptime) : 0,
|
|
195
|
-
memoryUsage: proc.monit.memory,
|
|
196
|
-
cpuUsage: proc.monit.cpu,
|
|
197
|
-
status: proc.pm2_env ? proc.pm2_env.status : null,
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
this.data.realtime.db = runtimeInfo;
|
|
201
|
-
|
|
202
|
-
historyItem.dbMem = runtimeInfo.memoryUsage;
|
|
203
|
-
} else {
|
|
204
|
-
this.data.realtime.db = {};
|
|
205
|
-
}
|
|
206
|
-
|
|
207
180
|
this.logger.info('server runtime info', historyItem);
|
|
208
181
|
|
|
209
182
|
this._push(historyItem);
|
package/lib/router/helper.js
CHANGED
|
@@ -836,7 +836,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
836
836
|
domainAliases.push(...dashboardAliasDomains);
|
|
837
837
|
|
|
838
838
|
try {
|
|
839
|
-
const result = await siteState.update({
|
|
839
|
+
const result = await siteState.update({ id: dashboardSite.id }, { $set: { domainAliases } });
|
|
840
840
|
|
|
841
841
|
updatedResult.push(result);
|
|
842
842
|
} catch (error) {
|
|
@@ -992,7 +992,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
992
992
|
* add rules in wellknown site
|
|
993
993
|
* This function should be called after `ensureDashboardRouting`
|
|
994
994
|
*
|
|
995
|
-
* @returns {boolean} if routing changed
|
|
995
|
+
* @returns {Promise<boolean>} if routing changed
|
|
996
996
|
*/
|
|
997
997
|
const ensureBlockletRouting = async (blocklet, context = {}) => {
|
|
998
998
|
const nodeInfo = await nodeState.read();
|
|
@@ -1008,7 +1008,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1008
1008
|
* remove custom rules of blocklet in old interface does not exist
|
|
1009
1009
|
* update custom rules of blocklet
|
|
1010
1010
|
*
|
|
1011
|
-
* @returns {boolean} if routing changed
|
|
1011
|
+
* @returns {Promise<boolean>} if routing changed
|
|
1012
1012
|
*/
|
|
1013
1013
|
const ensureBlockletCustomRouting = async (blocklet) => {
|
|
1014
1014
|
// Only one blocklet web interface can be declared since router 2.0
|
|
@@ -1053,7 +1053,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1053
1053
|
try {
|
|
1054
1054
|
// eslint-disable-next-line no-await-in-loop
|
|
1055
1055
|
await states.site.update(
|
|
1056
|
-
{
|
|
1056
|
+
{ id: site.id },
|
|
1057
1057
|
{ $set: { rules: site.rules.filter((x) => rulesToRemove.includes(x.id) === false) } }
|
|
1058
1058
|
);
|
|
1059
1059
|
changed = true;
|
|
@@ -1075,7 +1075,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1075
1075
|
* Update routing for blocklet when blocklet is upgraded
|
|
1076
1076
|
* This function should be called after `ensureDashboardRouting`
|
|
1077
1077
|
*
|
|
1078
|
-
* @returns {boolean} if routing changed
|
|
1078
|
+
* @returns {Promise<boolean>} if routing changed
|
|
1079
1079
|
*/
|
|
1080
1080
|
const ensureBlockletRoutingForUpgrade = async (blocklet, context = {}) => {
|
|
1081
1081
|
await routerManager.deleteRoutingRulesItemByDid(
|
|
@@ -1092,7 +1092,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
|
|
|
1092
1092
|
/**
|
|
1093
1093
|
* Remove routing for blocklet
|
|
1094
1094
|
*
|
|
1095
|
-
* @returns {boolean} if routing changed
|
|
1095
|
+
* @returns {Promise<boolean>} if routing changed
|
|
1096
1096
|
*/
|
|
1097
1097
|
const removeBlockletRouting = async (blocklet, context = {}) => {
|
|
1098
1098
|
const ruleChanged = await routerManager.deleteRoutingRulesItemByDid({ did: blocklet.meta.did }, context);
|
package/lib/router/manager.js
CHANGED
|
@@ -134,7 +134,7 @@ class RouterManager extends EventEmitter {
|
|
|
134
134
|
|
|
135
135
|
// eslint-disable-next-line no-unused-vars
|
|
136
136
|
async deleteRoutingSite({ id }, context = {}) {
|
|
137
|
-
const site = await states.site.findOne({
|
|
137
|
+
const site = await states.site.findOne({ id });
|
|
138
138
|
if ([DOMAIN_FOR_IP_SITE, DOMAIN_FOR_DEFAULT_SITE].includes(site.domain)) {
|
|
139
139
|
// eslint-disable-next-line quotes
|
|
140
140
|
throw new Error("Can not delete this site because it's protected");
|
|
@@ -143,7 +143,7 @@ class RouterManager extends EventEmitter {
|
|
|
143
143
|
// validate router config
|
|
144
144
|
await this.validateRouterConfig('deleteRoutingSite', { id });
|
|
145
145
|
|
|
146
|
-
const removedSiteCount = await states.site.remove({
|
|
146
|
+
const removedSiteCount = await states.site.remove({ id });
|
|
147
147
|
|
|
148
148
|
if (removedSiteCount === 0) {
|
|
149
149
|
throw new Error(`remove site ${id} failed`);
|
|
@@ -156,7 +156,7 @@ class RouterManager extends EventEmitter {
|
|
|
156
156
|
// eslint-disable-next-line no-unused-vars
|
|
157
157
|
async updateRoutingSite(params, context = {}) {
|
|
158
158
|
const site = await validateUpdateSite(params, context);
|
|
159
|
-
const existed = await states.site.findOne({
|
|
159
|
+
const existed = await states.site.findOne({ id: site.id });
|
|
160
160
|
if (!existed) {
|
|
161
161
|
throw new Error('Can not update non-existing site');
|
|
162
162
|
}
|
|
@@ -169,30 +169,27 @@ class RouterManager extends EventEmitter {
|
|
|
169
169
|
|
|
170
170
|
if (site.domain) {
|
|
171
171
|
const newDomain = site.domain;
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
if (ruleCountInDB > 0) {
|
|
172
|
+
const exist = await states.site.domainExists(newDomain);
|
|
173
|
+
if (exist) {
|
|
177
174
|
throw new Error(`Site ${newDomain} already exists`);
|
|
178
175
|
}
|
|
179
176
|
|
|
180
177
|
updateSet.domain = newDomain;
|
|
181
178
|
}
|
|
182
179
|
|
|
183
|
-
const updated = await states.site.update({
|
|
180
|
+
const updated = await states.site.update({ id: site.id }, { $set: updateSet });
|
|
184
181
|
|
|
185
182
|
logger.info('router.site.updated', { site, updated });
|
|
186
183
|
this.emit('router.site.updated', site.id);
|
|
187
184
|
|
|
188
|
-
const dbSite = await states.site.findOne({
|
|
185
|
+
const dbSite = await states.site.findOne({ id: site.id });
|
|
189
186
|
await attachRuntimeDomainAliases({ sites: dbSite, context, node: states.node });
|
|
190
187
|
return dbSite;
|
|
191
188
|
}
|
|
192
189
|
|
|
193
190
|
async addDomainAlias({ id, domainAlias: tmpAlias, force }, context = {}) {
|
|
194
191
|
const domainAlias = await validateAddDomainAlias(tmpAlias, context);
|
|
195
|
-
const dbSite = await states.site.findOne({
|
|
192
|
+
const dbSite = await states.site.findOne({ id });
|
|
196
193
|
if (!dbSite) {
|
|
197
194
|
throw new Error(`site ${id} does not exist`);
|
|
198
195
|
}
|
|
@@ -211,10 +208,7 @@ class RouterManager extends EventEmitter {
|
|
|
211
208
|
}
|
|
212
209
|
|
|
213
210
|
// check domain exists in site alias domain
|
|
214
|
-
const aliasDomainSite = await states.site.
|
|
215
|
-
$or: [{ domainAliases: domainAlias }, { 'domainAliases.value': domainAlias }],
|
|
216
|
-
});
|
|
217
|
-
|
|
211
|
+
const aliasDomainSite = await states.site.findByDomainAlias(domainAlias);
|
|
218
212
|
if (aliasDomainSite) {
|
|
219
213
|
if (!force) {
|
|
220
214
|
throw new Error(`${domainAlias} already exists`);
|
|
@@ -223,13 +217,14 @@ class RouterManager extends EventEmitter {
|
|
|
223
217
|
}
|
|
224
218
|
}
|
|
225
219
|
|
|
220
|
+
const doc = await states.site.findOne({ id });
|
|
226
221
|
const updateResult = await states.site.update(
|
|
227
|
-
{
|
|
228
|
-
{ $
|
|
222
|
+
{ id },
|
|
223
|
+
{ $set: { domainAliases: [...doc.domainAliases, { value: domainAlias, isProtected: false }] } }
|
|
229
224
|
);
|
|
230
225
|
logger.debug('add domain alias update result', { id, updateResult, domainAlias });
|
|
231
226
|
|
|
232
|
-
const newSite = await states.site.findOne({
|
|
227
|
+
const newSite = await states.site.findOne({ id });
|
|
233
228
|
await attachRuntimeDomainAliases({ sites: newSite, context, node: states.node });
|
|
234
229
|
|
|
235
230
|
return newSite;
|
|
@@ -237,7 +232,7 @@ class RouterManager extends EventEmitter {
|
|
|
237
232
|
|
|
238
233
|
async deleteDomainAlias({ id, domainAlias: tmpAlias }, context = {}) {
|
|
239
234
|
const domainAlias = await validateAddDomainAlias(tmpAlias, context);
|
|
240
|
-
const dbSite = await states.site.findOne({
|
|
235
|
+
const dbSite = await states.site.findOne({ id });
|
|
241
236
|
if (!dbSite) {
|
|
242
237
|
throw new Error(`site ${id} does not exist`);
|
|
243
238
|
}
|
|
@@ -250,7 +245,7 @@ class RouterManager extends EventEmitter {
|
|
|
250
245
|
return toLower(x.value) !== domainAlias;
|
|
251
246
|
});
|
|
252
247
|
|
|
253
|
-
const updateResult = await states.site.update({
|
|
248
|
+
const updateResult = await states.site.update({ id }, { $set: { domainAliases: dbSite.domainAliases } });
|
|
254
249
|
logger.debug('remove domain alias update result', { id, updateResult, domainAlias });
|
|
255
250
|
|
|
256
251
|
await attachRuntimeDomainAliases({ sites: dbSite, context, node: states.node });
|
|
@@ -268,7 +263,7 @@ class RouterManager extends EventEmitter {
|
|
|
268
263
|
rule.from.pathPrefix = tempRule.from.pathPrefix;
|
|
269
264
|
}
|
|
270
265
|
|
|
271
|
-
const dbSite = await states.site.findOne({
|
|
266
|
+
const dbSite = await states.site.findOne({ id });
|
|
272
267
|
if (!dbSite) {
|
|
273
268
|
throw new Error(`site ${id} does not exist`);
|
|
274
269
|
}
|
|
@@ -295,7 +290,7 @@ class RouterManager extends EventEmitter {
|
|
|
295
290
|
await states.site.addRuleToSite(id, x);
|
|
296
291
|
}
|
|
297
292
|
|
|
298
|
-
const newSite = await states.site.findOne({
|
|
293
|
+
const newSite = await states.site.findOne({ id });
|
|
299
294
|
await attachRuntimeDomainAliases({ sites: newSite, context, node: states.node });
|
|
300
295
|
|
|
301
296
|
this.emit('router.rule.created', newSite);
|
|
@@ -312,8 +307,11 @@ class RouterManager extends EventEmitter {
|
|
|
312
307
|
rule.from.pathPrefix = tmpRule.from.pathPrefix;
|
|
313
308
|
}
|
|
314
309
|
|
|
315
|
-
const dbSite = await states.site.findOne({
|
|
310
|
+
const dbSite = await states.site.findOne({ id });
|
|
316
311
|
if (!dbSite) {
|
|
312
|
+
throw new Error(`site ${id} does not exist`);
|
|
313
|
+
}
|
|
314
|
+
if (!dbSite.rules.find((x) => x.id === rule.id)) {
|
|
317
315
|
throw new Error(`site ${id}, rule ${rule.id} does not exist`);
|
|
318
316
|
}
|
|
319
317
|
|
|
@@ -344,9 +342,9 @@ class RouterManager extends EventEmitter {
|
|
|
344
342
|
...(await this.getRulesForMutation(rule)),
|
|
345
343
|
];
|
|
346
344
|
|
|
347
|
-
const updateResult = await states.site.update({
|
|
345
|
+
const updateResult = await states.site.update({ id }, { $set: { rules: newRules } });
|
|
348
346
|
logger.info('update result', { updateResult });
|
|
349
|
-
const newSite = await states.site.findOne({
|
|
347
|
+
const newSite = await states.site.findOne({ id });
|
|
350
348
|
|
|
351
349
|
await attachRuntimeDomainAliases({ sites: newSite, context, node: states.node });
|
|
352
350
|
|
|
@@ -356,7 +354,7 @@ class RouterManager extends EventEmitter {
|
|
|
356
354
|
}
|
|
357
355
|
|
|
358
356
|
async deleteRoutingRule({ id, ruleId }, context = {}) {
|
|
359
|
-
const tmpRule = await states.site.
|
|
357
|
+
const tmpRule = await states.site.getSiteByRuleId(id, ruleId);
|
|
360
358
|
if (!tmpRule) {
|
|
361
359
|
throw new Error(`rule item ${ruleId} in rule ${id} does not exist`);
|
|
362
360
|
}
|
|
@@ -371,11 +369,14 @@ class RouterManager extends EventEmitter {
|
|
|
371
369
|
await this.validateRouterConfig('deleteRoutingRule', { id, ruleId });
|
|
372
370
|
|
|
373
371
|
// 只要有匹配到的查询条件,不管是否删除成功都不会返回 0,所以这里没用 update 的返回值
|
|
374
|
-
await states.site.
|
|
375
|
-
|
|
372
|
+
const doc = await states.site.findOne({ id });
|
|
373
|
+
if (doc.rules.some((x) => x.id === ruleId || x.groupId === ruleId)) {
|
|
374
|
+
const newRules = doc.rules.filter((x) => x.id !== ruleId && x.groupId !== ruleId);
|
|
375
|
+
await states.site.update({ id }, { $set: { rules: newRules } });
|
|
376
|
+
}
|
|
376
377
|
|
|
377
378
|
logger.info('router.rule.removed', { id, ruleId });
|
|
378
|
-
const newSite = await states.site.findOne({
|
|
379
|
+
const newSite = await states.site.findOne({ id });
|
|
379
380
|
|
|
380
381
|
await attachRuntimeDomainAliases({ sites: newSite, context, node: states.node });
|
|
381
382
|
|
|
@@ -410,9 +411,8 @@ class RouterManager extends EventEmitter {
|
|
|
410
411
|
// eslint-disable-next-line no-unused-vars
|
|
411
412
|
async deleteRoutingRulesItemByDid({ did, ruleFilter }, context = {}) {
|
|
412
413
|
logger.info('deleteRoutingRulesItemByDid.did', { did });
|
|
413
|
-
const sites = await states.site.
|
|
414
|
-
if (!
|
|
415
|
-
logger.warn('deleteRoutingRulesItemByDid sites is not an array');
|
|
414
|
+
const sites = await states.site.getSitesByBlocklet(did);
|
|
415
|
+
if (!sites.length) {
|
|
416
416
|
return false;
|
|
417
417
|
}
|
|
418
418
|
|
|
@@ -429,7 +429,7 @@ class RouterManager extends EventEmitter {
|
|
|
429
429
|
return false;
|
|
430
430
|
});
|
|
431
431
|
|
|
432
|
-
tasks.push(states.site.update({
|
|
432
|
+
tasks.push(states.site.update({ id: site.id }, { $set: { rules: site.rules } })); // eslint-disable-line no-underscore-dangle
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
const result = await Promise.all(tasks);
|
|
@@ -461,10 +461,9 @@ class RouterManager extends EventEmitter {
|
|
|
461
461
|
// eslint-disable-next-line consistent-return
|
|
462
462
|
async repopulateRouting({ sites }) {
|
|
463
463
|
if (Array.isArray(sites) && sites.length) {
|
|
464
|
-
const result = await states.site.remove({}
|
|
464
|
+
const result = await states.site.remove({});
|
|
465
465
|
logger.info('routing rules all removed', { result });
|
|
466
|
-
|
|
467
|
-
await states.site.insert(sites.map((x) => ({ ...x, _id: x.id })));
|
|
466
|
+
await states.site.insertMany(sites.map((x) => ({ ...x, id: x.id })));
|
|
468
467
|
}
|
|
469
468
|
}
|
|
470
469
|
|
package/lib/states/access-key.js
CHANGED
|
@@ -18,19 +18,10 @@ const validatePassport = (passport) => {
|
|
|
18
18
|
|
|
19
19
|
const getUserName = (context) => get(context, 'user.fullName', '');
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @extends BaseState<import('@abtnode/models').AccessKeyState>
|
|
23
|
+
*/
|
|
21
24
|
class AccessKeyState extends BaseState {
|
|
22
|
-
constructor(baseDir, config = {}) {
|
|
23
|
-
super(baseDir, { filename: 'access_key.db', ...config });
|
|
24
|
-
|
|
25
|
-
this.onReady(() => {
|
|
26
|
-
this.ensureIndex({ fieldName: 'accessKeyId', unique: true }, (error) => {
|
|
27
|
-
if (error) {
|
|
28
|
-
logger.error('ensure unique index failed', { error });
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
25
|
async create(input, context) {
|
|
35
26
|
const { remark, passport, tag } = input || {};
|
|
36
27
|
|
|
@@ -62,14 +53,6 @@ class AccessKeyState extends BaseState {
|
|
|
62
53
|
};
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
async getAccessKeyByTag({ tag } = {}) {
|
|
66
|
-
if (!tag) {
|
|
67
|
-
throw new Error('tag should not be empty');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return this.findOne({ tag });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
56
|
// eslint-disable-next-line no-unused-vars
|
|
74
57
|
async list(params, context) {
|
|
75
58
|
const res = await this.paginate({}, { createdAt: -1 }, { pageSize: 100 });
|