dbgate-api-premium 5.5.7-alpha.45

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 (125) hide show
  1. package/.env +19 -0
  2. package/.yarnrc +2 -0
  3. package/README.md +1 -0
  4. package/env/dblogin/.env +14 -0
  5. package/env/portal/.env +70 -0
  6. package/env/singledb/.env +17 -0
  7. package/env/storage/.env +43 -0
  8. package/package.json +89 -0
  9. package/src/auth/authCommon.js +16 -0
  10. package/src/auth/authProvider.js +343 -0
  11. package/src/auth/storageAuthProvider.js +393 -0
  12. package/src/controllers/apps.js +280 -0
  13. package/src/controllers/archive.js +217 -0
  14. package/src/controllers/auth.js +136 -0
  15. package/src/controllers/config.js +271 -0
  16. package/src/controllers/connections.js +486 -0
  17. package/src/controllers/databaseConnections.js +561 -0
  18. package/src/controllers/files.js +222 -0
  19. package/src/controllers/jsldata.js +296 -0
  20. package/src/controllers/metadata.js +47 -0
  21. package/src/controllers/plugins.js +216 -0
  22. package/src/controllers/queryHistory.js +54 -0
  23. package/src/controllers/runners.js +234 -0
  24. package/src/controllers/scheduler.js +46 -0
  25. package/src/controllers/serverConnections.js +271 -0
  26. package/src/controllers/sessions.js +243 -0
  27. package/src/controllers/storage.js +380 -0
  28. package/src/controllers/storageDb.js +215 -0
  29. package/src/controllers/uploads.js +133 -0
  30. package/src/currentVersion.js +5 -0
  31. package/src/gistSecret.js +2 -0
  32. package/src/index.js +139 -0
  33. package/src/main.js +202 -0
  34. package/src/packagedPluginsContent.js +1 -0
  35. package/src/proc/connectProcess.js +38 -0
  36. package/src/proc/databaseConnectionProcess.js +431 -0
  37. package/src/proc/index.js +15 -0
  38. package/src/proc/jslDatastoreProcess.js +60 -0
  39. package/src/proc/serverConnectionProcess.js +188 -0
  40. package/src/proc/sessionProcess.js +390 -0
  41. package/src/proc/sshForwardProcess.js +75 -0
  42. package/src/shell/archiveReader.js +11 -0
  43. package/src/shell/archiveWriter.js +22 -0
  44. package/src/shell/autoIndexForeignKeysTransform.js +19 -0
  45. package/src/shell/collectorWriter.js +33 -0
  46. package/src/shell/consoleObjectWriter.js +16 -0
  47. package/src/shell/copyStream.js +48 -0
  48. package/src/shell/dataDuplicator.js +63 -0
  49. package/src/shell/dataTypeMapperTransform.js +21 -0
  50. package/src/shell/dbModelToJson.js +16 -0
  51. package/src/shell/deployDb.js +56 -0
  52. package/src/shell/download.js +15 -0
  53. package/src/shell/dropAllDbObjects.js +42 -0
  54. package/src/shell/dumpDatabase.js +49 -0
  55. package/src/shell/executeQuery.js +39 -0
  56. package/src/shell/fakeObjectReader.js +35 -0
  57. package/src/shell/finalizer.js +12 -0
  58. package/src/shell/generateDeploySql.js +95 -0
  59. package/src/shell/generateModelSql.js +30 -0
  60. package/src/shell/importDatabase.js +85 -0
  61. package/src/shell/index.js +80 -0
  62. package/src/shell/initializeApiEnvironment.js +9 -0
  63. package/src/shell/jslDataReader.js +9 -0
  64. package/src/shell/jsonLinesReader.js +52 -0
  65. package/src/shell/jsonLinesWriter.js +36 -0
  66. package/src/shell/jsonReader.js +84 -0
  67. package/src/shell/jsonToDbModel.js +9 -0
  68. package/src/shell/jsonWriter.js +97 -0
  69. package/src/shell/loadDatabase.js +27 -0
  70. package/src/shell/loadFile.js +10 -0
  71. package/src/shell/modifyJsonLinesReader.js +148 -0
  72. package/src/shell/queryReader.js +30 -0
  73. package/src/shell/registerPlugins.js +9 -0
  74. package/src/shell/requirePlugin.js +43 -0
  75. package/src/shell/runScript.js +19 -0
  76. package/src/shell/sqlDataWriter.js +52 -0
  77. package/src/shell/sqlTextReplacementTransform.js +32 -0
  78. package/src/shell/tableReader.js +39 -0
  79. package/src/shell/tableWriter.js +18 -0
  80. package/src/storageModel.js +819 -0
  81. package/src/utility/ColumnMapTransformStream.js +21 -0
  82. package/src/utility/DatastoreProxy.js +106 -0
  83. package/src/utility/EnsureStreamHeaderStream.js +31 -0
  84. package/src/utility/JsonLinesDatabase.js +148 -0
  85. package/src/utility/JsonLinesDatastore.js +232 -0
  86. package/src/utility/LineReader.js +88 -0
  87. package/src/utility/SSHConnection.js +251 -0
  88. package/src/utility/authProxy.js +133 -0
  89. package/src/utility/checkLicense.js +186 -0
  90. package/src/utility/childProcessChecker.js +21 -0
  91. package/src/utility/cleanDirectory.js +24 -0
  92. package/src/utility/cloudUpgrade.js +61 -0
  93. package/src/utility/connectUtility.js +111 -0
  94. package/src/utility/crypting.js +105 -0
  95. package/src/utility/diff2htmlPage.js +8 -0
  96. package/src/utility/directories.js +179 -0
  97. package/src/utility/downloadPackage.js +51 -0
  98. package/src/utility/downloader.js +25 -0
  99. package/src/utility/exceptions.js +9 -0
  100. package/src/utility/exportDbModel.js +31 -0
  101. package/src/utility/exportDbModelSql.js +80 -0
  102. package/src/utility/getChartExport.js +55 -0
  103. package/src/utility/getDiagramExport.js +25 -0
  104. package/src/utility/getExpressPath.js +10 -0
  105. package/src/utility/getJslFileName.js +16 -0
  106. package/src/utility/getMapExport.js +77 -0
  107. package/src/utility/hardwareFingerprint.js +89 -0
  108. package/src/utility/hasPermission.js +101 -0
  109. package/src/utility/importDbModel.js +9 -0
  110. package/src/utility/loadFilesRecursive.js +20 -0
  111. package/src/utility/loadModelFolder.js +29 -0
  112. package/src/utility/loadModelTransform.js +36 -0
  113. package/src/utility/pipeForkLogs.js +19 -0
  114. package/src/utility/platformInfo.js +62 -0
  115. package/src/utility/processArgs.js +39 -0
  116. package/src/utility/processComm.js +18 -0
  117. package/src/utility/requireEngineDriver.js +26 -0
  118. package/src/utility/requirePluginFunction.js +16 -0
  119. package/src/utility/socket.js +68 -0
  120. package/src/utility/sshTunnel.js +106 -0
  121. package/src/utility/sshTunnelProxy.js +36 -0
  122. package/src/utility/timingSafeCheckToken.js +9 -0
  123. package/src/utility/useController.js +99 -0
  124. package/tsconfig.json +13 -0
  125. package/webpack.config.js +55 -0
@@ -0,0 +1,106 @@
1
+ const portfinder = require('portfinder');
2
+ const stableStringify = require('json-stable-stringify');
3
+ const _ = require('lodash');
4
+ const AsyncLock = require('async-lock');
5
+ const lock = new AsyncLock();
6
+ const { fork } = require('child_process');
7
+ const processArgs = require('../utility/processArgs');
8
+ const { getLogger, extractErrorLogData } = require('dbgate-tools');
9
+ const pipeForkLogs = require('./pipeForkLogs');
10
+ const logger = getLogger('sshTunnel');
11
+
12
+ const sshTunnelCache = {};
13
+
14
+ const CONNECTION_FIELDS = [
15
+ 'sshHost',
16
+ 'sshPort',
17
+ 'sshLogin',
18
+ 'sshPassword',
19
+ 'sshMode',
20
+ 'sshKeyfile',
21
+ 'sshBastionHost',
22
+ 'sshKeyfilePassword',
23
+ ];
24
+ const TUNNEL_FIELDS = [...CONNECTION_FIELDS, 'server', 'port'];
25
+
26
+ function callForwardProcess(connection, tunnelConfig, tunnelCacheKey) {
27
+ let subprocess = fork(
28
+ global['API_PACKAGE'] || process.argv[1],
29
+ ['--is-forked-api', '--start-process', 'sshForwardProcess', ...processArgs.getPassArgs()],
30
+ {
31
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
32
+ }
33
+ );
34
+ pipeForkLogs(subprocess);
35
+
36
+ try {
37
+ subprocess.send({
38
+ msgtype: 'connect',
39
+ connection,
40
+ tunnelConfig,
41
+ });
42
+ } catch (err) {
43
+ logger.error(extractErrorLogData(err), 'Error connecting SSH');
44
+ }
45
+ return new Promise((resolve, reject) => {
46
+ subprocess.on('message', resp => {
47
+ // @ts-ignore
48
+ const { msgtype, errorMessage } = resp;
49
+ if (msgtype == 'connected') {
50
+ resolve(subprocess);
51
+ }
52
+ if (msgtype == 'error') {
53
+ reject(new Error(errorMessage));
54
+ }
55
+ });
56
+ subprocess.on('exit', code => {
57
+ logger.info('SSH forward process exited');
58
+ delete sshTunnelCache[tunnelCacheKey];
59
+ });
60
+ });
61
+ }
62
+
63
+ async function getSshTunnel(connection) {
64
+ const tunnelCacheKey = stableStringify(_.pick(connection, TUNNEL_FIELDS));
65
+
66
+ return await lock.acquire(tunnelCacheKey, async () => {
67
+ if (sshTunnelCache[tunnelCacheKey]) return sshTunnelCache[tunnelCacheKey];
68
+ const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
69
+ // workaround for `getPortPromise` not releasing the port quickly enough
70
+ await new Promise(resolve => setTimeout(resolve, 500));
71
+ const tunnelConfig = {
72
+ fromPort: localPort,
73
+ toPort: connection.port,
74
+ toHost: connection.server,
75
+ };
76
+ try {
77
+ logger.info(
78
+ `Creating SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`
79
+ );
80
+
81
+ const subprocess = await callForwardProcess(connection, tunnelConfig, tunnelCacheKey);
82
+
83
+ logger.info(
84
+ `Created SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`
85
+ );
86
+
87
+ sshTunnelCache[tunnelCacheKey] = {
88
+ state: 'ok',
89
+ localPort,
90
+ subprocess,
91
+ };
92
+ return sshTunnelCache[tunnelCacheKey];
93
+ } catch (err) {
94
+ logger.error(extractErrorLogData(err), 'Error creating SSH tunnel:');
95
+ // error is not cached
96
+ return {
97
+ state: 'error',
98
+ message: err.message,
99
+ };
100
+ }
101
+ });
102
+ }
103
+
104
+ module.exports = {
105
+ getSshTunnel,
106
+ };
@@ -0,0 +1,36 @@
1
+ const crypto = require('crypto');
2
+ const { getLogger, extractErrorLogData } = require('dbgate-tools');
3
+ const { getSshTunnel } = require('./sshTunnel');
4
+ const logger = getLogger('sshTunnelProxy');
5
+
6
+ const dispatchedMessages = {};
7
+
8
+ async function handleGetSshTunnelRequest({ msgid, connection }, subprocess) {
9
+ const response = await getSshTunnel(connection);
10
+ try {
11
+ subprocess.send({ msgtype: 'getsshtunnel-response', msgid, response });
12
+ } catch (err) {
13
+ logger.error(extractErrorLogData(err), 'Error sending to SSH tunnel');
14
+ }
15
+ }
16
+
17
+ function handleGetSshTunnelResponse({ msgid, response }, subprocess) {
18
+ const { resolve } = dispatchedMessages[msgid];
19
+ delete dispatchedMessages[msgid];
20
+ resolve(response);
21
+ }
22
+
23
+ async function getSshTunnelProxy(connection) {
24
+ if (!process.send) return getSshTunnel(connection);
25
+ const msgid = crypto.randomUUID();
26
+ process.send({ msgtype: 'getsshtunnel-request', msgid, connection });
27
+ return new Promise((resolve, reject) => {
28
+ dispatchedMessages[msgid] = { resolve, reject };
29
+ });
30
+ }
31
+
32
+ module.exports = {
33
+ handleGetSshTunnelRequest,
34
+ handleGetSshTunnelResponse,
35
+ getSshTunnelProxy,
36
+ };
@@ -0,0 +1,9 @@
1
+ const crypto = require('crypto');
2
+
3
+ function timingSafeCheckToken(a, b) {
4
+ if (!a || !b) return false;
5
+ if (a.length != b.length) return false;
6
+ return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
7
+ }
8
+
9
+ module.exports = timingSafeCheckToken;
@@ -0,0 +1,99 @@
1
+ const _ = require('lodash');
2
+ const express = require('express');
3
+ const getExpressPath = require('./getExpressPath');
4
+ const { MissingCredentialsError } = require('./exceptions');
5
+ const { getLogger, extractErrorLogData } = require('dbgate-tools');
6
+
7
+ const logger = getLogger('useController');
8
+ /**
9
+ * @param {string} route
10
+ */
11
+ module.exports = function useController(app, electron, route, controller) {
12
+ const router = express.Router();
13
+
14
+ if (controller._init) {
15
+ logger.info(`Calling init controller for controller ${route}`);
16
+ try {
17
+ controller._init();
18
+ } catch (err) {
19
+ logger.error(extractErrorLogData(err), `Error initializing controller, exiting application`);
20
+ process.exit(1);
21
+ }
22
+ }
23
+
24
+ for (const key of _.keys(controller)) {
25
+ const obj = controller[key];
26
+ if (!_.isFunction(obj)) continue;
27
+ const meta = controller[`${key}_meta`];
28
+ if (!meta) continue;
29
+
30
+ const routeAction = `/${_.kebabCase(key)}`;
31
+
32
+ if (electron) {
33
+ if (meta === true) {
34
+ const handler = `${route.substring(1)}-${_.kebabCase(key)}`;
35
+ // console.log('REGISTERING HANDLER', handler);
36
+ electron.ipcMain.handle(handler, async (event, args) => {
37
+ try {
38
+ const data = await controller[key](args);
39
+ // console.log('HANDLED API', handler, data);
40
+ if (data === undefined) return null;
41
+ return data;
42
+ } catch (err) {
43
+ if (err instanceof MissingCredentialsError) {
44
+ return {
45
+ missingCredentials: true,
46
+ apiErrorMessage: 'Missing credentials',
47
+ detail: err.detail,
48
+ };
49
+ }
50
+ return { apiErrorMessage: err.message };
51
+ }
52
+ });
53
+ }
54
+
55
+ continue;
56
+ }
57
+
58
+ let method = 'post';
59
+ let raw = false;
60
+
61
+ // if (_.isString(meta)) {
62
+ // method = meta;
63
+ // }
64
+ if (_.isPlainObject(meta)) {
65
+ method = meta.method;
66
+ raw = meta.raw;
67
+ }
68
+
69
+ if (raw) {
70
+ router[method](routeAction, (req, res) => controller[key](req, res));
71
+ } else {
72
+ router[method](routeAction, async (req, res) => {
73
+ // if (controller._init && !controller._init_called) {
74
+ // await controller._init();
75
+ // controller._init_called = true;
76
+ // }
77
+ try {
78
+ const data = await controller[key]({ ...req.body, ...req.query }, req);
79
+ res.json(data);
80
+ } catch (err) {
81
+ logger.error(extractErrorLogData(err), `Error when processing route ${route}/${key}`);
82
+ if (err instanceof MissingCredentialsError) {
83
+ res.json({
84
+ missingCredentials: true,
85
+ apiErrorMessage: 'Missing credentials',
86
+ detail: err.detail,
87
+ });
88
+ } else {
89
+ res.status(500).json({ apiErrorMessage: err.message });
90
+ }
91
+ }
92
+ });
93
+ }
94
+ }
95
+
96
+ if (app) {
97
+ app.use(getExpressPath(route), router);
98
+ }
99
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "allowJs": true,
5
+ "checkJs": true,
6
+ "noEmit": true,
7
+ "moduleResolution": "node",
8
+ "skipLibCheck": true,
9
+ },
10
+ "include": [
11
+ "src"
12
+ ]
13
+ }
@@ -0,0 +1,55 @@
1
+ var webpack = require('webpack');
2
+ var path = require('path');
3
+
4
+ var config = {
5
+ context: __dirname + '/src',
6
+
7
+ entry: {
8
+ app: './index.js',
9
+ },
10
+ target: 'node',
11
+ node: {
12
+ __dirname: false,
13
+ },
14
+ output: {
15
+ path: path.resolve(__dirname, 'dist'),
16
+ filename: 'bundle.js',
17
+ libraryTarget: 'commonjs2',
18
+ },
19
+
20
+ // optimization: {
21
+ // minimize: false,
22
+ // },
23
+
24
+ module: {
25
+ rules: [
26
+ {
27
+ test: /\.node$/,
28
+ use: 'node-loader',
29
+ },
30
+ ],
31
+ },
32
+ plugins: [
33
+ new webpack.IgnorePlugin({
34
+ checkResource(resource) {
35
+ const lazyImports = ['uws'];
36
+ if (!lazyImports.includes(resource)) {
37
+ return false;
38
+ }
39
+ try {
40
+ require.resolve(resource);
41
+ } catch (err) {
42
+ return true;
43
+ }
44
+ return false;
45
+ },
46
+ }),
47
+ ],
48
+ externals: {
49
+ 'better-sqlite3': 'commonjs better-sqlite3',
50
+ 'oracledb': 'commonjs oracledb',
51
+ 'msnodesqlv8': 'commonjs msnodesqlv8',
52
+ },
53
+ };
54
+
55
+ module.exports = config;