dbgate-api 6.6.0 → 6.6.2

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.
Files changed (56) hide show
  1. package/package.json +6 -6
  2. package/src/auth/authProvider.js +14 -2
  3. package/src/controllers/archive.js +1 -1
  4. package/src/controllers/auth.js +3 -2
  5. package/src/controllers/cloud.js +1 -1
  6. package/src/controllers/config.js +8 -5
  7. package/src/controllers/connections.js +12 -11
  8. package/src/controllers/databaseConnections.js +148 -83
  9. package/src/controllers/files.js +49 -19
  10. package/src/controllers/plugins.js +7 -4
  11. package/src/controllers/runners.js +10 -6
  12. package/src/controllers/scheduler.js +4 -3
  13. package/src/controllers/serverConnections.js +69 -14
  14. package/src/controllers/sessions.js +8 -5
  15. package/src/controllers/storage.js +0 -4
  16. package/src/controllers/uploads.js +2 -2
  17. package/src/currentVersion.js +2 -2
  18. package/src/index.js +36 -5
  19. package/src/main.js +59 -20
  20. package/src/proc/databaseConnectionProcess.js +45 -13
  21. package/src/proc/serverConnectionProcess.js +32 -6
  22. package/src/proc/sessionProcess.js +2 -2
  23. package/src/proc/sshForwardProcess.js +1 -1
  24. package/src/shell/archiveWriter.js +1 -1
  25. package/src/shell/copyStream.js +1 -1
  26. package/src/shell/executeQuery.js +3 -3
  27. package/src/shell/importDatabase.js +3 -3
  28. package/src/shell/jsonLinesReader.js +1 -1
  29. package/src/shell/jsonLinesWriter.js +1 -1
  30. package/src/shell/jsonReader.js +1 -1
  31. package/src/shell/jsonWriter.js +1 -1
  32. package/src/shell/loadDatabase.js +2 -2
  33. package/src/shell/modifyJsonLinesReader.js +1 -1
  34. package/src/shell/queryReader.js +1 -1
  35. package/src/shell/requirePlugin.js +6 -1
  36. package/src/shell/runScript.js +1 -1
  37. package/src/shell/sqlDataWriter.js +1 -1
  38. package/src/shell/tableReader.js +3 -3
  39. package/src/shell/tableWriter.js +1 -1
  40. package/src/shell/unzipDirectory.js +4 -4
  41. package/src/shell/zipDirectory.js +3 -3
  42. package/src/shell/zipJsonLinesData.js +3 -3
  43. package/src/storageModel.js +726 -105
  44. package/src/utility/DatastoreProxy.js +3 -3
  45. package/src/utility/JsonLinesDatastore.js +4 -2
  46. package/src/utility/appLogStore.js +119 -0
  47. package/src/utility/childProcessChecker.js +1 -1
  48. package/src/utility/cloudIntf.js +5 -5
  49. package/src/utility/connectUtility.js +1 -1
  50. package/src/utility/directories.js +2 -2
  51. package/src/utility/extractSingleFileFromZip.js +3 -3
  52. package/src/utility/hasPermission.js +286 -71
  53. package/src/utility/loadModelTransform.js +1 -1
  54. package/src/utility/sshTunnel.js +7 -7
  55. package/src/utility/sshTunnelProxy.js +1 -1
  56. package/src/utility/useController.js +3 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dbgate-api",
3
3
  "main": "src/index.js",
4
- "version": "6.6.0",
4
+ "version": "6.6.2",
5
5
  "homepage": "https://dbgate.org/",
