More SMS work.
Ylian Saint-Hilaire committed
Apr 22, 2020 at 02:23 UTC
2b6925205ff36d4966a08dd14ea4af570468b4b4
4 files changed
+36
-23
meshsms.js
+8
-15
@@ -43,7 +43,6 @@ module.exports.CreateMeshSMS = function (parent) {
43
// Send an SMS message
44
obj.sendSMS = function (to, msg, func) {
45
parent.debug('email', 'Sending SMS to: ' + to + ': ' + msg);
46
- console.log({ from: parent.config.sms.from, to: to, body: msg });
46
if (parent.config.sms.provider == 'twilio') {
47
obj.provider.messages.create({
48
from: parent.config.sms.from,
@@ -78,7 +77,7 @@ module.exports.CreateMeshSMS = function (parent) {
77
}
78
79
// Get the english email
81
- if ((htmlfile == null) || (txtfile == null)) {
80
+ if (txtfile == null) {
81
var pathTxt = obj.parent.path.join(emailsPath, 'sms-messages.txt');
82
if (obj.parent.fs.existsSync(pathTxt)) {
83
txtfile = obj.parent.fs.readFileSync(pathTxt).toString();
@@ -89,8 +88,8 @@ module.exports.CreateMeshSMS = function (parent) {
88
if (txtfile == null) { return null; }
89
90
// Decode the TXT file
92
- lines = txtfile.split('\r\n').join('\n').split('\n')
93
- if (lines.length >= templateNumber) return null;
91
+ var lines = txtfile.split('\r\n').join('\n').split('\n')
92
+ if (lines.length <= templateNumber) return null;
93
94
return lines[templateNumber];
95
}
@@ -99,22 +98,16 @@ module.exports.CreateMeshSMS = function (parent) {
98
obj.sendPhoneCheck = function (domain, phoneNumber, verificationCode, language, func) {
99
parent.debug('email', "Sending verification SMS to " + phoneNumber);
100
102
- var template = getTemplate(0, domain, language);
103
- if ((template == null) || (template.htmlSubject == null) || (template.txtSubject == null)) {
104
- parent.debug('email', "Error: Failed to get SMS template"); // No SMS template found
105
- return;
106
- }
101
+ var sms = getTemplate(0, domain, language);
102
+ if (sms == null) { parent.debug('email', "Error: Failed to get SMS template"); return; } // No SMS template found
103
104
// Setup the template
109
- template.split("[[0]]").join(domain.title ? domain.title : 'MeshCentral');
110
- template.split("[[1]]").join(verificationCode);
105
+ sms = sms.split('[[0]]').join(domain.title ? domain.title : 'MeshCentral');
106
+ sms = sms.split('[[1]]').join(verificationCode);
107
108
// Send the SMS
113
- obj.sendSMS(phoneNumber, template, func);
109
+ obj.sendSMS(phoneNumber, sms, func);
110
};
111
112
return obj;
113
};
118
-
119
-// +18632703894
120
-// SMS 5032700426 "This is a test"
meshuser.js
+16
-8
@@ -3713,24 +3713,20 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3713
if (parent.parent.smsserver == null) return;
3714
if (common.validateString(command.phone, 1, 18) == false) break; // Check phone length
3715
if (command.phone.match(/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/) == false) break; // Check phone
3716
- var code = getRandomEightDigitInteger();
3717
- //console.log(code);
3716
+ const code = getRandomEightDigitInteger();
3717
3719
- // TODO: We need to tie this cookie to this session and limit how many times we can guess the code
3720
- const phoneCookie = parent.parent.encodeCookie({ a: 'verifyPhone', c: code, p: command.phone });
3721
-
3722
- ws.send(JSON.stringify({ action: 'verifyPhone', cookie: phoneCookie, success: true })); // DEBUG
3723
- /*
3718
+ // TODO: We need limit how many times we can guess the code
3719
+ const phoneCookie = parent.parent.encodeCookie({ a: 'verifyPhone', c: code, p: command.phone, s: ws.sessionId });
3720
parent.parent.smsserver.sendPhoneCheck(domain, command.phone, code, parent.getLanguageCodes(req), function (success) {
3721
ws.send(JSON.stringify({ action: 'verifyPhone', cookie: phoneCookie, success: success }));
3722
});
3727
- */
3723
break;
3724
}
3725
case 'confirmPhone': {
3726
if ((parent.parent.smsserver == null) || (typeof command.cookie != 'string') || (typeof command.code != 'number')) break; // Input checks
3727
var cookie = parent.parent.decodeCookie(command.cookie);
3728
if (cookie == null) break; // Invalid cookie
3729
+ if (cookie.s != ws.sessionId) break; // Invalid session
3730
if (cookie.c != command.code) { ws.send(JSON.stringify({ action: 'verifyPhone', cookie: command.cookie, success: true })); break; } // Code does not match
3731
3732
// Set the user's phone
@@ -3758,6 +3754,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3754
3755
break;
3756
}
3757
+ case 'smsuser': { // Send a SMS message to a user
3758
+ if (parent.parent.smsserver == null) break;
3759
+ if ((user.siteadmin & 2) == 0) break;
3760
+ if (common.validateString(command.userid, 1, 2048) == false) break;
3761
+ if (common.validateString(command.msg, 1, 160) == false) break;
3762
+ var smsuser = parent.users[command.userid];
3763
+ if ((smsuser == null) || (smsuser.phone == null)) break;
3764
+ parent.parent.smsserver.sendSMS(smsuser.phone, command.msg, function (success) {
3765
+ // TODO
3766
+ });
3767
+ break;
3768
+ }
3769
case 'getClip': {
3770
if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid
3771
public/images/phone12.png
Binary files /dev/null and b/public/images/phone12.png differ
views/default.handlebars
+12
@@ -9799,6 +9799,7 @@
9799
}
9800
9801
if ((user.otpsecret > 0) || (user.otphkeys > 0)) { username += ' <img src="images/key12.png" height=12 width=11 title="' + "2nd factor authentication enabled" + '" style="margin-top:2px" />'; }
9802
+ if (user.phone != null) { username += ' <img src="images/phone12.png" height=12 width=7 title="' + "Verified phone number" + '" style="margin-top:2px" />'; }
9803
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { username += ' <img src="images/padlock12.png" height=12 width=8 title="' + "Account is locked" + '" style="margin-top:2px" />'; }
9804
9805
x += '<tr tabindex=0 onmouseover=userMouseHover(this,1) onmouseout=userMouseHover(this,0) onkeypress="if (event.key==\'Enter\') gotoUser(\'' + encodeURIComponent(user._id) + '\')"><td>';
@@ -9907,6 +9908,16 @@
9908
return false;
9909
}
9910
9911
+ function showSendSMS(userid) {
9912
+ if (xxdialogMode) return;
9913
+ setDialogMode(2, "Send SMS", 3, showSendSMSEx, '<textarea id=d2smsText maxlength=160 style=background-color:#fcf3cf;width:100%;height:100px;resize:none onKeyUp=showSendSMSValidate()></textarea><span style=font-size:10px><span>', decodeURIComponent(userid));
9914
+ Q('d2smsText').focus();
9915
+ showSendSMSValidate();
9916
+ }
9917
+
9918
+ function showSendSMSValidate() { QE('idx_dlgOkButton', Q('d2smsText').value.length > 0); }
9919
+ function showSendSMSEx(b, tag) { if (Q('d2smsText').value.length > 0) { meshserver.send({ action: 'smsuser', userid: tag, msg: Q('d2smsText').value }); } }
9920
+
9921
function showUserAlertDialog(e, userid) {
9922
if (xxdialogMode) return;
9923
haltEvent(e);
@@ -10657,6 +10668,7 @@
10668
10669
// Add action buttons
10670
x += '<input type=button value=\"' + "Notes" + '\" title=\"' + "View notes about this user" + '\" onclick=showNotes(false,"' + userid + '") />';
10671
+ if (user.phone && (features & 0x02000000)) { x += '<input type=button value=\"' + "SMS" + '\" title=\"' + "Send a SMS message to this user" + '\" onclick=showSendSMS("' + encodeURIComponent(userid) + '") />'; }
10672
if (!self && (activeSessions > 0)) { x += '<input type=button value=\"' + "Notify" + '\" title=\"' + "Send user notification" + '\" onclick=showUserAlertDialog(event,"' + userid + '") />'; }
10673
10674
// Setup the panel