dbgate-api 6.5.5 → 6.5.6
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 +5 -5
- package/src/controllers/auth.js +41 -14
- package/src/controllers/config.js +41 -16
- package/src/controllers/storage.js +0 -2
- package/src/currentVersion.js +2 -2
- package/src/storageModel.js +68 -62
- package/src/utility/authProxy.js +7 -0
- package/src/utility/cloudIntf.js +13 -1
- package/src/utility/loginchecker.js +4 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "6.5.
|
|
4
|
+
"version": "6.5.6",
|
|
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.5.
|
|
33
|
+
"dbgate-datalib": "^6.5.6",
|
|
34
34
|
"dbgate-query-splitter": "^4.11.5",
|
|
35
|
-
"dbgate-sqltree": "^6.5.
|
|
36
|
-
"dbgate-tools": "^6.5.
|
|
35
|
+
"dbgate-sqltree": "^6.5.6",
|
|
36
|
+
"dbgate-tools": "^6.5.6",
|
|
37
37
|
"debug": "^4.3.4",
|
|
38
38
|
"diff": "^5.0.0",
|
|
39
39
|
"diff2html": "^3.4.13",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@types/fs-extra": "^9.0.11",
|
|
87
87
|
"@types/lodash": "^4.14.149",
|
|
88
|
-
"dbgate-types": "^6.5.
|
|
88
|
+
"dbgate-types": "^6.5.6",
|
|
89
89
|
"env-cmd": "^10.1.0",
|
|
90
90
|
"jsdoc-to-markdown": "^9.0.5",
|
|
91
91
|
"node-loader": "^1.0.2",
|
package/src/controllers/auth.js
CHANGED
|
@@ -21,7 +21,13 @@ const {
|
|
|
21
21
|
} = require('../utility/cloudIntf');
|
|
22
22
|
const socket = require('../utility/socket');
|
|
23
23
|
const { sendToAuditLog } = require('../utility/auditlog');
|
|
24
|
-
const {
|
|
24
|
+
const {
|
|
25
|
+
isLoginLicensed,
|
|
26
|
+
LOGIN_LIMIT_ERROR,
|
|
27
|
+
markTokenAsLoggedIn,
|
|
28
|
+
markUserAsActive,
|
|
29
|
+
markLoginAsLoggedOut,
|
|
30
|
+
} = require('../utility/loginchecker');
|
|
25
31
|
|
|
26
32
|
const logger = getLogger('auth');
|
|
27
33
|
|
|
@@ -61,6 +67,11 @@ function authMiddleware(req, res, next) {
|
|
|
61
67
|
|
|
62
68
|
// const isAdminPage = req.headers['x-is-admin-page'] == 'true';
|
|
63
69
|
|
|
70
|
+
if (process.env.SKIP_ALL_AUTH) {
|
|
71
|
+
// API is not authorized for basic auth
|
|
72
|
+
return next();
|
|
73
|
+
}
|
|
74
|
+
|
|
64
75
|
if (process.env.BASIC_AUTH) {
|
|
65
76
|
// API is not authorized for basic auth
|
|
66
77
|
return next();
|
|
@@ -79,7 +90,7 @@ function authMiddleware(req, res, next) {
|
|
|
79
90
|
try {
|
|
80
91
|
const decoded = jwt.verify(token, getTokenSecret());
|
|
81
92
|
req.user = decoded;
|
|
82
|
-
|
|
93
|
+
markUserAsActive(decoded.licenseUid, token);
|
|
83
94
|
|
|
84
95
|
return next();
|
|
85
96
|
} catch (err) {
|
|
@@ -124,19 +135,23 @@ module.exports = {
|
|
|
124
135
|
message: 'Administration login successful',
|
|
125
136
|
});
|
|
126
137
|
|
|
138
|
+
const licenseUid = `superadmin`;
|
|
139
|
+
const accessToken = jwt.sign(
|
|
140
|
+
{
|
|
141
|
+
login: 'superadmin',
|
|
142
|
+
permissions: await storage.loadSuperadminPermissions(),
|
|
143
|
+
roleId: -3,
|
|
144
|
+
licenseUid,
|
|
145
|
+
},
|
|
146
|
+
getTokenSecret(),
|
|
147
|
+
{
|
|
148
|
+
expiresIn: getTokenLifetime(),
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
markTokenAsLoggedIn(licenseUid, accessToken);
|
|
152
|
+
|
|
127
153
|
return {
|
|
128
|
-
accessToken
|
|
129
|
-
{
|
|
130
|
-
login: 'superadmin',
|
|
131
|
-
permissions: await storage.loadSuperadminPermissions(),
|
|
132
|
-
roleId: -3,
|
|
133
|
-
licenseUid: `superadmin`,
|
|
134
|
-
},
|
|
135
|
-
getTokenSecret(),
|
|
136
|
-
{
|
|
137
|
-
expiresIn: getTokenLifetime(),
|
|
138
|
-
}
|
|
139
|
-
),
|
|
154
|
+
accessToken,
|
|
140
155
|
};
|
|
141
156
|
}
|
|
142
157
|
|
|
@@ -192,5 +207,17 @@ module.exports = {
|
|
|
192
207
|
return tokenHolder;
|
|
193
208
|
},
|
|
194
209
|
|
|
210
|
+
logoutAdmin_meta: true,
|
|
211
|
+
async logoutAdmin() {
|
|
212
|
+
await markLoginAsLoggedOut('superadmin');
|
|
213
|
+
return true;
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
logoutUser_meta: true,
|
|
217
|
+
async logoutUser({}, req) {
|
|
218
|
+
await markLoginAsLoggedOut(req?.user?.licenseUid);
|
|
219
|
+
return true;
|
|
220
|
+
},
|
|
221
|
+
|
|
195
222
|
authMiddleware,
|
|
196
223
|
};
|
|
@@ -16,7 +16,7 @@ const connections = require('../controllers/connections');
|
|
|
16
16
|
const { getAuthProviderFromReq } = require('../auth/authProvider');
|
|
17
17
|
const { checkLicense, checkLicenseKey } = require('../utility/checkLicense');
|
|
18
18
|
const storage = require('./storage');
|
|
19
|
-
const { getAuthProxyUrl } = require('../utility/authProxy');
|
|
19
|
+
const { getAuthProxyUrl, tryToGetRefreshedLicense } = require('../utility/authProxy');
|
|
20
20
|
const { getPublicHardwareFingerprint } = require('../utility/hardwareFingerprint');
|
|
21
21
|
const { extractErrorMessage } = require('dbgate-tools');
|
|
22
22
|
const {
|
|
@@ -109,6 +109,7 @@ module.exports = {
|
|
|
109
109
|
),
|
|
110
110
|
isAdminPasswordMissing,
|
|
111
111
|
isInvalidToken: req?.isInvalidToken,
|
|
112
|
+
skipAllAuth: !!process.env.SKIP_ALL_AUTH,
|
|
112
113
|
adminPasswordState: adminConfig?.adminPasswordState,
|
|
113
114
|
storageDatabase: process.env.STORAGE_DATABASE,
|
|
114
115
|
logsFilePath: getLogsFilePath(),
|
|
@@ -191,6 +192,7 @@ module.exports = {
|
|
|
191
192
|
return {
|
|
192
193
|
...this.fillMissingSettings(JSON.parse(settingsText)),
|
|
193
194
|
'other.licenseKey': platformInfo.isElectron ? await this.loadLicenseKey() : undefined,
|
|
195
|
+
// 'other.licenseKey': await this.loadLicenseKey(),
|
|
194
196
|
};
|
|
195
197
|
}
|
|
196
198
|
} catch (err) {
|
|
@@ -208,21 +210,34 @@ module.exports = {
|
|
|
208
210
|
},
|
|
209
211
|
|
|
210
212
|
saveLicenseKey_meta: true,
|
|
211
|
-
async saveLicenseKey({ licenseKey }) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
213
|
+
async saveLicenseKey({ licenseKey, forceSave = false, tryToRenew = false }) {
|
|
214
|
+
if (!forceSave) {
|
|
215
|
+
const decoded = jwt.decode(licenseKey?.trim());
|
|
216
|
+
if (!decoded) {
|
|
217
|
+
return {
|
|
218
|
+
status: 'error',
|
|
219
|
+
errorMessage: 'Invalid license key',
|
|
220
|
+
};
|
|
221
|
+
}
|
|
219
222
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
const { exp } = decoded;
|
|
224
|
+
if (exp * 1000 < Date.now()) {
|
|
225
|
+
let renewed = false;
|
|
226
|
+
if (tryToRenew) {
|
|
227
|
+
const newLicenseKey = await tryToGetRefreshedLicense(licenseKey);
|
|
228
|
+
if (newLicenseKey.status == 'ok') {
|
|
229
|
+
licenseKey = newLicenseKey.token;
|
|
230
|
+
renewed = true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!renewed) {
|
|
235
|
+
return {
|
|
236
|
+
status: 'error',
|
|
237
|
+
errorMessage: 'License key is expired',
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
226
241
|
}
|
|
227
242
|
|
|
228
243
|
try {
|
|
@@ -297,7 +312,7 @@ module.exports = {
|
|
|
297
312
|
// this.settingsValue = updated;
|
|
298
313
|
|
|
299
314
|
if (currentValue['other.licenseKey'] != values['other.licenseKey']) {
|
|
300
|
-
await this.saveLicenseKey({ licenseKey: values['other.licenseKey'] });
|
|
315
|
+
await this.saveLicenseKey({ licenseKey: values['other.licenseKey'], forceSave: true });
|
|
301
316
|
socket.emitChanged(`config-changed`);
|
|
302
317
|
}
|
|
303
318
|
}
|
|
@@ -327,6 +342,16 @@ module.exports = {
|
|
|
327
342
|
return resp;
|
|
328
343
|
},
|
|
329
344
|
|
|
345
|
+
getNewLicense_meta: true,
|
|
346
|
+
async getNewLicense({ oldLicenseKey }) {
|
|
347
|
+
const newLicenseKey = await tryToGetRefreshedLicense(oldLicenseKey);
|
|
348
|
+
const res = await checkLicenseKey(newLicenseKey.token);
|
|
349
|
+
if (res.status == 'ok') {
|
|
350
|
+
res.licenseKey = newLicenseKey.token;
|
|
351
|
+
}
|
|
352
|
+
return res;
|
|
353
|
+
},
|
|
354
|
+
|
|
330
355
|
recryptDatabaseForExport(db) {
|
|
331
356
|
const encryptionKey = generateTransportEncryptionKey();
|
|
332
357
|
const transportEncryptor = createTransportEncryptor(encryptionKey);
|
package/src/currentVersion.js
CHANGED
package/src/storageModel.js
CHANGED
|
@@ -519,6 +519,12 @@ module.exports = {
|
|
|
519
519
|
"dataType": "int",
|
|
520
520
|
"notNull": false
|
|
521
521
|
},
|
|
522
|
+
{
|
|
523
|
+
"pureName": "connections",
|
|
524
|
+
"columnName": "useSeparateSchemas",
|
|
525
|
+
"dataType": "int",
|
|
526
|
+
"notNull": false
|
|
527
|
+
},
|
|
522
528
|
{
|
|
523
529
|
"pureName": "connections",
|
|
524
530
|
"columnName": "defaultDatabase",
|
|
@@ -682,6 +688,49 @@ module.exports = {
|
|
|
682
688
|
]
|
|
683
689
|
}
|
|
684
690
|
},
|
|
691
|
+
{
|
|
692
|
+
"pureName": "roles",
|
|
693
|
+
"columns": [
|
|
694
|
+
{
|
|
695
|
+
"pureName": "roles",
|
|
696
|
+
"columnName": "id",
|
|
697
|
+
"dataType": "int",
|
|
698
|
+
"autoIncrement": true,
|
|
699
|
+
"notNull": true
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"pureName": "roles",
|
|
703
|
+
"columnName": "name",
|
|
704
|
+
"dataType": "varchar(250)",
|
|
705
|
+
"notNull": false
|
|
706
|
+
}
|
|
707
|
+
],
|
|
708
|
+
"foreignKeys": [],
|
|
709
|
+
"primaryKey": {
|
|
710
|
+
"pureName": "roles",
|
|
711
|
+
"constraintType": "primaryKey",
|
|
712
|
+
"constraintName": "PK_roles",
|
|
713
|
+
"columns": [
|
|
714
|
+
{
|
|
715
|
+
"columnName": "id"
|
|
716
|
+
}
|
|
717
|
+
]
|
|
718
|
+
},
|
|
719
|
+
"preloadedRows": [
|
|
720
|
+
{
|
|
721
|
+
"id": -1,
|
|
722
|
+
"name": "anonymous-user"
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"id": -2,
|
|
726
|
+
"name": "logged-user"
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
"id": -3,
|
|
730
|
+
"name": "superadmin"
|
|
731
|
+
}
|
|
732
|
+
]
|
|
733
|
+
},
|
|
685
734
|
{
|
|
686
735
|
"pureName": "role_connections",
|
|
687
736
|
"columns": [
|
|
@@ -794,47 +843,45 @@ module.exports = {
|
|
|
794
843
|
}
|
|
795
844
|
},
|
|
796
845
|
{
|
|
797
|
-
"pureName": "
|
|
846
|
+
"pureName": "users",
|
|
798
847
|
"columns": [
|
|
799
848
|
{
|
|
800
|
-
"pureName": "
|
|
849
|
+
"pureName": "users",
|
|
801
850
|
"columnName": "id",
|
|
802
851
|
"dataType": "int",
|
|
803
852
|
"autoIncrement": true,
|
|
804
853
|
"notNull": true
|
|
805
854
|
},
|
|
806
855
|
{
|
|
807
|
-
"pureName": "
|
|
808
|
-
"columnName": "
|
|
856
|
+
"pureName": "users",
|
|
857
|
+
"columnName": "login",
|
|
858
|
+
"dataType": "varchar(250)",
|
|
859
|
+
"notNull": false
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"pureName": "users",
|
|
863
|
+
"columnName": "password",
|
|
864
|
+
"dataType": "varchar(250)",
|
|
865
|
+
"notNull": false
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
"pureName": "users",
|
|
869
|
+
"columnName": "email",
|
|
809
870
|
"dataType": "varchar(250)",
|
|
810
871
|
"notNull": false
|
|
811
872
|
}
|
|
812
873
|
],
|
|
813
874
|
"foreignKeys": [],
|
|
814
875
|
"primaryKey": {
|
|
815
|
-
"pureName": "
|
|
876
|
+
"pureName": "users",
|
|
816
877
|
"constraintType": "primaryKey",
|
|
817
|
-
"constraintName": "
|
|
878
|
+
"constraintName": "PK_users",
|
|
818
879
|
"columns": [
|
|
819
880
|
{
|
|
820
881
|
"columnName": "id"
|
|
821
882
|
}
|
|
822
883
|
]
|
|
823
|
-
}
|
|
824
|
-
"preloadedRows": [
|
|
825
|
-
{
|
|
826
|
-
"id": -1,
|
|
827
|
-
"name": "anonymous-user"
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
"id": -2,
|
|
831
|
-
"name": "logged-user"
|
|
832
|
-
},
|
|
833
|
-
{
|
|
834
|
-
"id": -3,
|
|
835
|
-
"name": "superadmin"
|
|
836
|
-
}
|
|
837
|
-
]
|
|
884
|
+
}
|
|
838
885
|
},
|
|
839
886
|
{
|
|
840
887
|
"pureName": "user_connections",
|
|
@@ -1008,47 +1055,6 @@ module.exports = {
|
|
|
1008
1055
|
}
|
|
1009
1056
|
]
|
|
1010
1057
|
}
|
|
1011
|
-
},
|
|
1012
|
-
{
|
|
1013
|
-
"pureName": "users",
|
|
1014
|
-
"columns": [
|
|
1015
|
-
{
|
|
1016
|
-
"pureName": "users",
|
|
1017
|
-
"columnName": "id",
|
|
1018
|
-
"dataType": "int",
|
|
1019
|
-
"autoIncrement": true,
|
|
1020
|
-
"notNull": true
|
|
1021
|
-
},
|
|
1022
|
-
{
|
|
1023
|
-
"pureName": "users",
|
|
1024
|
-
"columnName": "login",
|
|
1025
|
-
"dataType": "varchar(250)",
|
|
1026
|
-
"notNull": false
|
|
1027
|
-
},
|
|
1028
|
-
{
|
|
1029
|
-
"pureName": "users",
|
|
1030
|
-
"columnName": "password",
|
|
1031
|
-
"dataType": "varchar(250)",
|
|
1032
|
-
"notNull": false
|
|
1033
|
-
},
|
|
1034
|
-
{
|
|
1035
|
-
"pureName": "users",
|
|
1036
|
-
"columnName": "email",
|
|
1037
|
-
"dataType": "varchar(250)",
|
|
1038
|
-
"notNull": false
|
|
1039
|
-
}
|
|
1040
|
-
],
|
|
1041
|
-
"foreignKeys": [],
|
|
1042
|
-
"primaryKey": {
|
|
1043
|
-
"pureName": "users",
|
|
1044
|
-
"constraintType": "primaryKey",
|
|
1045
|
-
"constraintName": "PK_users",
|
|
1046
|
-
"columns": [
|
|
1047
|
-
{
|
|
1048
|
-
"columnName": "id"
|
|
1049
|
-
}
|
|
1050
|
-
]
|
|
1051
|
-
}
|
|
1052
1058
|
}
|
|
1053
1059
|
],
|
|
1054
1060
|
"collections": [],
|
package/src/utility/authProxy.js
CHANGED
|
@@ -40,6 +40,12 @@ function getLicenseHttpHeaders() {
|
|
|
40
40
|
return {};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
async function tryToGetRefreshedLicense(oldLicenseKey) {
|
|
44
|
+
return {
|
|
45
|
+
status: 'error',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
43
49
|
module.exports = {
|
|
44
50
|
isAuthProxySupported,
|
|
45
51
|
authProxyGetRedirectUrl,
|
|
@@ -52,4 +58,5 @@ module.exports = {
|
|
|
52
58
|
callCompleteOnCursorApi,
|
|
53
59
|
callRefactorSqlQueryApi,
|
|
54
60
|
getLicenseHttpHeaders,
|
|
61
|
+
tryToGetRefreshedLicense,
|
|
55
62
|
};
|
package/src/utility/cloudIntf.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
|
+
const crypto = require('crypto');
|
|
2
3
|
const fs = require('fs-extra');
|
|
3
4
|
const _ = require('lodash');
|
|
4
5
|
const path = require('path');
|
|
@@ -216,7 +217,7 @@ async function updateCloudFiles(isRefresh) {
|
|
|
216
217
|
{
|
|
217
218
|
headers: {
|
|
218
219
|
...getLicenseHttpHeaders(),
|
|
219
|
-
...(await
|
|
220
|
+
...(await getCloudInstanceHeaders()),
|
|
220
221
|
'x-app-version': currentVersion.version,
|
|
221
222
|
},
|
|
222
223
|
}
|
|
@@ -300,6 +301,17 @@ async function callCloudApiGet(endpoint, signinHolder = null, additionalHeaders
|
|
|
300
301
|
return resp.data;
|
|
301
302
|
}
|
|
302
303
|
|
|
304
|
+
async function getCloudInstanceHeaders() {
|
|
305
|
+
if (!(await fs.exists(path.join(datadir(), 'cloud-instance.txt')))) {
|
|
306
|
+
const newInstanceId = crypto.randomUUID();
|
|
307
|
+
await fs.writeFile(path.join(datadir(), 'cloud-instance.txt'), newInstanceId);
|
|
308
|
+
}
|
|
309
|
+
const instanceId = await fs.readFile(path.join(datadir(), 'cloud-instance.txt'), 'utf-8');
|
|
310
|
+
return {
|
|
311
|
+
'x-cloud-instance': instanceId,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
303
315
|
async function callCloudApiPost(endpoint, body, signinHolder = null) {
|
|
304
316
|
if (!signinHolder) {
|
|
305
317
|
signinHolder = await getCloudSigninHolder();
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
// only in DbGate Premium
|
|
2
2
|
|
|
3
|
-
function markUserAsActive(licenseUid) {}
|
|
3
|
+
function markUserAsActive(licenseUid, token) {}
|
|
4
4
|
|
|
5
5
|
async function isLoginLicensed(req, licenseUid) {
|
|
6
6
|
return true;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
function markLoginAsLoggedOut(licenseUid) {}
|
|
10
|
+
|
|
9
11
|
const LOGIN_LIMIT_ERROR = '';
|
|
10
12
|
|
|
11
13
|
module.exports = {
|
|
12
14
|
markUserAsActive,
|
|
13
15
|
isLoginLicensed,
|
|
16
|
+
markLoginAsLoggedOut,
|
|
14
17
|
LOGIN_LIMIT_ERROR,
|
|
15
18
|
};
|