dbgate-api-premium 6.6.0 → 6.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/src/auth/authProvider.js +14 -2
- package/src/auth/storageAuthProvider.js +89 -22
- package/src/controllers/archive.js +1 -1
- package/src/controllers/auth.js +3 -2
- package/src/controllers/cloud.js +1 -1
- package/src/controllers/config.js +8 -5
- package/src/controllers/connections.js +12 -11
- package/src/controllers/databaseConnections.js +148 -83
- package/src/controllers/files.js +49 -19
- package/src/controllers/plugins.js +7 -4
- package/src/controllers/runners.js +10 -6
- package/src/controllers/scheduler.js +4 -3
- package/src/controllers/serverConnections.js +69 -14
- package/src/controllers/sessions.js +8 -5
- package/src/controllers/storage.js +81 -51
- package/src/controllers/storageDb.js +118 -4
- package/src/controllers/uploads.js +2 -2
- package/src/currentVersion.js +2 -2
- package/src/index.js +36 -5
- package/src/main.js +59 -20
- package/src/proc/databaseConnectionProcess.js +45 -13
- package/src/proc/serverConnectionProcess.js +32 -6
- package/src/proc/sessionProcess.js +2 -2
- package/src/proc/sshForwardProcess.js +1 -1
- package/src/shell/archiveWriter.js +1 -1
- package/src/shell/copyStream.js +1 -1
- package/src/shell/executeQuery.js +3 -3
- package/src/shell/importDatabase.js +3 -3
- package/src/shell/jsonLinesReader.js +1 -1
- package/src/shell/jsonLinesWriter.js +1 -1
- package/src/shell/jsonReader.js +1 -1
- package/src/shell/jsonWriter.js +1 -1
- package/src/shell/loadDatabase.js +2 -2
- package/src/shell/modifyJsonLinesReader.js +1 -1
- package/src/shell/queryReader.js +1 -1
- package/src/shell/requirePlugin.js +6 -1
- package/src/shell/runScript.js +1 -1
- package/src/shell/sqlDataWriter.js +1 -1
- package/src/shell/tableReader.js +3 -3
- package/src/shell/tableWriter.js +1 -1
- package/src/shell/unzipDirectory.js +4 -4
- package/src/shell/zipDirectory.js +3 -3
- package/src/shell/zipJsonLinesData.js +3 -3
- package/src/storageModel.js +726 -105
- package/src/utility/DatastoreProxy.js +3 -3
- package/src/utility/JsonLinesDatastore.js +4 -2
- package/src/utility/appLogStore.js +119 -0
- package/src/utility/auditlog.js +1 -1
- package/src/utility/authProxy.js +4 -4
- package/src/utility/checkLicense.js +10 -4
- package/src/utility/childProcessChecker.js +1 -1
- package/src/utility/cloudIntf.js +5 -5
- package/src/utility/cloudUpgrade.js +4 -4
- package/src/utility/connectUtility.js +1 -1
- package/src/utility/directories.js +2 -2
- package/src/utility/extractSingleFileFromZip.js +3 -3
- package/src/utility/hasPermission.js +286 -71
- package/src/utility/loadModelTransform.js +1 -1
- package/src/utility/sshTunnel.js +7 -7
- package/src/utility/sshTunnelProxy.js +1 -1
- package/src/utility/useController.js +3 -3
|
@@ -2,23 +2,23 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { setAuthProviders, getAuthProviderById } = require('../auth/authProvider');
|
|
5
|
-
const { createStorageAuthProvider } = require('../auth/storageAuthProvider');
|
|
5
|
+
const { createStorageAuthProvider, SuperadminAuthProvider } = require('../auth/storageAuthProvider');
|
|
6
6
|
const {
|
|
7
7
|
getStorageConnection,
|
|
8
8
|
getDbConnectionParams,
|
|
9
9
|
storageSelectFmt,
|
|
10
10
|
storageReadUserRolePermissions,
|
|
11
|
-
loadSuperadminPermissions,
|
|
12
11
|
storageReadConfig,
|
|
13
12
|
storageWriteConfig,
|
|
14
13
|
getStorageConnectionError,
|
|
15
14
|
storageSaveRelationDiff,
|
|
16
15
|
selectStorageIdentity,
|
|
16
|
+
storageSaveDetailPermissionsDiff,
|
|
17
17
|
} = require('./storageDb');
|
|
18
|
-
const { hasPermission } = require('../utility/hasPermission');
|
|
18
|
+
const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
|
|
19
19
|
const { changeSetToSql, removeSchemaFromChangeSet } = require('dbgate-datalib');
|
|
20
20
|
const storageModel = require('../storageModel');
|
|
21
|
-
const { dumpSqlCommand, dumpSqlSelect } = require('dbgate-sqltree');
|
|
21
|
+
const { dumpSqlCommand, dumpSqlSelect, createLogCompoudCondition } = require('dbgate-sqltree');
|
|
22
22
|
const {
|
|
23
23
|
runCommandOnDriver,
|
|
24
24
|
getLogger,
|
|
@@ -64,6 +64,7 @@ module.exports = {
|
|
|
64
64
|
if (defIndex < 0) {
|
|
65
65
|
defIndex = enabledConfig.findIndex(x => x.type == 'local');
|
|
66
66
|
}
|
|
67
|
+
providers.push(new SuperadminAuthProvider());
|
|
67
68
|
|
|
68
69
|
setAuthProviders(providers, providers[defIndex]);
|
|
69
70
|
|
|
@@ -94,14 +95,14 @@ module.exports = {
|
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
97
|
if (resp.status == 'error') {
|
|
97
|
-
logger.error(`Error refreshing license: ${resp.message}`);
|
|
98
|
+
logger.error(`DBGM-00146 Error refreshing license: ${resp.message}`);
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
if (resp.status != 'ok') {
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
const { token } = resp;
|
|
104
|
-
logger.info('License succesfully refreshed');
|
|
105
|
+
logger.info('DBGM-00022 License succesfully refreshed');
|
|
105
106
|
if (process.env.STORAGE_DATABASE) {
|
|
106
107
|
await this.writeConfig({ group: 'license', config: { licenseKey: token } });
|
|
107
108
|
} else {
|
|
@@ -112,6 +113,7 @@ module.exports = {
|
|
|
112
113
|
|
|
113
114
|
connections_meta: true,
|
|
114
115
|
async connections(req) {
|
|
116
|
+
const loadedPermissions = await loadPermissionsFromRequest(req);
|
|
115
117
|
if (!process.env.STORAGE_DATABASE) {
|
|
116
118
|
return null;
|
|
117
119
|
}
|
|
@@ -121,7 +123,7 @@ module.exports = {
|
|
|
121
123
|
|
|
122
124
|
let resp = null;
|
|
123
125
|
|
|
124
|
-
if (hasPermission('all-connections',
|
|
126
|
+
if (hasPermission('all-connections', loadedPermissions)) {
|
|
125
127
|
resp = await storageSelectFmt(`select ~connections.* from ~connections`);
|
|
126
128
|
} else if (userId) {
|
|
127
129
|
resp = await storageSelectFmt(
|
|
@@ -142,9 +144,8 @@ module.exports = {
|
|
|
142
144
|
);
|
|
143
145
|
} else {
|
|
144
146
|
resp = await storageSelectFmt(
|
|
145
|
-
`select
|
|
146
|
-
|
|
147
|
-
where ~role_connections.~role_id = %v`,
|
|
147
|
+
`select ~connections.* from ~connections
|
|
148
|
+
where exists (select * from ~role_connections where ~role_connections.~connection_id = ~connections.~id and ~role_connections.~role_id = %v)`,
|
|
148
149
|
roleId ?? -1
|
|
149
150
|
);
|
|
150
151
|
}
|
|
@@ -153,7 +154,7 @@ module.exports = {
|
|
|
153
154
|
return [];
|
|
154
155
|
}
|
|
155
156
|
const res = [];
|
|
156
|
-
if (hasPermission('internal-storage',
|
|
157
|
+
if (hasPermission('internal-storage', loadedPermissions)) {
|
|
157
158
|
res.push(await this.getConnection({ conid: '__storage' }));
|
|
158
159
|
}
|
|
159
160
|
if (resp) {
|
|
@@ -330,10 +331,6 @@ module.exports = {
|
|
|
330
331
|
return storageReadUserRolePermissions(userId);
|
|
331
332
|
},
|
|
332
333
|
|
|
333
|
-
async loadSuperadminPermissions() {
|
|
334
|
-
return loadSuperadminPermissions();
|
|
335
|
-
},
|
|
336
|
-
|
|
337
334
|
getConnectionsForLoginPage_meta: true,
|
|
338
335
|
getConnectionsForLoginPage({ amoid }) {
|
|
339
336
|
return getAuthProviderById(amoid).getLoginPageConnections();
|
|
@@ -488,6 +485,10 @@ module.exports = {
|
|
|
488
485
|
: (await storageSelectFmt('select ~connection_id from ~user_connections where ~user_id = %v', id)).map(
|
|
489
486
|
x => x.connection_id
|
|
490
487
|
);
|
|
488
|
+
const databasePermissions =
|
|
489
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~user_databases where ~user_id = %v', id);
|
|
490
|
+
const tablePermissions =
|
|
491
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~user_tables where ~user_id = %v', id);
|
|
491
492
|
|
|
492
493
|
return {
|
|
493
494
|
...resp[0],
|
|
@@ -497,6 +498,8 @@ module.exports = {
|
|
|
497
498
|
usedRoles,
|
|
498
499
|
allConnections,
|
|
499
500
|
usedConnections,
|
|
501
|
+
databasePermissions,
|
|
502
|
+
tablePermissions,
|
|
500
503
|
encryptPassword: !!(resp[0]?.password?.startsWith('crypt:') || id == 'new'),
|
|
501
504
|
};
|
|
502
505
|
},
|
|
@@ -505,7 +508,8 @@ module.exports = {
|
|
|
505
508
|
async saveUserDetail(user) {
|
|
506
509
|
const [conn, driver] = await getStorageConnection();
|
|
507
510
|
|
|
508
|
-
const { login, password, email, usedRoles, usedConnections, permissions } =
|
|
511
|
+
const { login, password, email, usedRoles, usedConnections, permissions, databasePermissions, tablePermissions } =
|
|
512
|
+
encryptUser(user);
|
|
509
513
|
let id = user.id;
|
|
510
514
|
|
|
511
515
|
if (id == null) {
|
|
@@ -534,6 +538,32 @@ module.exports = {
|
|
|
534
538
|
await storageSaveRelationDiff('user_roles', 'user_id', 'role_id', id, usedRoles);
|
|
535
539
|
await storageSaveRelationDiff('user_connections', 'user_id', 'connection_id', id, usedConnections);
|
|
536
540
|
|
|
541
|
+
await storageSaveDetailPermissionsDiff(
|
|
542
|
+
'user_databases',
|
|
543
|
+
'user_id',
|
|
544
|
+
id,
|
|
545
|
+
['connection_id', 'database_names_list', 'database_names_regex', 'database_permission_role_id'],
|
|
546
|
+
databasePermissions
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
await storageSaveDetailPermissionsDiff(
|
|
550
|
+
'user_tables',
|
|
551
|
+
'user_id',
|
|
552
|
+
id,
|
|
553
|
+
[
|
|
554
|
+
'connection_id',
|
|
555
|
+
'database_names_list',
|
|
556
|
+
'database_names_regex',
|
|
557
|
+
'schema_names_list',
|
|
558
|
+
'schema_names_regex',
|
|
559
|
+
'table_names_list',
|
|
560
|
+
'table_names_regex',
|
|
561
|
+
'table_permission_role_id',
|
|
562
|
+
'table_permission_scope_id',
|
|
563
|
+
],
|
|
564
|
+
tablePermissions
|
|
565
|
+
);
|
|
566
|
+
|
|
537
567
|
return true;
|
|
538
568
|
},
|
|
539
569
|
|
|
@@ -678,6 +708,11 @@ module.exports = {
|
|
|
678
708
|
: (await storageSelectFmt('select ~connection_id from ~role_connections where ~role_id = %v', id)).map(
|
|
679
709
|
x => x.connection_id
|
|
680
710
|
);
|
|
711
|
+
const databasePermissions =
|
|
712
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~role_databases where ~role_id = %v', id);
|
|
713
|
+
const tablePermissions =
|
|
714
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~role_tables where ~role_id = %v', id);
|
|
715
|
+
|
|
681
716
|
|
|
682
717
|
return {
|
|
683
718
|
...resp[0],
|
|
@@ -687,6 +722,8 @@ module.exports = {
|
|
|
687
722
|
usedUsers,
|
|
688
723
|
allConnections,
|
|
689
724
|
usedConnections,
|
|
725
|
+
databasePermissions,
|
|
726
|
+
tablePermissions,
|
|
690
727
|
};
|
|
691
728
|
},
|
|
692
729
|
|
|
@@ -706,7 +743,7 @@ module.exports = {
|
|
|
706
743
|
async saveRoleDetail(role) {
|
|
707
744
|
const [conn, driver] = await getStorageConnection();
|
|
708
745
|
|
|
709
|
-
const { name, usedConnections, usedUsers, permissions } =
|
|
746
|
+
const { name, usedConnections, usedUsers, permissions, databasePermissions, tablePermissions } = role;
|
|
710
747
|
let id = role.id;
|
|
711
748
|
|
|
712
749
|
if (id == null) {
|
|
@@ -722,42 +759,38 @@ module.exports = {
|
|
|
722
759
|
await storageSaveRelationDiff('user_roles', 'role_id', 'user_id', id, usedUsers);
|
|
723
760
|
await storageSaveRelationDiff('role_connections', 'role_id', 'connection_id', id, usedConnections);
|
|
724
761
|
|
|
762
|
+
await storageSaveDetailPermissionsDiff(
|
|
763
|
+
'role_databases',
|
|
764
|
+
'role_id',
|
|
765
|
+
id,
|
|
766
|
+
['connection_id', 'database_names_list', 'database_names_regex', 'database_permission_role_id'],
|
|
767
|
+
databasePermissions
|
|
768
|
+
);
|
|
769
|
+
|
|
770
|
+
await storageSaveDetailPermissionsDiff(
|
|
771
|
+
'role_tables',
|
|
772
|
+
'role_id',
|
|
773
|
+
id,
|
|
774
|
+
[
|
|
775
|
+
'connection_id',
|
|
776
|
+
'database_names_list',
|
|
777
|
+
'database_names_regex',
|
|
778
|
+
'schema_names_list',
|
|
779
|
+
'schema_names_regex',
|
|
780
|
+
'table_names_list',
|
|
781
|
+
'table_names_regex',
|
|
782
|
+
'table_permission_role_id',
|
|
783
|
+
'table_permission_scope_id',
|
|
784
|
+
],
|
|
785
|
+
tablePermissions
|
|
786
|
+
);
|
|
787
|
+
|
|
725
788
|
return true;
|
|
726
789
|
},
|
|
727
790
|
|
|
728
791
|
getAuditLog_meta: true,
|
|
729
792
|
async getAuditLog({ offset = 0, limit = 100, dateFrom = 0, dateTo = new Date().getTime(), filters = {} }) {
|
|
730
793
|
const [conn, driver] = await getStorageConnection();
|
|
731
|
-
const conditions = [
|
|
732
|
-
{
|
|
733
|
-
conditionType: 'binary',
|
|
734
|
-
operator: '>=',
|
|
735
|
-
left: { exprType: 'column', columnName: 'created' },
|
|
736
|
-
right: { exprType: 'value', value: dateFrom },
|
|
737
|
-
},
|
|
738
|
-
{
|
|
739
|
-
conditionType: 'binary',
|
|
740
|
-
operator: '<=',
|
|
741
|
-
left: { exprType: 'column', columnName: 'created' },
|
|
742
|
-
right: { exprType: 'value', value: dateTo },
|
|
743
|
-
},
|
|
744
|
-
];
|
|
745
|
-
for (const [key, values] of Object.entries(filters)) {
|
|
746
|
-
if (values.length == 1 && values[0] == null) {
|
|
747
|
-
// @ts-ignore
|
|
748
|
-
conditions.push({
|
|
749
|
-
conditionType: 'isNull',
|
|
750
|
-
expr: { exprType: 'column', columnName: key },
|
|
751
|
-
});
|
|
752
|
-
continue;
|
|
753
|
-
}
|
|
754
|
-
// @ts-ignore
|
|
755
|
-
conditions.push({
|
|
756
|
-
conditionType: 'in',
|
|
757
|
-
expr: { exprType: 'column', columnName: key },
|
|
758
|
-
values,
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
794
|
const COLUMNS = [
|
|
762
795
|
'id',
|
|
763
796
|
'created',
|
|
@@ -780,10 +813,7 @@ module.exports = {
|
|
|
780
813
|
exprType: 'column',
|
|
781
814
|
columnName,
|
|
782
815
|
})),
|
|
783
|
-
where:
|
|
784
|
-
conditionType: 'and',
|
|
785
|
-
conditions,
|
|
786
|
-
},
|
|
816
|
+
where: createLogCompoudCondition(filters, 'created', dateFrom, dateTo),
|
|
787
817
|
range: {
|
|
788
818
|
limit: limit,
|
|
789
819
|
offset: offset,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
2
1
|
const storageModel = require('../storageModel');
|
|
3
2
|
const dbgateApi = require('../shell');
|
|
4
3
|
const {
|
|
@@ -86,6 +85,8 @@ let storageDriver = null;
|
|
|
86
85
|
let storageConnectionError = null;
|
|
87
86
|
|
|
88
87
|
async function getStorageConnectionCore() {
|
|
88
|
+
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
89
|
+
|
|
89
90
|
if (storageConnection) {
|
|
90
91
|
return [storageConnection, storageDriver];
|
|
91
92
|
}
|
|
@@ -103,7 +104,9 @@ async function getStorageConnectionCore() {
|
|
|
103
104
|
try {
|
|
104
105
|
newConnection = await storageDriver.connect(dbConnectionParams);
|
|
105
106
|
const version = await storageDriver.getVersion(newConnection);
|
|
106
|
-
logger.info(
|
|
107
|
+
logger.info(
|
|
108
|
+
`DBGM-00023 Connected to storage database ${dbConnectionParams.engine}, version ${version?.versionText}`
|
|
109
|
+
);
|
|
107
110
|
storageConnectionError = null;
|
|
108
111
|
} catch (err) {
|
|
109
112
|
storageConnectionError = err;
|
|
@@ -113,7 +116,7 @@ async function getStorageConnectionCore() {
|
|
|
113
116
|
} catch (err) {}
|
|
114
117
|
newConnection = null;
|
|
115
118
|
}
|
|
116
|
-
logger.error(extractErrorLogData(err), 'Error connecting to storage database, retrying in 5 seconds');
|
|
119
|
+
logger.error(extractErrorLogData(err), 'DBGM-00024 Error connecting to storage database, retrying in 5 seconds');
|
|
117
120
|
// sleep 5 seconds
|
|
118
121
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
119
122
|
}
|
|
@@ -149,7 +152,7 @@ function getStorageConnection() {
|
|
|
149
152
|
gettingStorageConnectionPromise = null;
|
|
150
153
|
})
|
|
151
154
|
.catch(err => {
|
|
152
|
-
logger.error(extractErrorLogData(err), 'Error connecting to storage database');
|
|
155
|
+
logger.error(extractErrorLogData(err), 'DBGM-00147 Error connecting to storage database');
|
|
153
156
|
gettingStorageConnectionPromise = null;
|
|
154
157
|
});
|
|
155
158
|
|
|
@@ -216,6 +219,34 @@ async function storageReadRolePermissions(roleId) {
|
|
|
216
219
|
return resp.map(x => x.permission);
|
|
217
220
|
}
|
|
218
221
|
|
|
222
|
+
async function readComplexUserRolePermissions(userId, userPermissionsTable, rolePermissionsTable) {
|
|
223
|
+
const rolePermissionsResp = await storageSelectFmt(
|
|
224
|
+
'select * from %i where %i.~role_id in (select ~role_id from ~user_roles where ~user_roles.~user_id = %v)',
|
|
225
|
+
rolePermissionsTable,
|
|
226
|
+
rolePermissionsTable,
|
|
227
|
+
userId
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const userPermissionsResp = await storageSelectFmt(
|
|
231
|
+
'select * from %i where %i.~user_id = %v',
|
|
232
|
+
userPermissionsTable,
|
|
233
|
+
userPermissionsTable,
|
|
234
|
+
userId
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
return [...rolePermissionsResp, ...userPermissionsResp];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function readComplexRolePermissions(roleId, rolePermissionsTable) {
|
|
241
|
+
const rolePermissionsResp = await storageSelectFmt(
|
|
242
|
+
'select * from %i where %i.~role_id = %v',
|
|
243
|
+
rolePermissionsTable,
|
|
244
|
+
rolePermissionsTable,
|
|
245
|
+
roleId
|
|
246
|
+
);
|
|
247
|
+
return rolePermissionsResp;
|
|
248
|
+
}
|
|
249
|
+
|
|
219
250
|
async function loadSuperadminPermissions() {
|
|
220
251
|
const rolePermissions = await storageReadRolePermissions(-3);
|
|
221
252
|
return [...getPredefinedPermissions('superadmin'), ...rolePermissions];
|
|
@@ -283,6 +314,57 @@ async function storageSaveRelationDiff(table, idColumn, valueColumn, idValue, ne
|
|
|
283
314
|
}
|
|
284
315
|
}
|
|
285
316
|
|
|
317
|
+
function sanitizePermissionCollectionRow(collectionRow, valueColumns) {
|
|
318
|
+
const res = {};
|
|
319
|
+
let hasValue = false;
|
|
320
|
+
for (const col of valueColumns) {
|
|
321
|
+
if (col.endsWith('_list') || col.endsWith('_regex')) {
|
|
322
|
+
res[col] = collectionRow[col]?.trim() ? collectionRow[col]?.trim() : null;
|
|
323
|
+
} else if (col.endsWith('_id')) {
|
|
324
|
+
res[col] = collectionRow[col] ? parseInt(collectionRow[col]) : null;
|
|
325
|
+
} else {
|
|
326
|
+
res[col] = collectionRow[col] || null;
|
|
327
|
+
}
|
|
328
|
+
if (res[col]) {
|
|
329
|
+
hasValue = true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (!hasValue) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
return res;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async function storageSaveDetailPermissionsDiff(table, idColumn, idValue, valueColumns, valuesCollection) {
|
|
339
|
+
const [conn, driver] = await getStorageConnection();
|
|
340
|
+
if (!conn) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (valuesCollection) {
|
|
345
|
+
// Delete existing database permissions for this user
|
|
346
|
+
await runQueryFmt(driver, conn, 'delete from %i where %i = %v', table, idColumn, idValue);
|
|
347
|
+
|
|
348
|
+
// Insert new database permissions
|
|
349
|
+
for (const collectionRow of valuesCollection) {
|
|
350
|
+
const sanitizedRow = sanitizePermissionCollectionRow(collectionRow, valueColumns);
|
|
351
|
+
if (!sanitizedRow) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
await runQueryFmt(
|
|
355
|
+
driver,
|
|
356
|
+
conn,
|
|
357
|
+
'insert into %i (%i, %,i) values (%v, %,v)',
|
|
358
|
+
table,
|
|
359
|
+
idColumn,
|
|
360
|
+
valueColumns,
|
|
361
|
+
idValue,
|
|
362
|
+
valueColumns.map(col => sanitizedRow[col])
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
286
368
|
function getStorageConnectionError() {
|
|
287
369
|
return storageConnectionError;
|
|
288
370
|
}
|
|
@@ -300,6 +382,33 @@ async function selectStorageIdentity(tableName) {
|
|
|
300
382
|
return Object.entries(resp.rows[0])[0][1];
|
|
301
383
|
}
|
|
302
384
|
|
|
385
|
+
async function storageCheckRoleConnectionAccess(roleId, conid) {
|
|
386
|
+
const resp = await storageSelectFmt(
|
|
387
|
+
'select 1 from ~role_connections inner join ~connections on ~role_connections.~connection_id = ~connections.~id where ~role_connections.~role_id = %v and ~connections.~conid = %v',
|
|
388
|
+
roleId,
|
|
389
|
+
conid
|
|
390
|
+
);
|
|
391
|
+
return resp.length > 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async function storageCheckUserRoleConnectionAccess(userId, conid) {
|
|
395
|
+
const respByUser = await storageSelectFmt(
|
|
396
|
+
'select 1 from ~user_connections inner join ~connections on ~user_connections.~connection_id = ~connections.~id where ~user_connections.~user_id = %v and ~connections.~conid = %v',
|
|
397
|
+
userId,
|
|
398
|
+
conid
|
|
399
|
+
);
|
|
400
|
+
const respByRole = await storageSelectFmt(
|
|
401
|
+
'select 1 from ~role_connections inner join ~user_roles on ~role_connections.~role_id = ~user_roles.~role_id inner join ~connections on ~role_connections.~connection_id = ~connections.~id where ~user_roles.~user_id = %v and ~connections.~conid = %v',
|
|
402
|
+
userId,
|
|
403
|
+
conid
|
|
404
|
+
);
|
|
405
|
+
const respByLogged = await storageSelectFmt(
|
|
406
|
+
'select 1 from ~role_connections inner join ~connections on ~role_connections.~connection_id = ~connections.~id where ~role_connections.~role_id = -2 and ~connections.~conid = %v',
|
|
407
|
+
conid
|
|
408
|
+
);
|
|
409
|
+
return respByUser.length > 0 || respByRole.length > 0 || respByLogged.length > 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
303
412
|
module.exports = {
|
|
304
413
|
getStorageConnection,
|
|
305
414
|
storageSelectFmt,
|
|
@@ -314,4 +423,9 @@ module.exports = {
|
|
|
314
423
|
storageSqlCommandFmt,
|
|
315
424
|
storageSaveRelationDiff,
|
|
316
425
|
selectStorageIdentity,
|
|
426
|
+
storageSaveDetailPermissionsDiff,
|
|
427
|
+
readComplexUserRolePermissions,
|
|
428
|
+
readComplexRolePermissions,
|
|
429
|
+
storageCheckRoleConnectionAccess,
|
|
430
|
+
storageCheckUserRoleConnectionAccess,
|
|
317
431
|
};
|
|
@@ -28,7 +28,7 @@ module.exports = {
|
|
|
28
28
|
}
|
|
29
29
|
const uploadName = crypto.randomUUID();
|
|
30
30
|
const filePath = path.join(uploadsdir(), uploadName);
|
|
31
|
-
logger.info(`Uploading file ${data.name}, size=${data.size}`);
|
|
31
|
+
logger.info(`DBGM-00025 Uploading file ${data.name}, size=${data.size}`);
|
|
32
32
|
|
|
33
33
|
data.mv(filePath, () => {
|
|
34
34
|
res.json({
|
|
@@ -115,7 +115,7 @@ module.exports = {
|
|
|
115
115
|
|
|
116
116
|
return response.data;
|
|
117
117
|
} catch (err) {
|
|
118
|
-
logger.error(extractErrorLogData(err), 'Error uploading gist');
|
|
118
|
+
logger.error(extractErrorLogData(err), 'DBGM-00148 Error uploading gist');
|
|
119
119
|
|
|
120
120
|
return {
|
|
121
121
|
apiErrorMessage: err.message,
|
package/src/currentVersion.js
CHANGED
package/src/index.js
CHANGED
|
@@ -5,11 +5,12 @@ const moment = require('moment');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { logsdir, setLogsFilePath, getLogsFilePath } = require('./utility/directories');
|
|
7
7
|
const currentVersion = require('./currentVersion');
|
|
8
|
+
const _ = require('lodash');
|
|
8
9
|
|
|
9
10
|
const logger = getLogger('apiIndex');
|
|
10
11
|
|
|
11
12
|
process.on('uncaughtException', err => {
|
|
12
|
-
logger.fatal(extractErrorLogData(err), 'Uncaught exception, exiting process');
|
|
13
|
+
logger.fatal(extractErrorLogData(err), 'DBGM-00259 Uncaught exception, exiting process');
|
|
13
14
|
process.exit(1);
|
|
14
15
|
});
|
|
15
16
|
|
|
@@ -33,6 +34,9 @@ if (processArgs.processDisplayName) {
|
|
|
33
34
|
// }
|
|
34
35
|
|
|
35
36
|
function configureLogger() {
|
|
37
|
+
const { initializeRecentLogProvider, pushToRecentLogs } = require('./utility/appLogStore');
|
|
38
|
+
initializeRecentLogProvider();
|
|
39
|
+
|
|
36
40
|
const logsFilePath = path.join(logsdir(), `${moment().format('YYYY-MM-DD-HH-mm')}-${process.pid}.ndjson`);
|
|
37
41
|
setLogsFilePath(logsFilePath);
|
|
38
42
|
setLoggerName('main');
|
|
@@ -40,6 +44,8 @@ function configureLogger() {
|
|
|
40
44
|
const consoleLogLevel = process.env.CONSOLE_LOG_LEVEL || process.env.LOG_LEVEL || 'info';
|
|
41
45
|
const fileLogLevel = process.env.FILE_LOG_LEVEL || process.env.LOG_LEVEL || 'debug';
|
|
42
46
|
|
|
47
|
+
const streamsByDatePart = {};
|
|
48
|
+
|
|
43
49
|
const logConfig = {
|
|
44
50
|
base: { pid: process.pid },
|
|
45
51
|
targets: [
|
|
@@ -49,10 +55,35 @@ function configureLogger() {
|
|
|
49
55
|
level: consoleLogLevel,
|
|
50
56
|
},
|
|
51
57
|
{
|
|
52
|
-
type: '
|
|
58
|
+
type: 'objstream',
|
|
53
59
|
// @ts-ignore
|
|
54
60
|
level: fileLogLevel,
|
|
55
|
-
|
|
61
|
+
objstream: {
|
|
62
|
+
send(msg) {
|
|
63
|
+
const datePart = moment(msg.time).format('YYYY-MM-DD');
|
|
64
|
+
if (!streamsByDatePart[datePart]) {
|
|
65
|
+
streamsByDatePart[datePart] = fs.createWriteStream(
|
|
66
|
+
path.join(logsdir(), `${moment().format('YYYY-MM-DD-HH-mm')}-${process.pid}.ndjson`),
|
|
67
|
+
{ flags: 'a' }
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const additionals = {};
|
|
71
|
+
const finalMsg =
|
|
72
|
+
_.isString(msg.msg) && msg.msg.match(/^DBGM-\d\d\d\d\d/)
|
|
73
|
+
? {
|
|
74
|
+
...msg,
|
|
75
|
+
msg: msg.msg.substring(10).trimStart(),
|
|
76
|
+
msgcode: msg.msg.substring(0, 10),
|
|
77
|
+
...additionals,
|
|
78
|
+
}
|
|
79
|
+
: {
|
|
80
|
+
...msg,
|
|
81
|
+
...additionals,
|
|
82
|
+
};
|
|
83
|
+
streamsByDatePart[datePart].write(`${JSON.stringify(finalMsg)}\n`);
|
|
84
|
+
pushToRecentLogs(finalMsg);
|
|
85
|
+
},
|
|
86
|
+
},
|
|
56
87
|
},
|
|
57
88
|
],
|
|
58
89
|
};
|
|
@@ -101,10 +132,10 @@ function configureLogger() {
|
|
|
101
132
|
|
|
102
133
|
if (processArgs.listenApi) {
|
|
103
134
|
configureLogger();
|
|
104
|
-
logger.info(`Starting API process version ${currentVersion.version}`);
|
|
135
|
+
logger.info(`DBGM-00026 Starting API process version ${currentVersion.version}`);
|
|
105
136
|
|
|
106
137
|
if (process.env.DEBUG_PRINT_ENV_VARIABLES) {
|
|
107
|
-
logger.info('Debug print environment variables:');
|
|
138
|
+
logger.info('DBGM-00027 Debug print environment variables:');
|
|
108
139
|
for (const key of Object.keys(process.env)) {
|
|
109
140
|
logger.info(` ${key}: ${JSON.stringify(process.env[key])}`);
|
|
110
141
|
}
|