diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj
index 37ee0ca1..6097d310 100644
--- a/MeshCentralServer.njsproj
+++ b/MeshCentralServer.njsproj
@@ -97,6 +97,7 @@
+
@@ -618,25 +619,31 @@
+
+
+
+
+
+
diff --git a/firebase.js b/firebase.js
new file mode 100644
index 00000000..1bf752cb
--- /dev/null
+++ b/firebase.js
@@ -0,0 +1,72 @@
+/**
+* @description MeshCentral Firebase communication module
+* @author Ylian Saint-Hilaire
+* @copyright Intel Corporation 2018-2021
+* @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";
+
+// Construct the Firebase object
+module.exports.CreateFirebase = function (parent, senderid, serverkey) {
+ var obj = {};
+ obj.messageId = 1;
+
+ const Sender = require('node-xcs').Sender;
+ const Message = require('node-xcs').Message;
+ const Notification = require('node-xcs').Notification;
+ const xcs = new Sender(senderid, serverkey);
+
+ // Messages received from client (excluding receipts)
+ xcs.on('message', function (messageId, from, data, category) {
+ console.log('Firebase-Message', messageId, from, data, category);
+ });
+
+ // Only fired for messages where options.delivery_receipt_requested = true
+ /*
+ xcs.on('receipt', function (messageId, from, data, category) { console.log('Firebase-Receipt', messageId, from, data, category); });
+ xcs.on('connected', function () { console.log('Connected'); });
+ xcs.on('disconnected', function () { console.log('disconnected'); });
+ xcs.on('online', function () { console.log('online'); });
+ xcs.on('error', function (e) { console.log('error', e); });
+ xcs.on('message-error', function (e) { console.log('message-error', e); });
+ */
+
+ xcs.start();
+
+ //var payload = { notification: { title: command.title, body: command.msg }, data: { url: obj.msgurl } };
+ //var options = { priority: 'High', timeToLive: 5 * 60 }; // TTL: 5 minutes, priority 'Normal' or 'High'
+
+ // Send an outbound push notification
+ obj.sendToDevice = function (token, payload, options, func) {
+ // Built the on-screen notification
+ var notification = null;
+ if (payload.notification) {
+ var notification = new Notification('ic_launcher')
+ .title(payload.notification.title)
+ .body(payload.notification.body)
+ .build();
+ }
+
+ // Build the message
+ var message = new Message('msg_' + (++obj.messageId));
+ if (options.priority) { message.priority(options.priority); }
+ if (payload.data) { for (var i in payload.data) { message.addData(i, payload.data[i]); } }
+ if (notification) { message.notification(notification) }
+ message.build();
+
+ // Send the message
+ function callback(result) { callback.func(result.getMessageId(), result.getError(), result.getErrorDescription()) }
+ callback.func = func;
+ xcs.sendNoRetry(message, token, callback);
+ }
+
+ return obj;
+};
\ No newline at end of file
diff --git a/meshcentral.js b/meshcentral.js
index 32d782d8..712ccb9f 100644
--- a/meshcentral.js
+++ b/meshcentral.js
@@ -1545,15 +1545,8 @@ function CreateMeshCentralServer(config, args) {
}
// Setup Firebase
- if (config.firebase != null) {
- try {
- obj.firebase = require('firebase-admin');
- var firebaseServiceAccount = require(obj.path.join(obj.datapath, config.firebase.serviceaccountkeyfile));
- obj.firebase.initializeApp({ credential: obj.firebase.credential.cert(firebaseServiceAccount) });
- } catch (ex) {
- console.log('Unable to setup Firebase: ' + ex);
- delete obj.firebase;
- }
+ if ((config.firebase != null) && (typeof config.firebase.senderid == 'string') && (typeof config.firebase.serverkey == 'string')) {
+ obj.firebase = require('./firebase').CreateFirebase(this, config.firebase.senderid, config.firebase.serverkey);
}
// Start periodic maintenance
@@ -3066,7 +3059,7 @@ function mainStart() {
}
// Firebase Support
- if (config.firebase != null) { modules.push('firebase-admin'); }
+ if (config.firebase != null) { modules.push('node-xcs'); }
// Syslog support
if ((require('os').platform() != 'win32') && (config.settings.syslog || config.settings.syslogjson)) { modules.push('modern-syslog'); }
diff --git a/meshrelay.js b/meshrelay.js
index 46f1bdac..aec63528 100644
--- a/meshrelay.js
+++ b/meshrelay.js
@@ -414,11 +414,12 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
}
}
});
+ parent.wsrelays[obj.id] = { peer1: obj, state: 1 }; // No timeout on connections with push notification.
} else {
ws._socket.pause(); // Hold traffic until the other connection
parent.parent.debug('relay', 'Relay holding: ' + obj.id + ' (' + obj.req.clientIp + ') ' + (obj.authenticated ? 'Authenticated' : ''));
+ parent.wsrelays[obj.id] = { peer1: obj, state: 1, timeout: setTimeout(closeBothSides, 60000) };
}
- parent.wsrelays[obj.id] = { peer1: obj, state: 1, timeout: setTimeout(closeBothSides, 30000) };
// Check if a peer server has this connection
if (parent.parent.multiServer != null) {
@@ -485,15 +486,15 @@ function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
command.title = (domain.title ? domain.title : 'MeshCentral');
var payload = { notification: { title: command.title, body: command.msg }, data: { url: obj.msgurl } };
var options = { priority: 'High', timeToLive: 5 * 60 }; // TTL: 5 minutes, priority 'Normal' or 'High'
- parent.parent.firebase.messaging().sendToDevice(obj.pmt, payload, options)
- .then(function (response) {
+ parent.parent.firebase.sendToDevice(obj.pmt, payload, options, function (id, err, errdesc) {
+ if (err == null) {
parent.parent.debug('email', 'Successfully send push message to device ' + obj.nodename + ', title: ' + command.title + ', msg: ' + command.msg);
try { ws.send(JSON.stringify({ action: 'ctrl', value: 1 })); } catch (ex) { } // Push notification success
- })
- .catch(function (error) {
- parent.parent.debug('email', 'Failed to send push message to device ' + obj.nodename + ', title: ' + command.title + ', msg: ' + command.msg + ', error: ' + error);
+ } else {
+ parent.parent.debug('email', 'Failed to send push message to device ' + obj.nodename + ', title: ' + command.title + ', msg: ' + command.msg + ', error: ' + errdesc);
try { ws.send(JSON.stringify({ action: 'ctrl', value: 2 })); } catch (ex) { } // Push notification failed
- });
+ }
+ });
}
}
});
diff --git a/meshuser.js b/meshuser.js
index 260bfbc2..52fdb590 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -5207,13 +5207,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Send out a push message to the device
var payload = { notification: { title: command.title, body: command.msg } };
var options = { priority: "Normal", timeToLive: 5 * 60 }; // TTL: 5 minutes
- parent.parent.firebase.messaging().sendToDevice(node.pmt, payload, options)
- .then(function (response) {
+ parent.parent.firebase.sendToDevice(node.pmt, payload, options, function (id, err, errdesc) {
+ if (err == null) {
parent.parent.debug('email', 'Successfully send push message to device ' + node.name + ', title: ' + command.title + ', msg: ' + command.msg);
- })
- .catch(function (error) {
- parent.parent.debug('email', 'Failed to send push message to device ' + node.name + ', title: ' + command.title + ', msg: ' + command.msg + ', error: ' + error);
- });
+ } else {
+ parent.parent.debug('email', 'Failed to send push message to device ' + node.name + ', title: ' + command.title + ', msg: ' + command.msg + ', error: ' + errdesc);
+ }
+ });
}
}
});
@@ -5231,14 +5231,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Send out a push message to the device
var payload = { data: { console: command.console, session: ws.sessionId } };
var options = { priority: "Normal", timeToLive: 60 }; // TTL: 1 minutes, priority 'Normal' or 'High'
- parent.parent.firebase.messaging().sendToDevice(node.pmt, payload, options)
- .then(function (response) {
+ parent.parent.firebase.sendToDevice(node.pmt, payload, options, function (id, err, errdesc) {
+ if (err == null) {
try { ws.send(JSON.stringify({ action: 'msg', type: 'console', nodeid: node._id, value: 'OK' })); } catch (ex) { }
- })
- .catch(function (error) {
- try { ws.send(JSON.stringify({ action: 'msg', type: 'console', nodeid: node._id, value: 'Failed: ' + error })); } catch (ex) { }
- parent.parent.debug('email', 'Failed to send push console message to device ' + node.name + ', command: ' + command.console + ', error: ' + error);
- });
+ } else {
+ try { ws.send(JSON.stringify({ action: 'msg', type: 'console', nodeid: node._id, value: 'Failed: ' + errdesc })); } catch (ex) { }
+ parent.parent.debug('email', 'Failed to send push console message to device ' + node.name + ', command: ' + command.console + ', error: ' + errdesc);
+ }
+ });
}
}
});
diff --git a/package.json b/package.json
index 987d0f3d..3510ece1 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
"author": "Ylian Saint-Hilaire ",
"main": "meshcentral.js",
"bin": {
- "meshcentral": "./bin/meshcentral"
+ "meshcentral": "bin/meshcentral"
},
"license": "Apache-2.0",
"files": [
@@ -53,7 +53,6 @@
"xmldom": "^0.1.27",
"yauzl": "^2.10.0"
},
- "devDependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/Ylianst/MeshCentral.git"