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
+ ♦
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 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);