dbgate-api-premium 6.6.8 → 6.6.10
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api-premium",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "6.6.
|
|
4
|
+
"version": "6.6.10",
|
|
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.
|
|
33
|
+
"dbgate-datalib": "^6.6.10",
|
|
34
34
|
"dbgate-query-splitter": "^4.11.7",
|
|
35
|
-
"dbgate-sqltree": "^6.6.
|
|
36
|
-
"dbgate-tools": "^6.6.
|
|
35
|
+
"dbgate-sqltree": "^6.6.10",
|
|
36
|
+
"dbgate-tools": "^6.6.10",
|
|
37
37
|
"debug": "^4.3.4",
|
|
38
38
|
"diff": "^5.0.0",
|
|
39
39
|
"diff2html": "^3.4.13",
|
|
@@ -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.
|
|
89
|
+
"dbgate-types": "^6.6.10",
|
|
90
90
|
"env-cmd": "^10.1.0",
|
|
91
91
|
"jsdoc-to-markdown": "^9.0.5",
|
|
92
92
|
"node-loader": "^1.0.2",
|
|
@@ -29,7 +29,17 @@ const generateDeploySql = require('../shell/generateDeploySql');
|
|
|
29
29
|
const { createTwoFilesPatch } = require('diff');
|
|
30
30
|
const diff2htmlPage = require('../utility/diff2htmlPage');
|
|
31
31
|
const processArgs = require('../utility/processArgs');
|
|
32
|
-
const {
|
|
32
|
+
const {
|
|
33
|
+
testConnectionPermission,
|
|
34
|
+
hasPermission,
|
|
35
|
+
loadPermissionsFromRequest,
|
|
36
|
+
loadTablePermissionsFromRequest,
|
|
37
|
+
getTablePermissionRole,
|
|
38
|
+
loadDatabasePermissionsFromRequest,
|
|
39
|
+
getDatabasePermissionRole,
|
|
40
|
+
getTablePermissionRoleLevelIndex,
|
|
41
|
+
testDatabaseRolePermission,
|
|
42
|
+
} = require('../utility/hasPermission');
|
|
33
43
|
const { MissingCredentialsError } = require('../utility/exceptions');
|
|
34
44
|
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
35
45
|
const crypto = require('crypto');
|
|
@@ -100,7 +110,7 @@ module.exports = {
|
|
|
100
110
|
socket.emitChanged(`database-status-changed`, { conid, database });
|
|
101
111
|
},
|
|
102
112
|
|
|
103
|
-
handle_ping() {
|
|
113
|
+
handle_ping() {},
|
|
104
114
|
|
|
105
115
|
// session event handlers
|
|
106
116
|
|
|
@@ -256,23 +266,24 @@ module.exports = {
|
|
|
256
266
|
auditLogger:
|
|
257
267
|
auditLogSessionGroup && select?.from?.name?.pureName
|
|
258
268
|
? response => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
269
|
+
sendToAuditLog(req, {
|
|
270
|
+
category: 'dbop',
|
|
271
|
+
component: 'DatabaseConnectionsController',
|
|
272
|
+
event: 'sql.select',
|
|
273
|
+
action: 'select',
|
|
274
|
+
severity: 'info',
|
|
275
|
+
conid,
|
|
276
|
+
database,
|
|
277
|
+
schemaName: select?.from?.name?.schemaName,
|
|
278
|
+
pureName: select?.from?.name?.pureName,
|
|
279
|
+
sumint1: response?.rows?.length,
|
|
280
|
+
sessionParam: `${conid}::${database}::${select?.from?.name?.schemaName || '0'}::${
|
|
281
|
+
select?.from?.name?.pureName
|
|
271
282
|
}`,
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
283
|
+
sessionGroup: auditLogSessionGroup,
|
|
284
|
+
message: `Loaded table data from ${select?.from?.name?.pureName}`,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
276
287
|
: null,
|
|
277
288
|
}
|
|
278
289
|
);
|
|
@@ -335,21 +346,21 @@ module.exports = {
|
|
|
335
346
|
auditLogger:
|
|
336
347
|
auditLogSessionGroup && options?.pureName
|
|
337
348
|
? response => {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
349
|
+
sendToAuditLog(req, {
|
|
350
|
+
category: 'dbop',
|
|
351
|
+
component: 'DatabaseConnectionsController',
|
|
352
|
+
event: 'nosql.collectionData',
|
|
353
|
+
action: 'select',
|
|
354
|
+
severity: 'info',
|
|
355
|
+
conid,
|
|
356
|
+
database,
|
|
357
|
+
pureName: options?.pureName,
|
|
358
|
+
sumint1: response?.result?.rows?.length,
|
|
359
|
+
sessionParam: `${conid}::${database}::${options?.pureName}`,
|
|
360
|
+
sessionGroup: auditLogSessionGroup,
|
|
361
|
+
message: `Loaded collection data ${options?.pureName}`,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
353
364
|
: null,
|
|
354
365
|
}
|
|
355
366
|
);
|
|
@@ -455,10 +466,18 @@ module.exports = {
|
|
|
455
466
|
[changeSet.inserts, 'create_update_delete'],
|
|
456
467
|
[changeSet.deletes, 'create_update_delete'],
|
|
457
468
|
[changeSet.updates, 'update_only'],
|
|
458
|
-
]
|
|
469
|
+
];
|
|
459
470
|
for (const [operations, requiredRole] of fieldsAndRoles) {
|
|
460
471
|
for (const operation of operations) {
|
|
461
|
-
const role = getTablePermissionRole(
|
|
472
|
+
const role = getTablePermissionRole(
|
|
473
|
+
conid,
|
|
474
|
+
database,
|
|
475
|
+
'tables',
|
|
476
|
+
operation.schemaName,
|
|
477
|
+
operation.pureName,
|
|
478
|
+
tablePermissions,
|
|
479
|
+
databasePermissions
|
|
480
|
+
);
|
|
462
481
|
if (getTablePermissionRoleLevelIndex(role) < getTablePermissionRoleLevelIndex(requiredRole)) {
|
|
463
482
|
throw new Error('DBGM-00262 Permission not granted');
|
|
464
483
|
}
|
|
@@ -628,7 +647,15 @@ module.exports = {
|
|
|
628
647
|
function applyTablePermissionRole(list, objectTypeField) {
|
|
629
648
|
const res = [];
|
|
630
649
|
for (const item of list ?? []) {
|
|
631
|
-
const tablePermissionRole = getTablePermissionRole(
|
|
650
|
+
const tablePermissionRole = getTablePermissionRole(
|
|
651
|
+
conid,
|
|
652
|
+
database,
|
|
653
|
+
objectTypeField,
|
|
654
|
+
item.schemaName,
|
|
655
|
+
item.pureName,
|
|
656
|
+
tablePermissions,
|
|
657
|
+
databasePermissionRole
|
|
658
|
+
);
|
|
632
659
|
if (tablePermissionRole != 'deny') {
|
|
633
660
|
res.push({
|
|
634
661
|
...item,
|
|
@@ -647,7 +674,7 @@ module.exports = {
|
|
|
647
674
|
functions: applyTablePermissionRole(opened.structure.functions, 'functions'),
|
|
648
675
|
triggers: applyTablePermissionRole(opened.structure.triggers, 'triggers'),
|
|
649
676
|
collections: applyTablePermissionRole(opened.structure.collections, 'collections'),
|
|
650
|
-
}
|
|
677
|
+
};
|
|
651
678
|
return res;
|
|
652
679
|
}
|
|
653
680
|
|
|
@@ -881,17 +908,17 @@ module.exports = {
|
|
|
881
908
|
return {
|
|
882
909
|
...(command == 'backup'
|
|
883
910
|
? driver.backupDatabaseCommand(
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
911
|
+
connection,
|
|
912
|
+
{ outputFile, database, options, selectedTables, skippedTables, argsFormat },
|
|
913
|
+
// @ts-ignore
|
|
914
|
+
externalTools
|
|
915
|
+
)
|
|
889
916
|
: driver.restoreDatabaseCommand(
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
917
|
+
connection,
|
|
918
|
+
{ inputFile, database, options, argsFormat },
|
|
919
|
+
// @ts-ignore
|
|
920
|
+
externalTools
|
|
921
|
+
)),
|
|
895
922
|
transformMessage: driver.transformNativeCommandMessage
|
|
896
923
|
? message => driver.transformNativeCommandMessage(message, command)
|
|
897
924
|
: null,
|
|
@@ -990,7 +1017,10 @@ module.exports = {
|
|
|
990
1017
|
async executeSessionQuery({ sesid, conid, database, sql }, req) {
|
|
991
1018
|
await testConnectionPermission(conid, req);
|
|
992
1019
|
logger.info({ sesid, sql }, 'DBGM-00010 Processing query');
|
|
993
|
-
sessions.dispatchMessage(sesid,
|
|
1020
|
+
sessions.dispatchMessage(sesid, {
|
|
1021
|
+
message: 'Query execution started',
|
|
1022
|
+
sql,
|
|
1023
|
+
});
|
|
994
1024
|
|
|
995
1025
|
const opened = await this.ensureOpened(conid, database);
|
|
996
1026
|
opened.subprocess.send({ msgtype: 'executeSessionQuery', sql, sesid });
|
|
@@ -83,6 +83,16 @@ module.exports = {
|
|
|
83
83
|
socket.emit(`session-recordset-${sesid}`, { jslid, resultIndex });
|
|
84
84
|
},
|
|
85
85
|
|
|
86
|
+
handle_endrecordset(sesid, props) {
|
|
87
|
+
const { jslid, rowCount, durationMs } = props;
|
|
88
|
+
this.dispatchMessage(sesid, {
|
|
89
|
+
message: `Query returned ${rowCount} rows in ${durationMs} ms`,
|
|
90
|
+
rowCount,
|
|
91
|
+
durationMs,
|
|
92
|
+
jslid,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
|
|
86
96
|
handle_stats(sesid, stats) {
|
|
87
97
|
jsldata.notifyChangedStats(stats);
|
|
88
98
|
},
|
|
@@ -97,6 +107,12 @@ module.exports = {
|
|
|
97
107
|
socket.emit(`session-initialize-file-${jslid}`);
|
|
98
108
|
},
|
|
99
109
|
|
|
110
|
+
handle_changedCurrentDatabase(sesid, props) {
|
|
111
|
+
const { database } = props;
|
|
112
|
+
this.dispatchMessage(sesid, `Current database changed to ${database}`);
|
|
113
|
+
socket.emit(`session-changedb-${sesid}`, { database });
|
|
114
|
+
},
|
|
115
|
+
|
|
100
116
|
handle_ping() {},
|
|
101
117
|
|
|
102
118
|
create_meta: true,
|
|
@@ -182,7 +198,10 @@ module.exports = {
|
|
|
182
198
|
});
|
|
183
199
|
|
|
184
200
|
logger.info({ sesid, sql }, 'DBGM-00019 Processing query');
|
|
185
|
-
this.dispatchMessage(sesid,
|
|
201
|
+
this.dispatchMessage(sesid, {
|
|
202
|
+
message: 'Query execution started',
|
|
203
|
+
sql,
|
|
204
|
+
});
|
|
186
205
|
session.subprocess.send({
|
|
187
206
|
msgtype: 'executeQuery',
|
|
188
207
|
sql,
|
package/src/currentVersion.js
CHANGED
package/src/utility/authProxy.js
CHANGED
|
@@ -11,6 +11,8 @@ const logger = getLogger('authProxy');
|
|
|
11
11
|
|
|
12
12
|
const AUTH_PROXY_URL = process.env.LOCAL_AUTH_PROXY
|
|
13
13
|
? 'http://localhost:3110'
|
|
14
|
+
: process.env.PROD_AUTH_PROXY
|
|
15
|
+
? 'https://auth.dbgate.eu'
|
|
14
16
|
: process.env.DEVWEB || process.env.DEVMODE
|
|
15
17
|
? 'https://auth-proxy.dbgate.udolni.net'
|
|
16
18
|
: 'https://auth.dbgate.eu';
|
|
@@ -151,11 +153,12 @@ async function getAwsIamToken(props) {
|
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
async function obtainRefreshedLicense() {
|
|
154
|
-
|
|
156
|
+
const activeLicenseKey = licenseKey ?? process.env.DBGATE_LICENSE;
|
|
157
|
+
if (!activeLicenseKey) {
|
|
155
158
|
return null;
|
|
156
159
|
}
|
|
157
160
|
|
|
158
|
-
const decoded = jwt.decode(
|
|
161
|
+
const decoded = jwt.decode(activeLicenseKey?.trim());
|
|
159
162
|
if (!decoded?.end) {
|
|
160
163
|
logger.info('DBGM-00078 Invalid license found');
|
|
161
164
|
return null;
|
|
@@ -171,7 +174,7 @@ async function obtainRefreshedLicense() {
|
|
|
171
174
|
{
|
|
172
175
|
headers: {
|
|
173
176
|
'Content-Type': 'application/json',
|
|
174
|
-
Authorization: `Bearer ${
|
|
177
|
+
Authorization: `Bearer ${activeLicenseKey}`,
|
|
175
178
|
},
|
|
176
179
|
}
|
|
177
180
|
);
|
|
@@ -207,10 +207,6 @@ async function checkLicense() {
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
if (process.env.DBGATE_LICENSE) {
|
|
211
|
-
return checkLicenseKey(process.env.DBGATE_LICENSE);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
210
|
if (platformInfo.isAwsUbuntuLayout && getCloudToken() == 'b93c7491890460063003a02de06ec84a') {
|
|
215
211
|
const metadata = await getAwsMetadata();
|
|
216
212
|
if (metadata?.amiId) {
|
|
@@ -238,16 +234,23 @@ async function checkLicense() {
|
|
|
238
234
|
}
|
|
239
235
|
|
|
240
236
|
const datadir = path.join(os.homedir(), '.dbgate');
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
237
|
+
const licenseKeyPath = path.join(datadir, 'license.key');
|
|
238
|
+
if (fs.existsSync(licenseKeyPath)) {
|
|
239
|
+
try {
|
|
240
|
+
const licenseKey = fs.readFileSync(licenseKeyPath, {
|
|
241
|
+
encoding: 'utf-8',
|
|
242
|
+
});
|
|
243
|
+
setAuthProxyLicense(licenseKey);
|
|
244
|
+
if (licenseKey) {
|
|
245
|
+
return checkLicenseKey(licenseKey);
|
|
246
|
+
}
|
|
247
|
+
} catch (err) {
|
|
248
|
+
logger.warn(extractErrorLogData(err), 'Error loading license key');
|
|
248
249
|
}
|
|
249
|
-
}
|
|
250
|
-
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (process.env.DBGATE_LICENSE) {
|
|
253
|
+
return checkLicenseKey(process.env.DBGATE_LICENSE);
|
|
251
254
|
}
|
|
252
255
|
|
|
253
256
|
if (isElectron()) {
|
|
@@ -14,6 +14,7 @@ class QueryStreamTableWriter {
|
|
|
14
14
|
this.currentChangeIndex = 1;
|
|
15
15
|
this.initializedFile = false;
|
|
16
16
|
this.sesid = sesid;
|
|
17
|
+
this.started = new Date().getTime();
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false) {
|
|
@@ -118,6 +119,13 @@ class QueryStreamTableWriter {
|
|
|
118
119
|
this.chartProcessor = null;
|
|
119
120
|
}
|
|
120
121
|
}
|
|
122
|
+
process.send({
|
|
123
|
+
msgtype: 'endrecordset',
|
|
124
|
+
jslid: this.jslid,
|
|
125
|
+
rowCount: this.currentRowCount,
|
|
126
|
+
sesid: this.sesid,
|
|
127
|
+
durationMs: new Date().getTime() - this.started,
|
|
128
|
+
});
|
|
121
129
|
resolve();
|
|
122
130
|
});
|
|
123
131
|
} else {
|
|
@@ -148,6 +156,7 @@ class StreamHandler {
|
|
|
148
156
|
// this.error = this.error.bind(this);
|
|
149
157
|
this.done = this.done.bind(this);
|
|
150
158
|
this.info = this.info.bind(this);
|
|
159
|
+
this.changedCurrentDatabase = this.changedCurrentDatabase.bind(this);
|
|
151
160
|
|
|
152
161
|
// use this for cancelling - not implemented
|
|
153
162
|
// this.stream = null;
|
|
@@ -166,6 +175,10 @@ class StreamHandler {
|
|
|
166
175
|
}
|
|
167
176
|
}
|
|
168
177
|
|
|
178
|
+
changedCurrentDatabase(database) {
|
|
179
|
+
process.send({ msgtype: 'changedCurrentDatabase', database, sesid: this.sesid });
|
|
180
|
+
}
|
|
181
|
+
|
|
169
182
|
recordset(columns) {
|
|
170
183
|
if (this.rowsLimitOverflow) {
|
|
171
184
|
return;
|