Added messenger web application.

Ylian Saint-Hilaire committed Nov 29, 2018 at 17:59 UTC d30b5f348e800b7d1cc981106ff3a5706d32b58b
5 files changed +130 -9
letsEncrypt.js
+1 -1
@@ -125,6 +125,6 @@ module.exports.CreateLetsEncrypt = function (parent) {
125 };
126
127 return obj;
128 - } catch (e) { console.error(e); } // Unable to start Let's Encrypt
128 + } catch (ex) { console.log(ex); } // Unable to start Let's Encrypt
129 return null;
130 };
\ No newline at end of file
meshcentral.js
+6
@@ -14,6 +14,9 @@
14 /*jshint esversion: 6 */
15 "use strict";
16
17 +// If running NodeJS less than version 8, try to polyfill promisify
18 +try { if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) < 8) { require('util.promisify').shim(); } } catch (ex) { }
19 +
20 // If app metrics is available
21 if (process.argv[2] == '--launch') { try { require('appmetrics-dash').monitor({ url: '/', title: 'MeshCentral', port: 88, host: '127.0.0.1' }); } catch (e) { } }
22
@@ -1277,6 +1280,9 @@ function mainStart(args) {
1280 if (config.settings.mongodb != null) { modules.push('mongojs'); } // Add MongoDB
1281 if (config.smtp != null) { modules.push('nodemailer'); } // Add SMTP support
1282
1283 + // If running NodeJS < 8, install "util.promisify"
1284 + if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) < 8) { modules.push('util.promisify'); }
1285 +
1286 // Install any missing modules and launch the server
1287 InstallModules(modules, function () { meshserver = CreateMeshCentralServer(config, args); meshserver.Start(); });
1288 });
package.json
+5 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.2.3-o",
3 + "version": "0.2.3-r",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
@@ -35,12 +35,16 @@
35 "express-handlebars": "^3.0.0",
36 "express-session": "^1.15.6",
37 "express-ws": "^3.0.0",
38 + "greenlock": "^2.4.10",
39 + "le-acme-core": "^2.1.4",
40 + "le-store-certbot": "^2.2.1",
41 "meshcentral": "*",
42 "minimist": "^1.2.0",
43 "multiparty": "^4.2.1",
44 "nedb": "^1.8.0",
45 "node-forge": "^0.7.6",
46 "nodemailer": "^4.7.0",
47 + "util.promisify": "^1.0.0",
48 "ws": "^6.1.2",
49 "xmldom": "^0.1.27",
50 "yauzl": "^2.9.1"
public/messenger.htm new
+106
@@ -0,0 +1,106 @@
1 +<!DOCTYPE html>
2 +<html style=height:100%>
3 + <head>
4 + <meta http-equiv=X-UA-Compatible content="IE=edge">
5 + <meta content="text/html;charset=utf-8" http-equiv=Content-Type>
6 + <meta name=format-detection content="telephone=no">
7 + <link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
8 + <script type="text/javascript" src="scripts/common-0.0.1.js"></script>
9 + </head>
10 + <body style="font-family:Arial,Helvetica,sans-serif">
11 + <div id="xtop" style="position:absolute;left:0;right:0;top:0;height:30px;background-color:#036;color:#c8c8c8"><div style="padding-top:6px;padding-left:6px;font-size:medium"><b>Messenger<span id="xtitle"></span></b></div></div>
12 + <div id="xmiddle" style="position:absolute;left:0;right:0;top:30px;bottom:30px">
13 + <div id="xmsg" style="position:absolute;left:0;right:0;top:0px;bottom:0px;padding:5px;overflow-y:scroll"></div>
14 + </div>
15 + <div id="xbottom" style="position:absolute;left:0;right:0;bottom:0px;height:30px;background-color:#036">
16 + <div style="position:absolute;left:5px;right:215px;bottom:4px;top:4px;background-color:aliceblue"><input id="xouttext" type="text" style="width:calc(100% - 5px)" onfocus=onUserInputFocus(1) onblur=onUserInputFocus(0) /></div>
17 + <input type="button" id="sendButton" value="Send" style="position:absolute;right:110px;width:100px;top:4px;" onclick="xsend(event)" />
18 + <input type="button" id="clearButton" value="Clear" style="position:absolute;right:5px;width:100px;top:4px;" onclick="xclear(event)" />
19 + </div>
20 + <script type="text/javascript">
21 + var userInputFocus = 0;
22 + var controlsEnabled = true;
23 + var args = parseUriArgs();
24 + var socket = null;
25 + var state = 0;
26 +
27 + // Set the title
28 + if (args.title) { QH('xtitle', ' - ' + args.title); }
29 +
30 + // Trap document key presses
31 + document.onkeypress = function ondockeypress(e) {
32 + if (controlsEnabled == true) {
33 + if ((e.keyCode == 8) && (userInputFocus == 0)) {
34 + // Backspace
35 + var outtext = Q('xouttext').value;
36 + if (outtext.length > 0) { Q('xouttext').value = outtext.substring(0, outtext.length - 1); }
37 + } else if (e.keyCode == 13) {
38 + // Return
39 + xsend(e);
40 + } else {
41 + // Any other key
42 + if ((userInputFocus == 0) && (e.key.length == 1)) { Q('xouttext').value = Q('xouttext').value + e.key; }
43 + }
44 + }
45 + if (userInputFocus == 0) { haltEvent(e); return false; }
46 + }
47 +
48 + function onUserInputFocus(x) { userInputFocus = x; }
49 + function xclear(event) { QH('xmsg', ''); }
50 + function xcontrol(msg) {
51 + QA('xmsg', '<div style="clear:both"><div style="color:gray;float:left;margin-bottom:2px">' + msg + '</div><div></div></div>');
52 + Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
53 + }
54 + function xrecv(msg) {
55 + QA('xmsg', '<div style="clear:both"><div style="background-color:#00cc99;color:black;border-radius:5px;padding:5px;float:left;margin-bottom:5px;margin-right:20px">' + msg + '</div><div></div></div>');
56 + Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
57 + }
58 +
59 + function xsend(event) {
60 + var outtext = Q('xouttext').value;
61 + if (outtext.length > 0) {
62 + Q('xouttext').value = '';
63 + QA('xmsg', '<div style="clear:both"><div style="background-color:#0099ff;color:black;border-radius:5px;padding:5px;float:right;margin-bottom:5px;margin-left:20px">' + outtext + '</div><div></div></div>');
64 + Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
65 + socket.send(JSON.stringify({ action: 'chat', msg: outtext }));
66 + }
67 + }
68 +
69 + function enableControls(lock) {
70 + controlsEnabled = lock;
71 + QE('sendButton', lock);
72 + QE('clearButton', lock);
73 + QE('xouttext', lock);
74 + }
75 +
76 + function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
77 + function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = parsedUri[x]; break; } case 1: { r[name] = parsedUri[x]; var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } } } return r; }
78 +
79 + // Get started
80 + enableControls(false);
81 + if ((typeof args.id == 'string') && (args.id.length > 0)) {
82 + xcontrol('Connecting...');
83 + socket = new WebSocket(window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/meshrelay.ashx?id=' + args.id);
84 + socket.onopen = function () { xcontrol('Waiting for other user...'); }
85 + socket.onerror = function (e) { console.error(e); }
86 + socket.onclose = function () { enableControls(false); xcontrol('Connection closed.'); socket = null; }
87 + socket.onmessage = function (msg) {
88 + if ((state == 0) && (typeof msg.data == 'string')) { enableControls(true); xcontrol('Connected.'); state = 1; return; }
89 + if (state == 1) {
90 + if (typeof msg.data == 'string') {
91 + var obj = JSON.parse(msg.data);
92 + switch (obj.action) {
93 + case 'chat': { xrecv(obj.msg); break; }
94 + }
95 + } else {
96 + //xrecv(JSON.stringify(msg));
97 + }
98 + }
99 + }
100 + } else {
101 + xcontrol('Error: No connection key specified.');
102 + }
103 +
104 + </script>
105 +</body>
106 +</html>
redirserver.js
+12 -7
@@ -52,13 +52,18 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
52
53 // Renter the terms of service.
54 obj.app.get("/MeshServerRootCert.cer", function (req, res) {
55 - res.set({ "Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0", "Content-Type": "application/octet-stream", "Content-Disposition": "attachment; filename=" + obj.certificates.RootName + ".cer" });
56 - var rootcert = obj.certificates.root.cert;
57 - var i = rootcert.indexOf("-----BEGIN CERTIFICATE-----\r\n");
58 - if (i >= 0) { rootcert = rootcert.substring(i + 29); }
59 - i = rootcert.indexOf("-----END CERTIFICATE-----");
60 - if (i >= 0) { rootcert = rootcert.substring(i, 0); }
61 - res.send(new Buffer(rootcert, "base64"));
55 + // The redirection server starts before certificates are loaded, make sure to handle the case where no certificate is loaded now.
56 + if (obj.certificates != null) {
57 + res.set({ "Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0", "Content-Type": "application/octet-stream", "Content-Disposition": "attachment; filename=" + obj.certificates.RootName + ".cer" });
58 + var rootcert = obj.certificates.root.cert;
59 + var i = rootcert.indexOf("-----BEGIN CERTIFICATE-----\r\n");
60 + if (i >= 0) { rootcert = rootcert.substring(i + 29); }
61 + i = rootcert.indexOf("-----END CERTIFICATE-----");
62 + if (i >= 0) { rootcert = rootcert.substring(i, 0); }
63 + res.send(new Buffer(rootcert, "base64"));
64 + } else {
65 + res.sendStatus(404);
66 + }
67 });
68
69 // Add HTTP security headers to all responses