mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Improved scalability and migration support from MeshCentral1
This commit is contained in:
		
							parent
							
								
									81ccbae15c
								
							
						
					
					
						commit
						bff85f428a
					
				
					 8 changed files with 123 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -112,7 +112,7 @@ module.exports.CreateAmtScanner = function (parent) {
 | 
			
		|||
    obj.performScan = function () {
 | 
			
		||||
        //console.log('performScan');
 | 
			
		||||
        if (obj.action == false) { return false; }
 | 
			
		||||
        obj.parent.db.getLocalAmtNodes(function (err, docs) {
 | 
			
		||||
        obj.parent.db.getLocalAmtNodes(10, function (err, docs) { // TODO: handler more than 10 computer scan at the same time.
 | 
			
		||||
            for (var i in obj.scanTable) { obj.scanTable[i].present = false; }
 | 
			
		||||
            if (err == null && docs.length > 0) {
 | 
			
		||||
                for (var i in docs) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								db.js
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								db.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -109,7 +109,7 @@ module.exports.CreateDB = function (parent) {
 | 
			
		|||
    obj.dispose = function () { for (var x in obj) { if (obj[x].close) { obj[x].close(); } delete obj[x]; } }
 | 
			
		||||
    obj.clearOldEntries = function (type, days, domain) { var cutoff = Date.now() - (1000 * 60 * 60 * 24 * days); obj.file.remove({ type: type, time: { $lt: cutoff } }, { multi: true }); }
 | 
			
		||||
    obj.getPowerTimeline = function (nodeid, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }).exec(func); } else { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }, func); } }
 | 
			
		||||
    obj.getLocalAmtNodes = function (func) { obj.file.find({ type: 'node', host: { $exists: true, $ne: null }, intelamt: { $exists: true } }, func); }
 | 
			
		||||
    obj.getLocalAmtNodes = function (limit, func) { obj.file.find({ type: 'node', host: { $exists: true, $ne: null }, intelamt: { $exists: true } }).limit(limit, func); }
 | 
			
		||||
    obj.getAmtUuidNode = function (meshid, uuid, func) { obj.file.find({ type: 'node', meshid: meshid, 'intelamt.uuid': uuid }, func); }
 | 
			
		||||
 | 
			
		||||
    // This is used to rate limit a number of operation per day. Returns a startValue each new days, but you can substract it and save the value in the db.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
        try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
 | 
			
		||||
        
 | 
			
		||||
        // Check for invalid arguments
 | 
			
		||||
        var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen'];
 | 
			
		||||
        var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin'];
 | 
			
		||||
        for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
 | 
			
		||||
        if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
 | 
			
		||||
        for (var i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence.
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
    obj.StartEx = function () {
 | 
			
		||||
        //var wincmd = require('node-windows');
 | 
			
		||||
        //wincmd.list(function (svc) { console.log(svc); }, true);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        // Write the server state
 | 
			
		||||
        obj.updateServerState('state', 'starting');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -265,12 +265,14 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
            if (obj.args.dbimport) {
 | 
			
		||||
                // Import the entire database from a JSON file
 | 
			
		||||
                if (obj.args.dbimport == true) { obj.args.dbimport = obj.getConfigFilePath('meshcentral.db.json'); }
 | 
			
		||||
                var json = null, json2 = "";
 | 
			
		||||
                try { json = obj.fs.readFileSync(obj.args.dbimport); } catch (e) { console.log('Invalid JSON file: ' + obj.args.dbimport + '.'); process.exit(); }
 | 
			
		||||
                for (var i = 0; i < json.length; i++) { if (json[i] >= 32) json2 += String.fromCharCode(json[i]); } // Remove all bad chars
 | 
			
		||||
                var json = null, json2 = "", badCharCount = 0;
 | 
			
		||||
                try { json = obj.fs.readFileSync(obj.args.dbimport, { encoding: 'utf8' }); } catch (e) { console.log('Invalid JSON file: ' + obj.args.dbimport + '.'); process.exit(); }
 | 
			
		||||
                for (var i = 0; i < json.length; i++) { if (json.charCodeAt(i) >= 32) { json2 += json[i]; } else { var tt = json.charCodeAt(i); if (tt != 10 && tt != 13) { badCharCount++; } } } // Remove all bad chars
 | 
			
		||||
                if (badCharCount > 0) { console.log(badCharCount + ' invalid character(s) where removed.'); }
 | 
			
		||||
                try { json = JSON.parse(json2); } catch (e) { console.log('Invalid JSON format: ' + obj.args.dbimport + ': ' + e); process.exit(); }
 | 
			
		||||
                if ((json == null) || (typeof json.length != 'number') || (json.length < 1)) { console.log('Invalid JSON format: ' + obj.args.dbimport + '.'); }
 | 
			
		||||
                for (var i in json) { if ((json[i].type == "mesh") && (json[i].links != null)) { for (var j in json[i].links) { var esc = obj.common.escapeFieldName(j); if (esc !== j) { json[i].links[esc] = json[i].links[j]; delete json[i].links[j]; } } } } // Escape MongoDB invalid field chars
 | 
			
		||||
                //for (var i in json) { if ((json[i].type == "node") && (json[i].host != null)) { json[i].rname = json[i].host; delete json[i].host; } } // DEBUG: Change host to rname
 | 
			
		||||
                obj.db.RemoveAll(function () { obj.db.InsertMany(json, function (err) { if (err != null) { console.log(err); } else { console.log('Imported ' + json.length + ' objects(s) from ' + obj.args.dbimport + '.'); } process.exit(); }); });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -279,6 +281,42 @@ function CreateMeshCentralServer(config, args) {
 | 
			
		|||
            obj.db.clearOldEntries('event', 30); // Clear all event entires that are older than 30 days.
 | 
			
		||||
            obj.db.clearOldEntries('power', 10); // Clear all event entires that are older than 10 days. If a node is connected longer than 10 days, current power state will be used for everything.
 | 
			
		||||
 | 
			
		||||
            // Setup a site administrator
 | 
			
		||||
            if ((obj.args.admin) && (typeof obj.args.admin == 'string')) {
 | 
			
		||||
                var adminname = obj.args.admin.split('/');
 | 
			
		||||
                if (adminname.length == 1) { adminname = 'user//' + adminname[0]; }
 | 
			
		||||
                else if (adminname.length == 2) { adminname = 'user/' + adminname[0] + '/' + adminname[1]; }
 | 
			
		||||
                else { console.log('Invalid administrator name.'); process.exit(); return; }
 | 
			
		||||
                obj.db.Get(adminname, function (err, user) {
 | 
			
		||||
                    if (user.length != 1) { console.log('Invalid user name.'); process.exit(); return; }
 | 
			
		||||
                    user[0].siteadmin = 0xFFFFFFFF;
 | 
			
		||||
                    obj.db.Set(user[0], function () {
 | 
			
		||||
                        if (user[0].domain == '') { console.log('User ' + user[0].name + ' set to site administrator.'); } else { console.log('User ' + user[0].name + ' of domain ' + user[0].domain + ' set to site administrator.'); }
 | 
			
		||||
                        process.exit();
 | 
			
		||||
                        return;
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Remove a site administrator
 | 
			
		||||
            if ((obj.args.unadmin) && (typeof obj.args.unadmin == 'string')) {
 | 
			
		||||
                var adminname = obj.args.unadmin.split('/');
 | 
			
		||||
                if (adminname.length == 1) { adminname = 'user//' + adminname[0]; }
 | 
			
		||||
                else if (adminname.length == 2) { adminname = 'user/' + adminname[0] + '/' + adminname[1]; }
 | 
			
		||||
                else { console.log('Invalid administrator name.'); process.exit(); return; }
 | 
			
		||||
                obj.db.Get(adminname, function (err, user) {
 | 
			
		||||
                    if (user.length != 1) { console.log('Invalid user name.'); process.exit(); return; }
 | 
			
		||||
                    if (user[0].siteadmin) { delete user[0].siteadmin; }
 | 
			
		||||
                    obj.db.Set(user[0], function () {
 | 
			
		||||
                        if (user[0].domain == '') { console.log('User ' + user[0].name + ' is not a site administrator.'); } else { console.log('User ' + user[0].name + ' of domain ' + user[0].domain + ' is not a site administrator.'); }
 | 
			
		||||
                        process.exit();
 | 
			
		||||
                        return;
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Perform other database cleanup
 | 
			
		||||
            obj.db.cleanup();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -717,6 +717,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                        if (command.amttls == '0') { command.amttls = 0; } else if (command.amttls == '1') { command.amttls = 1; } // Check TLS flag
 | 
			
		||||
                        if ((command.amttls != 1) && (command.amttls != 0)) break;
 | 
			
		||||
 | 
			
		||||
                        // If we are in WAN-only mode, hostname is not used
 | 
			
		||||
                        if ((obj.parent.parent.args.wanonly == true) && (command.hostname)) { delete command.hostname; }
 | 
			
		||||
 | 
			
		||||
                        // Get the mesh
 | 
			
		||||
                        var mesh = obj.parent.meshes[command.meshid];
 | 
			
		||||
                        if (mesh) {
 | 
			
		||||
| 
						 | 
				
			
			@ -972,6 +975,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
 | 
			
		|||
                                var changes = [], change = 0, event = { etype: 'node', username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id };
 | 
			
		||||
                                event.msg = ": ";
 | 
			
		||||
 | 
			
		||||
                                // If we are in WAN-only mode, host is not used
 | 
			
		||||
                                if ((obj.parent.parent.args.wanonly == true) && (command.host)) { delete command.host; }
 | 
			
		||||
 | 
			
		||||
                                // Look for a change
 | 
			
		||||
                                if (command.icon && (command.icon != node.icon)) { change = 1; node.icon = command.icon; changes.push('icon'); }
 | 
			
		||||
                                if (command.name && (command.name != node.name)) { change = 1; node.name = command.name; changes.push('name'); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,4 +531,10 @@ a {
 | 
			
		|||
 | 
			
		||||
.deskToolsBar:hover {
 | 
			
		||||
    background-color: #EFE8B6;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.userTableHeader {
 | 
			
		||||
    border-bottom: 1pt solid lightgray;
 | 
			
		||||
    padding-top: 4px;
 | 
			
		||||
    padding-bottom: 4px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,8 @@
 | 
			
		|||
    "AllowLoginToken": true,
 | 
			
		||||
    "AllowFraming": true,
 | 
			
		||||
    "WebRTC": false,
 | 
			
		||||
    "ClickOnce": false
 | 
			
		||||
    "ClickOnce": false,
 | 
			
		||||
    "UserAllowedIP" : "127.0.0.1,::1,192.168.0.100"
 | 
			
		||||
  },
 | 
			
		||||
  "_domains": {
 | 
			
		||||
    "": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -246,7 +246,10 @@
 | 
			
		|||
                    <div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
 | 
			
		||||
                        <div class=style7 style=width:16px;height:100%;float:left> </div>
 | 
			
		||||
                        <div class=h1 style=height:100%;float:left> </div>
 | 
			
		||||
                        <div class=style14 style=height:100%;float:left>  <input type=button onclick=showCreateNewAccountDialog() value="New Account..." /> </div>
 | 
			
		||||
                        <div class=style14 style=height:100%;float:left>  
 | 
			
		||||
                            <input type=button onclick=showCreateNewAccountDialog() value="New Account..." /> 
 | 
			
		||||
                            <input id=UserSearchInput type=text style=width:120px placeholder=Search onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) /> 
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class=auto-style1 style="height:100%;float:right">
 | 
			
		||||
                            <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div>
 | 
			
		||||
                            <div class=h2 style="height:100%;float:right"> </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -748,6 +751,7 @@
 | 
			
		|||
        var sort = 0;
 | 
			
		||||
        var searchFocus = 0;
 | 
			
		||||
        var mapSearchFocus = 0;
 | 
			
		||||
        var userSearchFocus = 0;
 | 
			
		||||
        var consoleFocus = 0;
 | 
			
		||||
        var showRealNames = false;
 | 
			
		||||
        var meshserver = null;
 | 
			
		||||
| 
						 | 
				
			
			@ -1412,6 +1416,18 @@
 | 
			
		|||
            if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeys(e);
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeys(e);
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 15) return agentConsoleHandleKeys(e);
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 4) {
 | 
			
		||||
                if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
 | 
			
		||||
                var processed = 0;
 | 
			
		||||
                if (e.key) {
 | 
			
		||||
                    if (e.key.length === 1 && userSearchFocus == 0) { Q('UserSearchInput').value = ((Q('UserSearchInput').value + e.key)); processed = 1; }
 | 
			
		||||
                    if (e.keyCode == 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = x.substring(0, x.length - 1); processed = 1; }
 | 
			
		||||
                    if (e.keyCode == 27) { Q('UserSearchInput').value = ''; processed = 1; }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (e.charCode != 0 && userSearchFocus == 0) { Q('UserSearchInput').value = ((Q('UserSearchInput').value + String.fromCharCode(e.charCode))); processed = 1; }
 | 
			
		||||
                }
 | 
			
		||||
                if (processed > 0) { if (processed == 1) { onUserSearchInputChanged(); } return haltEvent(e); }
 | 
			
		||||
            }
 | 
			
		||||
            if (xxdialogMode || xxcurrentView != 1) return;
 | 
			
		||||
            if (e.ctrlKey == true && e.charCode == 96) {
 | 
			
		||||
                showRealNames = !showRealNames;
 | 
			
		||||
| 
						 | 
				
			
			@ -1449,6 +1465,11 @@
 | 
			
		|||
            if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); }
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 15) { return agentConsoleHandleKeys(e); }
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 4) { 
 | 
			
		||||
                if (e.keyCode === 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = (x.substring(0, x.length - 1)); processed = 1; }
 | 
			
		||||
                if (e.keyCode === 27) { Q('UserSearchInput').value = ''; processed = 1; }
 | 
			
		||||
                if (processed > 0) { if (processed == 1) { onSearchInputChanged(); } return haltEvent(e); }
 | 
			
		||||
            }
 | 
			
		||||
            if (xxdialogMode || xxcurrentView != 1 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
 | 
			
		||||
            var processed = 0;
 | 
			
		||||
            if (Q('viewselect').value < 3) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1466,6 +1487,7 @@
 | 
			
		|||
            if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeyUp(e);
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeyUp(e);
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { p13folderup(9999); haltEvent(e); return false; } // F5 Refresh on files
 | 
			
		||||
            if (!xxdialogMode && xxcurrentView == 4) { if ((e.keyCode === 8 && searchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
 | 
			
		||||
            if (xxdialogMode && e.keyCode == 27) { dialogclose(0); }
 | 
			
		||||
            if (xxdialogMode || xxcurrentView != 0 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
 | 
			
		||||
            if (Q('viewselect').value < 3) { if ((e.keyCode === 8 && searchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
 | 
			
		||||
| 
						 | 
				
			
			@ -2110,6 +2132,7 @@
 | 
			
		|||
        function deviceHostSort(a, b) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; }
 | 
			
		||||
        function onSearchFocus(x) { searchFocus = x; }
 | 
			
		||||
        function onMapSearchFocus(x) { mapSearchFocus = x; }
 | 
			
		||||
        function onUserSearchFocus(x) { userSearchFocus = x; }
 | 
			
		||||
        function onConsoleFocus(x) { consoleFocus = x; }
 | 
			
		||||
 | 
			
		||||
        function onSearchInputChanged() {
 | 
			
		||||
| 
						 | 
				
			
			@ -2838,10 +2861,10 @@
 | 
			
		|||
                x += addDeviceAttribute('<span title="The name of the administrative group this computer belong to">Mesh</span>', '<a  title="The name of the group this computer belong to" onclick=gotoMesh("' + node.meshid + '") style=cursor:pointer>' + EscapeHtml(meshes[node.meshid].name) + '</a>');
 | 
			
		||||
 | 
			
		||||
                // Attribute: Name
 | 
			
		||||
                if (node.rname != null) { x += addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>', '<span title="The name of this computer as set in the operating system">' + EscapeHtml(node.rname) + '</span>'); }
 | 
			
		||||
                if ((node.rname != null) && (node.name != node.rname)) { x += addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>', '<span title="The name of this computer as set in the operating system">' + EscapeHtml(node.rname) + '</span>'); }
 | 
			
		||||
 | 
			
		||||
                // Attribute: Host
 | 
			
		||||
                if ((mesh.mtype == 1) || (node.name != node.host)) {
 | 
			
		||||
                if ((features & 1) == 0) { // If not WAN-only, local hostname is in use
 | 
			
		||||
                    if ((meshrights & 4) != 0) {
 | 
			
		||||
                        if (node.host) {
 | 
			
		||||
                            x += addDeviceAttribute('Hostname', '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
 | 
			
		||||
| 
						 | 
				
			
			@ -5126,19 +5149,27 @@
 | 
			
		|||
            if ((users == null) || ((features & 4) != 0)) { QH('p3users', ''); return; }
 | 
			
		||||
 | 
			
		||||
            // Sort the list of user id's
 | 
			
		||||
            var sortedUserIds = [];
 | 
			
		||||
            var sortedUserIds = [], maxUsers = 100, hiddenUsers = 0;
 | 
			
		||||
            for (var i in users) { sortedUserIds.push(i); }
 | 
			
		||||
            sortedUserIds.sort();
 | 
			
		||||
 | 
			
		||||
            // Get search
 | 
			
		||||
            var userSearch = Q('UserSearchInput').value.toLowerCase();
 | 
			
		||||
 | 
			
		||||
            // Display the users using the sorted list
 | 
			
		||||
            var x = '<table style=width:100% cellpadding=0 cellspacing=0>', addHeader = true;
 | 
			
		||||
            // Online users
 | 
			
		||||
            for (var i in sortedUserIds) {
 | 
			
		||||
                var user = users[sortedUserIds[i]], sessions = null;
 | 
			
		||||
                if (wssessions != null) { sessions = wssessions[user._id]; }
 | 
			
		||||
                if (sessions != null) {
 | 
			
		||||
                    if (addHeader) { x += '<tr><td style="border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px">Online Users</td></tr>'; addHeader = false; }
 | 
			
		||||
                    x += addUserHtml(user, sessions);
 | 
			
		||||
                if ((sessions != null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) {
 | 
			
		||||
                    if (maxUsers > 0) {
 | 
			
		||||
                        if (addHeader) { x += '<tr><td class=userTableHeader>Online Users'; addHeader = false; }
 | 
			
		||||
                        x += addUserHtml(user, sessions);
 | 
			
		||||
                        maxUsers--; 
 | 
			
		||||
                    } else {
 | 
			
		||||
                        hiddenUsers++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            addHeader = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -5146,12 +5177,19 @@
 | 
			
		|||
            for (var i in sortedUserIds) {
 | 
			
		||||
                var user = users[sortedUserIds[i]], sessions = null;
 | 
			
		||||
                if (wssessions != null) { sessions = wssessions[user._id]; }
 | 
			
		||||
                if (sessions == null) {
 | 
			
		||||
                    if (addHeader) { x += '<tr><td style="border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px">Offline Users</td></tr>'; addHeader = false; }
 | 
			
		||||
                    x += addUserHtml(user, sessions);
 | 
			
		||||
                if ((sessions == null) && (user.name.toLowerCase().indexOf(userSearch) >= 0)) {
 | 
			
		||||
                    if (maxUsers > 0) {
 | 
			
		||||
                        if (addHeader) { x += '<tr><td class=userTableHeader>Offline Users'; addHeader = false; }
 | 
			
		||||
                        x += addUserHtml(user, sessions);
 | 
			
		||||
                        maxUsers--; 
 | 
			
		||||
                    } else {
 | 
			
		||||
                        hiddenUsers++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            x += '</table>';
 | 
			
		||||
            if (hiddenUsers == 1) { x += '<br />1 more user not shown, use search box to look for users...<br />'; }
 | 
			
		||||
            else if (hiddenUsers > 1) { x += '<br />' + hiddenUsers + ' more users not shown, use search box to look for users...<br />'; }
 | 
			
		||||
            QH('p3users', x);
 | 
			
		||||
 | 
			
		||||
            // Update current user panel if needed
 | 
			
		||||
| 
						 | 
				
			
			@ -5191,7 +5229,7 @@
 | 
			
		|||
            x += '<div class=bar style=height:24px;width:100%;font-size:medium>';
 | 
			
		||||
            x += '<div style=float:left;height:24px;width:24px;background-color:white><div class="' + icon + gray + '" style=width:16px;margin-top:4px;margin-left:2px;height:16px></div></div>';
 | 
			
		||||
            x += '<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>';
 | 
			
		||||
            x += '<div><span>' + username + '</span><span style=float:right>' + msg + '</span></div></div></td></tr>';
 | 
			
		||||
            x += '<div><span>' + username + '</span><span style=float:right>' + msg + '</span></div></div>'; // </td></tr>
 | 
			
		||||
            return x;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5294,6 +5332,8 @@
 | 
			
		|||
            meshserver.send(x);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function onUserSearchInputChanged() { updateUsers(); }
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // MY USERS GENERAL
 | 
			
		||||
        //
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -316,6 +316,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
                    if (req.session.passhint) { delete req.session.passhint; }
 | 
			
		||||
                    if (req.body.viewmode) { req.session.viewmode = req.body.viewmode; }
 | 
			
		||||
                    if (req.body.host) {
 | 
			
		||||
                        // TODO: This is a terrible search!!! FIX THIS.
 | 
			
		||||
                        /*
 | 
			
		||||
                        obj.db.GetAllType('node', function (err, docs) {
 | 
			
		||||
                            for (var i = 0; i < docs.length; i++) {
 | 
			
		||||
                                if (docs[i].name == req.body.host) {
 | 
			
		||||
| 
						 | 
				
			
			@ -327,6 +329,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
                            // This redirect happens after finding node is completed
 | 
			
		||||
                            res.redirect(domain.url);
 | 
			
		||||
                        });
 | 
			
		||||
                        */
 | 
			
		||||
                    } else {
 | 
			
		||||
                        res.redirect(domain.url);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -722,6 +725,15 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
 | 
			
		|||
            if ((parent.config != null) && (parent.config.settings != null) && (parent.config.settings.allowframing == true)) { features += 32; } // Allow site within iframe
 | 
			
		||||
            var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
 | 
			
		||||
            res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer });
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
            var xoptions = { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer };
 | 
			
		||||
            var xpath = obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login');
 | 
			
		||||
            console.log('Render...');
 | 
			
		||||
            res.render(xpath, xoptions, function (err, html) {
 | 
			
		||||
                console.log(err, html);
 | 
			
		||||
            });
 | 
			
		||||
            */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue