mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 13:13:58 +00:00
auth providert refactor WIP
This commit is contained in:
11
packages/api/src/auth/authCommon.js
Normal file
11
packages/api/src/auth/authCommon.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const tokenSecret = crypto.randomUUID();
|
||||||
|
|
||||||
|
export function getTokenLifetime() {
|
||||||
|
return process.env.TOKEN_LIFETIME || '1d';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTokenSecret() {
|
||||||
|
return tokenSecret;
|
||||||
|
}
|
||||||
216
packages/api/src/auth/authProvider.js
Normal file
216
packages/api/src/auth/authProvider.js
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
const { getTokenSecret, getTokenLifetime } = require('./authCommon');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const axios = require('axios');
|
||||||
|
const { getLogger } = require('dbgate-tools');
|
||||||
|
|
||||||
|
const AD = require('activedirectory2').promiseWrapper;
|
||||||
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
|
const logger = getLogger('authProvider');
|
||||||
|
|
||||||
|
let envLoginsCache = null;
|
||||||
|
let envLoginsLoaded = false;
|
||||||
|
|
||||||
|
function getEnvLogins() {
|
||||||
|
if (envLoginsLoaded) {
|
||||||
|
return envLoginsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = [];
|
||||||
|
if (process.env.LOGIN && process.env.PASSWORD) {
|
||||||
|
res.push({
|
||||||
|
login: process.env.LOGIN,
|
||||||
|
password: process.env.PASSWORD,
|
||||||
|
permissions: process.env.PERMISSIONS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (process.env.LOGINS) {
|
||||||
|
const logins = _.compact(process.env.LOGINS.split(',').map(x => x.trim()));
|
||||||
|
for (const login of logins) {
|
||||||
|
const password = process.env[`LOGIN_PASSWORD_${login}`];
|
||||||
|
const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
|
||||||
|
if (password) {
|
||||||
|
res.push({
|
||||||
|
login,
|
||||||
|
password,
|
||||||
|
permissions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
envLoginsCache = res.length > 0 ? res : null;
|
||||||
|
envLoginsLoaded = true;
|
||||||
|
return envLoginsCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AuthProviderBase {
|
||||||
|
async login(login, password) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getBasicAuthLogins() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldAuthorizeApi() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
oauthToken(params) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentLogin(req) {}
|
||||||
|
|
||||||
|
getCurrentPermissions(req) {
|
||||||
|
return process.env.PERMISSIONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OAuthProvider extends AuthProviderBase {
|
||||||
|
shouldAuthorizeApi() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async oauthToken(params) {
|
||||||
|
const { redirectUri, code } = params;
|
||||||
|
|
||||||
|
const scopeParam = process.env.OAUTH_SCOPE ? `&scope=${process.env.OAUTH_SCOPE}` : '';
|
||||||
|
const resp = await axios.default.post(
|
||||||
|
`${process.env.OAUTH_TOKEN}`,
|
||||||
|
`grant_type=authorization_code&code=${encodeURIComponent(code)}&redirect_uri=${encodeURIComponent(
|
||||||
|
redirectUri
|
||||||
|
)}&client_id=${process.env.OAUTH_CLIENT_ID}&client_secret=${process.env.OAUTH_CLIENT_SECRET}${scopeParam}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const { access_token, refresh_token } = resp.data;
|
||||||
|
|
||||||
|
const payload = jwt.decode(access_token);
|
||||||
|
|
||||||
|
logger.info({ payload }, 'User payload returned from OAUTH');
|
||||||
|
|
||||||
|
const login =
|
||||||
|
process.env.OAUTH_LOGIN_FIELD && payload && payload[process.env.OAUTH_LOGIN_FIELD]
|
||||||
|
? payload[process.env.OAUTH_LOGIN_FIELD]
|
||||||
|
: 'oauth';
|
||||||
|
|
||||||
|
if (
|
||||||
|
process.env.OAUTH_ALLOWED_LOGINS &&
|
||||||
|
!process.env.OAUTH_ALLOWED_LOGINS.split(',').find(x => x.toLowerCase().trim() == login.toLowerCase().trim())
|
||||||
|
) {
|
||||||
|
return { error: `Username ${login} not allowed to log in` };
|
||||||
|
}
|
||||||
|
|
||||||
|
const groups =
|
||||||
|
process.env.OAUTH_GROUP_FIELD && payload && payload[process.env.OAUTH_GROUP_FIELD]
|
||||||
|
? payload[process.env.OAUTH_GROUP_FIELD]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const allowedGroups = process.env.OAUTH_ALLOWED_GROUPS
|
||||||
|
? process.env.OAUTH_ALLOWED_GROUPS.split(',').map(group => group.toLowerCase().trim())
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (process.env.OAUTH_ALLOWED_GROUPS && !groups.some(group => allowedGroups.includes(group.toLowerCase().trim()))) {
|
||||||
|
return { error: `Username ${login} does not belong to an allowed group` };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access_token) {
|
||||||
|
return {
|
||||||
|
accessToken: jwt.sign({ login }, getTokenSecret(), { expiresIn: getTokenLifetime() }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { error: 'Token not found' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ADProvider extends AuthProviderBase {
|
||||||
|
async login(login, password) {
|
||||||
|
const adConfig = {
|
||||||
|
url: process.env.AD_URL,
|
||||||
|
baseDN: process.env.AD_BASEDN,
|
||||||
|
username: process.env.AD_USERNAME,
|
||||||
|
password: process.env.AD_PASSOWRD,
|
||||||
|
};
|
||||||
|
const ad = new AD(adConfig);
|
||||||
|
try {
|
||||||
|
const res = await ad.authenticate(login, password);
|
||||||
|
if (!res) {
|
||||||
|
return { error: 'Login failed' };
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
process.env.AD_ALLOWED_LOGINS &&
|
||||||
|
!process.env.AD_ALLOWED_LOGINS.split(',').find(x => x.toLowerCase().trim() == login.toLowerCase().trim())
|
||||||
|
) {
|
||||||
|
return { error: `Username ${login} not allowed to log in` };
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
accessToken: jwt.sign({ login }, getTokenSecret(), { expiresIn: getTokenLifetime() }),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return { error: 'Login failed' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldAuthorizeApi() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LoginsProvider extends AuthProviderBase {
|
||||||
|
async login(login, password) {
|
||||||
|
const logins = getEnvLogins();
|
||||||
|
if (!logins) {
|
||||||
|
return { error: 'Logins not configured' };
|
||||||
|
}
|
||||||
|
const foundLogin = logins.find(x => x.login == login);
|
||||||
|
if (foundLogin && foundLogin.password && foundLogin.password == password) {
|
||||||
|
return {
|
||||||
|
accessToken: jwt.sign({ login }, getTokenSecret(), { expiresIn: getTokenLifetime() }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return { error: 'Invalid credentials' };
|
||||||
|
}
|
||||||
|
|
||||||
|
getBasicAuthLogins() {
|
||||||
|
const logins = getEnvLogins();
|
||||||
|
if (logins && process.env.BASIC_AUTH) {
|
||||||
|
return _.fromPairs(logins.filter(x => x.password).map(x => [x.login, x.password]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldAuthorizeApi() {
|
||||||
|
return !process.env.BASIC_AUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function detectEnvAuthProvider() {
|
||||||
|
if (process.env.AUTH_PROVIDER) {
|
||||||
|
return process.env.AUTH_PROVIDER;
|
||||||
|
}
|
||||||
|
if (process.env.OAUTH_AUTH) {
|
||||||
|
return 'oauth';
|
||||||
|
}
|
||||||
|
if (process.env.AD_URL) {
|
||||||
|
return 'ad';
|
||||||
|
}
|
||||||
|
if (getEnvLogins()) {
|
||||||
|
return 'logins';
|
||||||
|
}
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAuthProvider() {
|
||||||
|
const authProvider = detectEnvAuthProvider();
|
||||||
|
switch (authProvider) {
|
||||||
|
case 'oauth':
|
||||||
|
return new OAuthProvider();
|
||||||
|
case 'ad':
|
||||||
|
return new ADProvider();
|
||||||
|
case 'logins':
|
||||||
|
return new LoginsProvider();
|
||||||
|
default:
|
||||||
|
return new AuthProviderBase();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,18 +5,14 @@ const { getLogins } = require('../utility/hasPermission');
|
|||||||
const { getLogger } = require('dbgate-tools');
|
const { getLogger } = require('dbgate-tools');
|
||||||
const AD = require('activedirectory2').promiseWrapper;
|
const AD = require('activedirectory2').promiseWrapper;
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
const { getTokenSecret, getTokenLifetime } = require('../auth/authCommon');
|
||||||
|
const { createAuthProvider } = require('../auth/authProvider');
|
||||||
|
const { create } = require('lodash');
|
||||||
|
|
||||||
const logger = getLogger('auth');
|
const logger = getLogger('auth');
|
||||||
|
|
||||||
const tokenSecret = crypto.randomUUID();
|
|
||||||
|
|
||||||
function shouldAuthorizeApi() {
|
function shouldAuthorizeApi() {
|
||||||
const logins = getLogins();
|
return createAuthProvider().shouldAuthorizeApi();
|
||||||
return !!process.env.OAUTH_AUTH || !!process.env.AD_URL || (!!logins && !process.env.BASIC_AUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTokenLifetime() {
|
|
||||||
return process.env.TOKEN_LIFETIME || '1d';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function unauthorizedResponse(req, res, text) {
|
function unauthorizedResponse(req, res, text) {
|
||||||
@@ -46,7 +42,7 @@ function authMiddleware(req, res, next) {
|
|||||||
}
|
}
|
||||||
const token = authHeader.split(' ')[1];
|
const token = authHeader.split(' ')[1];
|
||||||
try {
|
try {
|
||||||
const decoded = jwt.verify(token, tokenSecret);
|
const decoded = jwt.verify(token, getTokenSecret());
|
||||||
req.user = decoded;
|
req.user = decoded;
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -63,104 +59,13 @@ function authMiddleware(req, res, next) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
oauthToken_meta: true,
|
oauthToken_meta: true,
|
||||||
async oauthToken(params) {
|
async oauthToken(params) {
|
||||||
const { redirectUri, code } = params;
|
return createAuthProvider().oauthToken(params);
|
||||||
|
|
||||||
const scopeParam = process.env.OAUTH_SCOPE ? `&scope=${process.env.OAUTH_SCOPE}` : '';
|
|
||||||
const resp = await axios.default.post(
|
|
||||||
`${process.env.OAUTH_TOKEN}`,
|
|
||||||
`grant_type=authorization_code&code=${encodeURIComponent(code)}&redirect_uri=${encodeURIComponent(
|
|
||||||
redirectUri
|
|
||||||
)}&client_id=${process.env.OAUTH_CLIENT_ID}&client_secret=${process.env.OAUTH_CLIENT_SECRET}${scopeParam}`
|
|
||||||
);
|
|
||||||
|
|
||||||
const { access_token, refresh_token } = resp.data;
|
|
||||||
|
|
||||||
const payload = jwt.decode(access_token);
|
|
||||||
|
|
||||||
logger.info({ payload }, 'User payload returned from OAUTH');
|
|
||||||
|
|
||||||
const login =
|
|
||||||
process.env.OAUTH_LOGIN_FIELD && payload && payload[process.env.OAUTH_LOGIN_FIELD]
|
|
||||||
? payload[process.env.OAUTH_LOGIN_FIELD]
|
|
||||||
: 'oauth';
|
|
||||||
|
|
||||||
if (
|
|
||||||
process.env.OAUTH_ALLOWED_LOGINS &&
|
|
||||||
!process.env.OAUTH_ALLOWED_LOGINS.split(',').find(x => x.toLowerCase().trim() == login.toLowerCase().trim())
|
|
||||||
) {
|
|
||||||
return { error: `Username ${login} not allowed to log in` };
|
|
||||||
}
|
|
||||||
|
|
||||||
const groups =
|
|
||||||
process.env.OAUTH_GROUP_FIELD && payload && payload[process.env.OAUTH_GROUP_FIELD]
|
|
||||||
? payload[process.env.OAUTH_GROUP_FIELD]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const allowedGroups =
|
|
||||||
process.env.OAUTH_ALLOWED_GROUPS
|
|
||||||
? process.env.OAUTH_ALLOWED_GROUPS.split(',').map(group => group.toLowerCase().trim())
|
|
||||||
: [];
|
|
||||||
|
|
||||||
if (
|
|
||||||
process.env.OAUTH_ALLOWED_GROUPS &&
|
|
||||||
!groups.some(group => allowedGroups.includes(group.toLowerCase().trim()))
|
|
||||||
) {
|
|
||||||
return { error: `Username ${login} does not belong to an allowed group` };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (access_token) {
|
|
||||||
return {
|
|
||||||
accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: getTokenLifetime() }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { error: 'Token not found' };
|
|
||||||
},
|
},
|
||||||
login_meta: true,
|
login_meta: true,
|
||||||
async login(params) {
|
async login(params) {
|
||||||
const { login, password } = params;
|
const { login, password } = params;
|
||||||
|
|
||||||
if (process.env.AD_URL) {
|
return createAuthProvider().login(login, password);
|
||||||
const adConfig = {
|
|
||||||
url: process.env.AD_URL,
|
|
||||||
baseDN: process.env.AD_BASEDN,
|
|
||||||
username: process.env.AD_USERNAME,
|
|
||||||
password: process.env.AD_PASSOWRD,
|
|
||||||
};
|
|
||||||
const ad = new AD(adConfig);
|
|
||||||
try {
|
|
||||||
const res = await ad.authenticate(login, password);
|
|
||||||
if (!res) {
|
|
||||||
return { error: 'Login failed' };
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
process.env.AD_ALLOWED_LOGINS &&
|
|
||||||
!process.env.AD_ALLOWED_LOGINS.split(',').find(x => x.toLowerCase().trim() == login.toLowerCase().trim())
|
|
||||||
) {
|
|
||||||
return { error: `Username ${login} not allowed to log in` };
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: getTokenLifetime() }),
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
logger.error({ err }, 'Failed active directory authentization');
|
|
||||||
return {
|
|
||||||
error: err.message,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const logins = getLogins();
|
|
||||||
if (!logins) {
|
|
||||||
return { error: 'Logins not configured' };
|
|
||||||
}
|
|
||||||
const foundLogin = logins.find(x => x.login == login);
|
|
||||||
if (foundLogin && foundLogin.password && foundLogin.password == password) {
|
|
||||||
return {
|
|
||||||
accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: getTokenLifetime() }),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return { error: 'Invalid credentials' };
|
|
||||||
},
|
},
|
||||||
|
|
||||||
authMiddleware,
|
authMiddleware,
|
||||||
|
|||||||
@@ -3,4 +3,8 @@ module.exports = {
|
|||||||
async connections() {
|
async connections() {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getConnection({ conid }) {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const getExpressPath = require('./utility/getExpressPath');
|
|||||||
const { getLogins } = require('./utility/hasPermission');
|
const { getLogins } = require('./utility/hasPermission');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const { getLogger } = require('dbgate-tools');
|
const { getLogger } = require('dbgate-tools');
|
||||||
|
const { createAuthProvider } = require('./auth/authProvider');
|
||||||
|
|
||||||
const logger = getLogger('main');
|
const logger = getLogger('main');
|
||||||
|
|
||||||
@@ -45,11 +46,11 @@ function start() {
|
|||||||
|
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
const logins = getLogins();
|
const basicAuthLogins = createAuthProvider().getBasicAuthLogins();
|
||||||
if (logins && process.env.BASIC_AUTH) {
|
if (basicAuthLogins) {
|
||||||
app.use(
|
app.use(
|
||||||
basicAuth({
|
basicAuth({
|
||||||
users: _.fromPairs(logins.filter(x => x.password).map(x => [x.login, x.password])),
|
users: basicAuthLogins,
|
||||||
challenge: true,
|
challenge: true,
|
||||||
realm: 'DbGate Web App',
|
realm: 'DbGate Web App',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,49 +24,48 @@ function hasPermission(tested, req) {
|
|||||||
return testPermission(tested, userPermissions[key]);
|
return testPermission(tested, userPermissions[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let loginsCache = null;
|
// let loginsCache = null;
|
||||||
let loginsLoaded = false;
|
// let loginsLoaded = false;
|
||||||
|
|
||||||
function getLogins() {
|
// function getLogins() {
|
||||||
if (loginsLoaded) {
|
// if (loginsLoaded) {
|
||||||
return loginsCache;
|
// return loginsCache;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const res = [];
|
// const res = [];
|
||||||
if (process.env.LOGIN && process.env.PASSWORD) {
|
// if (process.env.LOGIN && process.env.PASSWORD) {
|
||||||
res.push({
|
// res.push({
|
||||||
login: process.env.LOGIN,
|
// login: process.env.LOGIN,
|
||||||
password: process.env.PASSWORD,
|
// password: process.env.PASSWORD,
|
||||||
permissions: process.env.PERMISSIONS,
|
// permissions: process.env.PERMISSIONS,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
if (process.env.LOGINS) {
|
// if (process.env.LOGINS) {
|
||||||
const logins = _.compact(process.env.LOGINS.split(',').map(x => x.trim()));
|
// const logins = _.compact(process.env.LOGINS.split(',').map(x => x.trim()));
|
||||||
for (const login of logins) {
|
// for (const login of logins) {
|
||||||
const password = process.env[`LOGIN_PASSWORD_${login}`];
|
// const password = process.env[`LOGIN_PASSWORD_${login}`];
|
||||||
const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
|
// const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
|
||||||
if (password) {
|
// if (password) {
|
||||||
res.push({
|
// res.push({
|
||||||
login,
|
// login,
|
||||||
password,
|
// password,
|
||||||
permissions,
|
// permissions,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// } else if (process.env.OAUTH_PERMISSIONS) {
|
||||||
else if (process.env.OAUTH_PERMISSIONS) {
|
// const login_permission_keys = Object.keys(process.env).filter(key => _.startsWith(key, 'LOGIN_PERMISSIONS_'));
|
||||||
const login_permission_keys = Object.keys(process.env).filter((key) => _.startsWith(key, 'LOGIN_PERMISSIONS_'))
|
// for (const permissions_key of login_permission_keys) {
|
||||||
for (const permissions_key of login_permission_keys) {
|
// const login = permissions_key.replace('LOGIN_PERMISSIONS_', '');
|
||||||
const login = permissions_key.replace('LOGIN_PERMISSIONS_', '');
|
// const permissions = process.env[permissions_key];
|
||||||
const permissions = process.env[permissions_key];
|
// userPermissions[login] = compilePermissions(permissions);
|
||||||
userPermissions[login] = compilePermissions(permissions);
|
// }
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
loginsCache = res.length > 0 ? res : null;
|
// loginsCache = res.length > 0 ? res : null;
|
||||||
loginsLoaded = true;
|
// loginsLoaded = true;
|
||||||
return loginsCache;
|
// return loginsCache;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function connectionHasPermission(connection, req) {
|
function connectionHasPermission(connection, req) {
|
||||||
if (!connection) {
|
if (!connection) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { openedConnections, currentDatabase, openedConnectionsWithTemporary } from '../stores';
|
import { openedConnections, currentDatabase, openedConnectionsWithTemporary, getCurrentConfig } from '../stores';
|
||||||
import { apiCall, strmid } from './api';
|
import { apiCall, strmid } from './api';
|
||||||
import { getConnectionList } from './metadataLoaders';
|
import { getConnectionList } from './metadataLoaders';
|
||||||
|
|
||||||
@@ -10,7 +10,10 @@ import { getConnectionList } from './metadataLoaders';
|
|||||||
// };
|
// };
|
||||||
|
|
||||||
const doServerPing = value => {
|
const doServerPing = value => {
|
||||||
apiCall('server-connections/ping', { conidArray: ['__storage', ...value], strmid });
|
apiCall('server-connections/ping', {
|
||||||
|
conidArray: getCurrentConfig().storageDatabase ? ['__storage', ...value] : value,
|
||||||
|
strmid,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const doDatabasePing = value => {
|
const doDatabasePing = value => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
visibleWidgetSideBar,
|
visibleWidgetSideBar,
|
||||||
visibleHamburgerMenuWidget,
|
visibleHamburgerMenuWidget,
|
||||||
lockedDatabaseMode,
|
lockedDatabaseMode,
|
||||||
|
getCurrentConfig,
|
||||||
} from '../stores';
|
} from '../stores';
|
||||||
import mainMenuDefinition from '../../../../app/src/mainMenuDefinition';
|
import mainMenuDefinition from '../../../../app/src/mainMenuDefinition';
|
||||||
import hasPermission from '../utility/hasPermission';
|
import hasPermission from '../utility/hasPermission';
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
let domMainMenu;
|
let domMainMenu;
|
||||||
|
|
||||||
const widgets = [
|
const widgets = [
|
||||||
{
|
getCurrentConfig().storageDatabase && {
|
||||||
icon: 'icon admin',
|
icon: 'icon admin',
|
||||||
name: 'admin',
|
name: 'admin',
|
||||||
title: 'Administration',
|
title: 'Administration',
|
||||||
@@ -103,7 +104,7 @@
|
|||||||
<FontIcon icon="icon menu" />
|
<FontIcon icon="icon menu" />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#each widgets.filter(x => hasPermission(`widgets/${x.name}`)) as item}
|
{#each widgets.filter(x => x && hasPermission(`widgets/${x.name}`)) as item}
|
||||||
<div
|
<div
|
||||||
class="wrapper"
|
class="wrapper"
|
||||||
class:selected={item.name == $visibleSelectedWidget}
|
class:selected={item.name == $visibleSelectedWidget}
|
||||||
|
|||||||
Reference in New Issue
Block a user