mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
Merge branch 'license-refactor'
This commit is contained in:
commit
ddf385caac
@ -7,6 +7,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-log": "^4.4.1",
|
"electron-log": "^4.4.1",
|
||||||
"electron-updater": "^4.6.1",
|
"electron-updater": "^4.6.1",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lodash.clonedeepwith": "^4.5.0",
|
"lodash.clonedeepwith": "^4.5.0",
|
||||||
"patch-package": "^6.4.7"
|
"patch-package": "^6.4.7"
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@ const BrowserWindow = electron.BrowserWindow;
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const mainMenuDefinition = require('./mainMenuDefinition');
|
const mainMenuDefinition = require('./mainMenuDefinition');
|
||||||
const { settings } = require('cluster');
|
const { isProApp, checkLicense } = require('./proTools');
|
||||||
let disableAutoUpgrade = false;
|
let disableAutoUpgrade = false;
|
||||||
|
|
||||||
// require('@electron/remote/main').initialize();
|
// require('@electron/remote/main').initialize();
|
||||||
@ -299,9 +299,11 @@ function ensureBoundsVisible(bounds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
|
const datadir = path.join(os.homedir(), '.dbgate');
|
||||||
|
|
||||||
let settingsJson = {};
|
let settingsJson = {};
|
||||||
|
let licenseKey = null;
|
||||||
try {
|
try {
|
||||||
const datadir = path.join(os.homedir(), '.dbgate');
|
|
||||||
settingsJson = fillMissingSettings(
|
settingsJson = fillMissingSettings(
|
||||||
JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' }))
|
JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' }))
|
||||||
);
|
);
|
||||||
@ -309,12 +311,22 @@ function createWindow() {
|
|||||||
console.log('Error loading settings.json:', err.message);
|
console.log('Error loading settings.json:', err.message);
|
||||||
settingsJson = fillMissingSettings({});
|
settingsJson = fillMissingSettings({});
|
||||||
}
|
}
|
||||||
|
if (isProApp()) {
|
||||||
|
try {
|
||||||
|
licenseKey = fs.readFileSync(path.join(datadir, 'license.key'), { encoding: 'utf-8' });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Error loading license.key:', err.message);
|
||||||
|
licenseKey = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const licenseOk = !isProApp() || checkLicense(licenseKey) == 'premium';
|
||||||
|
|
||||||
let bounds = initialConfig['winBounds'];
|
let bounds = initialConfig['winBounds'];
|
||||||
if (bounds) {
|
if (bounds) {
|
||||||
bounds = ensureBoundsVisible(bounds);
|
bounds = ensureBoundsVisible(bounds);
|
||||||
}
|
}
|
||||||
useNativeMenu = settingsJson['app.useNativeMenu'];
|
useNativeMenu = settingsJson['app.useNativeMenu'] || !licenseOk;
|
||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1200,
|
width: 1200,
|
||||||
|
12
app/src/proTools.js
Normal file
12
app/src/proTools.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function isProApp() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkLicense(license) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
isProApp,
|
||||||
|
checkLicense,
|
||||||
|
};
|
@ -476,6 +476,11 @@ buffer-crc32@~0.2.3:
|
|||||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||||
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
|
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
|
||||||
|
|
||||||
|
buffer-equal-constant-time@1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||||
|
integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
|
||||||
|
|
||||||
buffer-equal@1.0.0:
|
buffer-equal@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
|
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
|
||||||
@ -927,6 +932,13 @@ duplexer3@^0.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
|
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
|
||||||
integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
|
integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
|
||||||
|
|
||||||
|
ecdsa-sig-formatter@1.0.11:
|
||||||
|
version "1.0.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
|
||||||
|
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
ejs@^3.1.7:
|
ejs@^3.1.7:
|
||||||
version "3.1.10"
|
version "3.1.10"
|
||||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
|
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
|
||||||
@ -1663,6 +1675,39 @@ jsonfile@^6.0.1:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
|
jsonwebtoken@^9.0.2:
|
||||||
|
version "9.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3"
|
||||||
|
integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==
|
||||||
|
dependencies:
|
||||||
|
jws "^3.2.2"
|
||||||
|
lodash.includes "^4.3.0"
|
||||||
|
lodash.isboolean "^3.0.3"
|
||||||
|
lodash.isinteger "^4.0.4"
|
||||||
|
lodash.isnumber "^3.0.3"
|
||||||
|
lodash.isplainobject "^4.0.6"
|
||||||
|
lodash.isstring "^4.0.1"
|
||||||
|
lodash.once "^4.0.0"
|
||||||
|
ms "^2.1.1"
|
||||||
|
semver "^7.5.4"
|
||||||
|
|
||||||
|
jwa@^1.4.1:
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
||||||
|
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
||||||
|
dependencies:
|
||||||
|
buffer-equal-constant-time "1.0.1"
|
||||||
|
ecdsa-sig-formatter "1.0.11"
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
jws@^3.2.2:
|
||||||
|
version "3.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
|
||||||
|
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
|
||||||
|
dependencies:
|
||||||
|
jwa "^1.4.1"
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
keyv@^3.0.0:
|
keyv@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
|
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
|
||||||
@ -1718,11 +1763,46 @@ lodash.escaperegexp@^4.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
|
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
|
||||||
integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==
|
integrity sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==
|
||||||
|
|
||||||
|
lodash.includes@^4.3.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||||
|
integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==
|
||||||
|
|
||||||
|
lodash.isboolean@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
|
||||||
|
integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==
|
||||||
|
|
||||||
lodash.isequal@^4.5.0:
|
lodash.isequal@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||||
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
|
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
|
||||||
|
|
||||||
|
lodash.isinteger@^4.0.4:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
|
||||||
|
integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==
|
||||||
|
|
||||||
|
lodash.isnumber@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
|
||||||
|
integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==
|
||||||
|
|
||||||
|
lodash.isplainobject@^4.0.6:
|
||||||
|
version "4.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||||
|
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
|
||||||
|
|
||||||
|
lodash.isstring@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
|
||||||
|
integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==
|
||||||
|
|
||||||
|
lodash.once@^4.0.0:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
|
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
|
||||||
|
|
||||||
lodash@^4.17.15:
|
lodash@^4.17.15:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
@ -1860,6 +1940,11 @@ ms@2.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
|
ms@^2.1.1:
|
||||||
|
version "2.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
msnodesqlv8@^4.2.1:
|
msnodesqlv8@^4.2.1:
|
||||||
version "4.2.1"
|
version "4.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/msnodesqlv8/-/msnodesqlv8-4.2.1.tgz#59f2930e7f3b9b201d7288425a6ffa923ea1a573"
|
resolved "https://registry.yarnpkg.com/msnodesqlv8/-/msnodesqlv8-4.2.1.tgz#59f2930e7f3b9b201d7288425a6ffa923ea1a573"
|
||||||
@ -2322,6 +2407,11 @@ semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
|
|||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2"
|
||||||
integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==
|
integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==
|
||||||
|
|
||||||
|
semver@^7.5.4:
|
||||||
|
version "7.6.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
|
||||||
|
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
|
||||||
|
|
||||||
serialize-error@^7.0.1:
|
serialize-error@^7.0.1:
|
||||||
version "7.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
|
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
|
||||||
|
@ -30,6 +30,7 @@ function authMiddleware(req, res, next) {
|
|||||||
'/config/get',
|
'/config/get',
|
||||||
'/config/logout',
|
'/config/logout',
|
||||||
'/config/get-settings',
|
'/config/get-settings',
|
||||||
|
'/config/save-license-key',
|
||||||
'/auth/oauth-token',
|
'/auth/oauth-token',
|
||||||
'/auth/login',
|
'/auth/login',
|
||||||
'/auth/redirect',
|
'/auth/redirect',
|
||||||
|
@ -12,6 +12,8 @@ const currentVersion = require('../currentVersion');
|
|||||||
const platformInfo = require('../utility/platformInfo');
|
const platformInfo = require('../utility/platformInfo');
|
||||||
const connections = require('../controllers/connections');
|
const connections = require('../controllers/connections');
|
||||||
const { getAuthProviderFromReq } = require('../auth/authProvider');
|
const { getAuthProviderFromReq } = require('../auth/authProvider');
|
||||||
|
const { checkLicense, checkLicenseKey } = require('../utility/checkLicense');
|
||||||
|
const { storageWriteConfig } = require('./storageDb');
|
||||||
|
|
||||||
const lock = new AsyncLock();
|
const lock = new AsyncLock();
|
||||||
|
|
||||||
@ -45,6 +47,9 @@ module.exports = {
|
|||||||
'Basic authentization is not allowed, when using storage. Cannot use both STORAGE_DATABASE and BASIC_AUTH';
|
'Basic authentization is not allowed, when using storage. Cannot use both STORAGE_DATABASE and BASIC_AUTH';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkedLicense = await checkLicense();
|
||||||
|
const isLicenseValid = checkedLicense?.status == 'ok';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
runAsPortal: !!connections.portalConnections,
|
runAsPortal: !!connections.portalConnections,
|
||||||
singleDbConnection: connections.singleDbConnection,
|
singleDbConnection: connections.singleDbConnection,
|
||||||
@ -55,8 +60,8 @@ module.exports = {
|
|||||||
allowShellScripting: platformInfo.allowShellScripting,
|
allowShellScripting: platformInfo.allowShellScripting,
|
||||||
isDocker: platformInfo.isDocker,
|
isDocker: platformInfo.isDocker,
|
||||||
isElectron: platformInfo.isElectron,
|
isElectron: platformInfo.isElectron,
|
||||||
isLicenseValid: platformInfo.isLicenseValid,
|
isLicenseValid,
|
||||||
checkedLicense: platformInfo.checkedLicense,
|
checkedLicense,
|
||||||
configurationError,
|
configurationError,
|
||||||
logoutUrl: await authProvider.getLogoutUrl(),
|
logoutUrl: await authProvider.getLogoutUrl(),
|
||||||
permissions,
|
permissions,
|
||||||
@ -119,12 +124,38 @@ module.exports = {
|
|||||||
async loadSettings() {
|
async loadSettings() {
|
||||||
try {
|
try {
|
||||||
const settingsText = await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' });
|
const settingsText = await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' });
|
||||||
return this.fillMissingSettings(JSON.parse(settingsText));
|
return {
|
||||||
|
...this.fillMissingSettings(JSON.parse(settingsText)),
|
||||||
|
'other.licenseKey': platformInfo.isElectron ? await this.loadLicenseKey() : undefined,
|
||||||
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return this.fillMissingSettings({});
|
return this.fillMissingSettings({});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async loadLicenseKey() {
|
||||||
|
try {
|
||||||
|
const licenseKey = await fs.readFile(path.join(datadir(), 'license.key'), { encoding: 'utf-8' });
|
||||||
|
return licenseKey;
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
saveLicenseKey_meta: true,
|
||||||
|
async saveLicenseKey({ licenseKey }) {
|
||||||
|
try {
|
||||||
|
if (process.env.STORAGE_DATABASE) {
|
||||||
|
await storageWriteConfig('license', { licenseKey });
|
||||||
|
} else {
|
||||||
|
await fs.writeFile(path.join(datadir(), 'license.key'), licenseKey);
|
||||||
|
}
|
||||||
|
socket.emitChanged(`config-changed`);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
updateSettings_meta: true,
|
updateSettings_meta: true,
|
||||||
async updateSettings(values, req) {
|
async updateSettings(values, req) {
|
||||||
if (!hasPermission(`settings/change`, req)) return false;
|
if (!hasPermission(`settings/change`, req)) return false;
|
||||||
@ -134,10 +165,16 @@ module.exports = {
|
|||||||
try {
|
try {
|
||||||
const updated = {
|
const updated = {
|
||||||
...currentValue,
|
...currentValue,
|
||||||
...values,
|
..._.omit(values, ['other.licenseKey']),
|
||||||
};
|
};
|
||||||
await fs.writeFile(path.join(datadir(), 'settings.json'), JSON.stringify(updated, undefined, 2));
|
await fs.writeFile(path.join(datadir(), 'settings.json'), JSON.stringify(updated, undefined, 2));
|
||||||
// this.settingsValue = updated;
|
// this.settingsValue = updated;
|
||||||
|
|
||||||
|
if (currentValue['other.licenseKey'] != values['other.licenseKey']) {
|
||||||
|
await this.saveLicenseKey({ licenseKey: values['other.licenseKey'] });
|
||||||
|
socket.emitChanged(`config-changed`);
|
||||||
|
}
|
||||||
|
|
||||||
socket.emitChanged(`settings-changed`);
|
socket.emitChanged(`settings-changed`);
|
||||||
return updated;
|
return updated;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -152,4 +189,10 @@ module.exports = {
|
|||||||
const resp = await axios.default.get('https://raw.githubusercontent.com/dbgate/dbgate/master/CHANGELOG.md');
|
const resp = await axios.default.get('https://raw.githubusercontent.com/dbgate/dbgate/master/CHANGELOG.md');
|
||||||
return resp.data;
|
return resp.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkLicense_meta: true,
|
||||||
|
async checkLicense({ licenseKey }) {
|
||||||
|
const resp = await checkLicenseKey(licenseKey);
|
||||||
|
return resp;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
function checkLicense() {
|
function checkLicenseWeb() {
|
||||||
|
return {
|
||||||
|
status: 'ok',
|
||||||
|
type: 'community',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkLicenseApp() {
|
||||||
return {
|
return {
|
||||||
status: 'ok',
|
status: 'ok',
|
||||||
type: 'community',
|
type: 'community',
|
||||||
@ -6,5 +13,6 @@ function checkLicense() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
checkLicense,
|
checkLicenseWeb,
|
||||||
|
checkLicenseApp,
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,6 @@ const os = require('os');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const processArgs = require('./processArgs');
|
const processArgs = require('./processArgs');
|
||||||
const isElectron = require('is-electron');
|
const isElectron = require('is-electron');
|
||||||
const { checkLicense } = require('./checkLicense');
|
|
||||||
|
|
||||||
const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform;
|
const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform;
|
||||||
const isWindows = platform === 'win32';
|
const isWindows = platform === 'win32';
|
||||||
@ -13,7 +12,6 @@ const isDocker = fs.existsSync('/home/dbgate-docker/public');
|
|||||||
const isDevMode = process.env.DEVMODE == '1';
|
const isDevMode = process.env.DEVMODE == '1';
|
||||||
const isNpmDist = !!global['IS_NPM_DIST'];
|
const isNpmDist = !!global['IS_NPM_DIST'];
|
||||||
const isForkedApi = processArgs.isForkedApi;
|
const isForkedApi = processArgs.isForkedApi;
|
||||||
const checkedLicense = checkLicense();
|
|
||||||
|
|
||||||
// function moduleAvailable(name) {
|
// function moduleAvailable(name) {
|
||||||
// try {
|
// try {
|
||||||
@ -32,8 +30,6 @@ const platformInfo = {
|
|||||||
isElectronBundle: isElectron() && !isDevMode,
|
isElectronBundle: isElectron() && !isDevMode,
|
||||||
isForkedApi,
|
isForkedApi,
|
||||||
isElectron: isElectron(),
|
isElectron: isElectron(),
|
||||||
checkedLicense,
|
|
||||||
isLicenseValid: checkedLicense?.status == 'ok',
|
|
||||||
isDevMode,
|
isDevMode,
|
||||||
isNpmDist,
|
isNpmDist,
|
||||||
isSnap: process.env.ELECTRON_SNAP == 'true',
|
isSnap: process.env.ELECTRON_SNAP == 'true',
|
||||||
|
114
packages/web/src/EnterLicensePage.svelte
Normal file
114
packages/web/src/EnterLicensePage.svelte
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { useConfig } from './utility/metadataLoaders';
|
||||||
|
import ErrorInfo from './elements/ErrorInfo.svelte';
|
||||||
|
import Link from './elements/Link.svelte';
|
||||||
|
import { internalRedirectTo } from './clientAuth';
|
||||||
|
import TextAreaField from './forms/TextAreaField.svelte';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import FormProviderCore from './forms/FormProviderCore.svelte';
|
||||||
|
import FormTextAreaField from './forms/FormTextAreaField.svelte';
|
||||||
|
import FormSubmit from './forms/FormSubmit.svelte';
|
||||||
|
import { apiCall } from './utility/api';
|
||||||
|
|
||||||
|
const config = useConfig();
|
||||||
|
const values = writable({ amoid: null, databaseServer: null });
|
||||||
|
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
const error = params.get('error');
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const removed = document.getElementById('starting_dbgate_zero');
|
||||||
|
if (removed) removed.remove();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormProviderCore {values}>
|
||||||
|
<div class="root theme-light theme-type-light">
|
||||||
|
<div class="text">DbGate</div>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="logo">
|
||||||
|
<img class="img" src="logo192.png" />
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="heading">License</div>
|
||||||
|
<FormTextAreaField label="License key" name="licenseKey" rows={5} />
|
||||||
|
|
||||||
|
<div class="submit">
|
||||||
|
<FormSubmit
|
||||||
|
value="Save license"
|
||||||
|
on:click={async e => {
|
||||||
|
const { licenseKey } = e.detail;
|
||||||
|
await apiCall('config/save-license-key', { licenseKey });
|
||||||
|
internalRedirectTo('/');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FormProviderCore>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.img {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
position: fixed;
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
font-size: 30pt;
|
||||||
|
font-family: monospace;
|
||||||
|
color: var(--theme-bg-2);
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root {
|
||||||
|
color: var(--theme-font-1);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: var(--theme-bg-1);
|
||||||
|
align-items: baseline;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
width: 600px;
|
||||||
|
max-width: 80vw;
|
||||||
|
/* max-width: 600px;
|
||||||
|
width: 40vw; */
|
||||||
|
border: 1px solid var(--theme-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: var(--theme-bg-0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
margin-top: 20vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
text-align: center;
|
||||||
|
margin: 1em;
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit {
|
||||||
|
margin: var(--dim-large-form-margin);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit :global(input) {
|
||||||
|
flex: 1;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
</style>
|
@ -2,6 +2,7 @@ import { ca } from 'date-fns/locale';
|
|||||||
import { apiCall, enableApi, getAuthCategory } from './utility/api';
|
import { apiCall, enableApi, getAuthCategory } from './utility/api';
|
||||||
import { getConfig } from './utility/metadataLoaders';
|
import { getConfig } from './utility/metadataLoaders';
|
||||||
import { isAdminPage } from './utility/pageDefs';
|
import { isAdminPage } from './utility/pageDefs';
|
||||||
|
import getElectron from './utility/getElectron';
|
||||||
|
|
||||||
export function isOauthCallback() {
|
export function isOauthCallback() {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
@ -117,11 +118,19 @@ export function handleOauthCallback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function handleAuthOnStartup(config, isAdminPage = false) {
|
export async function handleAuthOnStartup(config, isAdminPage = false) {
|
||||||
if (!config.isLicenseValid || config.configurationError) {
|
if (config.configurationError) {
|
||||||
internalRedirectTo(`/?page=error`);
|
internalRedirectTo(`/?page=error`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config.isLicenseValid) {
|
||||||
|
if (config.storageDatabase || getElectron()) {
|
||||||
|
internalRedirectTo(`/?page=license`);
|
||||||
|
} else {
|
||||||
|
internalRedirectTo(`/?page=error`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (getAuthCategory(config) == 'admin') {
|
if (getAuthCategory(config) == 'admin') {
|
||||||
if (localStorage.getItem('adminAccessToken')) {
|
if (localStorage.getItem('adminAccessToken')) {
|
||||||
return;
|
return;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
export let name;
|
export let name;
|
||||||
export let defaultValue = undefined;
|
export let defaultValue = undefined;
|
||||||
export let saveOnInput = false;
|
export let saveOnInput = false;
|
||||||
|
export let onChange = null;
|
||||||
|
|
||||||
const { values, setFieldValue } = getFormContext();
|
const { values, setFieldValue } = getFormContext();
|
||||||
</script>
|
</script>
|
||||||
@ -17,5 +18,8 @@
|
|||||||
if (saveOnInput) {
|
if (saveOnInput) {
|
||||||
setFieldValue(name, e.target['value']);
|
setFieldValue(name, e.target['value']);
|
||||||
}
|
}
|
||||||
|
if (onChange) {
|
||||||
|
onChange(e.target['value']);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -7,6 +7,7 @@ import { handleOauthCallback } from './clientAuth';
|
|||||||
import LoginPage from './LoginPage.svelte';
|
import LoginPage from './LoginPage.svelte';
|
||||||
import NotLoggedPage from './NotLoggedPage.svelte';
|
import NotLoggedPage from './NotLoggedPage.svelte';
|
||||||
import ErrorPage from './ErrorPage.svelte';
|
import ErrorPage from './ErrorPage.svelte';
|
||||||
|
import EnterLicensePage from './EnterLicensePage.svelte';
|
||||||
|
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const page = params.get('page');
|
const page = params.get('page');
|
||||||
@ -15,7 +16,6 @@ const isOauthCallback = handleOauthCallback();
|
|||||||
|
|
||||||
localStorageGarbageCollector();
|
localStorageGarbageCollector();
|
||||||
|
|
||||||
|
|
||||||
function createApp() {
|
function createApp() {
|
||||||
if (isOauthCallback) {
|
if (isOauthCallback) {
|
||||||
return null;
|
return null;
|
||||||
@ -34,6 +34,11 @@ function createApp() {
|
|||||||
target: document.body,
|
target: document.body,
|
||||||
props: {},
|
props: {},
|
||||||
});
|
});
|
||||||
|
case 'license':
|
||||||
|
return new EnterLicensePage({
|
||||||
|
target: document.body,
|
||||||
|
props: {},
|
||||||
|
});
|
||||||
case 'admin-login':
|
case 'admin-login':
|
||||||
return new LoginPage({
|
return new LoginPage({
|
||||||
target: document.body,
|
target: document.body,
|
||||||
|
@ -31,9 +31,15 @@
|
|||||||
import { isMac } from '../utility/common';
|
import { isMac } from '../utility/common';
|
||||||
import getElectron from '../utility/getElectron';
|
import getElectron from '../utility/getElectron';
|
||||||
import ThemeSkeleton from './ThemeSkeleton.svelte';
|
import ThemeSkeleton from './ThemeSkeleton.svelte';
|
||||||
|
import { isProApp } from '../utility/proTools';
|
||||||
|
import FormTextAreaField from '../forms/FormTextAreaField.svelte';
|
||||||
|
import { apiCall } from '../utility/api';
|
||||||
|
import { useSettings } from '../utility/metadataLoaders';
|
||||||
|
import { derived } from 'svelte/store';
|
||||||
|
|
||||||
const electron = getElectron();
|
const electron = getElectron();
|
||||||
let restartWarning = false;
|
let restartWarning = false;
|
||||||
|
let licenseKeyCheckResult = null;
|
||||||
|
|
||||||
export let selectedTab = 0;
|
export let selectedTab = 0;
|
||||||
|
|
||||||
@ -58,6 +64,23 @@ ORDER BY
|
|||||||
$selectedWidget = 'plugins';
|
$selectedWidget = 'plugins';
|
||||||
$visibleWidgetSideBar = true;
|
$visibleWidgetSideBar = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settings = useSettings();
|
||||||
|
const settingsValues = derived(settings, $settings => {
|
||||||
|
if (!$settings) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return $settings;
|
||||||
|
});
|
||||||
|
|
||||||
|
$: licenseKey = $settingsValues['other.licenseKey'];
|
||||||
|
let checkedLicenseKey = false;
|
||||||
|
$: if (licenseKey && !checkedLicenseKey) {
|
||||||
|
checkedLicenseKey = true;
|
||||||
|
apiCall('config/check-license', { licenseKey }).then(result => {
|
||||||
|
licenseKeyCheckResult = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SettingsFormProvider>
|
<SettingsFormProvider>
|
||||||
@ -70,6 +93,7 @@ ORDER BY
|
|||||||
isInline
|
isInline
|
||||||
tabs={[
|
tabs={[
|
||||||
{ label: 'General', slot: 1 },
|
{ label: 'General', slot: 1 },
|
||||||
|
isProApp() && electron && { label: 'License', slot: 7 },
|
||||||
{ label: 'Connection', slot: 2 },
|
{ label: 'Connection', slot: 2 },
|
||||||
{ label: 'Themes', slot: 3 },
|
{ label: 'Themes', slot: 3 },
|
||||||
{ label: 'Default Actions', slot: 4 },
|
{ label: 'Default Actions', slot: 4 },
|
||||||
@ -317,11 +341,34 @@ ORDER BY
|
|||||||
<svelte:fragment slot="6">
|
<svelte:fragment slot="6">
|
||||||
<div class="heading">Other</div>
|
<div class="heading">Other</div>
|
||||||
|
|
||||||
<FormTextField
|
<FormTextField name="other.gistCreateToken" label="API token for creating error gists" defaultValue="" />
|
||||||
name="other.gistCreateToken"
|
</svelte:fragment>
|
||||||
label="API token for creating error gists"
|
|
||||||
defaultValue=""
|
<svelte:fragment slot="7">
|
||||||
|
<div class="heading">License</div>
|
||||||
|
<FormTextAreaField
|
||||||
|
name="other.licenseKey"
|
||||||
|
label="License key"
|
||||||
|
rows={7}
|
||||||
|
onChange={async value => {
|
||||||
|
licenseKeyCheckResult = await apiCall('config/check-license', { licenseKey: value });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
{#if licenseKeyCheckResult}
|
||||||
|
<div class="m-3 ml-5">
|
||||||
|
{#if licenseKeyCheckResult.status == 'ok'}
|
||||||
|
<div>
|
||||||
|
<FontIcon icon="img ok" /> License key is valid
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
License valid to: {licenseKeyCheckResult.validTo}
|
||||||
|
</div>
|
||||||
|
<div>License key expiration: {licenseKeyCheckResult.expiration}</div>
|
||||||
|
{:else if licenseKeyCheckResult.status == 'error'}
|
||||||
|
<FontIcon icon="img error" /> License key is invalid
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
</FormValues>
|
</FormValues>
|
||||||
|
3
packages/web/src/utility/proTools.ts
Normal file
3
packages/web/src/utility/proTools.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function isProApp() {
|
||||||
|
return false;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user