From c62bc9c962fd72edff34dac0b3e1730b619ec641 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Sat, 22 Oct 2022 10:42:16 -0700 Subject: [PATCH] Third round of Telegram support changes, can now edit messaging account (#4650) --- meshcentral-config-schema.json | 1 + meshuser.js | 23 +++++++++++++++++-- public/images/messaging12.png | Bin 0 -> 273 bytes public/images/messaging40.png | Bin 895 -> 922 bytes views/default.handlebars | 39 +++++++++++++++++++++++++-------- 5 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 public/images/messaging12.png diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index e7c9dc06a8..44e36fb793 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -527,6 +527,7 @@ "sms2factor": { "type": "boolean", "default": true, "description": "Set to false to disable SMS 2FA." }, "push2factor": { "type": "boolean", "default": true, "description": "Set to false to disable push notification 2FA." }, "otp2factor": { "type": "boolean", "default": true, "description": "Set to false to disable one-time-password 2FA." }, + "msg2factor": { "type": "boolean", "default": true, "description": "Set to false to disable user messaging 2FA." }, "backupcode2factor": { "type": "boolean", "default": true, "description": "Set to false to disable 2FA backup codes." }, "single2factorWarning": { "type": "boolean", "default": true, "description": "Set to false to disable single 2FA warning." }, "lock2factor": { "type": "boolean", "default": false, "description": "When set to true, prevents any changes to 2FA." }, diff --git a/meshuser.js b/meshuser.js index 7b855f8b14..e0f9666f9a 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1387,6 +1387,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (command.resetNextLogin === true) { chguser.passchange = -1; } if ((command.consent != null) && (typeof command.consent == 'number')) { if (command.consent == 0) { delete chguser.consent; } else { chguser.consent = command.consent; } change = 1; } if ((command.phone != null) && (typeof command.phone == 'string') && ((command.phone == '') || isPhoneNumber(command.phone))) { if (command.phone == '') { delete chguser.phone; } else { chguser.phone = command.phone; } change = 1; } + if ((command.msghandle != null) && (typeof command.msghandle == 'string')) { if (command.msghandle == '') { delete chguser.msghandle; } else { chguser.msghandle = command.msghandle; } change = 1; } if ((command.flags != null) && (typeof command.flags == 'number')) { // Flags: 1 = Account Image, 2 = Session Recording if ((command.flags == 0) && (chguser.flags != null)) { delete chguser.flags; change = 1; } else { if (command.flags !== chguser.flags) { chguser.flags = command.flags; change = 1; } } @@ -5250,7 +5251,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'pong': serverCommandPong, 'powertimeline': serverCommandPowerTimeline, 'print': serverCommandPrint, - 'removePhone': serverCommandremovePhone, + 'removePhone': serverCommandRemovePhone, + 'removeMessaging': serverCommandRemoveMessaging, 'removeuserfromusergroup': serverCommandRemoveUserFromUserGroup, 'report': serverCommandReport, 'serverclearerrorlog': serverCommandServerClearErrorLog, @@ -6304,7 +6306,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use function serverCommandPrint(command) { console.log(command.value); } - function serverCommandremovePhone(command) { + function serverCommandRemovePhone(command) { // Do not allow this command when logged in using a login token if (req.session.loginToken != null) return; @@ -6321,6 +6323,23 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, event); } + function serverCommandRemoveMessaging(command) { + // Do not allow this command when logged in using a login token + if (req.session.loginToken != null) return; + + if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here. + if (user.msghandle == null) return; + + // Clear the user's phone + delete user.msghandle; + db.SetUser(user); + + // Event the change + var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msgid: 157, msgArgs: [user.name], msg: 'Removed messaging account of user ' + EscapeHtml(user.name), domain: domain.id }; + 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(['*', 'server-users', user._id], obj, event); + } + function serverCommandRemoveUserFromUserGroup(command) { var err = null; try { diff --git a/public/images/messaging12.png b/public/images/messaging12.png new file mode 100644 index 0000000000000000000000000000000000000000..9a5acfeec665861ad937d29c934fb74e00201578 GIT binary patch literal 273 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!;4)7a#}JL+{{Fq!PjBP;PE|0fh}_fvycKC!{hcss|jjR%p44Vk3Hc|UChYF#xOS_;OXrpTq}Ss OX7F_Nb6Mw<&;$UJMpyR$ literal 0 HcmV?d00001 diff --git a/public/images/messaging40.png b/public/images/messaging40.png index a826e90052748380185f5bcb52416d694efae75b..f677154976ad329a9d89859db8fc2ed35911cf21 100644 GIT binary patch delta 862 zcmV-k1EKu?2AT(uNq@rt01m?e$8V@)0009oNkl+WMks)ka!T zTeQVu!PvBE%_f`O^_$%xt=ObVY?1+gFgxG>+dcf5+5Ki_5r6Ms)~CeE`u@VP3Avcb zjBu3|2L_tgMwncXqz0=RzheJraPzdR9Exdrm8R?Ex{eCi?To+}g)qWH(7&__q)k@T z=g8;LyWa++Z52+LJr*aS!6irER8NJKMhLg+W-2RK1>9d`7n^>zuD|zWU|ibnTK0#@ zzYOj?H!M9Ho_}cm6;bsfD8}JdjLSgkPljaml zwXfGiV(L4%NvD_xG|5V;Wv{!-7(qqVnm95?A+n;;3V(v|@;ZO%_h5Jg;`qFCg66OZ zl_U^~900+aISPT9-A7<`aI*w=XgbD>~Kk+bG2nj7eY`Eh8>Ip;&EuS=LxmUDXt>0wV46YYUa42{o9R-QR6Ev zaR`^89)C_7X%4Uutdtg7F4EXA7`(ml3#=$-Xv_mPku*)TZt&B1ZXLV{?V1_pmChMi zy};r*27Mk4t_{$x8#)g_S@A(fxBS$L!Tc4brk9T72~*^Rh|NkaMZE6wOvg#I)SZOm zAf5880_P7^5=lpajdxYx`iN3@Vz(Yx+CCKrW7Q*7XED5r<$!_XcXi3Nzp zv`H2&8c7Wr_&i~_?uV9=$;D=2gB0_31Ug z?|6HAyLUT#w|n=4Z+2#ma+o$hkLFsO^JA!ONdXd%0GJk}8K|Ua_kf+ELa@#BW zKd^PeO;G86wEL0W$Wl%@@C~_&oQ3FJGn0aJf+BVt;kFgrLyn{otuLrFf3nlaJ|x@U zAsLOFM-D;svzdt@xv0_`&|XH?n{j@;L`EU`Oor9O3o5-6?G-8?FFP=a)h-f z0vAI?(DM!=CF!=6Z3tZq@)IjfbDs5!Iw%^!gQgch^_*S714yUH5xUR`E2#7WY~LVj zIMG48N7ix$dHHHqj#mXH3x9)c6gu@&aL^31LoxoB<9|>3$=IC=AE;3V`C&6hu9b7a zu5_B6Dp9ac`p&q@*%fp7P9Ft(r089Yk^fO~6qGVaI zDDxDYmA*4}h0;nS?MOXlDL5m2C#+aluAYF)j)a+^;I#DXVvE~tTrtkYNoJKJ(-fSP zej?$bjeiP7C7Y2WlN97LE1zNGumxO-SjlGP=rq-ZTbe)UjGL)ivKDaNsW`^z#uX%I zkgwA12D~zh81cBN!jPgdjNT7#`*FV z83=0D5HCo|{v)(}kk69|WOGm}mSn+v;n`vcVtWz3?ntCa!Ji0U=M5oSAas;^5*~m N002ovPDHLkV1j!ml9m7f diff --git a/views/default.handlebars b/views/default.handlebars index ad714baf05..9b145db556 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -11964,7 +11964,7 @@ x = '
'; x += '
' + "Verified handle" + '
' + EscapeHtml(userinfo.msghandle) + '
'; x += '
'; - setDialogMode(2, "Messaging Notifications", 3, account_managePhoneRemove, x); + setDialogMode(2, "Messaging Notifications", 3, account_manageMessagingRemove, x); account_managePhoneRemoveValidate(); } else { x = '
'; @@ -11985,6 +11985,7 @@ function account_manageMessagingValidate(x) { var ok = (Q('d2handleinput').value.length > 0); QE('idx_dlgOkButton', ok); if ((x == 1) && ok) { dialogclose(1); } } function account_manageMessagingAdd() { if (Q('d2handleinput').value.length == 0) return; QE('d2handleinput', false); meshserver.send({ action: 'verifyMessaging', service: Q('d2serviceselect').value, handle: Q('d2handleinput').value }); } function account_manageMessagingConfirm(b, tag) { meshserver.send({ action: 'confirmMessaging', code: Q('d2phoneCodeInput').value, cookie: tag }); } + function account_manageMessagingRemove() { if (Q('d2delPhone').checked) { meshserver.send({ action: 'removeMessaging' }); } } function account_manageAuthEmail() { if (xxdialogMode || ((features & 0x00800000) == 0)) return; @@ -14616,6 +14617,7 @@ if ((user.otpsecret > 0) || (user.otphkeys > 0) || ((user.otpekey == 1) && (features & 0x00800000)) || ((user.phone != null) && (features & 0x04000000))) { username += ' '; } if (user.phone != null) { username += ' '; } if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { username += ' '; } + if ((user.msghandle != null) && (features2 & 0x02000000)) { username += ' '; } x += '
'; x += '
'; x += '
'; @@ -15686,7 +15688,7 @@ } if ((features2 & 0x02000000) || (user.msghandle != null)) { // If user messaging is enabled on the server or user has a messaging handle - x += addDeviceAttribute("Messaging", (user.msghandle?user.msghandle:('' + "None" + '')) + ' '); + x += addDeviceAttribute("Messaging", ' ' + (user.msghandle?user.msghandle:('' + "None" + '')) + ' '); } // Display features @@ -15757,6 +15759,7 @@ if (user.otpkeys > 0) { factors.push("Backup Codes"); } if (user.otpdev > 0) { factors.push("Device Push"); } if ((user.phone != null) && (features & 0x04000000)) { factors.push("SMS"); } + if ((user.msghandle != null) && (features2 & 0x04000000)) { factors.push("Messaging"); } x += addDeviceAttribute("Security", ' ' + factors.join(', ')); } @@ -15831,14 +15834,32 @@ p30editPhoneValidate(); } - function p30editMessaging() { // TODO + function p30editMessaging() { if (xxdialogMode) return; - var x = '
'; - x += '' + "SMS capable phone number for this user." + '
' + "Leave blank for none."; - x += '

' + "Phone number:" + '
'; - setDialogMode(2, "Phone Notifications", 3, p30editPhoneEx, x, 'verifyPhone'); - Q('d2phoneinput').focus(); - p30editPhoneValidate(); + var x = '
'; + x += '' + "Messaging account for this user." + '
' + "Leave blank for none."; + + var y = ''; + x += '
' + "Service" + '' + y; + x += '
' + "Handle" + ''; + x += '
'; + + setDialogMode(2, "Messaging Notifications", 3, p30editMessagingEx, x, 'verifyMessaging'); + Q('d2handleinput').focus(); + p30editMessagingValidate(); + } + + function p30editMessagingValidate(x) { if (x == 1) { dialogclose(1); } } + + // Send to the server the user's messaging account + function p30editMessagingEx() { + var handle = null; + if (Q('d2handleinput').value == '') { handle = ''; } + else if (Q('d2serviceselect').value == 1) { handle = 'telegram:@' + Q('d2handleinput').value; } + if (handle != null) { meshserver.send({ action: 'edituser', id: currentUser._id, msghandle: handle }); } } function p20edituserfeatures() {