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