6
6
  "repository": {
7
7
  "type": "git",
@@ -30,10 +30,10 @@
30
30
  "compare-versions": "^3.6.0",
31
31
  "cors": "^2.8.5",
32
32
  "cross-env": "^6.0.3",
33
- "dbgate-datalib": "^6.6.0",
33
+ "dbgate-datalib": "^6.6.2",
34
34
  "dbgate-query-splitter": "^4.11.5",
35
- "dbgate-sqltree": "^6.6.0",
36
- "dbgate-tools": "^6.6.0",
35
+ "dbgate-sqltree": "^6.6.2",
36
+ "dbgate-tools": "^6.6.2",
37
37
  "debug": "^4.3.4",
38
38
  "diff": "^5.0.0",
39
39
  "diff2html": "^3.4.13",
@@ -56,7 +56,7 @@
56
56
  "ncp": "^2.0.0",
57
57
  "node-cron": "^2.0.3",
58
58
  "on-finished": "^2.4.1",
59
- "pinomin": "^1.0.4",
59
+ "pinomin": "^1.0.5",
60
60
  "portfinder": "^1.0.28",
61
61
  "rimraf": "^3.0.0",
62
62
  "semver": "^7.6.3",
@@ -86,7 +86,7 @@
86
86
  "devDependencies": {
87
87
  "@types/fs-extra": "^9.0.11",
88
88
  "@types/lodash": "^4.14.149",
89
- "dbgate-types": "^6.6.0",
89
+ "dbgate-types": "^6.6.2",
90
90
  "env-cmd": "^10.1.0",
91
91
  "jsdoc-to-markdown": "^9.0.5",
92
92
  "node-loader": "^1.0.2",
@@ -36,12 +36,24 @@ class AuthProviderBase {
36
36
  return !!req?.user || !!req?.auth;
37
37
  }
38
38
 
39
- getCurrentPermissions(req) {
39
+ async getCurrentPermissions(req) {
40
40
  const login = this.getCurrentLogin(req);
41
41
  const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
42
42
  return permissions || process.env.PERMISSIONS;
43
43
  }
44
44
 
45
+ async checkCurrentConnectionPermission(req, conid) {
46
+ return true;
47
+ }
48
+
49
+ async getCurrentDatabasePermissions(req) {
50
+ return [];
51
+ }
52
+
53
+ async getCurrentTablePermissions(req) {
54
+ return [];
55
+ }
56
+
45
57
  getLoginPageConnections() {
46
58
  return null;
47
59
  }
@@ -94,7 +106,7 @@ class OAuthProvider extends AuthProviderBase {
94
106
  payload = jwt.decode(id_token);
95
107
  }
96
108
 
97
- logger.info({ payload }, 'User payload returned from OAUTH');
109
+ logger.info({ payload }, 'DBGM-00002 User payload returned from OAUTH');
98
110
 
99
111
  const login =
100
112
  process.env.OAUTH_LOGIN_FIELD && payload && payload[process.env.OAUTH_LOGIN_FIELD]
@@ -102,7 +102,7 @@ module.exports = {
102
102
  ...fileType('.matview.sql', 'matview.sql'),
103
103
  ];
104
104
  } catch (err) {
105
- logger.error(extractErrorLogData(err), 'Error reading archive files');
105
+ logger.error(extractErrorLogData(err), 'DBGM-00001 Error reading archive files');
106
106
  return [];
107
107
  }
108
108
  },
@@ -51,6 +51,7 @@ function authMiddleware(req, res, next) {
51
51
  '/auth/oauth-token',
52
52
  '/auth/login',
53
53
  '/auth/redirect',
54
+ '/redirect',
54
55
  '/stream',
55
56
  '/storage/get-connections-for-login-page',
56
57
  '/storage/set-admin-password',
@@ -99,7 +100,7 @@ function authMiddleware(req, res, next) {
99
100
  return next();
100
101
  }
101
102
 
102
- logger.error(extractErrorLogData(err), 'Sending invalid token error');
103
+ logger.error(extractErrorLogData(err), 'DBGM-00098 Sending invalid token error');
103
104
 
104
105
  return unauthorizedResponse(req, res, 'invalid token');
105
106
  }
@@ -139,9 +140,9 @@ module.exports = {
139
140
  const accessToken = jwt.sign(
140
141
  {
141
142
  login: 'superadmin',
142
- permissions: await storage.loadSuperadminPermissions(),
143
143
  roleId: -3,
144
144
  licenseUid,
145
+ amoid: 'superadmin',
145
146
  },
146
147
  getTokenSecret(),
147
148
  {
@@ -45,7 +45,7 @@ module.exports = {
45
45
  const resp = await callCloudApiGet('content-list');
46
46
  return resp;
47
47
  } catch (err) {
48
- logger.error(extractErrorLogData(err), 'Error getting cloud content list');
48
+ logger.error(extractErrorLogData(err), 'DBGM-00099 Error getting cloud content list');
49
49
 
50
50
  return [];
51
51
  }
@@ -3,7 +3,7 @@ const os = require('os');
3
3
  const path = require('path');
4
4
  const axios = require('axios');
5
5
  const { datadir, getLogsFilePath } = require('../utility/directories');
6
- const { hasPermission } = require('../utility/hasPermission');
6
+ const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
7
7
  const socket = require('../utility/socket');
8
8
  const _ = require('lodash');
9
9
  const AsyncLock = require('async-lock');
@@ -46,7 +46,7 @@ module.exports = {
46
46
  async get(_params, req) {
47
47
  const authProvider = getAuthProviderFromReq(req);
48
48
  const login = authProvider.getCurrentLogin(req);
49
- const permissions = authProvider.getCurrentPermissions(req);
49
+ const permissions = await authProvider.getCurrentPermissions(req);
50
50
  const isUserLoggedIn = authProvider.isUserLoggedIn(req);
51
51
 
52
52
  const singleConid = authProvider.getSingleConnectionId(req);
@@ -280,7 +280,8 @@ module.exports = {
280
280
 
281
281
  updateSettings_meta: true,
282
282
  async updateSettings(values, req) {
283
- if (!hasPermission(`settings/change`, req)) return false;
283
+ const loadedPermissions = await loadPermissionsFromRequest(req);
284
+ if (!hasPermission(`settings/change`, loadedPermissions)) return false;
284
285
  cachedSettingsValue = null;
285
286
 
286
287
  const res = await lock.acquire('settings', async () => {
@@ -392,7 +393,8 @@ module.exports = {
392
393
 
393
394
  exportConnectionsAndSettings_meta: true,
394
395
  async exportConnectionsAndSettings(_params, req) {
395
- if (!hasPermission(`admin/config`, req)) {
396
+ const loadedPermissions = await loadPermissionsFromRequest(req);
397
+ if (!hasPermission(`admin/config`, loadedPermissions)) {
396
398
  throw new Error('Permission denied: admin/config');
397
399
  }
398
400
 
@@ -416,7 +418,8 @@ module.exports = {
416
418
 
417
419
  importConnectionsAndSettings_meta: true,
418
420
  async importConnectionsAndSettings({ db }, req) {
419
- if (!hasPermission(`admin/config`, req)) {
421
+ const loadedPermissions = await loadPermissionsFromRequest(req);
422
+ if (!hasPermission(`admin/config`, loadedPermissions)) {
420
423
  throw new Error('Permission denied: admin/config');
421
424
  }
422
425
 
@@ -14,7 +14,7 @@ const JsonLinesDatabase = require('../utility/JsonLinesDatabase');
14
14
  const processArgs = require('../utility/processArgs');
15
15
  const { safeJsonParse, getLogger, extractErrorLogData } = require('dbgate-tools');
16
16
  const platformInfo = require('../utility/platformInfo');
17
- const { connectionHasPermission, testConnectionPermission } = require('../utility/hasPermission');
17
+ const { connectionHasPermission, testConnectionPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
18
18
  const pipeForkLogs = require('../utility/pipeForkLogs');
19
19
  const requireEngineDriver = require('../utility/requireEngineDriver');
20
20
  const { getAuthProviderById } = require('../auth/authProvider');
@@ -116,12 +116,12 @@ function getPortalCollections() {
116
116
  }
117
117
  }
118
118
 
119
- logger.info({ connections: connections.map(pickSafeConnectionInfo) }, 'Using connections from ENV variables');
119
+ logger.info({ connections: connections.map(pickSafeConnectionInfo) }, 'DBGM-00005 Using connections from ENV variables');
120
120
  const noengine = connections.filter(x => !x.engine);
121
121
  if (noengine.length > 0) {
122
122
  logger.warn(
123
123
  { connections: noengine.map(x => x._id) },
124
- 'Invalid CONNECTIONS configuration, missing ENGINE for connection ID'
124
+ 'DBGM-00006 Invalid CONNECTIONS configuration, missing ENGINE for connection ID'
125
125
  );
126
126
  }
127
127
  return connections;
@@ -227,6 +227,7 @@ module.exports = {
227
227
  list_meta: true,
228
228
  async list(_params, req) {
229
229
  const storage = require('./storage');
230
+ const loadedPermissions = await loadPermissionsFromRequest(req);
230
231
 
231
232
  const storageConnections = await storage.connections(req);
232
233
  if (storageConnections) {
@@ -234,9 +235,9 @@ module.exports = {
234
235
  }
235
236
  if (portalConnections) {
236
237
  if (platformInfo.allowShellConnection) return portalConnections;
237
- return portalConnections.map(maskConnection).filter(x => connectionHasPermission(x, req));
238
+ return portalConnections.map(maskConnection).filter(x => connectionHasPermission(x, loadedPermissions));
238
239
  }
239
- return (await this.datastore.find()).filter(x => connectionHasPermission(x, req));
240
+ return (await this.datastore.find()).filter(x => connectionHasPermission(x, loadedPermissions));
240
241
  },
241
242
 
242
243
  async getUsedEngines() {
@@ -375,7 +376,7 @@ module.exports = {
375
376
  update_meta: true,
376
377
  async update({ _id, values }, req) {
377
378
  if (portalConnections) return;
378
- testConnectionPermission(_id, req);
379
+ await testConnectionPermission(_id, req);
379
380
  const res = await this.datastore.patch(_id, values);
380
381
  socket.emitChanged('connection-list-changed');
381
382
  return res;
@@ -392,7 +393,7 @@ module.exports = {
392
393
  updateDatabase_meta: true,
393
394
  async updateDatabase({ conid, database, values }, req) {
394
395
  if (portalConnections) return;
395
- testConnectionPermission(conid, req);
396
+ await testConnectionPermission(conid, req);
396
397
  const conn = await this.datastore.get(conid);
397
398
  let databases = (conn && conn.databases) || [];
398
399
  if (databases.find(x => x.name == database)) {
@@ -410,7 +411,7 @@ module.exports = {
410
411
  delete_meta: true,
411
412
  async delete(connection, req) {
412
413
  if (portalConnections) return;
413
- testConnectionPermission(connection, req);
414
+ await testConnectionPermission(connection, req);
414
415
  const res = await this.datastore.remove(connection._id);
415
416
  socket.emitChanged('connection-list-changed');
416
417
  return res;
@@ -452,7 +453,7 @@ module.exports = {
452
453
  _id: '__model',
453
454
  };
454
455
  }
455
- testConnectionPermission(conid, req);
456
+ await testConnectionPermission(conid, req);
456
457
  return this.getCore({ conid, mask: true });
457
458
  },
458
459
 
@@ -530,7 +531,7 @@ module.exports = {
530
531
  socket.emit('got-volatile-token', { strmid, savedConId: conid, volatileConId: volatile._id });
531
532
  return { success: true };
532
533
  } catch (err) {
533
- logger.error(extractErrorLogData(err), 'Error getting DB token');
534
+ logger.error(extractErrorLogData(err), 'DBGM-00100 Error getting DB token');
534
535
  return { error: err.message };
535
536
  }
536
537
  },
@@ -546,7 +547,7 @@ module.exports = {
546
547
  const resp = await authProvider.login(null, null, { conid: volatile._id }, req);
547
548
  return resp;
548
549
  } catch (err) {
549
- logger.error(extractErrorLogData(err), 'Error getting DB token');
550
+ logger.error(extractErrorLogData(err), 'DBGM-00101 Error getting DB token');
550
551
  return { error: err.message };
551
552
  }
552
553
  },