From f262dd9aa1e08a681963d0bfc91f9dcb5aec2a75 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 9 Jan 2022 20:29:54 -0500 Subject: [PATCH 1/4] Added function for updateUserImage + bugfix --- meshuser.js | 74 ++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/meshuser.js b/meshuser.js index 7b4c43b0..c6a49b8e 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1331,43 +1331,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // OK Response if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'edituser', responseid: command.responseid, result: 'ok' })); } catch (ex) { } } - break; - } - case 'updateUserImage': - { - if (req.session.loginToken != null) break; // Do not allow this command when logged in using a login token - - var uid = user._id; - if ((typeof command.userid == 'string') && ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0)) { uid = command.userid; } - - var chguser = parent.users[uid], flags = 0, change = 0; - if (chguser == null) break; - if (typeof chguser.flags == 'number') { flags = chguser.flags; } - - if (command.image == 0) { - // Delete the image - db.Remove('im' + uid); - if ((flags & 1) != 0) { flags -= 1; change = 1; } - } else if ((typeof command.image == 'string') && (command.image.length < 600000) && ((command.image.startsWith('data:image/png;base64,') || (command.image.startsWith('data:image/jpeg;base64,'))))) { - // Save the new image - db.Set({ _id: 'im' + uid, image: command.image }); - if ((flags & 1) == 0) { flags += 1; } - change = 1; - } - - // Update the user if needed - if (change == 1) { - chguser.flags = flags; - db.SetUser(chguser); - - // Event the change - var targets = ['*', 'server-users', user._id, chguser._id]; - if (allTargetGroups) { for (var i in allTargetGroups) { targets.push('server-users:' + i); } } - var event = { etype: 'user', userid: uid, username: chguser.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msgid: 66, msgArgs: [chguser.name], msg: 'Account changed: ' + chguser.name, domain: domain.id, accountImageChange: 1 }; - if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. - parent.parent.DispatchEvent(targets, obj, event); - } - break; } case 'usergroups': @@ -5007,6 +4970,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'servertimelinestats': serverCommandServerTimelineStats, 'serverupdate': serverCommandServerUpdate, 'serverversion': serverCommandServerVersion, + 'updateUserImage': serverCommandUpdateUserImage, 'urlargs': serverCommandUrlArgs, 'users': serverCommandUsers, 'verifyemail': serverCommandVerifyEmail, @@ -6099,6 +6063,42 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.parent.getServerTags(function (tags, err) { try { ws.send(JSON.stringify({ action: 'serverversion', tags: tags })); } catch (ex) { } }); } + function serverCommandUpdateUserImage(command) { + if (req.session.loginToken != null) return; // Do not allow this command when logged in using a login token + + var uid = user._id; + if ((typeof command.userid == 'string') && ((user.siteadmin & SITERIGHT_MANAGEUSERS) != 0)) { uid = command.userid; } + + var chguser = parent.users[uid], flags = 0, change = 0; + if (chguser == null) return; + if (typeof chguser.flags == 'number') { flags = chguser.flags; } + + if (command.image == 0) { + // Delete the image + db.Remove('im' + uid); + if ((flags & 1) != 0) { flags -= 1; change = 1; } + } else if ((typeof command.image == 'string') && (command.image.length < 600000) && ((command.image.startsWith('data:image/png;base64,') || (command.image.startsWith('data:image/jpeg;base64,'))))) { + // Save the new image + db.Set({ _id: 'im' + uid, image: command.image }); + if ((flags & 1) == 0) { flags += 1; } + change = 1; + } + + // Update the user if needed + if (change == 1) { + chguser.flags = flags; + db.SetUser(chguser); + + // Event the change + var targets = ['*', 'server-users', user._id, chguser._id]; + var allTargetGroups = chguser.groups; + if (allTargetGroups) { for (var i in allTargetGroups) { targets.push('server-users:' + i); } } + var event = { etype: 'user', userid: uid, username: chguser.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msgid: 66, msgArgs: [chguser.name], msg: 'Account changed: ' + chguser.name, domain: domain.id, accountImageChange: 1 }; + if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. + parent.parent.DispatchEvent(targets, obj, event); + } + } + function serverCommandUrlArgs(command) { console.log(req.query); console.log(command.args); From 96fa6e87d5b0bf3d9bc98ef3872ae42d3b41ff62 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 9 Jan 2022 21:04:34 -0500 Subject: [PATCH 2/4] Factor smsuser + remove unused variable --- meshuser.js | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/meshuser.js b/meshuser.js index c6a49b8e..d8abfd2d 100644 --- a/meshuser.js +++ b/meshuser.js @@ -3527,29 +3527,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use delete obj.hardwareKeyRegistrationRequest; break; } - case 'smsuser': { // Send a SMS message to a user - var errMsg = null, errId = 0, smsuser = null; - if (parent.parent.smsserver == null) { errMsg = "SMS gateway not enabled"; errId = 23; } - else if ((user.siteadmin & 2) == 0) { errMsg = "No user management rights"; errId = 24; } - else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = "Invalid username"; errId = 2; } - else if (common.validateString(command.msg, 1, 160) == false) { errMsg = "Invalid SMS message"; errId = 25; } - else { - smsuser = parent.users[command.userid]; - if (smsuser == null) { errMsg = "Invalid username"; errId = 2; } - else if (smsuser.phone == null) { errMsg = "No phone number for this user"; errId = 26; } - } - - if (errMsg != null) { displayNotificationMessage(errMsg); break; } - - parent.parent.smsserver.sendSMS(smsuser.phone, command.msg, function (success, msg) { - if (success) { - displayNotificationMessage("SMS succesfuly sent.", null, null, null, 27); - } else { - if (typeof msg == 'string') { displayNotificationMessage("SMS error: " + msg, null, null, null, 29, [msg]); } else { displayNotificationMessage("SMS error", null, null, null, 28); } - } - }); - break; - } case 'emailuser': { // Send a email message to a user var errMsg = null, emailuser = null; if (domain.mailserver == null) { errMsg = 'Email server not enabled'; } @@ -4970,6 +4947,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'servertimelinestats': serverCommandServerTimelineStats, 'serverupdate': serverCommandServerUpdate, 'serverversion': serverCommandServerVersion, + 'smsuser': serverCommandSmsUser, 'updateUserImage': serverCommandUpdateUserImage, 'urlargs': serverCommandUrlArgs, 'users': serverCommandUsers, @@ -6063,6 +6041,29 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.parent.getServerTags(function (tags, err) { try { ws.send(JSON.stringify({ action: 'serverversion', tags: tags })); } catch (ex) { } }); } + function serverCommandSmsUser(command) { + var errMsg = null, smsuser = null; + if (parent.parent.smsserver == null) { errMsg = "SMS gateway not enabled"; } + else if ((user.siteadmin & 2) == 0) { errMsg = "No user management rights"; } + else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = "Invalid username"; } + else if (common.validateString(command.msg, 1, 160) == false) { errMsg = "Invalid SMS message"; } + else { + smsuser = parent.users[command.userid]; + if (smsuser == null) { errMsg = "Invalid username"; } + else if (smsuser.phone == null) { errMsg = "No phone number for this user"; } + } + + if (errMsg != null) { displayNotificationMessage(errMsg); return; } + + parent.parent.smsserver.sendSMS(smsuser.phone, command.msg, function (success, msg) { + if (success) { + displayNotificationMessage("SMS succesfuly sent.", null, null, null, 27); + } else { + if (typeof msg == 'string') { displayNotificationMessage("SMS error: " + msg, null, null, null, 29, [msg]); } else { displayNotificationMessage("SMS error", null, null, null, 28); } + } + }); + } + function serverCommandUpdateUserImage(command) { if (req.session.loginToken != null) return; // Do not allow this command when logged in using a login token From 6ce252482fd63a4c1f6c89cc37194e4ac98943d5 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 9 Jan 2022 21:14:11 -0500 Subject: [PATCH 3/4] Added function handlers for getcookie,emailuser --- meshuser.js | 79 +++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/meshuser.js b/meshuser.js index d8abfd2d..5648d981 100644 --- a/meshuser.js +++ b/meshuser.js @@ -3014,26 +3014,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } break; } - case 'getcookie': - { - // Check if this user has rights on this nodeid - if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid - parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { - if ((node == null) || ((rights & MESHRIGHT_REMOTECONTROL) == 0) || (visible == false)) return; // Access denied. - - // Add a user authentication cookie to a url - var cookieContent = { userid: user._id, domainid: user.domain }; - if (command.nodeid) { cookieContent.nodeid = command.nodeid; } - if (command.tcpaddr) { cookieContent.tcpaddr = command.tcpaddr; } // Indicates the browser want the agent to TCP connect to a remote address - if (command.tcpport) { cookieContent.tcpport = command.tcpport; } // Indicates the browser want the agent to TCP connect to a remote port - if (command.ip) { cookieContent.ip = command.ip; } // Indicates the browser want to agent to relay a TCP connection to a IP:port - if (node.mtype == 3) { cookieContent.lc = 1; command.localRelay = true; } // Indicate this is for a local connection - command.cookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey); - command.trustedCert = parent.isTrustedCert(domain); - try { ws.send(JSON.stringify(command)); } catch (ex) { } - }); - break; - } case 'inviteAgent': { var err = null, mesh = null; @@ -3527,25 +3507,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use delete obj.hardwareKeyRegistrationRequest; break; } - case 'emailuser': { // Send a email message to a user - var errMsg = null, emailuser = null; - if (domain.mailserver == null) { errMsg = 'Email server not enabled'; } - else if ((user.siteadmin & 2) == 0) { errMsg = 'No user management rights'; } - else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = 'Invalid userid'; } - else if (common.validateString(command.subject, 1, 1000) == false) { errMsg = 'Invalid subject message'; } - else if (common.validateString(command.msg, 1, 10000) == false) { errMsg = 'Invalid message'; } - else { - emailuser = parent.users[command.userid]; - if (emailuser == null) { errMsg = 'Invalid userid'; } - else if (emailuser.email == null) { errMsg = 'No validated email address for this user'; } - else if (emailuser.emailVerified !== true) { errMsg = 'No validated email address for this user'; } - } - - if (errMsg != null) { displayNotificationMessage(errMsg); break; } - domain.mailserver.sendMail(emailuser.email, command.subject, command.msg); - displayNotificationMessage("Email sent.", null, null, null, 14); - break; - } case 'getClip': { if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid @@ -4925,7 +4886,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'changelang': serverCommandChangeLang, 'close': serverCommandClose, 'confirmPhone': serverCommandConfirmPhone, + 'emailuser': serverCommandEmailUser, 'files': serverCommandFiles, + 'getcookie': serverCommandGetCookie, 'getnetworkinfo': serverCommandGetNetworkInfo, 'getsysinfo': serverCommandGetSysInfo, 'intersession': serverCommandInterSession, @@ -5703,11 +5666,49 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, event); } + function serverCommandEmailUser(command) { + var errMsg = null, emailuser = null; + if (domain.mailserver == null) { errMsg = 'Email server not enabled'; } + else if ((user.siteadmin & 2) == 0) { errMsg = 'No user management rights'; } + else if (common.validateString(command.userid, 1, 2048) == false) { errMsg = 'Invalid userid'; } + else if (common.validateString(command.subject, 1, 1000) == false) { errMsg = 'Invalid subject message'; } + else if (common.validateString(command.msg, 1, 10000) == false) { errMsg = 'Invalid message'; } + else { + emailuser = parent.users[command.userid]; + if (emailuser == null) { errMsg = 'Invalid userid'; } + else if (emailuser.email == null) { errMsg = 'No validated email address for this user'; } + else if (emailuser.emailVerified !== true) { errMsg = 'No validated email address for this user'; } + } + + if (errMsg != null) { displayNotificationMessage(errMsg); return; } + domain.mailserver.sendMail(emailuser.email, command.subject, command.msg); + displayNotificationMessage("Email sent.", null, null, null, 14); + } + function serverCommandFiles(command) { // Send the full list of server files to the browser app updateUserFiles(user, ws, domain); } + function serverCommandGetCookie(command) { + // Check if this user has rights on this nodeid + if (common.validateString(command.nodeid, 1, 1024) == false) return; // Check nodeid + parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { + if ((node == null) || ((rights & MESHRIGHT_REMOTECONTROL) == 0) || (visible == false)) return; // Access denied. + + // Add a user authentication cookie to a url + var cookieContent = { userid: user._id, domainid: user.domain }; + if (command.nodeid) { cookieContent.nodeid = command.nodeid; } + if (command.tcpaddr) { cookieContent.tcpaddr = command.tcpaddr; } // Indicates the browser want the agent to TCP connect to a remote address + if (command.tcpport) { cookieContent.tcpport = command.tcpport; } // Indicates the browser want the agent to TCP connect to a remote port + if (command.ip) { cookieContent.ip = command.ip; } // Indicates the browser want to agent to relay a TCP connection to a IP:port + if (node.mtype == 3) { cookieContent.lc = 1; command.localRelay = true; } // Indicate this is for a local connection + command.cookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey); + command.trustedCert = parent.isTrustedCert(domain); + try { ws.send(JSON.stringify(command)); } catch (ex) { } + }); + } + function serverCommandGetNetworkInfo(command) { if (!validNodeIdAndDomain(command)) return; From 1398ca583b6400dfd55e341a1247edefb0f87329 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 9 Jan 2022 21:22:03 -0500 Subject: [PATCH 4/4] Added command function handlers for get,set clip --- meshuser.js | 54 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/meshuser.js b/meshuser.js index 5648d981..54a683e2 100644 --- a/meshuser.js +++ b/meshuser.js @@ -3507,32 +3507,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use delete obj.hardwareKeyRegistrationRequest; break; } - case 'getClip': { - if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid - - // Get the node and the rights for this node - parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { - if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return; - - // Ask for clipboard data from agent - var agent = parent.wsagents[node._id]; - if (agent != null) { try { agent.send(JSON.stringify({ action: 'getClip' })); } catch (ex) { } } - }); - break; - } - case 'setClip': { - if (common.validateString(command.data, 1, 65535) == false) break; // Check - - // Get the node and the rights for this node - parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { - if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return; - - // Send clipboard data to the agent - var agent = parent.wsagents[node._id]; - if (agent != null) { try { agent.send(JSON.stringify({ action: 'setClip', data: command.data })); } catch (ex) { } } - }); - break; - } case 'userWebState': { if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here. if (common.validateString(command.state, 1, 30000) == false) break; // Check state size, no more than 30k @@ -4888,6 +4862,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'confirmPhone': serverCommandConfirmPhone, 'emailuser': serverCommandEmailUser, 'files': serverCommandFiles, + 'getClip': serverCommandGetClip, 'getcookie': serverCommandGetCookie, 'getnetworkinfo': serverCommandGetNetworkInfo, 'getsysinfo': serverCommandGetSysInfo, @@ -4910,6 +4885,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'servertimelinestats': serverCommandServerTimelineStats, 'serverupdate': serverCommandServerUpdate, 'serverversion': serverCommandServerVersion, + 'setClip': serverCommandSetClip, 'smsuser': serverCommandSmsUser, 'updateUserImage': serverCommandUpdateUserImage, 'urlargs': serverCommandUrlArgs, @@ -5690,6 +5666,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use updateUserFiles(user, ws, domain); } + function serverCommandGetClip(command) { + if (common.validateString(command.nodeid, 1, 1024) == false) return; // Check nodeid + + // Get the node and the rights for this node + parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { + if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return; + + // Ask for clipboard data from agent + var agent = parent.wsagents[node._id]; + if (agent != null) { try { agent.send(JSON.stringify({ action: 'getClip' })); } catch (ex) { } } + }); + } + function serverCommandGetCookie(command) { // Check if this user has rights on this nodeid if (common.validateString(command.nodeid, 1, 1024) == false) return; // Check nodeid @@ -6042,6 +6031,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.parent.getServerTags(function (tags, err) { try { ws.send(JSON.stringify({ action: 'serverversion', tags: tags })); } catch (ex) { } }); } + function serverCommandSetClip(command) { + if (common.validateString(command.data, 1, 65535) == false) return; // Check + + // Get the node and the rights for this node + parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) { + if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return; + + // Send clipboard data to the agent + var agent = parent.wsagents[node._id]; + if (agent != null) { try { agent.send(JSON.stringify({ action: 'setClip', data: command.data })); } catch (ex) { } } + }); + } + function serverCommandSmsUser(command) { var errMsg = null, smsuser = null; if (parent.parent.smsserver == null) { errMsg = "SMS gateway not enabled"; }