diff --git a/db.js b/db.js index c5704534..0c552139 100644 --- a/db.js +++ b/db.js @@ -99,7 +99,7 @@ module.exports.CreateDB = function (args, datapath) { obj.StoreEvent = function (ids, source, event) { obj.file.insert(event); } obj.GetEvents = function (ids, domain, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }, func) } } obj.GetEventsWithLimit = function (ids, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } } - obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); } + obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); obj.file.remove({ _id: 'nt' + id }); } obj.RemoveAllEvents = function (domain) { obj.file.remove({ type: 'event', domain: domain }, { multi: true }); } obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); } obj.DeleteDomain = function (domain, func) { obj.file.remove({ domain: domain }, { multi: true }, func); } diff --git a/meshuser.js b/meshuser.js index d19e3603..ff2d9bf0 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1021,49 +1021,101 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) { case 'setNotes': { // Argument validation - if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid - if ((command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain + if (obj.common.validateString(command.id, 1, 1024) == false) break; // Check id + var splitid = command.id.split('/'); + if ((splitid.length != 3) || (splitid[1] != domain.id)) return; // Invalid domain, operation only valid for current domain + var idtype = splitid[0]; + if ((idtype != 'user') && (idtype != 'mesh') && (idtype != 'node')) return; - // Check if this user has rights on this nodeid to set notes - obj.db.Get(command.nodeid, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???) - if (nodes.length == 1) { - var meshlinks = user.links[nodes[0].meshid]; - if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights & obj.parent.MESHRIGHT_SETNOTES != 0)) { - // Set the node's notes - if (obj.common.validateString(command.notes, 1) == false) { - obj.db.Remove('nt' + command.nodeid); // Delete the note for this node - } else { - obj.db.Set({ _id: 'nt' + command.nodeid, value: command.notes }); // Set the note for this node + if (idtype == 'node') { + // Check if this user has rights on this id to set notes + obj.db.Get(command.id, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???) + if (nodes.length == 1) { + var meshlinks = user.links[nodes[0].meshid]; + if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights & obj.parent.MESHRIGHT_SETNOTES != 0)) { + // Set the id's notes + if (obj.common.validateString(command.notes, 1) == false) { + obj.db.Remove('nt' + command.id); // Delete the note for this node + } else { + obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node + } } } + }); + } else if (idtype == 'mesh') { + // Get the mesh for this device + var mesh = obj.parent.meshes[command.id]; + if (mesh) { + // Check if this user has rights to do this + if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; } + + // Set the id's notes + if (obj.common.validateString(command.notes, 1) == false) { + obj.db.Remove('nt' + command.id); // Delete the note for this node + } else { + obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node + } } - }); + } else if ((idtype == 'user') && ((user.siteadmin & 2) != 0)) { + // Set the id's notes + if (obj.common.validateString(command.notes, 1) == false) { + obj.db.Remove('nt' + command.id); // Delete the note for this node + } else { + obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node + } + } + break; } case 'getNotes': { // Argument validation - if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid - if ((command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain + if (obj.common.validateString(command.id, 1, 1024) == false) break; // Check id + var splitid = command.id.split('/'); + if ((splitid.length != 3) || (splitid[1] != domain.id)) return; // Invalid domain, operation only valid for current domain + var idtype = splitid[0]; + if ((idtype != 'user') && (idtype != 'mesh') && (idtype != 'node')) return; - // Get the device - obj.db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); return; } - var node = nodes[0]; + if (idtype == 'node') { + // Get the device + obj.db.Get(command.id, function (err, nodes) { + if (nodes.length != 1) return; + var node = nodes[0]; + // Get the mesh for this device + var mesh = obj.parent.meshes[node.meshid]; + if (mesh) { + // Check if this user has rights to do this + if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; } + + // Get the notes about this node + obj.db.Get('nt' + command.id, function (err, notes) { + if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); + }); + } + }); + } else if (idtype == 'mesh') { // Get the mesh for this device - var mesh = obj.parent.meshes[node.meshid]; + var mesh = obj.parent.meshes[command.id]; if (mesh) { // Check if this user has rights to do this if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; } // Get the notes about this node - obj.db.Get('nt' + command.nodeid, function (err, notes) { - if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', nodeid: command.nodeid, notes: null })); return; } - ws.send(JSON.stringify({ action: 'getNotes', nodeid: command.nodeid, notes: notes[0].value })); + obj.db.Get('nt' + command.id, function (err, notes) { + if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); }); } - }); + } else if ((idtype == 'user') && ((user.siteadmin & 2) != 0)) { + // Get the notes about this node + obj.db.Get('nt' + command.id, function (err, notes) { + if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); + }); + } + break; } } diff --git a/package.json b/package.json index 11251218..2d3eb6ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.1.6-k", + "version": "0.1.6-l", "keywords": [ "Remote Management", "Intel AMT", diff --git a/views/default.handlebars b/views/default.handlebars index 2f9179f0..ba8a56e3 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1092,7 +1092,7 @@ } case 'getNotes':{ var n = Q('d2devNotes'); - if (n && (message.nodeid == n.attributes['nodeid'].value)) { + if (n && (message.id == decodeURIComponent(n.attributes['noteid'].value))) { if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); } var ro = n.attributes['ro'].value == 'true'; if (ro == false) { // If we have permissions, set read/write on this note. @@ -2817,7 +2817,7 @@ x += '
'; // Show action button, only show if we have permissions 4, 8, 64 if ((meshrights & 76) != 0) { x += ''; } - x += ''; + x += ''; QH('p10html', x); // Show node last 7 days timeline @@ -2898,13 +2898,13 @@ go(panel); } - function deviceNotesFunction(readonly, nodeid) { + function showNotes(readonly, noteid) { if (xxdialogMode) return; - setDialogMode(2, "Device Notes", 2, deviceNotesFunctionEx, '', nodeid); - meshserver.send({ action: 'getNotes', nodeid: nodeid }); + setDialogMode(2, "Notes", 2, showNotesEx, 'Notes can be viewed and changed by other administrators.', noteid); + meshserver.send({ action: 'getNotes', id: decodeURIComponent(noteid) }); } - function deviceNotesFunctionEx(buttons, tag) { meshserver.send({ action: 'setNotes', nodeid: tag, notes: encodeURIComponent(Q('d2devNotes').value) }); } + function showNotesEx(buttons, tag) { meshserver.send({ action: 'setNotes', id: decodeURIComponent(tag), notes: encodeURIComponent(Q('d2devNotes').value) }); } function deviceActionFunction() { var meshrights = meshes[currentNode.meshid].links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights; @@ -4452,7 +4452,9 @@ x += addHtmlValue('Type', meshtype); x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]); - x += '
'; + x += '
'; + + x += '

'; var currentMeshLinks = currentMesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()]; if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += ' Add User'; } @@ -4550,7 +4552,7 @@ x += 'Mesh Agent Console
'; x += 'Server Files
'; x += 'Wake Devices
'; - x += 'Edit Notes
'; + x += 'Edit Device Notes
'; x += ''; setDialogMode(2, "Add User to Mesh", 3, p20showAddMeshUserDialogEx, x); p20validateAddMeshUserDialog(); @@ -5068,7 +5070,7 @@ x += '
'; // Add action buttons - //x += ''; + x += ''; if (!self && (activeSessions > 0)) { x += ''; } // Setup the panel