Started work on agent install using invitation code.

Ylian Saint-Hilaire committed Mar 16, 2020 at 15:23 UTC eb1c6a0be1751f8d2381c9346f61059c84cb5022
4 files changed +249
translate/translate.js
+1
@@ -18,6 +18,7 @@ var minify = null;
18
19 var meshCentralSourceFiles = [
20 "../views/agentinvite.handlebars",
21 + "../views/invite.handlebars",
22 "../views/default.handlebars",
23 "../views/default-mobile.handlebars",
24 "../views/download.handlebars",
translate/translate.json
+31
@@ -7807,6 +7807,7 @@
7807 "agentinvite.handlebars->container->topbar->uiMenuButton->uiMenu",
7808 "default.handlebars->container->topbar->1->1->uiMenuButton->uiMenu",
7809 "error404.handlebars->container->topbar->uiMenuButton->uiMenu",
7810 + "invite.handlebars->container->topbar->uiMenuButton->uiMenu",
7811 "login.handlebars->container->topbar->uiMenuButton->uiMenu",
7812 "terms.handlebars->container->topbar->uiMenuButton->uiMenu"
7813 ]
@@ -9781,6 +9782,12 @@
9782 "login.handlebars->5->9"
9783 ]
9784 },
9785 + {
9786 + "en": "Invalid invitation code.",
9787 + "xloc": [
9788 + "invite.handlebars->3->1"
9789 + ]
9790 + },
9791 {
9792 "cs": "Neplatný token, zkuste to znovu.",
9793 "de": "Ungültiges Token, versuchen Sie es erneut.",
@@ -9823,6 +9830,12 @@
9830 "default.handlebars->27->263"
9831 ]
9832 },
9833 + {
9834 + "en": "Invitation Code",
9835 + "xloc": [
9836 + "invite.handlebars->container->column_l->5->1->0->3->1"
9837 + ]
9838 + },
9839 {
9840 "cs": "Pozvat",
9841 "de": "Einladen",
@@ -10524,6 +10537,7 @@
10537 "agentinvite.handlebars->container->topbar->uiMenuButton->uiMenu",
10538 "default.handlebars->container->topbar->1->1->uiMenuButton->uiMenu",
10539 "error404.handlebars->container->topbar->uiMenuButton->uiMenu",
10540 + "invite.handlebars->container->topbar->uiMenuButton->uiMenu",
10541 "login.handlebars->container->topbar->uiMenuButton->uiMenu",
10542 "terms.handlebars->container->topbar->uiMenuButton->uiMenu"
10543 ]
@@ -17805,6 +17819,12 @@
17819 "login.handlebars->5->27"
17820 ]
17821 },
17822 + {
17823 + "en": "Submit",
17824 + "xloc": [
17825 + "invite.handlebars->container->column_l->5->1->0->3->3->3"
17826 + ]
17827 + },
17828 {
17829 "cs": "Úspěch",
17830 "de": "Erfolg",
@@ -18275,6 +18295,12 @@
18295 "default.handlebars->27->1006"
18296 ]
18297 },
18298 + {
18299 + "en": "This is a portal for computer remote management and support.",
18300 + "xloc": [
18301 + "invite.handlebars->container->column_l->3"
18302 + ]
18303 + },
18304 {
18305 "cs": "Toto není bezpečná zásada, protože aktivaci budou provádět agenti.",
18306 "de": "Dies ist keine sichere Richtlinie, da Agenten die Aktivierung durchführen.",
@@ -18640,6 +18666,7 @@
18666 "agentinvite.handlebars->container->topbar->uiMenuButton->uiMenu",
18667 "default.handlebars->container->topbar->1->1->uiMenuButton->uiMenu",
18668 "error404.handlebars->container->topbar->uiMenuButton->uiMenu",
18669 + "invite.handlebars->container->topbar->uiMenuButton->uiMenu",
18670 "login.handlebars->container->topbar->uiMenuButton->uiMenu",
18671 "terms.handlebars->container->topbar->uiMenuButton->uiMenu"
18672 ]
@@ -18723,6 +18750,7 @@
18750 "agentinvite.handlebars->container->topbar->uiMenuButton->uiMenu",
18751 "default.handlebars->container->topbar->1->1->uiMenuButton->uiMenu",
18752 "error404.handlebars->container->topbar->uiMenuButton->uiMenu",
18753 + "invite.handlebars->container->topbar->uiMenuButton->uiMenu",
18754 "login.handlebars->container->topbar->uiMenuButton->uiMenu",
18755 "terms.handlebars->container->topbar->uiMenuButton->uiMenu"
18756 ]
@@ -19690,6 +19718,7 @@
19718 "agentinvite.handlebars->container->topbar",
19719 "default.handlebars->container->topbar->1->1",
19720 "error404.handlebars->container->topbar",
19721 + "invite.handlebars->container->topbar",
19722 "login.handlebars->container->topbar",
19723 "terms.handlebars->container->topbar"
19724 ]
@@ -20139,6 +20168,7 @@
20168 "pt": "Bem vindo",
20169 "ru": "Добро пожаловать",
20170 "xloc": [
20171 + "invite.handlebars->container->column_l->1",
20172 "login.handlebars->container->column_l->1"
20173 ]
20174 },
@@ -21922,6 +21952,7 @@
21952 "agentinvite.handlebars->container->topbar->uiMenuButton",
21953 "default.handlebars->container->topbar->1->1->uiMenuButton",
21954 "error404.handlebars->container->topbar->uiMenuButton",
21955 + "invite.handlebars->container->topbar->uiMenuButton",
21956 "login.handlebars->container->topbar->uiMenuButton",
21957 "terms.handlebars->container->topbar->uiMenuButton"
21958 ]
views/invite.handlebars new
+202
@@ -0,0 +1,202 @@
1 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 +<html>
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="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
7 + <meta name="apple-mobile-web-app-capable" content="yes" />
8 + <meta name="format-detection" content="telephone=no" />
9 + <link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
10 + <script type="text/javascript" src="scripts/common-0.0.1.js"></script>
11 + <title>Agent Installation</title>
12 + <style>
13 + .tab {
14 + overflow: hidden;
15 + border: 1px solid #ccc;
16 + background-color: #f1f1f1;
17 + }
18 +
19 + .tab button {
20 + background-color: inherit;
21 + float: left;
22 + border: none;
23 + outline: none;
24 + cursor: pointer;
25 + padding: 14px 16px;
26 + transition: 0.3s;
27 + }
28 +
29 + .tab button:hover {
30 + background-color: #ddd;
31 + }
32 +
33 + .tab button.active {
34 + background-color: #8f8;
35 + }
36 +
37 + .tabcontent {
38 + display: none;
39 + padding: 6px 12px;
40 + border: 1px solid #ccc;
41 + border-top: none;
42 + }
43 +
44 + </style>
45 +</head>
46 +<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
47 + <div id="container">
48 + <!-- Begin Masthead -->
49 + <div id="masthead" class=noselect style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
50 + <div style="float:left">{{{titlehtml}}}</div>
51 + <div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
52 + <strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
53 + </div>
54 + <div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
55 + <strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
56 + </div>
57 + <p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
58 + </div>
59 + <div id="page_leftbar">
60 + <div style="height:16px"></div>
61 + </div>
62 + <div id=topbar class="noselect style3" style="height:24px;position:relative">
63 + <div id=uiMenuButton title="User interface selection" onclick="showUserInterfaceSelectMenu()">
64 + &diams;
65 + <div id=uiMenu style="display:none">
66 + <div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title="Left bar interface"><div class="uiSelector1"></div></div>
67 + <div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title="Top bar interface"><div class="uiSelector2"></div></div>
68 + <div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title="Fixed width interface"><div class="uiSelector3"></div></div>
69 + <div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title="Toggle night mode"><div class="uiSelector4"></div></div>
70 + </div>
71 + </div>
72 + </div>
73 + <div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
74 + <h1>Welcome</h1>
75 + <p>
76 + This is a portal for computer remote management and support.
77 + </p>
78 + <table style="text-align:center;margin-top:60px;width:100%">
79 + <tr>
80 + <td style="width:33%"></td>
81 + <td style="font-size:20px;background-color:#DDD;padding:12px;border-radius:16px">
82 + <div style="margin-bottom:10px">Invitation&nbsp;Code</div>
83 + <form method=post>
84 + <div><input id="inviteCode" name="inviteCode" style="font-size:26px;text-align:center;border-radius:6px" maxlength="20" /></div>
85 + <div><input type="submit" style="margin-top:10px" value="Submit" /></div>
86 + </form>
87 + <div id="message" style="margin-top:8px;font-size:16px;display:none"></div>
88 + </td>
89 + <td style="width:33%"></td>
90 + </tr>
91 + </table>
92 + </div>
93 + <div id="footer">
94 + <table cellpadding="0" cellspacing="10" style="width: 100%">
95 + <tr>
96 + <td style="text-align:left"></td>
97 + <td style="text-align:right"></td>
98 + </tr>
99 + </table>
100 + </div>
101 + </div>
102 + <script>
103 + 'use strict';
104 + var urlargs = parseUriArgs();
105 + var uiMode = parseInt(getstore('uiMode', 1));
106 + var webPageStackMenu = false;
107 + var webPageFullScreen = true;
108 + var nightMode = (getstore('_nightMode', '0') == '1');
109 + userInterfaceSelectMenu();
110 + Q('inviteCode').focus();
111 + start();
112 + document.onclick = function (e) { Q('inviteCode').focus(); }
113 +
114 + function start() {
115 + if (urlargs.c != null) { Q('inviteCode').value = urlargs.c; }
116 +
117 + var messageid = parseInt('{{{messageid}}}');
118 + var okmessages = [''];
119 + var failmessages = ["Invalid invitation code."];
120 + if (messageid > 0) {
121 + var msg = '';
122 + if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
123 + else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
124 + if (msg != '') {
125 + if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span>'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span>'); }
126 + QH('message', msg);
127 + QV('message', true);
128 + }
129 + }
130 + }
131 +
132 + // Toggle user interface menu
133 + function showUserInterfaceSelectMenu() {
134 + Q('uiViewButton1').classList.remove('uiSelectorSel');
135 + Q('uiViewButton2').classList.remove('uiSelectorSel');
136 + Q('uiViewButton3').classList.remove('uiSelectorSel');
137 + Q('uiViewButton4').classList.remove('uiSelectorSel');
138 + try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
139 + QV('uiMenu', (QS('uiMenu').display == 'none'));
140 + if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
141 + }
142 +
143 + function userInterfaceSelectMenu(s) {
144 + if (s) { uiMode = s; putstore('uiMode', uiMode); }
145 + webPageFullScreen = (uiMode < 3);
146 + webPageStackMenu = true;//(uiMode > 1);
147 + toggleFullScreen(0);
148 + toggleStackMenu(0);
149 + QC('column_l').add('room4submenu');
150 + }
151 +
152 + function toggleNightMode() {
153 + nightMode = !nightMode;
154 + if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
155 + putstore('_nightMode', nightMode ? '1' : '0');
156 + }
157 +
158 + // Toggle the web page to full screen
159 + function toggleFullScreen(toggle) {
160 + if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
161 + var hide = 0;
162 + //if (args.hide) { hide = parseInt(args.hide); }
163 + if (webPageFullScreen == false) {
164 + QC('body').remove('menu_stack');
165 + QC('body').remove('fullscreen');
166 + QC('body').remove('arg_hide');
167 + //if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
168 + //QV('UserDummyMenuSpan', false);
169 + //QV('page_leftbar', false);
170 + } else {
171 + QC('body').add('fullscreen');
172 + if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
173 + //QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
174 + //QV('page_leftbar', true);
175 + }
176 + QV('body', true);
177 + }
178 +
179 + // If FullScreen, toggle menu to be horisontal or vertical
180 + function toggleStackMenu(toggle) {
181 + if (webPageFullScreen == true) {
182 + if (toggle === 1) {
183 + webPageStackMenu = !webPageStackMenu;
184 + putstore('webPageStackMenu', webPageStackMenu);
185 + }
186 + if (webPageStackMenu == false) {
187 + QC('body').remove('menu_stack');
188 + } else {
189 + QC('body').add('menu_stack');
190 + //if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
191 + }
192 + }
193 + }
194 +
195 + function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
196 + function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
197 + function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
198 + function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
199 +
200 + </script>
201 +</body>
202 +</html>
webserver.js
+15
@@ -1263,6 +1263,19 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1263 }
1264 }
1265
1266 + // Called to process an agent invite GET/POST request
1267 + function handleInviteRequest(req, res) {
1268 + const domain = getDomain(req);
1269 + if (domain == null) { parent.debug('web', 'handleInviteRequest: failed checks.'); res.sendStatus(404); return; }
1270 + if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1271 + if ((req.body.inviteCode == null) || (req.body.inviteCode == '')) { render(req, res, getRenderPage('invite', req), getRenderArgs({ messageid: 0 }, domain)); return; } // No invitation code
1272 +
1273 + // Send invitation link, valid for 1 minute.
1274 + //res.redirect(domain.url + 'agentinvite?c=' + parent.encodeCookie({ a: 4, mid: 'mesh//xxxxx', f: 0, expire: 1 }, parent.invitationLinkEncryptionKey));
1275 +
1276 + render(req, res, getRenderPage('invite', req), getRenderArgs({ messageid: 100 }, domain)); // Bad invitation code
1277 + }
1278 +
1279 // Called to process an agent invite request
1280 function handleAgentInviteRequest(req, res) {
1281 const domain = getDomain(req);
@@ -3596,6 +3609,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3609 obj.app.post(url + 'resetpassword', handleResetPasswordRequest);
3610 obj.app.post(url + 'resetaccount', handleResetAccountRequest);
3611 obj.app.get(url + 'checkmail', handleCheckMailRequest);
3612 + obj.app.get(url + 'invite', handleInviteRequest);
3613 + obj.app.post(url + 'invite', handleInviteRequest);
3614 obj.app.get(url + 'agentinvite', handleAgentInviteRequest);
3615 obj.app.post(url + 'amtevents.ashx', obj.handleAmtEventRequest);
3616 obj.app.get(url + 'meshagents', obj.handleMeshAgentRequest);