mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
* @description MeshCentral SMS gateway communication module
 | 
						|
* @author Ylian Saint-Hilaire
 | 
						|
* @copyright Intel Corporation 2018-2020
 | 
						|
* @license Apache-2.0
 | 
						|
* @version v0.0.1
 | 
						|
*/
 | 
						|
 | 
						|
/*xjslint node: true */
 | 
						|
/*xjslint plusplus: true */
 | 
						|
/*xjslint maxlen: 256 */
 | 
						|
/*jshint node: true */
 | 
						|
/*jshint strict: false */
 | 
						|
/*jshint esversion: 6 */
 | 
						|
"use strict";
 | 
						|
 | 
						|
/*
 | 
						|
// For Twilio, add this in config.json
 | 
						|
"sms": {
 | 
						|
    "provider": "twilio",
 | 
						|
    "sid": "ACxxxxxxxxx",
 | 
						|
    "auth": "xxxxxxx",
 | 
						|
    "from": "+15555555555"
 | 
						|
},
 | 
						|
 | 
						|
// For Plivo, add this in config.json
 | 
						|
"sms": {
 | 
						|
    "provider": "plivo",
 | 
						|
    "id": "xxxxxxx",
 | 
						|
    "token": "xxxxxxx",
 | 
						|
    "from": "15555555555"
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
// Construct a MeshAgent object, called upon connection
 | 
						|
module.exports.CreateMeshSMS = function (parent) {
 | 
						|
    var obj = {};
 | 
						|
    obj.parent = parent;
 | 
						|
    obj.provider = null;
 | 
						|
 | 
						|
    // SMS gateway provider setup
 | 
						|
    switch (parent.config.sms.provider) {
 | 
						|
        case 'twilio': {
 | 
						|
            // Validate Twilio configuration values
 | 
						|
            if (typeof parent.config.sms.sid != 'string') { console.log('Invalid or missing SMS gateway provider sid.'); return null; }
 | 
						|
            if (typeof parent.config.sms.auth != 'string') { console.log('Invalid or missing SMS gateway provider auth.'); return null; }
 | 
						|
            if (typeof parent.config.sms.from != 'string') { console.log('Invalid or missing SMS gateway provider from.'); return null; }
 | 
						|
 | 
						|
            // Setup Twilio
 | 
						|
            var Twilio = require('twilio');
 | 
						|
            obj.provider = new Twilio(parent.config.sms.sid, parent.config.sms.auth);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case 'plivo': {
 | 
						|
            // Validate Plivo configuration values
 | 
						|
            if (typeof parent.config.sms.id != 'string') { console.log('Invalid or missing SMS gateway provider id.'); return null; }
 | 
						|
            if (typeof parent.config.sms.token != 'string') { console.log('Invalid or missing SMS gateway provider token.'); return null; }
 | 
						|
            if (typeof parent.config.sms.from != 'string') { console.log('Invalid or missing SMS gateway provider from.'); return null; }
 | 
						|
 | 
						|
            // Setup Plivo
 | 
						|
            var plivo = require('plivo');
 | 
						|
            obj.provider = new plivo.Client(parent.config.sms.id, parent.config.sms.token);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default: {
 | 
						|
            // Unknown SMS gateway provider
 | 
						|
            console.log('Unknown SMS gateway provider: ' + parent.config.sms.provider);
 | 
						|
            return null;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Send an SMS message
 | 
						|
    obj.sendSMS = function (to, msg, func) {
 | 
						|
        parent.debug('email', 'Sending SMS to: ' + to + ': ' + msg);
 | 
						|
        if (parent.config.sms.provider == 'twilio') { // Twilio
 | 
						|
            obj.provider.messages.create({
 | 
						|
                from: parent.config.sms.from,
 | 
						|
                to: to,
 | 
						|
                body: msg
 | 
						|
            }, function (err, result) {
 | 
						|
                if (err != null) { parent.debug('email', 'SMS error: ' + err.message); } else { parent.debug('email', 'SMS result: ' + JSON.stringify(result)); }
 | 
						|
                if (func != null) { func((err == null) && (result.status == 'queued'), err ? err.message : null, result); }
 | 
						|
            });
 | 
						|
        } else if (parent.config.sms.provider == 'plivo') { // Plivo
 | 
						|
            if (to.split('-').join('').split(' ').join('').split('+').join('').length == 10) { to = '1' + to; } // If we only have 10 digits, add a 1 in front.
 | 
						|
            obj.provider.messages.create(
 | 
						|
                parent.config.sms.from,
 | 
						|
                to,
 | 
						|
                msg
 | 
						|
            ).then(function (result) {
 | 
						|
                parent.debug('email', 'SMS result: ' + JSON.stringify(result));
 | 
						|
                if (func != null) { func((result != null) && (result.messageUuid != null), null, result); }
 | 
						|
            }
 | 
						|
            ).catch(function (err) {
 | 
						|
                var msg = null;
 | 
						|
                if ((err != null) && err.message) { msg = JSON.parse(err.message).error; }
 | 
						|
                parent.debug('email', 'SMS error: ' + msg);
 | 
						|
                if (func != null) { func(false, msg, null); }
 | 
						|
            }
 | 
						|
            );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Get the correct SMS template
 | 
						|
    function getTemplate(templateNumber, domain, lang) {
 | 
						|
        parent.debug('email', 'Getting SMS template #' + templateNumber + ', lang: ' + lang);
 | 
						|
        if (Array.isArray(lang)) { lang = lang[0]; } // TODO: For now, we only use the first language given.
 | 
						|
 | 
						|
        var r = {}, emailsPath = null;
 | 
						|
        if ((domain != null) && (domain.webemailspath != null)) { emailsPath = domain.webemailspath; }
 | 
						|
        else if (obj.parent.webEmailsOverridePath != null) { emailsPath = obj.parent.webEmailsOverridePath; }
 | 
						|
        else if (obj.parent.webEmailsPath != null) { emailsPath = obj.parent.webEmailsPath; }
 | 
						|
        if ((emailsPath == null) || (obj.parent.fs.existsSync(emailsPath) == false)) { return null }
 | 
						|
 | 
						|
        // Get the non-english email if needed
 | 
						|
        var txtfile = null;
 | 
						|
        if ((lang != null) && (lang != 'en')) {
 | 
						|
            var translationsPath = obj.parent.path.join(emailsPath, 'translations');
 | 
						|
            var translationsPathTxt = obj.parent.path.join(emailsPath, 'translations', 'sms-messages_' + lang + '.txt');
 | 
						|
            if (obj.parent.fs.existsSync(translationsPath) && obj.parent.fs.existsSync(translationsPathTxt)) {
 | 
						|
                txtfile = obj.parent.fs.readFileSync(translationsPathTxt).toString();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // Get the english email
 | 
						|
        if (txtfile == null) {
 | 
						|
            var pathTxt = obj.parent.path.join(emailsPath, 'sms-messages.txt');
 | 
						|
            if (obj.parent.fs.existsSync(pathTxt)) {
 | 
						|
                txtfile = obj.parent.fs.readFileSync(pathTxt).toString();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        // No email templates
 | 
						|
        if (txtfile == null) { return null; }
 | 
						|
 | 
						|
        // Decode the TXT file
 | 
						|
        var lines = txtfile.split('\r\n').join('\n').split('\n')
 | 
						|
        if (lines.length <= templateNumber) return null;
 | 
						|
 | 
						|
        return lines[templateNumber];
 | 
						|
    }
 | 
						|
 | 
						|
    // Send phone number verification SMS
 | 
						|
    obj.sendPhoneCheck = function (domain, phoneNumber, verificationCode, language, func) {
 | 
						|
        parent.debug('email', "Sending verification SMS to " + phoneNumber);
 | 
						|
 | 
						|
        var sms = getTemplate(0, domain, language);
 | 
						|
        if (sms == null) { parent.debug('email', "Error: Failed to get SMS template"); return; } // No SMS template found
 | 
						|
 | 
						|
        // Setup the template
 | 
						|
        sms = sms.split('[[0]]').join(domain.title ? domain.title : 'MeshCentral');
 | 
						|
        sms = sms.split('[[1]]').join(verificationCode);
 | 
						|
 | 
						|
        // Send the SMS
 | 
						|
        obj.sendSMS(phoneNumber, sms, func);
 | 
						|
    };
 | 
						|
 | 
						|
    // Send phone number verification SMS
 | 
						|
    obj.sendToken = function (domain, phoneNumber, verificationCode, language, func) {
 | 
						|
        parent.debug('email', "Sending login token SMS to " + phoneNumber);
 | 
						|
 | 
						|
        var sms = getTemplate(1, domain, language);
 | 
						|
        if (sms == null) { parent.debug('email', "Error: Failed to get SMS template"); return; } // No SMS template found
 | 
						|
 | 
						|
        // Setup the template
 | 
						|
        sms = sms.split('[[0]]').join(domain.title ? domain.title : 'MeshCentral');
 | 
						|
        sms = sms.split('[[1]]').join(verificationCode);
 | 
						|
 | 
						|
        // Send the SMS
 | 
						|
        obj.sendSMS(phoneNumber, sms, func);
 | 
						|
    };
 | 
						|
 | 
						|
    return obj;
 | 
						|
};
 |