Added command handlers for updateAgents,report

Noah Zalev committed Jan 10, 2022 at 13:35 UTC 685f429509ed088901772915dad49111f8611329
1 file changed +160 -160
meshuser.js
+160 -160
@@ -4318,12 +4318,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4318
4319 break;
4320 }
4321 - case 'updateAgents': {
4322 - // Update agents for selected devices
4323 - if (common.validateStrArray(command.nodeids, 1) == false) break; // Check nodeids
4324 - for (var i in command.nodeids) { routeCommandToNode({ action: 'msg', type: 'console', nodeid: command.nodeids[i], value: 'agentupdate' }, MESHRIGHT_ADMIN, 0); }
4325 - break;
4326 - }
4321 case 'previousLogins': {
4322 // TODO: Make a better database call to get filtered data.
4323 if (command.userid == null) {
@@ -4659,158 +4653,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4653
4654 break;
4655 }
4662 - case 'report': {
4663 - // Report request. Validate the input
4664 - if (common.validateInt(command.type, 1, 2) == false) break; // Validate type
4665 - if (common.validateInt(command.groupBy, 1, 3) == false) break; // Validate groupBy: 1 = User, 2 = Device, 3 = Day
4666 - if ((typeof command.start != 'number') || (typeof command.end != 'number') || (command.start >= command.end)) break; // Validate start and end time
4667 - const manageAllDeviceGroups = ((user.siteadmin == 0xFFFFFFFF) && (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0));
4668 - if ((command.devGroup != null) && (manageAllDeviceGroups == false) && ((user.links == null) || (user.links[command.devGroup] == null))) break; // Asking for a device group that is not allowed
4669 -
4670 - const msgIdFilter = [5, 10, 11, 12, 122, 123, 124, 125, 126];
4671 -
4672 - if (command.type == 1) { // This is the remote session report. Shows desktop, terminal, files...
4673 - // If we are not user administrator on this site, only search for events with our own user id.
4674 - var ids = [user._id];
4675 - if ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0) {
4676 - if (command.devGroup != null) {
4677 - ids = [ user._id, command.devGroup ];
4678 - } else {
4679 - if (manageAllDeviceGroups) { ids = ['*']; } else if (user.links) { for (var i in user.links) { ids.push(i); } }
4680 - }
4681 - }
4682 -
4683 - // Get the events in the time range
4684 - // MySQL or MariaDB query will ignore the MsgID filter.
4685 - db.GetEventsTimeRange(ids, domain.id, msgIdFilter, new Date(command.start * 1000), new Date(command.end * 1000), function (err, docs) {
4686 - if (err != null) return;
4687 - var data = { groups: {} };
4688 - var guestNamePresent = false;
4689 -
4690 - // Columns
4691 - if (command.groupBy == 1) {
4692 - data.groupFormat = 'user';
4693 - data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'meshid', title: "devgroup", format: 'mesh' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
4694 - } else if (command.groupBy == 2) {
4695 - data.groupFormat = 'nodemesh';
4696 - data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'userid', title: "user", format: 'user' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
4697 - } else if (command.groupBy == 3) {
4698 - data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'meshid', title: "devgroup", format: 'mesh' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'userid', title: "user", format: 'user' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
4699 - }
4700 -
4701 - // Add traffic columns
4702 - if (command.showTraffic) {
4703 - data.columns.push({ id: 'bytesin', title: "bytesin", format: 'bytes', align: 'center', sumBy: 'protocol' });
4704 - data.columns.push({ id: 'bytesout', title: "bytesout", format: 'bytes', align: 'center', sumBy: 'protocol' });
4705 - }
4706 -
4707 - // Rows
4708 - for (var i in docs) {
4709 - // If MySQL or MariaDB query, we can't filter on MsgID, so we have to do it here.
4710 - if (msgIdFilter.indexOf(docs[i].msgid) < 0) continue;
4711 - if ((command.devGroup != null) && (docs[i].ids != null) && (docs[i].ids.indexOf(command.devGroup) == -1)) continue;
4712 -
4713 - var entry = { time: docs[i].time.valueOf() };
4714 -
4715 - // UserID
4716 - if (command.groupBy != 1) { entry.userid = docs[i].userid; }
4717 - if (command.groupBy != 2) { entry.nodeid = docs[i].nodeid; }
4718 - entry.protocol = docs[i].protocol;
4719 -
4720 - // Device Group
4721 - if (docs[i].ids != null) { for (var j in docs[i].ids) { if (docs[i].ids[j].startsWith('mesh/')) { entry.meshid = docs[i].ids[j]; } } }
4722 -
4723 - // Add traffic data
4724 - if (command.showTraffic) { entry.bytesin = docs[i].bytesin; entry.bytesout = docs[i].bytesout; }
4725 -
4726 - // Add guest name if present
4727 - if (docs[i].guestname != null) { entry.guestname = docs[i].guestname; guestNamePresent = true; }
4728 -
4729 - // Session length
4730 - if (((docs[i].msgid >= 10) && (docs[i].msgid <= 12)) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[3] == 'number')) { entry.length = docs[i].msgArgs[3]; }
4731 - else if ((docs[i].msgid >= 122) && (docs[i].msgid <= 126) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[0] == 'number')) { entry.length = docs[i].msgArgs[0]; }
4732 -
4733 - if (command.groupBy == 1) { // Add entry to per user
4734 - if (data.groups[docs[i].userid] == null) { data.groups[docs[i].userid] = { entries: [] }; }
4735 - data.groups[docs[i].userid].entries.push(entry);
4736 - } else if (command.groupBy == 2) { // Add entry to per mesh+device
4737 - if (entry.meshid != null) {
4738 - var k = docs[i].nodeid + '/' + entry.meshid;
4739 - if (data.groups[k] == null) { data.groups[k] = { entries: [] }; }
4740 - data.groups[k].entries.push(entry);
4741 - } else {
4742 - if (data.groups[docs[i].nodeid] == null) { data.groups[docs[i].nodeid] = { entries: [] }; }
4743 - data.groups[docs[i].nodeid].entries.push(entry);
4744 - }
4745 - } else if (command.groupBy == 3) { // Add entry to per day
4746 - var day;
4747 - if ((typeof command.l == 'string') && (typeof command.tz == 'string')) {
4748 - day = new Date(docs[i].time).toLocaleDateString(command.l, { timeZone: command.tz });
4749 - } else {
4750 - day = docs[i].time; // TODO
4751 - }
4752 - if (data.groups[day] == null) { data.groups[day] = { entries: [] }; }
4753 - data.groups[day].entries.push(entry);
4754 - }
4755 -
4756 - }
4757 -
4758 - // Remove guest column if not needed
4759 - if (guestNamePresent == false) {
4760 - if ((command.groupBy == 1) || (command.groupBy == 3)) {
4761 - data.columns.splice(3, 1);
4762 - } else if (command.groupBy == 2) {
4763 - data.columns.splice(2, 1);
4764 - }
4765 - }
4766 -
4767 - try { ws.send(JSON.stringify({ action: 'report', data: data })); } catch (ex) { }
4768 - });
4769 - }
4770 -
4771 - if (command.type == 2) { // This is the user traffic usage report.
4772 - // If we are not user administrator on this site, only search for events with our own user id.
4773 - var ids = [user._id]; // If we are nto user administrator, only count our own traffic.
4774 - if ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0) { ids = ['*']; } // If user administrator, count traffic of all users.
4775 -
4776 - // Get the events in the time range
4777 - // MySQL or MariaDB query will ignore the MsgID filter.
4778 - db.GetEventsTimeRange(ids, domain.id, msgIdFilter, new Date(command.start * 1000), new Date(command.end * 1000), function (err, docs) {
4779 - if (err != null) return;
4780 - var data = { groups: { 0: { entries: [] } } };
4781 - data.columns = [{ id: 'userid', title: "user", format: 'user' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: true }, { id: 'bytesin', title: "bytesin", format: 'bytes', align: 'center', sumBy: true }, { id: 'bytesout', title: "bytesout", format: 'bytes', align: 'center', sumBy: true }];
4782 - var userEntries = {};
4783 -
4784 - // Sum all entry logs for each user
4785 - for (var i in docs) {
4786 - // If MySQL or MariaDB query, we can't filter on MsgID, so we have to do it here.
4787 - if (msgIdFilter.indexOf(docs[i].msgid) < 0) continue;
4788 - if ((command.devGroup != null) && (docs[i].ids != null) && (docs[i].ids.indexOf(command.devGroup) == -1)) continue;
4789 -
4790 - // Fetch or create the user entry
4791 - var userEntry = userEntries[docs[i].userid];
4792 - if (userEntry == null) { userEntry = { userid: docs[i].userid, length: 0, bytesin: 0, bytesout: 0}; }
4793 - if (docs[i].bytesin) { userEntry.bytesin += docs[i].bytesin; }
4794 - if (docs[i].bytesout) { userEntry.bytesout += docs[i].bytesout; }
4795 -
4796 - // Session length
4797 - if (((docs[i].msgid >= 10) && (docs[i].msgid <= 12)) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[3] == 'number')) { userEntry.length += docs[i].msgArgs[3]; }
4798 - else if ((docs[i].msgid >= 122) && (docs[i].msgid <= 126) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[0] == 'number')) { userEntry.length += docs[i].msgArgs[0]; }
4799 -
4800 - // Set the user entry
4801 - userEntries[docs[i].userid] = userEntry;
4802 - }
4803 -
4804 - var userEntries2 = [];
4805 - for (var i in userEntries) { userEntries2.push(userEntries[i]); }
4806 - data.groups[0].entries = userEntries2;
4807 -
4808 - try { ws.send(JSON.stringify({ action: 'report', data: data })); } catch (ex) { }
4809 - });
4810 - }
4811 -
4812 - break;
4813 - }
4656 case 'endDesktopMultiplex': {
4657 var err = null, xuser = null;
4658 try {
@@ -4879,6 +4721,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4721 'print': serverCommandPrint,
4722 'removePhone': serverCommandremovePhone,
4723 'removeuserfromusergroup': serverCommandRemoveUserFromUserGroup,
4724 + 'report': serverCommandReport,
4725 'serverclearerrorlog': serverCommandServerClearErrorLog,
4726 'serverconsole': serverCommandServerConsole,
4727 'servererrors': serverCommandServerErrors,
@@ -4889,7 +4732,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4732 'setClip': serverCommandSetClip,
4733 'smsuser': serverCommandSmsUser,
4734 'trafficdelta': serverCommandTrafficDelta,
4892 - 'trafficstats': serverCommandtrafficStats,
4735 + 'trafficstats': serverCommandTrafficStats,
4736 + 'updateAgents': serverCommandUpdateAgents,
4737 'updateUserImage': serverCommandUpdateUserImage,
4738 'urlargs': serverCommandUrlArgs,
4739 'users': serverCommandUsers,
@@ -5956,6 +5800,156 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5800 if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removeuserfromusergroup', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
5801 }
5802
5803 + function serverCommandReport(command) {
5804 + if (common.validateInt(command.type, 1, 2) == false) return; // Validate type
5805 + if (common.validateInt(command.groupBy, 1, 3) == false) return; // Validate groupBy: 1 = User, 2 = Device, 3 = Day
5806 + if ((typeof command.start != 'number') || (typeof command.end != 'number') || (command.start >= command.end)) return; // Validate start and end time
5807 + const manageAllDeviceGroups = ((user.siteadmin == 0xFFFFFFFF) && (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0));
5808 + if ((command.devGroup != null) && (manageAllDeviceGroups == false) && ((user.links == null) || (user.links[command.devGroup] == null))) return; // Asking for a device group that is not allowed
5809 +
5810 + const msgIdFilter = [5, 10, 11, 12, 122, 123, 124, 125, 126];
5811 +
5812 + if (command.type == 1) { // This is the remote session report. Shows desktop, terminal, files...
5813 + // If we are not user administrator on this site, only search for events with our own user id.
5814 + var ids = [user._id];
5815 + if ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0) {
5816 + if (command.devGroup != null) {
5817 + ids = [ user._id, command.devGroup ];
5818 + } else {
5819 + if (manageAllDeviceGroups) { ids = ['*']; } else if (user.links) { for (var i in user.links) { ids.push(i); } }
5820 + }
5821 + }
5822 +
5823 + // Get the events in the time range
5824 + // MySQL or MariaDB query will ignore the MsgID filter.
5825 + db.GetEventsTimeRange(ids, domain.id, msgIdFilter, new Date(command.start * 1000), new Date(command.end * 1000), function (err, docs) {
5826 + if (err != null) return;
5827 + var data = { groups: {} };
5828 + var guestNamePresent = false;
5829 +
5830 + // Columns
5831 + if (command.groupBy == 1) {
5832 + data.groupFormat = 'user';
5833 + data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'meshid', title: "devgroup", format: 'mesh' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5834 + } else if (command.groupBy == 2) {
5835 + data.groupFormat = 'nodemesh';
5836 + data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'userid', title: "user", format: 'user' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5837 + } else if (command.groupBy == 3) {
5838 + data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'nodeid', title: "device", format: 'node' }, { id: 'meshid', title: "devgroup", format: 'mesh' }, { id: 'guestname', title: "guest", align: 'center' }, { id: 'userid', title: "user", format: 'user' }, { id: 'protocol', title: "session", format: 'protocol', align: 'center' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: 'protocol' } ];
5839 + }
5840 +
5841 + // Add traffic columns
5842 + if (command.showTraffic) {
5843 + data.columns.push({ id: 'bytesin', title: "bytesin", format: 'bytes', align: 'center', sumBy: 'protocol' });
5844 + data.columns.push({ id: 'bytesout', title: "bytesout", format: 'bytes', align: 'center', sumBy: 'protocol' });
5845 + }
5846 +
5847 + // Rows
5848 + for (var i in docs) {
5849 + // If MySQL or MariaDB query, we can't filter on MsgID, so we have to do it here.
5850 + if (msgIdFilter.indexOf(docs[i].msgid) < 0) continue;
5851 + if ((command.devGroup != null) && (docs[i].ids != null) && (docs[i].ids.indexOf(command.devGroup) == -1)) continue;
5852 +
5853 + var entry = { time: docs[i].time.valueOf() };
5854 +
5855 + // UserID
5856 + if (command.groupBy != 1) { entry.userid = docs[i].userid; }
5857 + if (command.groupBy != 2) { entry.nodeid = docs[i].nodeid; }
5858 + entry.protocol = docs[i].protocol;
5859 +
5860 + // Device Group
5861 + if (docs[i].ids != null) { for (var j in docs[i].ids) { if (docs[i].ids[j].startsWith('mesh/')) { entry.meshid = docs[i].ids[j]; } } }
5862 +
5863 + // Add traffic data
5864 + if (command.showTraffic) { entry.bytesin = docs[i].bytesin; entry.bytesout = docs[i].bytesout; }
5865 +
5866 + // Add guest name if present
5867 + if (docs[i].guestname != null) { entry.guestname = docs[i].guestname; guestNamePresent = true; }
5868 +
5869 + // Session length
5870 + if (((docs[i].msgid >= 10) && (docs[i].msgid <= 12)) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[3] == 'number')) { entry.length = docs[i].msgArgs[3]; }
5871 + else if ((docs[i].msgid >= 122) && (docs[i].msgid <= 126) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[0] == 'number')) { entry.length = docs[i].msgArgs[0]; }
5872 +
5873 + if (command.groupBy == 1) { // Add entry to per user
5874 + if (data.groups[docs[i].userid] == null) { data.groups[docs[i].userid] = { entries: [] }; }
5875 + data.groups[docs[i].userid].entries.push(entry);
5876 + } else if (command.groupBy == 2) { // Add entry to per mesh+device
5877 + if (entry.meshid != null) {
5878 + var k = docs[i].nodeid + '/' + entry.meshid;
5879 + if (data.groups[k] == null) { data.groups[k] = { entries: [] }; }
5880 + data.groups[k].entries.push(entry);
5881 + } else {
5882 + if (data.groups[docs[i].nodeid] == null) { data.groups[docs[i].nodeid] = { entries: [] }; }
5883 + data.groups[docs[i].nodeid].entries.push(entry);
5884 + }
5885 + } else if (command.groupBy == 3) { // Add entry to per day
5886 + var day;
5887 + if ((typeof command.l == 'string') && (typeof command.tz == 'string')) {
5888 + day = new Date(docs[i].time).toLocaleDateString(command.l, { timeZone: command.tz });
5889 + } else {
5890 + day = docs[i].time; // TODO
5891 + }
5892 + if (data.groups[day] == null) { data.groups[day] = { entries: [] }; }
5893 + data.groups[day].entries.push(entry);
5894 + }
5895 +
5896 + }
5897 +
5898 + // Remove guest column if not needed
5899 + if (guestNamePresent == false) {
5900 + if ((command.groupBy == 1) || (command.groupBy == 3)) {
5901 + data.columns.splice(3, 1);
5902 + } else if (command.groupBy == 2) {
5903 + data.columns.splice(2, 1);
5904 + }
5905 + }
5906 +
5907 + try { ws.send(JSON.stringify({ action: 'report', data: data })); } catch (ex) { }
5908 + });
5909 + }
5910 +
5911 + if (command.type == 2) { // This is the user traffic usage report.
5912 + // If we are not user administrator on this site, only search for events with our own user id.
5913 + var ids = [user._id]; // If we are nto user administrator, only count our own traffic.
5914 + if ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0) { ids = ['*']; } // If user administrator, count traffic of all users.
5915 +
5916 + // Get the events in the time range
5917 + // MySQL or MariaDB query will ignore the MsgID filter.
5918 + db.GetEventsTimeRange(ids, domain.id, msgIdFilter, new Date(command.start * 1000), new Date(command.end * 1000), function (err, docs) {
5919 + if (err != null) return;
5920 + var data = { groups: { 0: { entries: [] } } };
5921 + data.columns = [{ id: 'userid', title: "user", format: 'user' }, { id: 'length', title: "length", format: 'seconds', align: 'center', sumBy: true }, { id: 'bytesin', title: "bytesin", format: 'bytes', align: 'center', sumBy: true }, { id: 'bytesout', title: "bytesout", format: 'bytes', align: 'center', sumBy: true }];
5922 + var userEntries = {};
5923 +
5924 + // Sum all entry logs for each user
5925 + for (var i in docs) {
5926 + // If MySQL or MariaDB query, we can't filter on MsgID, so we have to do it here.
5927 + if (msgIdFilter.indexOf(docs[i].msgid) < 0) continue;
5928 + if ((command.devGroup != null) && (docs[i].ids != null) && (docs[i].ids.indexOf(command.devGroup) == -1)) continue;
5929 +
5930 + // Fetch or create the user entry
5931 + var userEntry = userEntries[docs[i].userid];
5932 + if (userEntry == null) { userEntry = { userid: docs[i].userid, length: 0, bytesin: 0, bytesout: 0}; }
5933 + if (docs[i].bytesin) { userEntry.bytesin += docs[i].bytesin; }
5934 + if (docs[i].bytesout) { userEntry.bytesout += docs[i].bytesout; }
5935 +
5936 + // Session length
5937 + if (((docs[i].msgid >= 10) && (docs[i].msgid <= 12)) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[3] == 'number')) { userEntry.length += docs[i].msgArgs[3]; }
5938 + else if ((docs[i].msgid >= 122) && (docs[i].msgid <= 126) && (docs[i].msgArgs != null) && (typeof docs[i].msgArgs == 'object') && (typeof docs[i].msgArgs[0] == 'number')) { userEntry.length += docs[i].msgArgs[0]; }
5939 +
5940 + // Set the user entry
5941 + userEntries[docs[i].userid] = userEntry;
5942 + }
5943 +
5944 + var userEntries2 = [];
5945 + for (var i in userEntries) { userEntries2.push(userEntries[i]); }
5946 + data.groups[0].entries = userEntries2;
5947 +
5948 + try { ws.send(JSON.stringify({ action: 'report', data: data })); } catch (ex) { }
5949 + });
5950 + }
5951 + }
5952 +
5953 function serverCommandServerClearErrorLog(command) {
5954 // Clear the server error log if user has site update permissions
5955 if (userHasSiteUpdate()) { fs.unlink(parent.parent.getConfigFilePath('mesherrors.txt'), function (err) { }); }
@@ -6076,10 +6070,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
6070 try { ws.send(JSON.stringify({ action: 'trafficdelta', delta: stats.delta })); } catch (ex) { }
6071 }
6072
6079 - function serverCommandtrafficStats(command) {
6073 + function serverCommandTrafficStats(command) {
6074 try { ws.send(JSON.stringify({ action: 'trafficstats', stats: parent.getTrafficStats() })); } catch (ex) { }
6075 }
6076
6077 + function serverCommandUpdateAgents(command) {
6078 + // Update agents for selected devices
6079 + if (common.validateStrArray(command.nodeids, 1) == false) break; // Check nodeids
6080 + for (var i in command.nodeids) { routeCommandToNode({ action: 'msg', type: 'console', nodeid: command.nodeids[i], value: 'agentupdate' }, MESHRIGHT_ADMIN, 0); }
6081 + }
6082 +
6083 function serverCommandUpdateUserImage(command) {
6084 if (req.session.loginToken != null) return; // Do not allow this command when logged in using a login token
6085