dbgate-api 4.7.4-alpha.1 → 4.7.4-alpha.14
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/.env +12 -1
- package/env/singledb/.env +2 -0
- package/package.json +5 -5
- package/src/controllers/config.js +19 -6
- package/src/controllers/connections.js +17 -5
- package/src/controllers/databaseConnections.js +3 -3
- package/src/controllers/files.js +22 -17
- package/src/controllers/plugins.js +8 -8
- package/src/controllers/runners.js +12 -5
- package/src/controllers/scheduler.js +3 -3
- package/src/controllers/serverConnections.js +1 -1
- package/src/controllers/sessions.js +14 -1
- package/src/currentVersion.js +2 -2
- package/src/index.js +1 -1
- package/src/main.js +21 -12
- package/src/proc/connectProcess.js +1 -1
- package/src/proc/databaseConnectionProcess.js +1 -1
- package/src/proc/serverConnectionProcess.js +6 -3
- package/src/proc/sessionProcess.js +1 -1
- package/src/shell/executeQuery.js +1 -1
- package/src/shell/generateDeploySql.js +1 -1
- package/src/shell/queryReader.js +17 -5
- package/src/shell/tableReader.js +1 -1
- package/src/shell/tableWriter.js +1 -1
- package/src/utility/connectUtility.js +39 -3
- package/src/utility/crypting.js +7 -1
- package/src/utility/directories.js +5 -1
- package/src/utility/hasPermission.js +50 -6
- package/src/utility/platformInfo.js +3 -1
- package/src/utility/processArgs.js +10 -2
- package/src/utility/useController.js +1 -1
package/.env
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
DEVMODE=1
|
|
2
|
+
# PERMISSIONS=~widgets/app,~widgets/plugins
|
|
2
3
|
# DISABLE_SHELL=1
|
|
3
|
-
# HIDE_APP_EDITOR=1
|
|
4
|
+
# HIDE_APP_EDITOR=1
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
DEVWEB=1
|
|
8
|
+
LOGINS=admin,test
|
|
9
|
+
|
|
10
|
+
LOGIN_PASSWORD_admin=admin
|
|
11
|
+
LOGIN_PERMISSIONS_admin=*
|
|
12
|
+
|
|
13
|
+
LOGIN_PASSWORD_test=test
|
|
14
|
+
LOGIN_PERMISSIONS_test=~*, widgets/database
|
package/env/singledb/.env
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "4.7.4-alpha.
|
|
4
|
+
"version": "4.7.4-alpha.14",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"compare-versions": "^3.6.0",
|
|
26
26
|
"cors": "^2.8.5",
|
|
27
27
|
"cross-env": "^6.0.3",
|
|
28
|
-
"dbgate-query-splitter": "^4.7.4-alpha.
|
|
29
|
-
"dbgate-sqltree": "^4.7.4-alpha.
|
|
30
|
-
"dbgate-tools": "^4.7.4-alpha.
|
|
28
|
+
"dbgate-query-splitter": "^4.7.4-alpha.14",
|
|
29
|
+
"dbgate-sqltree": "^4.7.4-alpha.14",
|
|
30
|
+
"dbgate-tools": "^4.7.4-alpha.14",
|
|
31
31
|
"diff": "^5.0.0",
|
|
32
32
|
"diff2html": "^3.4.13",
|
|
33
33
|
"eslint": "^6.8.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@types/fs-extra": "^9.0.11",
|
|
65
65
|
"@types/lodash": "^4.14.149",
|
|
66
|
-
"dbgate-types": "^4.7.4-alpha.
|
|
66
|
+
"dbgate-types": "^4.7.4-alpha.14",
|
|
67
67
|
"env-cmd": "^10.1.0",
|
|
68
68
|
"node-loader": "^1.0.2",
|
|
69
69
|
"nodemon": "^2.0.2",
|
|
@@ -3,7 +3,7 @@ const os = require('os');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const axios = require('axios');
|
|
5
5
|
const { datadir } = require('../utility/directories');
|
|
6
|
-
const hasPermission = require('../utility/hasPermission');
|
|
6
|
+
const { hasPermission, getLogins } = require('../utility/hasPermission');
|
|
7
7
|
const socket = require('../utility/socket');
|
|
8
8
|
const _ = require('lodash');
|
|
9
9
|
const AsyncLock = require('async-lock');
|
|
@@ -26,18 +26,31 @@ module.exports = {
|
|
|
26
26
|
// },
|
|
27
27
|
|
|
28
28
|
get_meta: true,
|
|
29
|
-
async get() {
|
|
30
|
-
const
|
|
29
|
+
async get(_params, req) {
|
|
30
|
+
const logins = getLogins();
|
|
31
|
+
const login = logins ? logins.find(x => x.login == (req.auth && req.auth.user)) : null;
|
|
32
|
+
const permissions = login ? login.permissions : null;
|
|
31
33
|
|
|
32
34
|
return {
|
|
33
35
|
runAsPortal: !!connections.portalConnections,
|
|
34
36
|
singleDatabase: connections.singleDatabase,
|
|
35
|
-
hideAppEditor: !!process.env.HIDE_APP_EDITOR,
|
|
37
|
+
// hideAppEditor: !!process.env.HIDE_APP_EDITOR,
|
|
38
|
+
allowShellConnection: platformInfo.allowShellConnection,
|
|
39
|
+
allowShellScripting: platformInfo.allowShellConnection,
|
|
36
40
|
permissions,
|
|
41
|
+
login,
|
|
37
42
|
...currentVersion,
|
|
38
43
|
};
|
|
39
44
|
},
|
|
40
45
|
|
|
46
|
+
logout_meta: {
|
|
47
|
+
method: 'get',
|
|
48
|
+
raw: true,
|
|
49
|
+
},
|
|
50
|
+
logout(req, res) {
|
|
51
|
+
res.status(401).send('Logged out<br><a href="../..">Back to DbGate</a>');
|
|
52
|
+
},
|
|
53
|
+
|
|
41
54
|
platformInfo_meta: true,
|
|
42
55
|
async platformInfo() {
|
|
43
56
|
return platformInfo;
|
|
@@ -65,8 +78,8 @@ module.exports = {
|
|
|
65
78
|
},
|
|
66
79
|
|
|
67
80
|
updateSettings_meta: true,
|
|
68
|
-
async updateSettings(values) {
|
|
69
|
-
if (!hasPermission(`settings/change
|
|
81
|
+
async updateSettings(values, req) {
|
|
82
|
+
if (!hasPermission(`settings/change`, req)) return false;
|
|
70
83
|
|
|
71
84
|
const res = await lock.acquire('update', async () => {
|
|
72
85
|
const currentValue = await this.getSettings();
|
|
@@ -5,12 +5,14 @@ const fs = require('fs-extra');
|
|
|
5
5
|
|
|
6
6
|
const { datadir, filesdir } = require('../utility/directories');
|
|
7
7
|
const socket = require('../utility/socket');
|
|
8
|
-
const { encryptConnection } = require('../utility/crypting');
|
|
8
|
+
const { encryptConnection, maskConnection } = require('../utility/crypting');
|
|
9
9
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
10
10
|
const { pickSafeConnectionInfo } = require('../utility/crypting');
|
|
11
11
|
const JsonLinesDatabase = require('../utility/JsonLinesDatabase');
|
|
12
12
|
|
|
13
13
|
const processArgs = require('../utility/processArgs');
|
|
14
|
+
const { safeJsonParse } = require('dbgate-tools');
|
|
15
|
+
const platformInfo = require('../utility/platformInfo');
|
|
14
16
|
|
|
15
17
|
function getNamedArgs() {
|
|
16
18
|
const res = {};
|
|
@@ -56,6 +58,7 @@ function getPortalCollections() {
|
|
|
56
58
|
singleDatabase: !!process.env[`DATABASE_${id}`] || !!process.env[`FILE_${id}`],
|
|
57
59
|
displayName: process.env[`LABEL_${id}`],
|
|
58
60
|
isReadOnly: process.env[`READONLY_${id}`],
|
|
61
|
+
databases: process.env[`DBCONFIG_${id}`] ? safeJsonParse(process.env[`DBCONFIG_${id}`]) : null,
|
|
59
62
|
|
|
60
63
|
// SSH tunnel
|
|
61
64
|
useSshTunnel: process.env[`USE_SSH_${id}`],
|
|
@@ -163,7 +166,9 @@ module.exports = {
|
|
|
163
166
|
|
|
164
167
|
list_meta: true,
|
|
165
168
|
async list() {
|
|
166
|
-
return portalConnections
|
|
169
|
+
return portalConnections && !platformInfo.allowShellConnection
|
|
170
|
+
? portalConnections.map(maskConnection)
|
|
171
|
+
: this.datastore.find();
|
|
167
172
|
},
|
|
168
173
|
|
|
169
174
|
test_meta: true,
|
|
@@ -242,14 +247,21 @@ module.exports = {
|
|
|
242
247
|
return res;
|
|
243
248
|
},
|
|
244
249
|
|
|
245
|
-
|
|
246
|
-
async get({ conid }) {
|
|
250
|
+
async getCore({ conid, mask = false }) {
|
|
247
251
|
if (!conid) return null;
|
|
248
|
-
if (portalConnections)
|
|
252
|
+
if (portalConnections) {
|
|
253
|
+
const res = portalConnections.find(x => x._id == conid) || null;
|
|
254
|
+
return mask && !platformInfo.allowShellConnection ? maskConnection(res) : res;
|
|
255
|
+
}
|
|
249
256
|
const res = await this.datastore.get(conid);
|
|
250
257
|
return res || null;
|
|
251
258
|
},
|
|
252
259
|
|
|
260
|
+
get_meta: true,
|
|
261
|
+
async get({ conid }) {
|
|
262
|
+
return this.getCore({ conid, mask: true });
|
|
263
|
+
},
|
|
264
|
+
|
|
253
265
|
newSqliteDatabase_meta: true,
|
|
254
266
|
async newSqliteDatabase({ file }) {
|
|
255
267
|
const sqliteDir = path.join(filesdir(), 'sqlite');
|
|
@@ -79,7 +79,7 @@ module.exports = {
|
|
|
79
79
|
async ensureOpened(conid, database) {
|
|
80
80
|
const existing = this.opened.find(x => x.conid == conid && x.database == database);
|
|
81
81
|
if (existing) return existing;
|
|
82
|
-
const connection = await connections.
|
|
82
|
+
const connection = await connections.getCore({ conid });
|
|
83
83
|
const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
|
|
84
84
|
'--is-forked-api',
|
|
85
85
|
'--start-process',
|
|
@@ -392,8 +392,8 @@ module.exports = {
|
|
|
392
392
|
const targetDb = generateDbPairingId(
|
|
393
393
|
extendDatabaseInfo(await this.structure({ conid: targetConid, database: targetDatabase }))
|
|
394
394
|
);
|
|
395
|
-
// const sourceConnection = await connections.
|
|
396
|
-
const connection = await connections.
|
|
395
|
+
// const sourceConnection = await connections.getCore({conid:sourceConid})
|
|
396
|
+
const connection = await connections.getCore({ conid: targetConid });
|
|
397
397
|
const driver = requireEngineDriver(connection);
|
|
398
398
|
const targetDbPaired = matchPairedObjects(sourceDb, targetDb, dbDiffOptions);
|
|
399
399
|
const diffRows = computeDbDiffRows(sourceDb, targetDbPaired, dbDiffOptions, driver);
|
package/src/controllers/files.js
CHANGED
|
@@ -3,7 +3,7 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { filesdir, archivedir, resolveArchiveFolder, uploadsdir, appdir } = require('../utility/directories');
|
|
5
5
|
const getChartExport = require('../utility/getChartExport');
|
|
6
|
-
const hasPermission = require('../utility/hasPermission');
|
|
6
|
+
const { hasPermission } = require('../utility/hasPermission');
|
|
7
7
|
const socket = require('../utility/socket');
|
|
8
8
|
const scheduler = require('./scheduler');
|
|
9
9
|
const getDiagramExport = require('../utility/getDiagramExport');
|
|
@@ -23,8 +23,8 @@ function deserialize(format, text) {
|
|
|
23
23
|
|
|
24
24
|
module.exports = {
|
|
25
25
|
list_meta: true,
|
|
26
|
-
async list({ folder }) {
|
|
27
|
-
if (!hasPermission(`files/${folder}/read
|
|
26
|
+
async list({ folder }, req) {
|
|
27
|
+
if (!hasPermission(`files/${folder}/read`, req)) return [];
|
|
28
28
|
const dir = path.join(filesdir(), folder);
|
|
29
29
|
if (!(await fs.exists(dir))) return [];
|
|
30
30
|
const files = (await fs.readdir(dir)).map(file => ({ folder, file }));
|
|
@@ -32,11 +32,11 @@ module.exports = {
|
|
|
32
32
|
},
|
|
33
33
|
|
|
34
34
|
listAll_meta: true,
|
|
35
|
-
async listAll() {
|
|
35
|
+
async listAll(_params, req) {
|
|
36
36
|
const folders = await fs.readdir(filesdir());
|
|
37
37
|
const res = [];
|
|
38
38
|
for (const folder of folders) {
|
|
39
|
-
if (!hasPermission(`files/${folder}/read
|
|
39
|
+
if (!hasPermission(`files/${folder}/read`, req)) continue;
|
|
40
40
|
const dir = path.join(filesdir(), folder);
|
|
41
41
|
const files = (await fs.readdir(dir)).map(file => ({ folder, file }));
|
|
42
42
|
res.push(...files);
|
|
@@ -45,31 +45,34 @@ module.exports = {
|
|
|
45
45
|
},
|
|
46
46
|
|
|
47
47
|
delete_meta: true,
|
|
48
|
-
async delete({ folder, file }) {
|
|
49
|
-
if (!hasPermission(`files/${folder}/write
|
|
48
|
+
async delete({ folder, file }, req) {
|
|
49
|
+
if (!hasPermission(`files/${folder}/write`, req)) return false;
|
|
50
50
|
await fs.unlink(path.join(filesdir(), folder, file));
|
|
51
51
|
socket.emitChanged(`files-changed-${folder}`);
|
|
52
52
|
socket.emitChanged(`all-files-changed`);
|
|
53
|
+
return true;
|
|
53
54
|
},
|
|
54
55
|
|
|
55
56
|
rename_meta: true,
|
|
56
|
-
async rename({ folder, file, newFile }) {
|
|
57
|
-
if (!hasPermission(`files/${folder}/write
|
|
57
|
+
async rename({ folder, file, newFile }, req) {
|
|
58
|
+
if (!hasPermission(`files/${folder}/write`, req)) return false;
|
|
58
59
|
await fs.rename(path.join(filesdir(), folder, file), path.join(filesdir(), folder, newFile));
|
|
59
60
|
socket.emitChanged(`files-changed-${folder}`);
|
|
60
61
|
socket.emitChanged(`all-files-changed`);
|
|
62
|
+
return true;
|
|
61
63
|
},
|
|
62
64
|
|
|
63
65
|
copy_meta: true,
|
|
64
|
-
async copy({ folder, file, newFile }) {
|
|
65
|
-
if (!hasPermission(`files/${folder}/write
|
|
66
|
+
async copy({ folder, file, newFile }, req) {
|
|
67
|
+
if (!hasPermission(`files/${folder}/write`, req)) return false;
|
|
66
68
|
await fs.copyFile(path.join(filesdir(), folder, file), path.join(filesdir(), folder, newFile));
|
|
67
69
|
socket.emitChanged(`files-changed-${folder}`);
|
|
68
70
|
socket.emitChanged(`all-files-changed`);
|
|
71
|
+
return true;
|
|
69
72
|
},
|
|
70
73
|
|
|
71
74
|
load_meta: true,
|
|
72
|
-
async load({ folder, file, format }) {
|
|
75
|
+
async load({ folder, file, format }, req) {
|
|
73
76
|
if (folder.startsWith('archive:')) {
|
|
74
77
|
const text = await fs.readFile(path.join(resolveArchiveFolder(folder.substring('archive:'.length)), file), {
|
|
75
78
|
encoding: 'utf-8',
|
|
@@ -81,20 +84,22 @@ module.exports = {
|
|
|
81
84
|
});
|
|
82
85
|
return deserialize(format, text);
|
|
83
86
|
} else {
|
|
84
|
-
if (!hasPermission(`files/${folder}/read
|
|
87
|
+
if (!hasPermission(`files/${folder}/read`, req)) return null;
|
|
85
88
|
const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
|
|
86
89
|
return deserialize(format, text);
|
|
87
90
|
}
|
|
88
91
|
},
|
|
89
92
|
|
|
90
93
|
save_meta: true,
|
|
91
|
-
async save({ folder, file, data, format }) {
|
|
94
|
+
async save({ folder, file, data, format }, req) {
|
|
92
95
|
if (folder.startsWith('archive:')) {
|
|
96
|
+
if (!hasPermission(`archive/write`, req)) return false;
|
|
93
97
|
const dir = resolveArchiveFolder(folder.substring('archive:'.length));
|
|
94
98
|
await fs.writeFile(path.join(dir, file), serialize(format, data));
|
|
95
99
|
socket.emitChanged(`archive-files-changed-${folder.substring('archive:'.length)}`);
|
|
96
100
|
return true;
|
|
97
101
|
} else if (folder.startsWith('app:')) {
|
|
102
|
+
if (!hasPermission(`apps/write`, req)) return false;
|
|
98
103
|
const app = folder.substring('app:'.length);
|
|
99
104
|
await fs.writeFile(path.join(appdir(), app, file), serialize(format, data));
|
|
100
105
|
socket.emitChanged(`app-files-changed-${app}`);
|
|
@@ -102,7 +107,7 @@ module.exports = {
|
|
|
102
107
|
apps.emitChangedDbApp(folder);
|
|
103
108
|
return true;
|
|
104
109
|
} else {
|
|
105
|
-
if (!hasPermission(`files/${folder}/write
|
|
110
|
+
if (!hasPermission(`files/${folder}/write`, req)) return false;
|
|
106
111
|
const dir = path.join(filesdir(), folder);
|
|
107
112
|
if (!(await fs.exists(dir))) {
|
|
108
113
|
await fs.mkdir(dir);
|
|
@@ -123,8 +128,8 @@ module.exports = {
|
|
|
123
128
|
},
|
|
124
129
|
|
|
125
130
|
favorites_meta: true,
|
|
126
|
-
async favorites() {
|
|
127
|
-
if (!hasPermission(`files/favorites/read
|
|
131
|
+
async favorites(_params, req) {
|
|
132
|
+
if (!hasPermission(`files/favorites/read`, req)) return [];
|
|
128
133
|
const dir = path.join(filesdir(), 'favorites');
|
|
129
134
|
if (!(await fs.exists(dir))) return [];
|
|
130
135
|
const files = await fs.readdir(dir);
|
|
@@ -7,7 +7,7 @@ const socket = require('../utility/socket');
|
|
|
7
7
|
const compareVersions = require('compare-versions');
|
|
8
8
|
const requirePlugin = require('../shell/requirePlugin');
|
|
9
9
|
const downloadPackage = require('../utility/downloadPackage');
|
|
10
|
-
const hasPermission = require('../utility/hasPermission');
|
|
10
|
+
const { hasPermission } = require('../utility/hasPermission');
|
|
11
11
|
const _ = require('lodash');
|
|
12
12
|
const packagedPluginsContent = require('../packagedPluginsContent');
|
|
13
13
|
|
|
@@ -73,7 +73,7 @@ module.exports = {
|
|
|
73
73
|
const res = [];
|
|
74
74
|
for (const packageName of _.union(files1, files2)) {
|
|
75
75
|
if (packageName == 'dist') continue;
|
|
76
|
-
|
|
76
|
+
if (!/^dbgate-plugin-.*$/.test(packageName)) continue;
|
|
77
77
|
try {
|
|
78
78
|
if (packagedContent && packagedContent[packageName]) {
|
|
79
79
|
const manifest = {
|
|
@@ -115,8 +115,8 @@ module.exports = {
|
|
|
115
115
|
// },
|
|
116
116
|
|
|
117
117
|
install_meta: true,
|
|
118
|
-
async install({ packageName }) {
|
|
119
|
-
if (!hasPermission(`plugins/install
|
|
118
|
+
async install({ packageName }, req) {
|
|
119
|
+
if (!hasPermission(`plugins/install`, req)) return;
|
|
120
120
|
const dir = path.join(pluginsdir(), packageName);
|
|
121
121
|
// @ts-ignore
|
|
122
122
|
if (!(await fs.exists(dir))) {
|
|
@@ -128,8 +128,8 @@ module.exports = {
|
|
|
128
128
|
},
|
|
129
129
|
|
|
130
130
|
uninstall_meta: true,
|
|
131
|
-
async uninstall({ packageName }) {
|
|
132
|
-
if (!hasPermission(`plugins/install
|
|
131
|
+
async uninstall({ packageName }, req) {
|
|
132
|
+
if (!hasPermission(`plugins/install`, req)) return;
|
|
133
133
|
const dir = path.join(pluginsdir(), packageName);
|
|
134
134
|
await fs.rmdir(dir, { recursive: true });
|
|
135
135
|
socket.emitChanged(`installed-plugins-changed`);
|
|
@@ -138,8 +138,8 @@ module.exports = {
|
|
|
138
138
|
},
|
|
139
139
|
|
|
140
140
|
upgrade_meta: true,
|
|
141
|
-
async upgrade({ packageName }) {
|
|
142
|
-
if (!hasPermission(`plugins/install
|
|
141
|
+
async upgrade({ packageName }, req) {
|
|
142
|
+
if (!hasPermission(`plugins/install`, req)) return;
|
|
143
143
|
const dir = path.join(pluginsdir(), packageName);
|
|
144
144
|
// @ts-ignore
|
|
145
145
|
if (await fs.exists(dir)) {
|
|
@@ -6,9 +6,10 @@ const byline = require('byline');
|
|
|
6
6
|
const socket = require('../utility/socket');
|
|
7
7
|
const { fork } = require('child_process');
|
|
8
8
|
const { rundir, uploadsdir, pluginsdir, getPluginBackendPath, packagedPluginList } = require('../utility/directories');
|
|
9
|
-
const { extractShellApiPlugins, extractShellApiFunctionName } = require('dbgate-tools');
|
|
9
|
+
const { extractShellApiPlugins, extractShellApiFunctionName, jsonScriptToJavascript } = require('dbgate-tools');
|
|
10
10
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
11
11
|
const processArgs = require('../utility/processArgs');
|
|
12
|
+
const platformInfo = require('../utility/platformInfo');
|
|
12
13
|
|
|
13
14
|
function extractPlugins(script) {
|
|
14
15
|
const requireRegex = /\s*\/\/\s*@require\s+([^\s]+)\s*\n/g;
|
|
@@ -110,7 +111,7 @@ module.exports = {
|
|
|
110
111
|
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
111
112
|
env: {
|
|
112
113
|
...process.env,
|
|
113
|
-
DBGATE_API: global['API_PACKAGE'] ||
|
|
114
|
+
DBGATE_API: global['API_PACKAGE'] || process.argv[1],
|
|
114
115
|
..._.fromPairs(pluginNames.map(name => [`PLUGIN_${_.camelCase(name)}`, getPluginBackendPath(name)])),
|
|
115
116
|
},
|
|
116
117
|
}
|
|
@@ -149,11 +150,17 @@ module.exports = {
|
|
|
149
150
|
|
|
150
151
|
start_meta: true,
|
|
151
152
|
async start({ script }) {
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
const runid = uuidv1();
|
|
154
|
+
|
|
155
|
+
if (script.type == 'json') {
|
|
156
|
+
const js = jsonScriptToJavascript(script);
|
|
157
|
+
return this.startCore(runid, scriptTemplate(js, false));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!platformInfo.allowShellScripting) {
|
|
161
|
+
return { errorMessage: 'Shell scripting is not allowed' };
|
|
154
162
|
}
|
|
155
163
|
|
|
156
|
-
const runid = uuidv1();
|
|
157
164
|
return this.startCore(runid, scriptTemplate(script, false));
|
|
158
165
|
},
|
|
159
166
|
|
|
@@ -3,7 +3,7 @@ const fs = require('fs-extra');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const cron = require('node-cron');
|
|
5
5
|
const runners = require('./runners');
|
|
6
|
-
const hasPermission = require('../utility/hasPermission');
|
|
6
|
+
const { hasPermission } = require('../utility/hasPermission');
|
|
7
7
|
|
|
8
8
|
const scheduleRegex = /\s*\/\/\s*@schedule\s+([^\n]+)\n/;
|
|
9
9
|
|
|
@@ -26,8 +26,8 @@ module.exports = {
|
|
|
26
26
|
this.tasks.push(task);
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
-
async reload() {
|
|
30
|
-
if (!hasPermission('files/shell/read')) return;
|
|
29
|
+
async reload(_params, req) {
|
|
30
|
+
if (!hasPermission('files/shell/read', req)) return;
|
|
31
31
|
const shellDir = path.join(filesdir(), 'shell');
|
|
32
32
|
await this.unload();
|
|
33
33
|
if (!(await fs.exists(shellDir))) return;
|
|
@@ -37,7 +37,7 @@ module.exports = {
|
|
|
37
37
|
const res = await lock.acquire(conid, async () => {
|
|
38
38
|
const existing = this.opened.find(x => x.conid == conid);
|
|
39
39
|
if (existing) return existing;
|
|
40
|
-
const connection = await connections.
|
|
40
|
+
const connection = await connections.getCore({ conid });
|
|
41
41
|
const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
|
|
42
42
|
'--is-forked-api',
|
|
43
43
|
'--start-process',
|
|
@@ -54,6 +54,9 @@ module.exports = {
|
|
|
54
54
|
this.dispatchMessage(sesid, 'Query execution finished');
|
|
55
55
|
}
|
|
56
56
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
57
|
+
if (session.loadingReader_jslid) {
|
|
58
|
+
socket.emit(`session-jslid-done-${session.loadingReader_jslid}`);
|
|
59
|
+
}
|
|
57
60
|
if (session.killOnDone) {
|
|
58
61
|
this.kill({ sesid });
|
|
59
62
|
}
|
|
@@ -78,7 +81,7 @@ module.exports = {
|
|
|
78
81
|
create_meta: true,
|
|
79
82
|
async create({ conid, database }) {
|
|
80
83
|
const sesid = uuidv1();
|
|
81
|
-
const connection = await connections.
|
|
84
|
+
const connection = await connections.getCore({ conid });
|
|
82
85
|
const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
|
|
83
86
|
'--is-forked-api',
|
|
84
87
|
'--start-process',
|
|
@@ -124,6 +127,7 @@ module.exports = {
|
|
|
124
127
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
125
128
|
session.killOnDone = true;
|
|
126
129
|
const jslid = uuidv1();
|
|
130
|
+
session.loadingReader_jslid = jslid;
|
|
127
131
|
const fileName = queryName && appFolder ? path.join(appdir(), appFolder, `${queryName}.query.sql`) : null;
|
|
128
132
|
|
|
129
133
|
session.subprocess.send({ msgtype: 'executeReader', sql, fileName, jslid });
|
|
@@ -131,6 +135,15 @@ module.exports = {
|
|
|
131
135
|
return { jslid };
|
|
132
136
|
},
|
|
133
137
|
|
|
138
|
+
stopLoadingReader_meta: true,
|
|
139
|
+
async stopLoadingReader({ jslid }) {
|
|
140
|
+
const session = this.opened.find(x => x.loadingReader_jslid == jslid);
|
|
141
|
+
if (session) {
|
|
142
|
+
this.kill({ sesid: session.sesid });
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
},
|
|
146
|
+
|
|
134
147
|
// cancel_meta: true,
|
|
135
148
|
// async cancel({ sesid }) {
|
|
136
149
|
// const session = this.opened.find((x) => x.sesid == sesid);
|
package/src/currentVersion.js
CHANGED
package/src/index.js
CHANGED
|
@@ -8,7 +8,7 @@ if (processArgs.startProcess) {
|
|
|
8
8
|
const proc = require('./proc');
|
|
9
9
|
const module = proc[processArgs.startProcess];
|
|
10
10
|
module.start();
|
|
11
|
-
} else if (!processArgs.checkParent && !global['API_PACKAGE']
|
|
11
|
+
} else if (!processArgs.checkParent && !global['API_PACKAGE']) {
|
|
12
12
|
const main = require('./main');
|
|
13
13
|
|
|
14
14
|
main.start();
|
package/src/main.js
CHANGED
|
@@ -29,6 +29,8 @@ const queryHistory = require('./controllers/queryHistory');
|
|
|
29
29
|
const { rundir } = require('./utility/directories');
|
|
30
30
|
const platformInfo = require('./utility/platformInfo');
|
|
31
31
|
const getExpressPath = require('./utility/getExpressPath');
|
|
32
|
+
const { getLogins } = require('./utility/hasPermission');
|
|
33
|
+
const _ = require('lodash');
|
|
32
34
|
|
|
33
35
|
function start() {
|
|
34
36
|
// console.log('process.argv', process.argv);
|
|
@@ -37,12 +39,11 @@ function start() {
|
|
|
37
39
|
|
|
38
40
|
const server = http.createServer(app);
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
const logins = getLogins();
|
|
43
|
+
if (logins) {
|
|
41
44
|
app.use(
|
|
42
45
|
basicAuth({
|
|
43
|
-
users:
|
|
44
|
-
[process.env.LOGIN]: process.env.PASSWORD,
|
|
45
|
-
},
|
|
46
|
+
users: _.fromPairs(logins.map(x => [x.login, x.password])),
|
|
46
47
|
challenge: true,
|
|
47
48
|
realm: 'DbGate Web App',
|
|
48
49
|
})
|
|
@@ -85,15 +86,11 @@ function start() {
|
|
|
85
86
|
if (platformInfo.isDocker) {
|
|
86
87
|
// server static files inside docker container
|
|
87
88
|
app.use(getExpressPath('/'), express.static('/home/dbgate-docker/public'));
|
|
88
|
-
} else {
|
|
89
|
-
if (!platformInfo.isNpmDist) {
|
|
90
|
-
app.get(getExpressPath('/'), (req, res) => {
|
|
91
|
-
res.send('DbGate API');
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
89
|
|
|
96
|
-
|
|
90
|
+
const port = process.env.PORT || 3000;
|
|
91
|
+
console.log('DbGate API listening on port', port);
|
|
92
|
+
server.listen(port);
|
|
93
|
+
} else if (platformInfo.isNpmDist) {
|
|
97
94
|
app.use(getExpressPath('/'), express.static(path.join(__dirname, '../../dbgate-web/public')));
|
|
98
95
|
getPort({
|
|
99
96
|
port: parseInt(
|
|
@@ -105,7 +102,19 @@ function start() {
|
|
|
105
102
|
console.log(`DbGate API listening on port ${port}`);
|
|
106
103
|
});
|
|
107
104
|
});
|
|
105
|
+
} else if (process.env.DEVWEB) {
|
|
106
|
+
console.log('__dirname', __dirname);
|
|
107
|
+
console.log(path.join(__dirname, '../../web/public/build'));
|
|
108
|
+
app.use(getExpressPath('/'), express.static(path.join(__dirname, '../../web/public')));
|
|
109
|
+
|
|
110
|
+
const port = process.env.PORT || 3000;
|
|
111
|
+
console.log('DbGate API & web listening on port', port);
|
|
112
|
+
server.listen(port);
|
|
108
113
|
} else {
|
|
114
|
+
app.get(getExpressPath('/'), (req, res) => {
|
|
115
|
+
res.send('DbGate API');
|
|
116
|
+
});
|
|
117
|
+
|
|
109
118
|
const port = process.env.PORT || 3000;
|
|
110
119
|
console.log('DbGate API listening on port', port);
|
|
111
120
|
server.listen(port);
|
|
@@ -20,7 +20,7 @@ function start() {
|
|
|
20
20
|
if (handleProcessCommunication(connection)) return;
|
|
21
21
|
try {
|
|
22
22
|
const driver = requireEngineDriver(connection);
|
|
23
|
-
const conn = await connectUtility(driver, connection);
|
|
23
|
+
const conn = await connectUtility(driver, connection, 'app');
|
|
24
24
|
const res = await driver.getVersion(conn);
|
|
25
25
|
process.send({ msgtype: 'connected', ...res });
|
|
26
26
|
} catch (e) {
|
|
@@ -108,7 +108,7 @@ async function handleConnect({ connection, structure, globalSettings }) {
|
|
|
108
108
|
|
|
109
109
|
if (!structure) setStatusName('pending');
|
|
110
110
|
const driver = requireEngineDriver(storedConnection);
|
|
111
|
-
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection));
|
|
111
|
+
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
|
|
112
112
|
await checkedAsyncCall(readVersion());
|
|
113
113
|
if (structure) {
|
|
114
114
|
analysedStructure = structure;
|
|
@@ -58,11 +58,14 @@ async function handleConnect(connection) {
|
|
|
58
58
|
|
|
59
59
|
const driver = requireEngineDriver(storedConnection);
|
|
60
60
|
try {
|
|
61
|
-
systemConnection = await connectUtility(driver, storedConnection);
|
|
61
|
+
systemConnection = await connectUtility(driver, storedConnection, 'app');
|
|
62
62
|
readVersion();
|
|
63
63
|
handleRefresh();
|
|
64
64
|
if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', false)) {
|
|
65
|
-
setInterval(
|
|
65
|
+
setInterval(
|
|
66
|
+
handleRefresh,
|
|
67
|
+
extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 5, 3600) * 1000
|
|
68
|
+
);
|
|
66
69
|
}
|
|
67
70
|
} catch (err) {
|
|
68
71
|
setStatus({
|
|
@@ -80,7 +83,7 @@ function handlePing() {
|
|
|
80
83
|
|
|
81
84
|
async function handleCreateDatabase({ name }) {
|
|
82
85
|
const driver = requireEngineDriver(storedConnection);
|
|
83
|
-
systemConnection = await connectUtility(driver, storedConnection);
|
|
86
|
+
systemConnection = await connectUtility(driver, storedConnection, 'app');
|
|
84
87
|
console.log(`RUNNING SCRIPT: CREATE DATABASE ${driver.dialect.quoteIdentifier(name)}`);
|
|
85
88
|
if (driver.createDatabase) {
|
|
86
89
|
await driver.createDatabase(systemConnection, name);
|
|
@@ -181,7 +181,7 @@ async function handleConnect(connection) {
|
|
|
181
181
|
storedConnection = connection;
|
|
182
182
|
|
|
183
183
|
const driver = requireEngineDriver(storedConnection);
|
|
184
|
-
systemConnection = await connectUtility(driver, storedConnection);
|
|
184
|
+
systemConnection = await connectUtility(driver, storedConnection, 'app');
|
|
185
185
|
for (const [resolve] of afterConnectCallbacks) {
|
|
186
186
|
resolve();
|
|
187
187
|
}
|
|
@@ -5,7 +5,7 @@ async function executeQuery({ connection = undefined, systemConnection = undefin
|
|
|
5
5
|
console.log(`Execute query ${sql}`);
|
|
6
6
|
|
|
7
7
|
if (!driver) driver = requireEngineDriver(connection);
|
|
8
|
-
const pool = systemConnection || (await connectUtility(driver, connection));
|
|
8
|
+
const pool = systemConnection || (await connectUtility(driver, connection, 'script'));
|
|
9
9
|
console.log(`Connected.`);
|
|
10
10
|
|
|
11
11
|
await driver.script(pool, sql);
|
|
@@ -21,7 +21,7 @@ async function generateDeploySql({
|
|
|
21
21
|
}) {
|
|
22
22
|
if (!driver) driver = requireEngineDriver(connection);
|
|
23
23
|
|
|
24
|
-
const pool = systemConnection || (await connectUtility(driver, connection));
|
|
24
|
+
const pool = systemConnection || (await connectUtility(driver, connection, 'read'));
|
|
25
25
|
if (!analysedStructure) {
|
|
26
26
|
analysedStructure = await driver.analyseFull(pool);
|
|
27
27
|
}
|
package/src/shell/queryReader.js
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
2
|
-
const { decryptConnection } = require('../utility/crypting');
|
|
3
2
|
const connectUtility = require('../utility/connectUtility');
|
|
4
3
|
|
|
5
|
-
async function queryReader({
|
|
6
|
-
|
|
4
|
+
async function queryReader({
|
|
5
|
+
connection,
|
|
6
|
+
query,
|
|
7
|
+
queryType,
|
|
8
|
+
// obsolete; use query instead
|
|
9
|
+
sql,
|
|
10
|
+
}) {
|
|
11
|
+
// if (sql && json) {
|
|
12
|
+
// throw new Error('Only one of sql or json could be set');
|
|
13
|
+
// }
|
|
14
|
+
// if (!sql && !json) {
|
|
15
|
+
// throw new Error('One of sql or json must be set');
|
|
16
|
+
// }
|
|
17
|
+
console.log(`Reading query ${query || sql}`);
|
|
18
|
+
// else console.log(`Reading query ${JSON.stringify(json)}`);
|
|
7
19
|
|
|
8
20
|
const driver = requireEngineDriver(connection);
|
|
9
|
-
const pool = await connectUtility(driver, connection);
|
|
21
|
+
const pool = await connectUtility(driver, connection, queryType == 'json' ? 'read' : 'script');
|
|
10
22
|
console.log(`Connected.`);
|
|
11
|
-
return await driver.readQuery(pool, sql);
|
|
23
|
+
return queryType == 'json' ? await driver.readJsonQuery(pool, query) : await driver.readQuery(pool, query || sql);
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
module.exports = queryReader;
|
package/src/shell/tableReader.js
CHANGED
|
@@ -4,7 +4,7 @@ const connectUtility = require('../utility/connectUtility');
|
|
|
4
4
|
|
|
5
5
|
async function tableReader({ connection, pureName, schemaName }) {
|
|
6
6
|
const driver = requireEngineDriver(connection);
|
|
7
|
-
const pool = await connectUtility(driver, connection);
|
|
7
|
+
const pool = await connectUtility(driver, connection, 'read');
|
|
8
8
|
console.log(`Connected.`);
|
|
9
9
|
|
|
10
10
|
const fullName = { pureName, schemaName };
|
package/src/shell/tableWriter.js
CHANGED
|
@@ -8,7 +8,7 @@ async function tableWriter({ connection, schemaName, pureName, driver, systemCon
|
|
|
8
8
|
if (!driver) {
|
|
9
9
|
driver = requireEngineDriver(connection);
|
|
10
10
|
}
|
|
11
|
-
const pool = systemConnection || (await connectUtility(driver, connection));
|
|
11
|
+
const pool = systemConnection || (await connectUtility(driver, connection, 'write'));
|
|
12
12
|
|
|
13
13
|
console.log(`Connected.`);
|
|
14
14
|
return await driver.writeTable(pool, { schemaName, pureName }, options);
|
|
@@ -4,11 +4,47 @@ const fs = require('fs-extra');
|
|
|
4
4
|
const { decryptConnection } = require('./crypting');
|
|
5
5
|
const { getSshTunnel } = require('./sshTunnel');
|
|
6
6
|
const { getSshTunnelProxy } = require('./sshTunnelProxy');
|
|
7
|
+
const platformInfo = require('../utility/platformInfo');
|
|
8
|
+
const connections = require('../controllers/connections');
|
|
9
|
+
|
|
10
|
+
async function loadConnection(driver, storedConnection, connectionMode) {
|
|
11
|
+
const { allowShellConnection } = platformInfo;
|
|
12
|
+
|
|
13
|
+
if (connectionMode == 'app') {
|
|
14
|
+
return storedConnection;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (storedConnection._id || !allowShellConnection) {
|
|
18
|
+
if (!storedConnection._id) {
|
|
19
|
+
throw new Error('Missing connection _id');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await connections._init();
|
|
23
|
+
const loaded = await connections.getCore({ conid: storedConnection._id });
|
|
24
|
+
const loadedWithDb = {
|
|
25
|
+
...loaded,
|
|
26
|
+
database: storedConnection.database,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if (loaded.isReadOnly) {
|
|
30
|
+
if (connectionMode == 'read') return loadedWithDb;
|
|
31
|
+
if (connectionMode == 'write') throw new Error('Cannot write readonly connection');
|
|
32
|
+
if (connectionMode == 'script') {
|
|
33
|
+
if (driver.readOnlySessions) return loadedWithDb;
|
|
34
|
+
throw new Error('Cannot write readonly connection');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return loadedWithDb;
|
|
38
|
+
}
|
|
39
|
+
return storedConnection;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function connectUtility(driver, storedConnection, connectionMode) {
|
|
43
|
+
const connectionLoaded = await loadConnection(driver, storedConnection, connectionMode);
|
|
7
44
|
|
|
8
|
-
async function connectUtility(driver, storedConnection) {
|
|
9
45
|
const connection = {
|
|
10
|
-
database:
|
|
11
|
-
...decryptConnection(
|
|
46
|
+
database: connectionLoaded.defaultDatabase,
|
|
47
|
+
...decryptConnection(connectionLoaded),
|
|
12
48
|
};
|
|
13
49
|
|
|
14
50
|
if (!connection.port && driver.defaultPort) connection.port = driver.defaultPort.toString();
|
package/src/utility/crypting.js
CHANGED
|
@@ -55,7 +55,7 @@ function encryptPasswordField(connection, field) {
|
|
|
55
55
|
[field]: 'crypt:' + getEncryptor().encrypt(connection[field]),
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
return connection;
|
|
58
|
+
return connection;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function decryptPasswordField(connection, field) {
|
|
@@ -75,6 +75,11 @@ function encryptConnection(connection) {
|
|
|
75
75
|
return connection;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
function maskConnection(connection) {
|
|
79
|
+
if (!connection) return connection;
|
|
80
|
+
return _.omit(connection, ['password', 'sshPassword', 'sshKeyfilePassword']);
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
function decryptConnection(connection) {
|
|
79
84
|
connection = decryptPasswordField(connection, 'password');
|
|
80
85
|
connection = decryptPasswordField(connection, 'sshPassword');
|
|
@@ -95,5 +100,6 @@ module.exports = {
|
|
|
95
100
|
loadEncryptionKey,
|
|
96
101
|
encryptConnection,
|
|
97
102
|
decryptConnection,
|
|
103
|
+
maskConnection,
|
|
98
104
|
pickSafeConnectionInfo,
|
|
99
105
|
};
|
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const cleanDirectory = require('./cleanDirectory');
|
|
5
5
|
const platformInfo = require('./platformInfo');
|
|
6
|
+
const processArgs = require('./processArgs');
|
|
6
7
|
|
|
7
8
|
const createDirectories = {};
|
|
8
9
|
const ensureDirectory = (dir, clean) => {
|
|
@@ -54,7 +55,10 @@ function packagedPluginsDir() {
|
|
|
54
55
|
}
|
|
55
56
|
if (platformInfo.isNpmDist) {
|
|
56
57
|
// node_modules
|
|
57
|
-
return global['
|
|
58
|
+
return global['PLUGINS_DIR'];
|
|
59
|
+
}
|
|
60
|
+
if (processArgs.pluginsDir) {
|
|
61
|
+
return processArgs.pluginsDir;
|
|
58
62
|
}
|
|
59
63
|
if (platformInfo.isElectronBundle) {
|
|
60
64
|
return path.resolve(__dirname, '../../plugins');
|
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
const { compilePermissions, testPermission } = require('dbgate-tools');
|
|
2
|
+
const _ = require('lodash');
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const userPermissions = {};
|
|
4
5
|
|
|
5
|
-
function hasPermission(tested) {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
function hasPermission(tested, req) {
|
|
7
|
+
const { user } = (req && req.auth) || {};
|
|
8
|
+
const key = user || '';
|
|
9
|
+
const logins = getLogins();
|
|
10
|
+
if (!userPermissions[key] && logins) {
|
|
11
|
+
const login = logins.find(x => x.login == user);
|
|
12
|
+
userPermissions[key] = compilePermissions(login ? login.permissions : null);
|
|
8
13
|
}
|
|
9
|
-
return testPermission(tested,
|
|
14
|
+
return testPermission(tested, userPermissions[key]);
|
|
10
15
|
}
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
let loginsCache = null;
|
|
18
|
+
let loginsLoaded = false;
|
|
19
|
+
|
|
20
|
+
function getLogins() {
|
|
21
|
+
if (loginsLoaded) {
|
|
22
|
+
return loginsCache;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const res = [];
|
|
26
|
+
if (process.env.LOGIN && process.env.PASSWORD) {
|
|
27
|
+
res.push({
|
|
28
|
+
login: process.env.LOGIN,
|
|
29
|
+
password: process.env.PASSWORD,
|
|
30
|
+
permissions: process.env.PERMISSIONS,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (process.env.LOGINS) {
|
|
34
|
+
const logins = _.compact(process.env.LOGINS.split(',').map(x => x.trim()));
|
|
35
|
+
for (const login of logins) {
|
|
36
|
+
const password = process.env[`LOGIN_PASSWORD_${login}`];
|
|
37
|
+
const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
|
|
38
|
+
if (password) {
|
|
39
|
+
res.push({
|
|
40
|
+
login,
|
|
41
|
+
password,
|
|
42
|
+
permissions,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
loginsCache = res.length > 0 ? res : null;
|
|
49
|
+
loginsLoaded = true;
|
|
50
|
+
return loginsCache;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = {
|
|
54
|
+
hasPermission,
|
|
55
|
+
getLogins,
|
|
56
|
+
};
|
|
@@ -10,7 +10,7 @@ const isMac = platform === 'darwin';
|
|
|
10
10
|
const isLinux = platform === 'linux';
|
|
11
11
|
const isDocker = fs.existsSync('/home/dbgate-docker/public');
|
|
12
12
|
const isDevMode = process.env.DEVMODE == '1';
|
|
13
|
-
const isNpmDist = !!global['
|
|
13
|
+
const isNpmDist = !!global['IS_NPM_DIST'];
|
|
14
14
|
const isForkedApi = processArgs.isForkedApi;
|
|
15
15
|
|
|
16
16
|
// function moduleAvailable(name) {
|
|
@@ -39,6 +39,8 @@ const platformInfo = {
|
|
|
39
39
|
environment: process.env.NODE_ENV,
|
|
40
40
|
platform,
|
|
41
41
|
runningInWebpack: !!process.env.WEBPACK_DEV_SERVER_URL,
|
|
42
|
+
allowShellConnection: !!process.env.SHELL_CONNECTION || !!isElectron(),
|
|
43
|
+
allowShellScripting: !!process.env.SHELL_SCRIPTING || !!isElectron(),
|
|
42
44
|
defaultKeyfile: path.join(os.homedir(), '.ssh/id_rsa'),
|
|
43
45
|
};
|
|
44
46
|
|
|
@@ -9,10 +9,17 @@ function getNamedArg(name) {
|
|
|
9
9
|
const checkParent = process.argv.includes('--checkParent');
|
|
10
10
|
const startProcess = getNamedArg('--start-process');
|
|
11
11
|
const isForkedApi = process.argv.includes('--is-forked-api');
|
|
12
|
+
const pluginsDir = getNamedArg('--plugins-dir');
|
|
12
13
|
|
|
13
14
|
function getPassArgs() {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const res = [];
|
|
16
|
+
if (global['NATIVE_MODULES']) {
|
|
17
|
+
res.push('--native-modules', global['NATIVE_MODULES']);
|
|
18
|
+
}
|
|
19
|
+
if (global['PLUGINS_DIR']) {
|
|
20
|
+
res.push('--plugins-dir', global['PLUGINS_DIR']);
|
|
21
|
+
}
|
|
22
|
+
return res;
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
module.exports = {
|
|
@@ -20,4 +27,5 @@ module.exports = {
|
|
|
20
27
|
startProcess,
|
|
21
28
|
isForkedApi,
|
|
22
29
|
getPassArgs,
|
|
30
|
+
pluginsDir,
|
|
23
31
|
};
|
|
@@ -62,7 +62,7 @@ module.exports = function useController(app, electron, route, controller) {
|
|
|
62
62
|
// controller._init_called = true;
|
|
63
63
|
// }
|
|
64
64
|
try {
|
|
65
|
-
let params = [{ ...req.body, ...req.query }];
|
|
65
|
+
let params = [{ ...req.body, ...req.query }, req];
|
|
66
66
|
if (rawParams) params = [req, res];
|
|
67
67
|
const data = await controller[key](...params);
|
|
68
68
|
res.json(data);
|