Added per-domain configuration of the MyServer action tab.
This commit is contained in:
parent
a934d723b9
commit
00ea208f0e
|
@ -170,7 +170,23 @@
|
|||
"welcomePicture": { "type": "string", "description": "Name of the PNG or JPEG file that will be shown on the login screen. Put this file in the meshcentral-data folder and place the file name here." },
|
||||
"hide": { "type": "integer" },
|
||||
"footer": { "type": "string" },
|
||||
"certUrl": { "type": "string", "format": "uri", "description": "https url when to get the TLS certificate that MeshAgent's will see when connecting to this server. This setting is used when a reverse proxy like NGINX is used in front of MeshCentral." },
|
||||
"certUrl": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"description": "https url when to get the TLS certificate that MeshAgent's will see when connecting to this server. This setting is used when a reverse proxy like NGINX is used in front of MeshCentral."
|
||||
},
|
||||
"myServer": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Backup": { "type": "boolean", "default": true, "description": "Allows administrators to backup the server from the My Server tab." },
|
||||
"Restore": { "type": "boolean", "default": true, "description": "Allows administrators to restore the server from the My Server tab." },
|
||||
"Upgrade": { "type": "boolean", "default": true, "description": "Allows administrators to update the server from the My Server tab." },
|
||||
"ShowLog": { "type": "boolean", "default": true, "description": "Allows administrators to see the server crash log the server from the My Server tab." },
|
||||
"Console": { "type": "boolean", "default": true, "description": "Allows administrators to access the server console from the My Server tab." },
|
||||
"Trace": { "type": "boolean", "default": true, "description": "Allows administrators to access the server trace tab from from the My Server tab." }
|
||||
}
|
||||
},
|
||||
"passwordRequirements": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
16
meshuser.js
16
meshuser.js
|
@ -444,8 +444,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: parent.CloneSafeUser(parent.users[user._id]) })); } catch (ex) { }
|
||||
|
||||
if (user.siteadmin === SITERIGHT_ADMIN) {
|
||||
// Send server tracing information
|
||||
try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { }
|
||||
// Check if tracing is allowed for this domain
|
||||
if ((domain.myserver == null) || (domain.myserver.trace === true)) {
|
||||
// Send server tracing information
|
||||
try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { }
|
||||
}
|
||||
|
||||
// Send any server warnings if any
|
||||
var serverWarnings = parent.parent.getServerWarnings();
|
||||
|
@ -807,6 +810,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// This is a server console message, only process this if full administrator
|
||||
if (user.siteadmin != SITERIGHT_ADMIN) break;
|
||||
|
||||
// Only accept is the console is allowed for this domain
|
||||
if ((domain.myserver != null) && (domain.myserver.console !== true)) break;
|
||||
|
||||
var r = '';
|
||||
var cmdargs = splitArgs(command.value);
|
||||
if (cmdargs.length == 0) break;
|
||||
|
@ -2600,6 +2606,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
{
|
||||
// Check the server version
|
||||
if ((user.siteadmin & 16) == 0) break;
|
||||
if ((domain.myserver != null) && (domain.myserver.upgrade !== true)) break;
|
||||
//parent.parent.getLatestServerVersion(function (currentVersion, latestVersion) { try { ws.send(JSON.stringify({ action: 'serverversion', current: currentVersion, latest: latestVersion })); } catch (ex) { } });
|
||||
parent.parent.getServerTags(function (tags, err) { try { ws.send(JSON.stringify({ action: 'serverversion', tags: tags })); } catch (ex) { } });
|
||||
break;
|
||||
|
@ -2608,6 +2615,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
{
|
||||
// Perform server update
|
||||
if ((user.siteadmin & 16) == 0) break;
|
||||
if ((domain.myserver != null) && (domain.myserver.upgrade !== true)) break;
|
||||
if ((command.version != null) && (typeof command.version != 'string')) break;
|
||||
parent.parent.performServerUpdate(command.version);
|
||||
break;
|
||||
|
@ -2616,6 +2624,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
{
|
||||
// Load the server error log
|
||||
if ((user.siteadmin & 16) == 0) break;
|
||||
if ((domain.myserver != null) && (domain.myserver.errorlog !== true)) break;
|
||||
fs.readFile(parent.parent.getConfigFilePath('mesherrors.txt'), 'utf8', function (err, data) { try { ws.send(JSON.stringify({ action: 'servererrors', data: data })); } catch (ex) { } });
|
||||
break;
|
||||
}
|
||||
|
@ -4512,6 +4521,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
break;
|
||||
}
|
||||
case 'traceinfo': {
|
||||
// Only accept is the tracing is allowed for this domain
|
||||
if ((domain.myserver != null) && (domain.myserver.trace !== true)) break;
|
||||
|
||||
if ((user.siteadmin === SITERIGHT_ADMIN) && (typeof command.traceSources == 'object')) {
|
||||
parent.parent.debugRemoteSources = command.traceSources;
|
||||
parent.parent.DispatchEvent(['*'], obj, { action: 'traceinfo', userid: user._id, username: user.name, traceSources: command.traceSources, nolog: 1, domain: domain.id });
|
||||
|
|
|
@ -140,6 +140,14 @@
|
|||
"_hide": 4,
|
||||
"_footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>",
|
||||
"_certUrl": "https://192.168.2.106:443/",
|
||||
"myServer": {
|
||||
"Backup": false,
|
||||
"Restore": false,
|
||||
"Upgrade": false,
|
||||
"ErrorLog": false,
|
||||
"Console": false,
|
||||
"Trace": false
|
||||
},
|
||||
"_passwordRequirements": {
|
||||
"min": 8,
|
||||
"max": 128,
|
||||
|
|
|
@ -31786,7 +31786,7 @@
|
|||
"zh-chs": "服务器统计",
|
||||
"zh-cht": "伺服器統計",
|
||||
"xloc": [
|
||||
"default.handlebars->container->column_l->p6->p6info->6"
|
||||
"default.handlebars->container->column_l->p6->p6info->5"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -474,8 +474,9 @@
|
|||
<div id="p2ServerActionsVersion"><div class="p2AccountActions"><span style="display:none"><strong>✓</strong></span></div><a href=# onclick="return server_showVersionDlg()">Check server version</a></div>
|
||||
<div id="p2ServerActionsErrors"><div class="p2AccountActions"><span style="display:none"><strong>✓</strong></span></div><a href=# onclick="return server_showErrorsDlg()">Show server error log</a></div>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<br /><strong>Server Statistics</strong><br /><br />
|
||||
<strong>Server Statistics</strong><br /><br />
|
||||
<div id="serverStats">
|
||||
<div id="serverCpuChartView" style="display:none">
|
||||
<div class="chartViewCanvas"><canvas id="serverCpuChart"></canvas></div>
|
||||
|
@ -1809,10 +1810,9 @@
|
|||
}
|
||||
|
||||
function updateSiteAdmin() {
|
||||
var noServerBackup = '{{{noServerBackup}}}';
|
||||
var serverFeatures = parseInt('{{{serverfeatures}}}');
|
||||
var siteRights = userinfo.siteadmin;
|
||||
var accountSettingsLocked = ((siteRights != 0xFFFFFFFF) && ((siteRights & 1024) != 0));
|
||||
if (noServerBackup == 1) { siteRights &= 0xFFFFFFFA; } // If not server backups allowed, remove server backup and restore permissions
|
||||
|
||||
// Update account actions
|
||||
QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0) && (accountSettingsLocked == false)); // Hide Account Security if in single user mode or domain authentication, 2 factor auth not supported.
|
||||
|
@ -1823,12 +1823,13 @@
|
|||
QV('p2AccountPassActions', ((features & 4) == 0) && (serverinfo.domainauth == false) && (userinfo != null) && (userinfo._id.split('/')[2].startsWith('~') == false)); // Hide Account Actions if in single user mode or domain authentication
|
||||
//QV('p2AccountImage', ((features & 4) == 0) && (serverinfo.domainauth == false)); // If account actions are not visible, also remove the image on that panel
|
||||
QV('p2AccountImage', !accountSettingsLocked)
|
||||
QV('p2ServerActions', siteRights & 21);
|
||||
QV('p2ServerActions', (siteRights & 21) && ((serverFeatures & 15) != 0));
|
||||
QV('LeftMenuMyServer', siteRights & 21); // 16 + 4 + 1
|
||||
QV('MainMenuMyServer', siteRights & 21);
|
||||
QV('p2ServerActionsBackup', siteRights & 1);
|
||||
QV('p2ServerActionsRestore', siteRights & 4);
|
||||
QV('p2ServerActionsVersion', siteRights & 16);
|
||||
QV('p2ServerActionsBackup', (siteRights & 1) && ((serverFeatures & 1) != 0));
|
||||
QV('p2ServerActionsRestore', (siteRights & 4) && ((serverFeatures & 2) != 0));
|
||||
QV('p2ServerActionsVersion', (siteRights & 16) && ((serverFeatures & 4) != 0));
|
||||
QV('p2ServerActionsErrors', (siteRights & 16) && ((serverFeatures & 8) != 0));
|
||||
QV('MainMenuMyFiles', siteRights & 8);
|
||||
QV('LeftMenuMyFiles', siteRights & 8);
|
||||
if (((siteRights & 8) == 0) && (xxcurrentView == 5)) { setDialogMode(0); go(1); }
|
||||
|
@ -1847,8 +1848,8 @@
|
|||
if (xxcurrentView == 4 || ((xxcurrentView >= 30) && (xxcurrentView < 40))) { setDialogMode(0); go(1); currentUser = null; }
|
||||
}
|
||||
meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
|
||||
QV('ServerConsole', userinfo.siteadmin === 0xFFFFFFFF);
|
||||
QV('ServerTrace', userinfo.siteadmin === 0xFFFFFFFF);
|
||||
QV('ServerConsole', (userinfo.siteadmin === 0xFFFFFFFF) && ((serverFeatures & 16) != 0));
|
||||
QV('ServerTrace', (userinfo.siteadmin === 0xFFFFFFFF) && ((serverFeatures & 32) != 0));
|
||||
if ((xxcurrentView == 115) && (userinfo.siteadmin != 0xFFFFFFFF)) { go(6); }
|
||||
if ((xxcurrentView == 6) && ((userinfo.siteadmin & 21) == 0)) { go(1); }
|
||||
|
||||
|
|
46
webserver.js
46
webserver.js
|
@ -2370,8 +2370,41 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
var customui = '';
|
||||
if (domain.customui != null) { customui = encodeURIComponent(JSON.stringify(domain.customui)); }
|
||||
|
||||
// Server features
|
||||
var serverFeatures = 63;
|
||||
if (domain.myserver) {
|
||||
if (domain.myserver.backup !== true) { serverFeatures -= 1; } // Allow server backups
|
||||
if (domain.myserver.restore !== true) { serverFeatures -= 2; } // Allow server restore
|
||||
if (domain.myserver.upgrade !== true) { serverFeatures -= 4; } // Allow server upgrade
|
||||
if (domain.myserver.errorlog !== true) { serverFeatures -= 8; } // Allow show server crash log
|
||||
if (domain.myserver.console !== true) { serverFeatures -= 16; } // Allow server console
|
||||
if (domain.myserver.trace !== true) { serverFeatures -= 32; } // Allow server tracing
|
||||
}
|
||||
|
||||
// Refresh the session
|
||||
render(req, res, getRenderPage('default', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: authRelayCookie, viewmode: viewmode, currentNode: currentNode, logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27'), domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, passRequirements: passRequirements, customui: customui, webcerthash: Buffer.from(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer, webstate: encodeURIComponent(webstate).replace(/'/g, '%27'), amtscanoptions: amtscanoptions, pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports() }, req, domain));
|
||||
render(req, res, getRenderPage('default', req, domain), getRenderArgs({
|
||||
authCookie: authCookie,
|
||||
authRelayCookie: authRelayCookie,
|
||||
viewmode: viewmode,
|
||||
currentNode: currentNode,
|
||||
logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27'),
|
||||
domain: domain.id,
|
||||
debuglevel: parent.debugLevel,
|
||||
serverDnsName: obj.getWebServerName(domain),
|
||||
serverRedirPort: args.redirport,
|
||||
serverPublicPort: httpsPort,
|
||||
serverfeatures: serverFeatures,
|
||||
features: features,
|
||||
sessiontime: args.sessiontime,
|
||||
mpspass: args.mpspass,
|
||||
passRequirements: passRequirements,
|
||||
customui: customui,
|
||||
webcerthash: Buffer.from(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'),
|
||||
footer: (domain.footer == null) ? '' : domain.footer,
|
||||
webstate: encodeURIComponent(webstate).replace(/'/g, '%27'),
|
||||
amtscanoptions: amtscanoptions,
|
||||
pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports()
|
||||
}, req, domain));
|
||||
});
|
||||
} else {
|
||||
// Send back the login application
|
||||
|
@ -4016,7 +4049,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
const domain = checkUserIpAddress(req, res);
|
||||
if (domain == null) { return; }
|
||||
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
|
||||
if ((!req.session) || (req.session == null) || (!req.session.userid) || (obj.parent.args.noserverbackup == 1)) { res.sendStatus(401); return; }
|
||||
if ((!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
|
||||
if ((domain.myserver != null) && (domain.myserver.backup !== true)) { res.sendStatus(401); return; }
|
||||
|
||||
var user = obj.users[req.session.userid];
|
||||
if ((user == null) || ((user.siteadmin & 1) == 0)) { res.sendStatus(401); return; } // Check if we have server backup rights
|
||||
|
||||
|
@ -4044,7 +4079,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
const domain = checkUserIpAddress(req, res);
|
||||
if (domain == null) { return; }
|
||||
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
|
||||
if (obj.parent.args.noserverbackup == 1) { res.sendStatus(401); return; }
|
||||
if ((domain.myserver != null) && (domain.myserver.restore !== true)) { res.sendStatus(401); return; }
|
||||
|
||||
var authUserid = null;
|
||||
if ((req.session != null) && (typeof req.session.userid == 'string')) { authUserid = req.session.userid; }
|
||||
const multiparty = require('multiparty');
|
||||
|
@ -4769,8 +4805,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
obj.app.get(url, handleRootRequest);
|
||||
obj.app.post(url, handleRootPostRequest);
|
||||
obj.app.get(url + 'refresh.ashx', function (req, res) { res.sendStatus(200); });
|
||||
obj.app.get(url + 'backup.zip', handleBackupRequest);
|
||||
obj.app.post(url + 'restoreserver.ashx', handleRestoreRequest);
|
||||
if ((domain.myserver == null) || (domain.myserver.backup === true)) { obj.app.get(url + 'backup.zip', handleBackupRequest); }
|
||||
if ((domain.myserver == null) || (domain.myserver.restore === true)) { obj.app.post(url + 'restoreserver.ashx', handleRestoreRequest); }
|
||||
obj.app.get(url + 'terms', handleTermsRequest);
|
||||
obj.app.get(url + 'xterm', handleXTermRequest);
|
||||
obj.app.post(url + 'login', handleLoginRequest);
|
||||
|
|
Loading…
Reference in New Issue