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.
- package/.env +19 -0
- package/.yarnrc +2 -0
- package/README.md +1 -0
- package/env/dblogin/.env +14 -0
- package/env/portal/.env +70 -0
- package/env/singledb/.env +17 -0
- package/env/storage/.env +43 -0
- package/package.json +89 -0
- package/src/auth/authCommon.js +16 -0
- package/src/auth/authProvider.js +343 -0
- package/src/auth/storageAuthProvider.js +393 -0
- package/src/controllers/apps.js +280 -0
- package/src/controllers/archive.js +217 -0
- package/src/controllers/auth.js +136 -0
- package/src/controllers/config.js +271 -0
- package/src/controllers/connections.js +486 -0
- package/src/controllers/databaseConnections.js +561 -0
- package/src/controllers/files.js +222 -0
- package/src/controllers/jsldata.js +296 -0
- package/src/controllers/metadata.js +47 -0
- package/src/controllers/plugins.js +216 -0
- package/src/controllers/queryHistory.js +54 -0
- package/src/controllers/runners.js +234 -0
- package/src/controllers/scheduler.js +46 -0
- package/src/controllers/serverConnections.js +271 -0
- package/src/controllers/sessions.js +243 -0
- package/src/controllers/storage.js +380 -0
- package/src/controllers/storageDb.js +215 -0
- package/src/controllers/uploads.js +133 -0
- package/src/currentVersion.js +5 -0
- package/src/gistSecret.js +2 -0
- package/src/index.js +139 -0
- package/src/main.js +202 -0
- package/src/packagedPluginsContent.js +1 -0
- package/src/proc/connectProcess.js +38 -0
- package/src/proc/databaseConnectionProcess.js +431 -0
- package/src/proc/index.js +15 -0
- package/src/proc/jslDatastoreProcess.js +60 -0
- package/src/proc/serverConnectionProcess.js +188 -0
- package/src/proc/sessionProcess.js +390 -0
- package/src/proc/sshForwardProcess.js +75 -0
- package/src/shell/archiveReader.js +11 -0
- package/src/shell/archiveWriter.js +22 -0
- package/src/shell/autoIndexForeignKeysTransform.js +19 -0
- package/src/shell/collectorWriter.js +33 -0
- package/src/shell/consoleObjectWriter.js +16 -0
- package/src/shell/copyStream.js +48 -0
- package/src/shell/dataDuplicator.js +63 -0
- package/src/shell/dataTypeMapperTransform.js +21 -0
- package/src/shell/dbModelToJson.js +16 -0
- package/src/shell/deployDb.js +56 -0
- package/src/shell/download.js +15 -0
- package/src/shell/dropAllDbObjects.js +42 -0
- package/src/shell/dumpDatabase.js +49 -0
- package/src/shell/executeQuery.js +39 -0
- package/src/shell/fakeObjectReader.js +35 -0
- package/src/shell/finalizer.js +12 -0
- package/src/shell/generateDeploySql.js +95 -0
- package/src/shell/generateModelSql.js +30 -0
- package/src/shell/importDatabase.js +85 -0
- package/src/shell/index.js +80 -0
- package/src/shell/initializeApiEnvironment.js +9 -0
- package/src/shell/jslDataReader.js +9 -0
- package/src/shell/jsonLinesReader.js +52 -0
- package/src/shell/jsonLinesWriter.js +36 -0
- package/src/shell/jsonReader.js +84 -0
- package/src/shell/jsonToDbModel.js +9 -0
- package/src/shell/jsonWriter.js +97 -0
- package/src/shell/loadDatabase.js +27 -0
- package/src/shell/loadFile.js +10 -0
- package/src/shell/modifyJsonLinesReader.js +148 -0
- package/src/shell/queryReader.js +30 -0
- package/src/shell/registerPlugins.js +9 -0
- package/src/shell/requirePlugin.js +43 -0
- package/src/shell/runScript.js +19 -0
- package/src/shell/sqlDataWriter.js +52 -0
- package/src/shell/sqlTextReplacementTransform.js +32 -0
- package/src/shell/tableReader.js +39 -0
- package/src/shell/tableWriter.js +18 -0
- package/src/storageModel.js +819 -0
- package/src/utility/ColumnMapTransformStream.js +21 -0
- package/src/utility/DatastoreProxy.js +106 -0
- package/src/utility/EnsureStreamHeaderStream.js +31 -0
- package/src/utility/JsonLinesDatabase.js +148 -0
- package/src/utility/JsonLinesDatastore.js +232 -0
- package/src/utility/LineReader.js +88 -0
- package/src/utility/SSHConnection.js +251 -0
- package/src/utility/authProxy.js +133 -0
- package/src/utility/checkLicense.js +186 -0
- package/src/utility/childProcessChecker.js +21 -0
- package/src/utility/cleanDirectory.js +24 -0
- package/src/utility/cloudUpgrade.js +61 -0
- package/src/utility/connectUtility.js +111 -0
- package/src/utility/crypting.js +105 -0
- package/src/utility/diff2htmlPage.js +8 -0
- package/src/utility/directories.js +179 -0
- package/src/utility/downloadPackage.js +51 -0
- package/src/utility/downloader.js +25 -0
- package/src/utility/exceptions.js +9 -0
- package/src/utility/exportDbModel.js +31 -0
- package/src/utility/exportDbModelSql.js +80 -0
- package/src/utility/getChartExport.js +55 -0
- package/src/utility/getDiagramExport.js +25 -0
- package/src/utility/getExpressPath.js +10 -0
- package/src/utility/getJslFileName.js +16 -0
- package/src/utility/getMapExport.js +77 -0
- package/src/utility/hardwareFingerprint.js +89 -0
- package/src/utility/hasPermission.js +101 -0
- package/src/utility/importDbModel.js +9 -0
- package/src/utility/loadFilesRecursive.js +20 -0
- package/src/utility/loadModelFolder.js +29 -0
- package/src/utility/loadModelTransform.js +36 -0
- package/src/utility/pipeForkLogs.js +19 -0
- package/src/utility/platformInfo.js +62 -0
- package/src/utility/processArgs.js +39 -0
- package/src/utility/processComm.js +18 -0
- package/src/utility/requireEngineDriver.js +26 -0
- package/src/utility/requirePluginFunction.js +16 -0
- package/src/utility/socket.js +68 -0
- package/src/utility/sshTunnel.js +106 -0
- package/src/utility/sshTunnelProxy.js +36 -0
- package/src/utility/timingSafeCheckToken.js +9 -0
- package/src/utility/useController.js +99 -0
- package/tsconfig.json +13 -0
- package/webpack.config.js +55 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { fork } = require('child_process');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const crypto = require('crypto');
|
|
6
|
+
|
|
7
|
+
const { datadir, filesdir } = require('../utility/directories');
|
|
8
|
+
const socket = require('../utility/socket');
|
|
9
|
+
const { encryptConnection, maskConnection } = require('../utility/crypting');
|
|
10
|
+
const { handleProcessCommunication } = require('../utility/processComm');
|
|
11
|
+
const { pickSafeConnectionInfo } = require('../utility/crypting');
|
|
12
|
+
const JsonLinesDatabase = require('../utility/JsonLinesDatabase');
|
|
13
|
+
|
|
14
|
+
const processArgs = require('../utility/processArgs');
|
|
15
|
+
const { safeJsonParse, getLogger, extractErrorLogData } = require('dbgate-tools');
|
|
16
|
+
const platformInfo = require('../utility/platformInfo');
|
|
17
|
+
const { connectionHasPermission, testConnectionPermission } = require('../utility/hasPermission');
|
|
18
|
+
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
19
|
+
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
20
|
+
const { getAuthProviderById } = require('../auth/authProvider');
|
|
21
|
+
const { startTokenChecking } = require('../utility/authProxy');
|
|
22
|
+
|
|
23
|
+
const logger = getLogger('connections');
|
|
24
|
+
|
|
25
|
+
let volatileConnections = {};
|
|
26
|
+
|
|
27
|
+
function getNamedArgs() {
|
|
28
|
+
const res = {};
|
|
29
|
+
for (let i = 0; i < process.argv.length; i++) {
|
|
30
|
+
const name = process.argv[i];
|
|
31
|
+
if (name.startsWith('--')) {
|
|
32
|
+
let value = process.argv[i + 1];
|
|
33
|
+
if (value && value.startsWith('--')) value = null;
|
|
34
|
+
res[name.substring(2)] = value == null ? true : value;
|
|
35
|
+
i++;
|
|
36
|
+
} else {
|
|
37
|
+
if (name.endsWith('.db') || name.endsWith('.sqlite') || name.endsWith('.sqlite3')) {
|
|
38
|
+
res.databaseFile = name;
|
|
39
|
+
res.engine = 'sqlite@dbgate-plugin-sqlite';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return res;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getDatabaseFileLabel(databaseFile) {
|
|
47
|
+
if (!databaseFile) return databaseFile;
|
|
48
|
+
const m = databaseFile.match(/[\/]([^\/]+)$/);
|
|
49
|
+
if (m) return m[1];
|
|
50
|
+
return databaseFile;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getPortalCollections() {
|
|
54
|
+
if (process.env.CONNECTIONS) {
|
|
55
|
+
const connections = _.compact(process.env.CONNECTIONS.split(',')).map(id => ({
|
|
56
|
+
_id: id,
|
|
57
|
+
engine: process.env[`ENGINE_${id}`],
|
|
58
|
+
server: process.env[`SERVER_${id}`],
|
|
59
|
+
user: process.env[`USER_${id}`],
|
|
60
|
+
password: process.env[`PASSWORD_${id}`],
|
|
61
|
+
passwordMode: process.env[`PASSWORD_MODE_${id}`],
|
|
62
|
+
port: process.env[`PORT_${id}`],
|
|
63
|
+
databaseUrl: process.env[`URL_${id}`],
|
|
64
|
+
useDatabaseUrl: !!process.env[`URL_${id}`],
|
|
65
|
+
databaseFile: process.env[`FILE_${id}`],
|
|
66
|
+
socketPath: process.env[`SOCKET_PATH_${id}`],
|
|
67
|
+
serviceName: process.env[`SERVICE_NAME_${id}`],
|
|
68
|
+
authType: process.env[`AUTH_TYPE_${id}`] || (process.env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
|
|
69
|
+
defaultDatabase:
|
|
70
|
+
process.env[`DATABASE_${id}`] ||
|
|
71
|
+
(process.env[`FILE_${id}`] ? getDatabaseFileLabel(process.env[`FILE_${id}`]) : null),
|
|
72
|
+
singleDatabase: !!process.env[`DATABASE_${id}`] || !!process.env[`FILE_${id}`],
|
|
73
|
+
displayName: process.env[`LABEL_${id}`],
|
|
74
|
+
isReadOnly: process.env[`READONLY_${id}`],
|
|
75
|
+
databases: process.env[`DBCONFIG_${id}`] ? safeJsonParse(process.env[`DBCONFIG_${id}`]) : null,
|
|
76
|
+
allowedDatabases: process.env[`ALLOWED_DATABASES_${id}`]?.replace(/\|/g, '\n'),
|
|
77
|
+
allowedDatabasesRegex: process.env[`ALLOWED_DATABASES_REGEX_${id}`],
|
|
78
|
+
parent: process.env[`PARENT_${id}`] || undefined,
|
|
79
|
+
useSeparateSchemas: !!process.env[`USE_SEPARATE_SCHEMAS_${id}`],
|
|
80
|
+
|
|
81
|
+
// SSH tunnel
|
|
82
|
+
useSshTunnel: process.env[`USE_SSH_${id}`],
|
|
83
|
+
sshHost: process.env[`SSH_HOST_${id}`],
|
|
84
|
+
sshPort: process.env[`SSH_PORT_${id}`],
|
|
85
|
+
sshMode: process.env[`SSH_MODE_${id}`],
|
|
86
|
+
sshLogin: process.env[`SSH_LOGIN_${id}`],
|
|
87
|
+
sshPassword: process.env[`SSH_PASSWORD_${id}`],
|
|
88
|
+
sshKeyfile: process.env[`SSH_KEY_FILE_${id}`],
|
|
89
|
+
sshKeyfilePassword: process.env[`SSH_KEY_FILE_PASSWORD_${id}`],
|
|
90
|
+
|
|
91
|
+
// SSL
|
|
92
|
+
useSsl: process.env[`USE_SSL_${id}`],
|
|
93
|
+
sslCaFile: process.env[`SSL_CA_FILE_${id}`],
|
|
94
|
+
sslCertFile: process.env[`SSL_CERT_FILE_${id}`],
|
|
95
|
+
sslCertFilePassword: process.env[`SSL_CERT_FILE_PASSWORD_${id}`],
|
|
96
|
+
sslKeyFile: process.env[`SSL_KEY_FILE_${id}`],
|
|
97
|
+
sslRejectUnauthorized: process.env[`SSL_REJECT_UNAUTHORIZED_${id}`],
|
|
98
|
+
trustServerCertificate: process.env[`SSL_TRUST_CERTIFICATE_${id}`],
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
logger.info({ connections: connections.map(pickSafeConnectionInfo) }, 'Using connections from ENV variables');
|
|
102
|
+
const noengine = connections.filter(x => !x.engine);
|
|
103
|
+
if (noengine.length > 0) {
|
|
104
|
+
logger.warn(
|
|
105
|
+
{ connections: noengine.map(x => x._id) },
|
|
106
|
+
'Invalid CONNECTIONS configutation, missing ENGINE for connection ID'
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return connections;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const args = getNamedArgs();
|
|
113
|
+
if (args.databaseFile) {
|
|
114
|
+
return [
|
|
115
|
+
{
|
|
116
|
+
_id: 'argv',
|
|
117
|
+
databaseFile: args.databaseFile,
|
|
118
|
+
singleDatabase: true,
|
|
119
|
+
defaultDatabase: getDatabaseFileLabel(args.databaseFile),
|
|
120
|
+
engine: args.engine,
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
if (args.databaseUrl) {
|
|
125
|
+
return [
|
|
126
|
+
{
|
|
127
|
+
_id: 'argv',
|
|
128
|
+
useDatabaseUrl: true,
|
|
129
|
+
...args,
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
if (args.server) {
|
|
134
|
+
return [
|
|
135
|
+
{
|
|
136
|
+
_id: 'argv',
|
|
137
|
+
...args,
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const portalConnections = getPortalCollections();
|
|
146
|
+
|
|
147
|
+
function getSingleDbConnection() {
|
|
148
|
+
if (process.env.SINGLE_CONNECTION && process.env.SINGLE_DATABASE) {
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
const connection = portalConnections.find(x => x._id == process.env.SINGLE_CONNECTION);
|
|
151
|
+
return {
|
|
152
|
+
connection,
|
|
153
|
+
name: process.env.SINGLE_DATABASE,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// @ts-ignore
|
|
157
|
+
const arg0 = (portalConnections || []).find(x => x._id == 'argv');
|
|
158
|
+
if (arg0) {
|
|
159
|
+
// @ts-ignore
|
|
160
|
+
if (arg0.singleDatabase) {
|
|
161
|
+
return {
|
|
162
|
+
connection: arg0,
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
name: arg0.defaultDatabase,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getSingleConnection() {
|
|
172
|
+
if (getSingleDbConnection()) return null;
|
|
173
|
+
if (process.env.SINGLE_CONNECTION) {
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
const connection = portalConnections.find(x => x._id == process.env.SINGLE_CONNECTION);
|
|
176
|
+
if (connection) {
|
|
177
|
+
return connection;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
const arg0 = (portalConnections || []).find(x => x._id == 'argv');
|
|
182
|
+
if (arg0) {
|
|
183
|
+
return arg0;
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const singleDbConnection = getSingleDbConnection();
|
|
189
|
+
const singleConnection = getSingleConnection();
|
|
190
|
+
|
|
191
|
+
module.exports = {
|
|
192
|
+
datastore: null,
|
|
193
|
+
opened: [],
|
|
194
|
+
singleDbConnection,
|
|
195
|
+
singleConnection,
|
|
196
|
+
portalConnections,
|
|
197
|
+
|
|
198
|
+
async _init() {
|
|
199
|
+
const dir = datadir();
|
|
200
|
+
if (!portalConnections) {
|
|
201
|
+
// @ts-ignore
|
|
202
|
+
this.datastore = new JsonLinesDatabase(path.join(dir, 'connections.jsonl'));
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
list_meta: true,
|
|
207
|
+
async list(_params, req) {
|
|
208
|
+
const storage = require('./storage');
|
|
209
|
+
|
|
210
|
+
const storageConnections = await storage.connections(req);
|
|
211
|
+
if (storageConnections) {
|
|
212
|
+
return storageConnections;
|
|
213
|
+
}
|
|
214
|
+
if (portalConnections) {
|
|
215
|
+
if (platformInfo.allowShellConnection) return portalConnections;
|
|
216
|
+
return portalConnections.map(maskConnection).filter(x => connectionHasPermission(x, req));
|
|
217
|
+
}
|
|
218
|
+
return (await this.datastore.find()).filter(x => connectionHasPermission(x, req));
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
test_meta: true,
|
|
222
|
+
test(connection) {
|
|
223
|
+
const subprocess = fork(
|
|
224
|
+
global['API_PACKAGE'] || process.argv[1],
|
|
225
|
+
[
|
|
226
|
+
'--is-forked-api',
|
|
227
|
+
'--start-process',
|
|
228
|
+
'connectProcess',
|
|
229
|
+
...processArgs.getPassArgs(),
|
|
230
|
+
// ...process.argv.slice(3),
|
|
231
|
+
],
|
|
232
|
+
{
|
|
233
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
pipeForkLogs(subprocess);
|
|
237
|
+
subprocess.send(connection);
|
|
238
|
+
return new Promise(resolve => {
|
|
239
|
+
subprocess.on('message', resp => {
|
|
240
|
+
if (handleProcessCommunication(resp, subprocess)) return;
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
const { msgtype } = resp;
|
|
243
|
+
if (msgtype == 'connected' || msgtype == 'error') {
|
|
244
|
+
resolve(resp);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
saveVolatile_meta: true,
|
|
251
|
+
async saveVolatile({ conid, user = undefined, password = undefined, accessToken = undefined, test = false }) {
|
|
252
|
+
const old = await this.getCore({ conid });
|
|
253
|
+
const res = {
|
|
254
|
+
...old,
|
|
255
|
+
_id: crypto.randomUUID(),
|
|
256
|
+
password,
|
|
257
|
+
accessToken,
|
|
258
|
+
passwordMode: undefined,
|
|
259
|
+
unsaved: true,
|
|
260
|
+
useRedirectDbLogin: false,
|
|
261
|
+
};
|
|
262
|
+
if (old.passwordMode == 'askUser') {
|
|
263
|
+
res.user = user;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (test) {
|
|
267
|
+
const testRes = await this.test(res);
|
|
268
|
+
if (testRes.msgtype == 'connected') {
|
|
269
|
+
volatileConnections[res._id] = res;
|
|
270
|
+
return {
|
|
271
|
+
...res,
|
|
272
|
+
msgtype: 'connected',
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
return testRes;
|
|
276
|
+
} else {
|
|
277
|
+
volatileConnections[res._id] = res;
|
|
278
|
+
return res;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
save_meta: true,
|
|
283
|
+
async save(connection) {
|
|
284
|
+
if (portalConnections) return;
|
|
285
|
+
let res;
|
|
286
|
+
const encrypted = encryptConnection(connection);
|
|
287
|
+
if (connection._id) {
|
|
288
|
+
res = await this.datastore.update(encrypted);
|
|
289
|
+
} else {
|
|
290
|
+
res = await this.datastore.insert(encrypted);
|
|
291
|
+
}
|
|
292
|
+
socket.emitChanged('connection-list-changed');
|
|
293
|
+
socket.emitChanged('used-apps-changed');
|
|
294
|
+
if (this._closeAll) {
|
|
295
|
+
this._closeAll(connection._id);
|
|
296
|
+
}
|
|
297
|
+
// for (const db of connection.databases || []) {
|
|
298
|
+
// socket.emitChanged(`db-apps-changed-${connection._id}-${db.name}`);
|
|
299
|
+
// }
|
|
300
|
+
return res;
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
update_meta: true,
|
|
304
|
+
async update({ _id, values }, req) {
|
|
305
|
+
if (portalConnections) return;
|
|
306
|
+
testConnectionPermission(_id, req);
|
|
307
|
+
const res = await this.datastore.patch(_id, values);
|
|
308
|
+
socket.emitChanged('connection-list-changed');
|
|
309
|
+
return res;
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
batchChangeFolder_meta: true,
|
|
313
|
+
async batchChangeFolder({ folder, newFolder }, req) {
|
|
314
|
+
// const updated = await this.datastore.find(x => x.parent == folder);
|
|
315
|
+
const res = await this.datastore.updateAll(x => (x.parent == folder ? { ...x, parent: newFolder } : x));
|
|
316
|
+
socket.emitChanged('connection-list-changed');
|
|
317
|
+
return res;
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
updateDatabase_meta: true,
|
|
321
|
+
async updateDatabase({ conid, database, values }, req) {
|
|
322
|
+
if (portalConnections) return;
|
|
323
|
+
testConnectionPermission(conid, req);
|
|
324
|
+
const conn = await this.datastore.get(conid);
|
|
325
|
+
let databases = (conn && conn.databases) || [];
|
|
326
|
+
if (databases.find(x => x.name == database)) {
|
|
327
|
+
databases = databases.map(x => (x.name == database ? { ...x, ...values } : x));
|
|
328
|
+
} else {
|
|
329
|
+
databases = [...databases, { name: database, ...values }];
|
|
330
|
+
}
|
|
331
|
+
const res = await this.datastore.patch(conid, { databases });
|
|
332
|
+
socket.emitChanged('connection-list-changed');
|
|
333
|
+
socket.emitChanged('used-apps-changed');
|
|
334
|
+
// socket.emitChanged(`db-apps-changed-${conid}-${database}`);
|
|
335
|
+
return res;
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
delete_meta: true,
|
|
339
|
+
async delete(connection, req) {
|
|
340
|
+
if (portalConnections) return;
|
|
341
|
+
testConnectionPermission(connection, req);
|
|
342
|
+
const res = await this.datastore.remove(connection._id);
|
|
343
|
+
socket.emitChanged('connection-list-changed');
|
|
344
|
+
return res;
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
async getCore({ conid, mask = false }) {
|
|
348
|
+
if (!conid) return null;
|
|
349
|
+
const volatile = volatileConnections[conid];
|
|
350
|
+
if (volatile) {
|
|
351
|
+
return volatile;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const storage = require('./storage');
|
|
355
|
+
|
|
356
|
+
const storageConnection = await storage.getConnection({ conid });
|
|
357
|
+
if (storageConnection) {
|
|
358
|
+
return storageConnection;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (portalConnections) {
|
|
362
|
+
const res = portalConnections.find(x => x._id == conid) || null;
|
|
363
|
+
return mask && !platformInfo.allowShellConnection ? maskConnection(res) : res;
|
|
364
|
+
}
|
|
365
|
+
const res = await this.datastore.get(conid);
|
|
366
|
+
return res || null;
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
get_meta: true,
|
|
370
|
+
async get({ conid }, req) {
|
|
371
|
+
if (conid == '__model') {
|
|
372
|
+
return {
|
|
373
|
+
_id: '__model',
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
testConnectionPermission(conid, req);
|
|
377
|
+
return this.getCore({ conid, mask: true });
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
newSqliteDatabase_meta: true,
|
|
381
|
+
async newSqliteDatabase({ file }) {
|
|
382
|
+
const sqliteDir = path.join(filesdir(), 'sqlite');
|
|
383
|
+
if (!(await fs.exists(sqliteDir))) {
|
|
384
|
+
await fs.mkdir(sqliteDir);
|
|
385
|
+
}
|
|
386
|
+
const databaseFile = path.join(sqliteDir, `${file}.sqlite`);
|
|
387
|
+
const res = await this.save({
|
|
388
|
+
engine: 'sqlite@dbgate-plugin-sqlite',
|
|
389
|
+
databaseFile,
|
|
390
|
+
singleDatabase: true,
|
|
391
|
+
defaultDatabase: `${file}.sqlite`,
|
|
392
|
+
});
|
|
393
|
+
return res;
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
dbloginWeb_meta: {
|
|
397
|
+
raw: true,
|
|
398
|
+
method: 'get',
|
|
399
|
+
},
|
|
400
|
+
async dbloginWeb(req, res) {
|
|
401
|
+
const { conid, state, redirectUri } = req.query;
|
|
402
|
+
const connection = await this.getCore({ conid });
|
|
403
|
+
const driver = requireEngineDriver(connection);
|
|
404
|
+
const authResp = await driver.getRedirectAuthUrl(connection, {
|
|
405
|
+
redirectUri,
|
|
406
|
+
state,
|
|
407
|
+
client: 'web',
|
|
408
|
+
});
|
|
409
|
+
res.redirect(authResp.url);
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
dbloginApp_meta: true,
|
|
413
|
+
async dbloginApp({ conid, state }) {
|
|
414
|
+
const connection = await this.getCore({ conid });
|
|
415
|
+
const driver = requireEngineDriver(connection);
|
|
416
|
+
const resp = await driver.getRedirectAuthUrl(connection, {
|
|
417
|
+
state,
|
|
418
|
+
client: 'app',
|
|
419
|
+
});
|
|
420
|
+
startTokenChecking(resp.sid, async token => {
|
|
421
|
+
const volatile = await this.saveVolatile({ conid, accessToken: token });
|
|
422
|
+
socket.emit('got-volatile-token', { savedConId: conid, volatileConId: volatile._id });
|
|
423
|
+
});
|
|
424
|
+
return resp;
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
dbloginToken_meta: true,
|
|
428
|
+
async dbloginToken({ code, conid, strmid, redirectUri, sid }) {
|
|
429
|
+
try {
|
|
430
|
+
const connection = await this.getCore({ conid });
|
|
431
|
+
const driver = requireEngineDriver(connection);
|
|
432
|
+
const accessToken = await driver.getAuthTokenFromCode(connection, { sid, code, redirectUri });
|
|
433
|
+
const volatile = await this.saveVolatile({ conid, accessToken });
|
|
434
|
+
// console.log('******************************** WE HAVE ACCESS TOKEN', accessToken);
|
|
435
|
+
socket.emit('got-volatile-token', { strmid, savedConId: conid, volatileConId: volatile._id });
|
|
436
|
+
return { success: true };
|
|
437
|
+
} catch (err) {
|
|
438
|
+
logger.error(extractErrorLogData(err), 'Error getting DB token');
|
|
439
|
+
return { error: err.message };
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
|
|
443
|
+
dbloginAuthToken_meta: true,
|
|
444
|
+
async dbloginAuthToken({ amoid, code, conid, redirectUri, sid }) {
|
|
445
|
+
try {
|
|
446
|
+
const connection = await this.getCore({ conid });
|
|
447
|
+
const driver = requireEngineDriver(connection);
|
|
448
|
+
const accessToken = await driver.getAuthTokenFromCode(connection, { code, redirectUri, sid });
|
|
449
|
+
const volatile = await this.saveVolatile({ conid, accessToken });
|
|
450
|
+
const authProvider = getAuthProviderById(amoid);
|
|
451
|
+
const resp = await authProvider.login(null, null, { conid: volatile._id });
|
|
452
|
+
return resp;
|
|
453
|
+
} catch (err) {
|
|
454
|
+
logger.error(extractErrorLogData(err), 'Error getting DB token');
|
|
455
|
+
return { error: err.message };
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
dbloginAuth_meta: true,
|
|
460
|
+
async dbloginAuth({ amoid, conid, user, password }) {
|
|
461
|
+
if (user || password) {
|
|
462
|
+
const saveResp = await this.saveVolatile({ conid, user, password, test: true });
|
|
463
|
+
if (saveResp.msgtype == 'connected') {
|
|
464
|
+
const loginResp = await getAuthProviderById(amoid).login(user, password, { conid: saveResp._id });
|
|
465
|
+
return loginResp;
|
|
466
|
+
}
|
|
467
|
+
return saveResp;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// user and password is stored in connection, volatile connection is not needed
|
|
471
|
+
const loginResp = await getAuthProviderById(amoid).login(null, null, { conid });
|
|
472
|
+
return loginResp;
|
|
473
|
+
},
|
|
474
|
+
|
|
475
|
+
volatileDbloginFromAuth_meta: true,
|
|
476
|
+
async volatileDbloginFromAuth({ conid }, req) {
|
|
477
|
+
const connection = await this.getCore({ conid });
|
|
478
|
+
const driver = requireEngineDriver(connection);
|
|
479
|
+
const accessToken = await driver.getAccessTokenFromAuth(connection, req);
|
|
480
|
+
if (accessToken) {
|
|
481
|
+
const volatile = await this.saveVolatile({ conid, accessToken });
|
|
482
|
+
return volatile;
|
|
483
|
+
}
|
|
484
|
+
return null;
|
|
485
|
+
},
|
|
486
|
+
};
|