dbgate-api-premium 5.5.7-alpha.60 → 5.5.7-alpha.68
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/config.js +3 -1
- package/src/controllers/connections.js +24 -0
- package/src/controllers/runners.js +1 -1
- package/src/controllers/serverConnections.js +1 -1
- package/src/controllers/storage.js +34 -1
- package/src/controllers/storageDb.js +1 -0
- package/src/currentVersion.js +2 -2
- package/src/utility/JsonLinesDatabase.js +9 -0
- package/src/utility/authProxy.js +39 -3
- package/src/utility/checkLicense.js +54 -6
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api-premium",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "5.5.7-alpha.
|
|
4
|
+
"version": "5.5.7-alpha.68",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"compare-versions": "^3.6.0",
|
|
30
30
|
"cors": "^2.8.5",
|
|
31
31
|
"cross-env": "^6.0.3",
|
|
32
|
-
"dbgate-datalib": "^5.5.7-alpha.
|
|
32
|
+
"dbgate-datalib": "^5.5.7-alpha.68",
|
|
33
33
|
"dbgate-query-splitter": "^4.11.2",
|
|
34
|
-
"dbgate-sqltree": "^5.5.7-alpha.
|
|
35
|
-
"dbgate-tools": "^5.5.7-alpha.
|
|
34
|
+
"dbgate-sqltree": "^5.5.7-alpha.68",
|
|
35
|
+
"dbgate-tools": "^5.5.7-alpha.68",
|
|
36
36
|
"debug": "^4.3.4",
|
|
37
37
|
"diff": "^5.0.0",
|
|
38
38
|
"diff2html": "^3.4.13",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@types/fs-extra": "^9.0.11",
|
|
83
83
|
"@types/lodash": "^4.14.149",
|
|
84
|
-
"dbgate-types": "^5.5.7-alpha.
|
|
84
|
+
"dbgate-types": "^5.5.7-alpha.68",
|
|
85
85
|
"env-cmd": "^10.1.0",
|
|
86
86
|
"jsdoc-to-markdown": "^9.0.5",
|
|
87
87
|
"node-loader": "^1.0.2",
|
|
@@ -62,6 +62,8 @@ module.exports = {
|
|
|
62
62
|
const logoutUrl = storageConnectionError ? null : await authProvider.getLogoutUrl();
|
|
63
63
|
const adminConfig = storageConnectionError ? null : await storage.readConfig({ group: 'admin' });
|
|
64
64
|
|
|
65
|
+
storage.startRefreshLicense();
|
|
66
|
+
|
|
65
67
|
const isAdminPasswordMissing = !!(
|
|
66
68
|
process.env.STORAGE_DATABASE &&
|
|
67
69
|
!process.env.ADMIN_PASSWORD &&
|
|
@@ -81,7 +83,7 @@ module.exports = {
|
|
|
81
83
|
isElectron: platformInfo.isElectron,
|
|
82
84
|
isLicenseValid,
|
|
83
85
|
isLicenseExpired: checkedLicense?.isExpired,
|
|
84
|
-
trialDaysLeft: checkedLicense?.
|
|
86
|
+
trialDaysLeft: checkedLicense?.licenseTypeObj?.isTrial && !checkedLicense?.isExpired ? checkedLicense?.daysLeft : null,
|
|
85
87
|
checkedLicense,
|
|
86
88
|
configurationError,
|
|
87
89
|
logoutUrl,
|
|
@@ -201,6 +201,7 @@ module.exports = {
|
|
|
201
201
|
// @ts-ignore
|
|
202
202
|
this.datastore = new JsonLinesDatabase(path.join(dir, 'connections.jsonl'));
|
|
203
203
|
}
|
|
204
|
+
await this.checkUnsavedConnectionsLimit();
|
|
204
205
|
},
|
|
205
206
|
|
|
206
207
|
list_meta: true,
|
|
@@ -300,6 +301,29 @@ module.exports = {
|
|
|
300
301
|
return res;
|
|
301
302
|
},
|
|
302
303
|
|
|
304
|
+
async checkUnsavedConnectionsLimit() {
|
|
305
|
+
const MAX_UNSAVED_CONNECTIONS = 5;
|
|
306
|
+
await this.datastore.transformAll(connections => {
|
|
307
|
+
const count = connections.filter(x => x.unsaved).length;
|
|
308
|
+
if (count > MAX_UNSAVED_CONNECTIONS) {
|
|
309
|
+
const res = [];
|
|
310
|
+
let unsavedToSkip = count - MAX_UNSAVED_CONNECTIONS;
|
|
311
|
+
for (const item of connections) {
|
|
312
|
+
if (item.unsaved) {
|
|
313
|
+
if (unsavedToSkip > 0) {
|
|
314
|
+
unsavedToSkip--;
|
|
315
|
+
} else {
|
|
316
|
+
res.push(item);
|
|
317
|
+
}
|
|
318
|
+
} else {
|
|
319
|
+
res.push(item);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return res;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
|
|
303
327
|
update_meta: true,
|
|
304
328
|
async update({ _id, values }, req) {
|
|
305
329
|
if (portalConnections) return;
|
|
@@ -111,7 +111,7 @@ module.exports = {
|
|
|
111
111
|
const scriptFile = path.join(uploadsdir(), runid + '.js');
|
|
112
112
|
fs.writeFileSync(`${scriptFile}`, scriptText);
|
|
113
113
|
fs.mkdirSync(directory);
|
|
114
|
-
const pluginNames =
|
|
114
|
+
const pluginNames = extractPlugins(scriptText);
|
|
115
115
|
logger.info({ scriptFile }, 'Running script');
|
|
116
116
|
// const subprocess = fork(scriptFile, ['--checkParent', '--max-old-space-size=8192'], {
|
|
117
117
|
const subprocess = fork(
|
|
@@ -52,7 +52,7 @@ module.exports = {
|
|
|
52
52
|
if (existing) return existing;
|
|
53
53
|
const connection = await connections.getCore({ conid });
|
|
54
54
|
if (!connection) {
|
|
55
|
-
throw new Error(`Connection with conid="${conid}" not
|
|
55
|
+
throw new Error(`Connection with conid="${conid}" not found`);
|
|
56
56
|
}
|
|
57
57
|
if (connection.passwordMode == 'askPassword' || connection.passwordMode == 'askUser') {
|
|
58
58
|
throw new MissingCredentialsError({ conid, passwordMode: connection.passwordMode });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const _ = require('lodash');
|
|
3
|
+
const path = require('path');
|
|
3
4
|
const { setAuthProviders, getAuthProviderById } = require('../auth/authProvider');
|
|
4
5
|
const { createStorageAuthProvider } = require('../auth/storageAuthProvider');
|
|
5
6
|
const {
|
|
@@ -16,8 +17,12 @@ const { hasPermission } = require('../utility/hasPermission');
|
|
|
16
17
|
const { changeSetToSql, removeSchemaFromChangeSet } = require('dbgate-datalib');
|
|
17
18
|
const storageModel = require('../storageModel');
|
|
18
19
|
const { dumpSqlCommand } = require('dbgate-sqltree');
|
|
19
|
-
const { runCommandOnDriver } = require('dbgate-tools');
|
|
20
|
+
const { runCommandOnDriver, getLogger } = require('dbgate-tools');
|
|
20
21
|
const socket = require('../utility/socket');
|
|
22
|
+
const { obtainRefreshedLicense } = require('../utility/authProxy');
|
|
23
|
+
const { datadir } = require('../utility/directories');
|
|
24
|
+
|
|
25
|
+
const logger = getLogger('storage');
|
|
21
26
|
|
|
22
27
|
function mapConnection(connnection) {
|
|
23
28
|
return {
|
|
@@ -32,6 +37,8 @@ async function runQueryFmt(driver, conn, query, ...args) {
|
|
|
32
37
|
await driver.query(conn, dmp.s);
|
|
33
38
|
}
|
|
34
39
|
|
|
40
|
+
let refreshLicenseStarted = false;
|
|
41
|
+
|
|
35
42
|
module.exports = {
|
|
36
43
|
async _init() {
|
|
37
44
|
if (!process.env.STORAGE_DATABASE) {
|
|
@@ -48,6 +55,32 @@ module.exports = {
|
|
|
48
55
|
setAuthProviders(providers, providers[defIndex]);
|
|
49
56
|
},
|
|
50
57
|
|
|
58
|
+
async startRefreshLicense() {
|
|
59
|
+
if (refreshLicenseStarted) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
refreshLicenseStarted = true;
|
|
63
|
+
const resp = await obtainRefreshedLicense();
|
|
64
|
+
if (!resp) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (resp.status == 'error') {
|
|
68
|
+
logger.error(`Error refreshing license: ${resp.message}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (resp.status != 'ok') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const { token } = resp;
|
|
75
|
+
logger.info('License succesfully refreshed');
|
|
76
|
+
if (process.env.STORAGE_DATABASE) {
|
|
77
|
+
await this.writeConfig({ group: 'license', config: { licenseKey: token } });
|
|
78
|
+
} else {
|
|
79
|
+
await fs.writeFile(path.join(datadir(), 'license.key'), token);
|
|
80
|
+
}
|
|
81
|
+
socket.emitChanged(`config-changed`);
|
|
82
|
+
},
|
|
83
|
+
|
|
51
84
|
connections_meta: true,
|
|
52
85
|
async connections(req) {
|
|
53
86
|
if (!process.env.STORAGE_DATABASE) {
|
package/src/currentVersion.js
CHANGED
|
@@ -111,6 +111,15 @@ class JsonLinesDatabase {
|
|
|
111
111
|
return removed;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
async transformAll(transformFunction) {
|
|
115
|
+
await this._ensureLoaded();
|
|
116
|
+
const newData = transformFunction(this.data);
|
|
117
|
+
if (newData) {
|
|
118
|
+
this.data = newData;
|
|
119
|
+
await this._save();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
114
123
|
// async _openReader() {
|
|
115
124
|
// return new Promise((resolve, reject) =>
|
|
116
125
|
// lineReader.open(this.filename, (err, reader) => {
|
package/src/utility/authProxy.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const { Signer } = require('@aws-sdk/rds-signer');
|
|
3
|
+
const jwt = require('jsonwebtoken');
|
|
4
|
+
const { getLogger, extractErrorLogData } = require('dbgate-tools');
|
|
3
5
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
+
const logger = getLogger('authProxy');
|
|
7
|
+
|
|
8
|
+
const AUTH_PROXY_URL = process.env.DEVWEB ? 'https://auth-proxy.dbgate.udolni.net' : 'https://auth.dbgate.eu';
|
|
9
|
+
// const AUTH_PROXY_URL = 'https://auth-proxy.dbgate.udolni.net';
|
|
6
10
|
|
|
7
11
|
let licenseKey = null;
|
|
8
12
|
|
|
@@ -91,7 +95,7 @@ function startTokenChecking(sid, callback) {
|
|
|
91
95
|
callback(resp.data.token);
|
|
92
96
|
}
|
|
93
97
|
} catch (err) {
|
|
94
|
-
|
|
98
|
+
logger.error(extractErrorLogData(err), 'Error checking token');
|
|
95
99
|
}
|
|
96
100
|
}, 500);
|
|
97
101
|
}
|
|
@@ -121,6 +125,37 @@ async function getAwsIamToken(props) {
|
|
|
121
125
|
return token;
|
|
122
126
|
}
|
|
123
127
|
|
|
128
|
+
async function obtainRefreshedLicense() {
|
|
129
|
+
if (!licenseKey) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const decoded = jwt.decode(licenseKey);
|
|
134
|
+
|
|
135
|
+
if (Date.now() > decoded.end * 1000) {
|
|
136
|
+
logger.info('License expired, trying to obtain fresh license');
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const respToken = await axios.default.post(
|
|
140
|
+
`${AUTH_PROXY_URL}/refresh-license`,
|
|
141
|
+
{},
|
|
142
|
+
{
|
|
143
|
+
headers: {
|
|
144
|
+
'Content-Type': 'application/json',
|
|
145
|
+
Authorization: `Bearer ${licenseKey}`,
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
return respToken.data;
|
|
150
|
+
} catch (err) {
|
|
151
|
+
return {
|
|
152
|
+
status: 'error',
|
|
153
|
+
message: err.message,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
124
159
|
module.exports = {
|
|
125
160
|
isAuthProxySupported,
|
|
126
161
|
authProxyGetRedirectUrl,
|
|
@@ -130,4 +165,5 @@ module.exports = {
|
|
|
130
165
|
getAuthProxyUrl,
|
|
131
166
|
supportsAwsIam,
|
|
132
167
|
getAwsIamToken,
|
|
168
|
+
obtainRefreshedLicense,
|
|
133
169
|
};
|
|
@@ -23,6 +23,46 @@ mQIDAQAB
|
|
|
23
23
|
-----END PUBLIC KEY-----
|
|
24
24
|
`;
|
|
25
25
|
|
|
26
|
+
const licenseTypeById = {
|
|
27
|
+
'1414ede2-dfb3-4539-a93d-24db7e5b59d9': {
|
|
28
|
+
// premium generated by stripe
|
|
29
|
+
name: 'Premium',
|
|
30
|
+
isPremium: true,
|
|
31
|
+
isForWeb: false,
|
|
32
|
+
isForApp: true,
|
|
33
|
+
},
|
|
34
|
+
'9682a88b-909f-48b1-adbf-c03622884421': {
|
|
35
|
+
name: 'Team Premium',
|
|
36
|
+
isPremium: true,
|
|
37
|
+
isForWeb: true,
|
|
38
|
+
isForApp: true,
|
|
39
|
+
},
|
|
40
|
+
'81456363-f167-41e3-9496-b540f4b0c150': {
|
|
41
|
+
name: 'Premium Trial',
|
|
42
|
+
isPremium: true,
|
|
43
|
+
isForWeb: true,
|
|
44
|
+
isForApp: true,
|
|
45
|
+
isTrial: true,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function getLicenseByDecoded(decoded) {
|
|
50
|
+
if (!decoded) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (decoded.licenseId) {
|
|
54
|
+
return licenseTypeById[decoded.licenseId];
|
|
55
|
+
}
|
|
56
|
+
if (decoded.licenseType == 'premium') {
|
|
57
|
+
if (decoded.isGeneratedTrial) {
|
|
58
|
+
return licenseTypeById['81456363-f167-41e3-9496-b540f4b0c150'];
|
|
59
|
+
} else {
|
|
60
|
+
return licenseTypeById['9682a88b-909f-48b1-adbf-c03622884421'];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
26
66
|
let awsMetadataLoaded = false;
|
|
27
67
|
let awsMetadata = null;
|
|
28
68
|
async function getAwsMetadata() {
|
|
@@ -71,20 +111,27 @@ function checkLicenseKey(licenseKey) {
|
|
|
71
111
|
const decoded = jwt.verify(licenseKey, publicKey, {
|
|
72
112
|
algorithms: ['RS256'],
|
|
73
113
|
});
|
|
74
|
-
|
|
75
|
-
|
|
114
|
+
|
|
115
|
+
const licenseTypeObj = getLicenseByDecoded(decoded);
|
|
116
|
+
|
|
117
|
+
if (
|
|
118
|
+
!licenseTypeObj ||
|
|
119
|
+
(platformInfo.isElectron && !licenseTypeObj.isForApp) ||
|
|
120
|
+
(!platformInfo.isElectron && !licenseTypeObj.isForWeb)
|
|
121
|
+
) {
|
|
122
|
+
logger.error(`Incorrect license type, found ${decoded.licenseType}`);
|
|
76
123
|
return {
|
|
77
124
|
status: 'error',
|
|
78
|
-
error: `Incorrect license type,
|
|
125
|
+
error: `Incorrect license type, found ${decoded.licenseType}`,
|
|
79
126
|
};
|
|
80
127
|
}
|
|
128
|
+
|
|
81
129
|
return {
|
|
82
130
|
status: 'ok',
|
|
83
|
-
type: 'premium',
|
|
84
131
|
validTo: decoded.validTo,
|
|
85
132
|
expiration: new Date(decoded.exp * 1000).toISOString(),
|
|
86
133
|
daysLeft: Math.round((decoded.exp * 1000 - Date.now()) / (24 * 60 * 60 * 1000)),
|
|
87
|
-
|
|
134
|
+
licenseTypeObj,
|
|
88
135
|
};
|
|
89
136
|
} catch (err) {
|
|
90
137
|
try {
|
|
@@ -187,5 +234,6 @@ function isProApp() {
|
|
|
187
234
|
module.exports = {
|
|
188
235
|
checkLicense,
|
|
189
236
|
checkLicenseKey,
|
|
190
|
-
isProApp
|
|
237
|
+
isProApp,
|
|
238
|
+
licenseTypeById,
|
|
191
239
|
};
|