More multi-language work.
Ylian Saint-Hilaire committed
Oct 18, 2019 at 19:35 UTC
620adfd6cb8f6df9af98b7fe3aefbbc967ad1797
3 files changed
+298
-9549
views/default-fr.handlebars
deleted
-9282
@@ -1,9282 +0,0 @@
1
-<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
2
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
3
- <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
4
- <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
5
- <meta name="apple-mobile-web-app-capable" content="yes">
6
- <meta name="format-detection" content="telephone=no">
7
- <link rel="shortcut icon" type="image/x-icon" href="{{{domainurl}}}favicon.ico">
8
- <link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
9
- <link type="text/css" href="styles/ol.css" media="screen" rel="stylesheet" title="CSS">
10
- <link type="text/css" href="styles/ol3-contextmenu.min.css" media="screen" rel="stylesheet" title="CSS">
11
- <script type="text/javascript" src="scripts/common-0.0.1.js"></script>
12
- <script type="text/javascript" src="scripts/meshcentral.js"></script>
13
- <script type="text/javascript" src="scripts/amt-0.2.0.js"></script>
14
- <script type="text/javascript" src="scripts/amt-wsman-0.2.0.js"></script>
15
- <script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
16
- <script type="text/javascript" src="scripts/amt-terminal-0.0.2.js"></script>
17
- <script type="text/javascript" src="scripts/zlib.js"></script>
18
- <script type="text/javascript" src="scripts/zlib-inflate.js"></script>
19
- <script type="text/javascript" src="scripts/zlib-adler32.js"></script>
20
- <script type="text/javascript" src="scripts/zlib-crc32.js"></script>
21
- <script type="text/javascript" src="scripts/amt-redir-ws-0.1.0.js"></script>
22
- <script type="text/javascript" src="scripts/amt-wsman-ws-0.2.0.js"></script>
23
- <script type="text/javascript" src="scripts/agent-redir-ws-0.1.1.js"></script>
24
- <script type="text/javascript" src="scripts/agent-redir-rtc-0.1.0.js"></script>
25
- <script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
26
- <script type="text/javascript" src="scripts/qrcode.min.js"></script>
27
- <script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
28
- <script keeplink="1" type="text/javascript" src="scripts/charts.js"></script>
29
- <script keeplink="1" type="text/javascript" src="scripts/filesaver.js"></script>
30
- <script keeplink="1" type="text/javascript" src="scripts/ol.js"></script>
31
- <script keeplink="1" type="text/javascript" src="scripts/ol3-contextmenu.js"></script>
32
- <title>{{{title}}}</title>
33
-</head>
34
-<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none;min-width:495px">
35
- <!-- right click menu -->
36
- <div id="contextMenu" class="contextMenu noselect" style="display:none">
37
- <div id="cxinfo" class="cmtext" onclick="cmaction(1,event)"><b>Information</b></div>
38
- <div id="cxdesktop" class="cmtext" onclick="cmaction(3,event)">Desktop</div>
39
- <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div>
40
- <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div>
41
- <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div>
42
- <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div>
43
- <hr id="cxmgroupsplit">
44
- <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style="display:none">Multi-Desktop</div>
45
- </div>
46
- <div id="meshContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
47
- <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div>
48
- <div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2,event)">Select None</div>
49
- <!--
50
- <hr id="cxmgroupsplit2" style="display:none" />
51
- <div id="cxmmdesktop" class="cmtext" style="display:none" onclick="cmmeshaction(3,event)">Multi-Desktop</div>
52
- -->
53
- </div>
54
- <div id="termShellContextMenu" class="contextMenu noselect" style="display:none;min-width:0px">
55
- <div id="cxtermnorm" class="cmtext" onclick="cmtermaction(1,event)">Normal Connect</div>
56
- <div id="cxtermps" class="cmtext" onclick="cmtermaction(2,event)">PowerShell Connect</div>
57
- </div>
58
- <!-- main page -->
59
- <div id="container">
60
- <div id="notifiyBox" class="notifiyBox" style="display:none"></div>
61
- <div id="masthead" class="noselect">
62
- <div class="title">{{{title}}}</div>
63
- <div class="title2">{{{title2}}}</div>
64
- <div style="float:right">
65
- <div id="notificationCount" onclick="clickNotificationIcon()" class="unselectable" style="display: none;" title="Click to view current notifications">0</div>
66
- </div>
67
- <p id="logoutControl">{{{logoutControl}}}<span id="idleTimeoutNotify" style="color:yellow"></span></p>
68
- </div>
69
- <div id="page_leftbar">
70
- <div style="height:16px"></div>
71
- <div id="LeftMenuMyDevices" tabindex="0" class="lbbutton lbbuttonsel" title="My Devices" onclick="go(1,event)" onkeypress="if (event.key=='Enter') { go(1); }">
72
- <div class="lb2"></div>
73
- </div>
74
- <div id="LeftMenuMyAccount" tabindex="0" class="lbbutton" title="My Account" onclick="go(2,event)" onkeypress="if (event.key=='Enter') { go(2); }">
75
- <div class="lb1"></div>
76
- </div>
77
- <div id="LeftMenuMyEvents" tabindex="0" class="lbbutton" title="My Events" onclick="go(3,event)" onkeypress="if (event.key=='Enter') { go(3); }">
78
- <div class="lb3"></div>
79
- </div>
80
- <div id="LeftMenuMyFiles" tabindex="0" class="lbbutton" style="display:none" title="My Files" onclick="go(5,event)" onkeypress="if (event.key=='Enter') { go(5); }">
81
- <div class="lb4"></div>
82
- </div>
83
- <div id="LeftMenuMyUsers" tabindex="0" class="lbbutton" style="display:none" title="My Users" onclick="go(4,event)" onkeypress="if (event.key=='Enter') { go(4); }">
84
- <div class="lb5"></div>
85
- </div>
86
- <div id="LeftMenuMyServer" tabindex="0" class="lbbutton" style="display:none" title="My Server" onclick="go(6,event)" onkeypress="if (event.key=='Enter') { go(6); }">
87
- <div class="lb6"></div>
88
- </div>
89
- </div>
90
- <div id="topbar" class="noselect">
91
- <div>
92
- <div style="position:relative">
93
- <div tabindex="0" id="uiMenuButton" title="User interface selection" onclick="showUserInterfaceSelectMenu()" onkeypress="if (event.key == 'Enter') showUserInterfaceSelectMenu()">
94
- ♦
95
- <div id="uiMenu" style="display:none">
96
- <div tabindex="0" id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Left bar interface" onkeypress="if (event.key == 'Enter') userInterfaceSelectMenu(1)"><div class="uiSelector1"></div></div>
97
- <div tabindex="0" id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Top bar interface" onkeypress="if (event.key == 'Enter') userInterfaceSelectMenu(2)"><div class="uiSelector2"></div></div>
98
- <div tabindex="0" id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Fixed width interface" onkeypress="if (event.key == 'Enter') userInterfaceSelectMenu(3)"><div class="uiSelector3"></div></div>
99
- <div tabindex="0" id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Toggle night mode" onkeypress="if (event.key == 'Enter') toggleNightMode()"><div class="uiSelector4"></div></div>
100
- </div>
101
- </div>
102
- <table id="MainMenuSpan" cellpadding="0" cellspacing="0" class="style1">
103
- <tbody><tr>
104
- <td tabindex="0" id="MainMenuMyDevices" class="topbar_td style3x" onclick="go(1,event)" onkeypress="if (event.key == 'Enter') go(1)">My Devices</td>
105
- <td tabindex="0" id="MainMenuMyAccount" class="topbar_td style3x" onclick="go(2,event)" onkeypress="if (event.key == 'Enter') go(2)">My Account</td>
106
- <td tabindex="0" id="MainMenuMyEvents" class="topbar_td style3x" onclick="go(3,event)" onkeypress="if (event.key == 'Enter') go(3)">My Events</td>
107
- <td tabindex="0" id="MainMenuMyFiles" class="topbar_td style3x" onclick="go(5,event)" onkeypress="if (event.key == 'Enter') go(5)">My Files</td>
108
- <td tabindex="0" id="MainMenuMyUsers" class="topbar_td style3x" onclick="go(4,event)" onkeypress="if (event.key == 'Enter') go(4)">My Users</td>
109
- <td tabindex="0" id="MainMenuMyServer" class="topbar_td style3x" onclick="go(6,event)" onkeypress="if (event.key == 'Enter') go(6)">My Server</td>
110
- <td class="topbar_td_end style3"> </td>
111
- </tr>
112
- </tbody></table>
113
- <div id="MainSubMenuSpan" style="display:none">
114
- <table id="MainSubMenu" cellpadding="0" cellspacing="0" class="style1">
115
- <tbody><tr>
116
- <td tabindex="0" id="MainDev" class="topbar_td style3x" onclick="go(10,event)" onkeypress="if (event.key == 'Enter') go(10)">General</td>
117
- <td tabindex="0" id="MainDevDesktop" class="topbar_td style3x" onclick="go(11,event)" onkeypress="if (event.key == 'Enter') go(11)">Desktop</td>
118
- <td tabindex="0" id="MainDevTerminal" class="topbar_td style3x" onclick="go(12,event)" onkeypress="if (event.key == 'Enter') go(12)">Terminal</td>
119
- <td tabindex="0" id="MainDevFiles" class="topbar_td style3x" onclick="go(13,event)" onkeypress="if (event.key == 'Enter') go(13)">Files</td>
120
- <td tabindex="0" id="MainDevEvents" class="topbar_td style3x" onclick="go(16,event)" onkeypress="if (event.key == 'Enter') go(16)">Events</td>
121
- <td tabindex="0" id="MainDevInfo" class="topbar_td style3x" onclick="go(17,event)" onkeypress="if (event.key == 'Enter') go(17)">Details</td>
122
- <td tabindex="0" id="MainDevAmt" class="topbar_td style3x" onclick="go(14,event)" onkeypress="if (event.key == 'Enter') go(14)">Intel® AMT</td>
123
- <td tabindex="0" id="MainDevConsole" class="topbar_td style3x" onclick="go(15,event)" onkeypress="if (event.key == 'Enter') go(15)">Console</td>
124
- <td tabindex="0" id="MainDevPlugins" class="topbar_td style3x" onclick="go(19,event)" onkeypress="if (event.key == 'Enter') go(19)">Plugins</td>
125
- <td class="topbar_td_end style3"> </td>
126
- </tr>
127
- </tbody></table>
128
- </div>
129
- <div id="MeshSubMenuSpan" style="display:none">
130
- <table id="MeshSubMenu" cellpadding="0" cellspacing="0" class="style1">
131
- <tbody><tr>
132
- <td tabindex="0" id="MeshGeneral" class="topbar_td style3x" onclick="go(20,event)" onkeypress="if (event.key == 'Enter') go(20)">General</td>
133
- <td class="topbar_td_end style3"> </td>
134
- </tr>
135
- </tbody></table>
136
- </div>
137
- <div id="UserSubMenuSpan" style="display:none">
138
- <table id="UserSubMenu" cellpadding="0" cellspacing="0" class="style1">
139
- <tbody><tr>
140
- <td tabindex="0" id="UserGeneral" class="topbar_td style3x" onclick="go(30,event)" onkeypress="if (event.key == 'Enter') go(30)">General</td>
141
- <td tabindex="0" id="UserEvents" class="topbar_td style3x" onclick="go(31,event)" onkeypress="if (event.key == 'Enter') go(31)">Events</td>
142
- <td class="topbar_td_end style3"> </td>
143
- </tr>
144
- </tbody></table>
145
- </div>
146
- <div id="ServerSubMenuSpan" style="display:none">
147
- <table id="ServerSubMenu" cellpadding="0" cellspacing="0" class="style1">
148
- <tbody><tr>
149
- <td tabindex="0" id="ServerGeneral" class="topbar_td style3x" onclick="go(6,event)" onkeypress="if (event.key == 'Enter') go(6)">General</td>
150
- <td tabindex="0" id="ServerStats" class="topbar_td style3x" onclick="go(40,event)" onkeypress="if (event.key == 'Enter') go(40)">Stats</td>
151
- <td tabindex="0" id="ServerConsole" class="topbar_td style3x" onclick="go(115,event)" onkeypress="if (event.key == 'Enter') go(115)">Console</td>
152
- <td tabindex="0" id="ServerTrace" class="topbar_td style3x" onclick="go(41,event)" onkeypress="if (event.key == 'Enter') go(41)">Trace</td>
153
- <td class="topbar_td_end style3"> </td>
154
- </tr>
155
- </tbody></table>
156
- </div>
157
- <div id="UserDummyMenuSpan">
158
- <table id="UserDummyMenu" cellpadding="0" cellspacing="0" class="style1">
159
- <tbody><tr><td class="style3" style=""> </td></tr>
160
- </tbody></table>
161
- </div>
162
- </div>
163
- </div>
164
- </div>
165
- <div id="column_l">
166
- <div id="p0" style="display:none">
167
- <div id="p0message"><span id="p0span">Server disconnected</span>, <href onclick="reload()" style="cursor:pointer"><u>click to reconnect</u></href>.</div>
168
- </div>
169
- <div id="p1" style="display:none">
170
- <div style="display:none" id="devListToolbarViewIcons">
171
- <div tabindex="0" id="devViewButton1" class="viewSelector" onclick="onDeviceViewChange(1)" onkeypress="if (event.key == 'Enter') { onDeviceViewChange(1); }" title="Columns"><div class="viewSelector2"></div></div>
172
- <div tabindex="0" id="devViewButton2" class="viewSelector" onclick="onDeviceViewChange(2)" onkeypress="if (event.key == 'Enter') { onDeviceViewChange(2); }" title="List"><div class="viewSelector1"></div></div>
173
- <div tabindex="0" id="devViewButton3" class="viewSelector" onclick="onDeviceViewChange(3)" onkeypress="if (event.key == 'Enter') { onDeviceViewChange(3); }" title="Desktops"><div class="viewSelector3"></div></div>
174
- <div tabindex="0" id="devViewButton4" class="viewSelector" onclick="onDeviceViewChange(4)" onkeypress="if (event.key == 'Enter') { onDeviceViewChange(4); }" title="Map"><div class="viewSelector4"></div></div>
175
- </div><div><h1>My Devices</h1></div>
176
- <table id="devListToolbarSpan" class="noselect">
177
- <tbody><tr>
178
- <td class="h1"></td>
179
- <td id="devListToolbar" class="style14" style="display:none">
180
- <input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All">
181
- <input type="button" id="GroupActionButton" disabled="disabled" value="Group Action" onclick="groupActionFunction()">
182
- <input id="SearchInput" type="text" placeholder="Filter" onchange="masterUpdate(5)" onkeyup="masterUpdate(5)" autocomplete="off" onfocus="onSearchFocus(1)" onblur="onSearchFocus(0)">
183
- <label><input type="checkbox" id="RealNameCheckBox" onclick="onRealNameCheckBox()"><span title="Show devices operating system name">OS Name</span></label>
184
- </td>
185
- <td id="kvmListToolbar" class="style14" style="display:none">
186
- <span id="kvmMultiConnectButtonSpan"><input type="button" onclick="connectAllKvmFunction()" value="Connect All"> </span>
187
- <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All">
188
- <span id="kvmAutoConnectButtonSpan"><label><input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect">Auto </label></span>
189
- <input type="button" onclick="showMultiDesktopSettings()" value="Settings">
190
- </td>
191
- <td id="devMapToolbar" class="style14" style="display:none">
192
- <input type="text" id="mapSearchLocation" placeholder="Search Location" onfocus="onMapSearchFocus(1)" onblur="onMapSearchFocus(0)">
193
- <input type="button" value="Search" title="Search for location" onclick="getSearchLocation()">
194
- <input type="button" id="refreshmap" title="Reset map view" value="Reset" onclick="refreshMap(false,true)">
195
- </td>
196
- <td class="auto-style1" style="height:100%">
197
- <div style="display:none" id="devListToolbarView">
198
- View
199
- <select id="viewselect" onchange="onDeviceViewChange()">
200
- <option value="1">Columns</option>
201
- <option value="2">List</option>
202
- <option value="3">Desktops</option>
203
- <option id="viewselectmapoption" value="4">Map</option>
204
- </select>
205
- </div>
206
- <div style="display:none" id="devListToolbarSort">
207
- Sort
208
- <select id="sortselect" onchange="masterUpdate(6)">
209
- <option>Group</option>
210
- <option>Power</option>
211
- <option>Device</option>
212
- <option>Tags</option>
213
- </select>
214
-
215
- </div>
216
- <div style="display:none" id="devListToolbarSize">
217
- Size
218
- <select id="sizeselect" onchange="onDeviceViewChange()">
219
- <option value="0">Small</option>
220
- <option value="1">Medium</option>
221
- <option value="2">Large</option>
222
- </select>
223
-
224
- </div>
225
- </td>
226
- <td class="h2"></td>
227
- </tr>
228
- </tbody></table>
229
- <div id="NoMeshesPanel" style="display:none">
230
- <table>
231
- <tbody><tr>
232
- <td valign="top" style="width: 50px">
233
- <img src="images/info.png">
234
- </td>
235
- <td>
236
- <div id="getStarted1">To get started, <a href="#" onclick="return account_createMesh()"><strong>click here to create a device group</strong></a>.</div>
237
- <div id="getStarted2">No device groups.</div>
238
- </td>
239
- </tr>
240
- </tbody></table>
241
- </div>
242
- <div id="xdevices" class="noselect" style="display:none"></div>
243
- <div id="xdevicesmap" style="display:none">
244
- <div id="xmapSearchResultsDlg" style="display:none">
245
- <div id="xmapSearchResultsBck">
246
- <div id="xmapSearchClose" onclick="mapCloseSearchWindow()"><b>X</b></div>
247
- <div style="padding:5px">Location Results</div>
248
- <div style="width:100%;margin:6px"></div>
249
- </div>
250
- <div id="xmapSearchResults" style="margin:6px"></div>
251
- </div>
252
- </div>
253
- <div id="xmap-info-window"></div>
254
- </div>
255
- <div id="p2" style="display:none">
256
- <h1>My Account</h1>
257
- <img id="p2AccountImage" alt="" src="images/clipboard-128.png">
258
- <div id="p2AccountSecurity" style="display:none">
259
- <p><strong>Account security</strong></p>
260
- <div style="margin-left:25px">
261
- <div id="manageAuthApp"><div class="p2AccountActions"><span id="authAppSetupCheck"><strong>✓</strong></span></div><span><a href="#" onclick="return account_manageAuthApp()">Manage authenticator app</a><br></span></div>
262
- <div id="manageHardwareOtp"><div class="p2AccountActions"><span id="authKeySetupCheck"><strong>✓</strong></span></div><span><a href="#" onclick="return account_manageHardwareOtp(0)">Manage security keys</a><br></span></div>
263
- <div id="manageOtp"><div class="p2AccountActions"><span id="authCodesSetupCheck"><strong>✓</strong></span></div><span><a href="#" onclick="return account_manageOtp(0)">Manage backup codes</a><br></span></div>
264
- </div>
265
- </div>
266
- <div id="p2AccountActions">
267
- <p><strong>Account actions</strong></p>
268
- <p class="mL">
269
- <span id="verifyEmailId" style="display:none"><a href="#" onclick="return account_showVerifyEmail()">Verify email</a><br></span>
270
- <span id="accountEnableNotificationsSpan" style="display:none"><a href="#" onclick="return account_enableNotifications()">Enable web notifications</a><br></span>
271
- <a href="#" onclick="return account_showLocalizationSettings()">Localization Settings</a><br>
272
- <a href="#" onclick="return account_showAccountNotifySettings()">Notification Settings</a><br>
273
- <span id="accountChangeEmailAddressSpan" style="display:none"><a href="#" onclick="return account_showChangeEmail()">Change email address</a><br></span>
274
- <a href="#" onclick="return account_showChangePassword()">Change password</a><span id="p2nextPasswordUpdateTime"></span><br>
275
- <a href="#" onclick="return account_showDeleteAccount()">Delete account</a><br>
276
- </p>
277
- <br style="clear:both">
278
- </div>
279
- <strong>Device Groups</strong>
280
- <span id="p2createMeshLink1">( <a href="#" onclick="return account_createMesh()" class="newMeshBtn"> New</a> )</span>
281
- <br><br>
282
- <div id="p2meshes"></div>
283
- <div id="p2noMeshFound" style="display:none">No device groups.<span id="p2createMeshLink2"> <a href="#" onclick="return account_createMesh()"><strong>Get started here!</strong></a></span></div>
284
- <br style="clear:both">
285
- </div>
286
- <div id="p3" style="display:none">
287
- <h1>My Events</h1>
288
- <table class="pTable">
289
- <tbody><tr>
290
- <td class="h1"></td>
291
- <td class="auto-style1">
292
- Show
293
- <select id="p3limitdropdown" onchange="refreshEvents()">
294
- <option value="60">Last 60</option>
295
- <option value="120">Last 120</option>
296
- <option value="250">Last 250</option>
297
- <option value="500">Last 500</option>
298
- <option value="1000">Last 1000</option>
299
- </select>
300
- <a href="#" onclick="p3showDownloadEventsDialog(2)"><img src="images/link4.png" height="10" width="10" title="Download Events" style="cursor:pointer"></a>
301
- </td>
302
- <td class="h2"></td>
303
- </tr>
304
- </tbody></table>
305
- <div id="p3events" style=""></div>
306
- </div>
307
- <div id="p4" style="display:none">
308
- <h1>My Users</h1>
309
- <table class="pTable">
310
- <tbody><tr>
311
- <td class="h1"></td>
312
- <td class="style14">
313
- <div style="float:right">
314
- <input type="button" onclick="showUserBroadcastDialog()" style="margin-right:6px" value="Broadcast">
315
- <a href="#" onclick="p4downloadUserInfo()"><img style="cursor:pointer" title="Download user information" src="images/link4.png"></a>
316
- <a href="#" onclick="p4batchAccountCreate()"><img id="p4UserBatchCreate" style="cursor:pointer;display:none" title="Batch create many user accounts" src="images/link6.png"></a>
317
- </div>
318
- <div>
319
- <input id="UserNewAccountButton" type="button" style="margin-left:6px" onclick="showCreateNewAccountDialog()" value="New Account...">
320
- <input id="UserSearchInput" type="text" style="width:120px;margin-left:6px" placeholder="Filter" onchange="onUserSearchInputChanged()" onkeyup="onUserSearchInputChanged()" autocomplete="off" onfocus="onUserSearchFocus(1)" onblur="onUserSearchFocus(0)">
321
- </div>
322
- </td>
323
- <td class="h2"></td>
324
- </tr>
325
- </tbody></table>
326
- <div id="p3users"></div>
327
- </div>
328
- <div id="p5" style="display:none">
329
- <h1>My Files</h1>
330
- <table id="p5toolbar" cellpadding="0" cellspacing="0">
331
- <tbody><tr>
332
- <td id="p5filehead" valign="bottom">
333
- <div id="p5rightOfButtons"></div>
334
- <div>
335
- <input type="button" id="p5FolderUp" disabled="disabled" onclick="return p5folderup();" value="Up">
336
- <input type="button" id="p5SelectAllButton" disabled="disabled" onclick="p5selectallfile();" value="Select All">
337
- <input type="button" id="p5RenameFileButton" disabled="disabled" value="Rename" onclick="p5renamefile();">
338
- <input type="button" id="p5DeleteFileButton" disabled="disabled" value="Delete" onclick="p5deletefile();">
339
- <!--<input type=button id=p5ViewFileButton disabled="disabled" value="View" onclick="p5viewfile()" /> -->
340
- <input type="button" id="p5NewFolderButton" disabled="disabled" value="New Folder" onclick="p5createfolder();">
341
- <input type="button" id="p5UploadButton" disabled="disabled" value="Upload" onclick="p5uploadFile()">
342
- <input type="button" id="p5CutButton" disabled="disabled" value="Cut" onclick="p5copyFile(1)">
343
- <input type="button" id="p5CopyButton" disabled="disabled" value="Copy" onclick="p5copyFile(0)">
344
- <input type="button" id="p5PasteButton" disabled="disabled" value="Paste" onclick="p5pasteFile()">
345
- </div>
346
- </td>
347
- </tr>
348
- <tr>
349
- <td id="p5filesubhead">
350
- <div style="float:right">
351
- <select id="p5sortdropdown" onchange="updateFiles()">
352
- <option value="1" selected="selected">Sort by name</option>
353
- <option value="2">Sort by size</option>
354
- <option value="3">Sort by date</option>
355
- <option value="4">Descend by name</option>
356
- <option value="5">Descend by size</option>
357
- <option value="6">Descend by date</option>
358
- </select>
359
- </div>
360
- <div> <span id="p5currentpath"></span></div>
361
- </td>
362
- </tr>
363
- </tbody></table>
364
- <div id="p5filetable">
365
- <!--
366
- <form id=p5fileCatchAll method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame>
367
- <input type=file id=p5fileCatchAllInput name=files style="position:absolute;left:0;width:100%;top:0;bottom:0;opacity:0;display:none" onchange="p5fileCatchAllInputChanged(event)" />
368
- <input id=p5fileDragLink2 name="link" style="display:none" />
369
- <input type=submit id=p5fileCatchAllSubmit style="display:none" />
370
- </form>
371
- -->
372
- <div id="p5PublicShare" style=""><div>These files are shared publicly, click "link" to get public url.</div></div>
373
- <div id="bigok" style="display:none"><b>✓</b></div>
374
- <div id="bigfail" style="display:none"><b>✗</b></div>
375
- <span id="p5files"></span>
376
- </div>
377
- <table id="p5toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0">
378
- <tbody><tr><td class="style6"> <span id="p5bottomstatus"></span></td></tr>
379
- </tbody></table>
380
- </div>
381
- <div id="p6" style="display:none">
382
- <img id="MainMeshImage" src="serverpic.ashx">
383
- <h1>My Server</h1>
384
- <div id="p2ServerActions">
385
- <p><strong>Server actions</strong></p>
386
- <div class="mL">
387
- <div id="p2ServerActionsBackup"><a href="{{{domainurl}}}backup.zip" rel="noreferrer noopener" target="_blank">Download server backup</a></div>
388
- <div id="p2ServerActionsRestore"><a href="#" onclick="return server_showRestoreDlg()">Restore server with backup</a></div>
389
- <div id="p2ServerActionsVersion"><a href="#" onclick="return server_showVersionDlg()">Check server version</a></div>
390
- <div id="p2ServerActionsErrors"><a href="#" onclick="return server_showErrorsDlg()">Show server error log</a></div>
391
- </div>
392
- </div>
393
- <br><strong>Server Statistics</strong><br><br>
394
- <div id="serverStats">
395
- <div id="serverCpuChartView" style="display:none">
396
- <div class="chartViewCanvas"><canvas id="serverCpuChart"></canvas></div>
397
- <div class="chartViewText" id="serverCpuChartText"></div>
398
- </div>
399
- <div id="serverMemoryChartView" style="display:none">
400
- <div class="chartViewCanvas"><canvas id="serverMemoryChart"></canvas></div>
401
- <div class="chartViewText" id="serverMemoryChartText"></div>
402
- </div><br><br>
403
- <div id="serverStatsTable"></div>
404
- </div>
405
- </div>
406
- <div id="p10" style="display:none">
407
- <table style="width:100%" cellpadding="0" cellspacing="0">
408
- <tbody><tr>
409
- <td style="width:auto" valign="top">
410
- <div id="p10title">
411
- <div id="p10BackButton"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
412
- <h1>General - <span id="p10deviceName"></span></h1>
413
- </div>
414
- <div id="p10html"></div>
415
- </td>
416
- <td style="width:20px"></td>
417
- <td style="width:200px">
418
- <a href="#" onclick="p10showiconselector()"><img id="MainComputerImage"></a>
419
- <div id="MainComputerState"></div>
420
- </td>
421
- </tr>
422
- </tbody></table><br>
423
- <div id="p10html2"></div>
424
- <div id="p10html3"></div>
425
- </div>
426
- <div id="p11" class="noselect" style="display:none">
427
- <div id="p11title">
428
- <div id="p11deviceNameHeader">
429
- <div id="p11BackButton"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
430
- <div id="devListToolbarViewIcons"><div class="viewSelector" onclick="deskToggleFull(event)" title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div>
431
- <h1>Desktop - <span id="p11deviceName"></span></h1>
432
- </div>
433
- </div>
434
- <div id="p11warning" onclick="showFeaturesDlg()">
435
- <div class="icon2"></div>
436
- <div class="warningbox">Intel® AMT Redirection port or KVM feature is disabled<span id="p11warninga">, click here to enable it.</span></div>
437
- </div>
438
- <div id="p11warning2" onclick="showPowerActionDlg()">
439
- <div class="icon2"></div>
440
- <div class="warningbox">Remote computer is not powered on, click here to issue a power command.</div>
441
- </div>
442
- <div id="deskarea0" cellpadding="0" cellspacing="0">
443
- <div id="deskarea1" class="areaHead">
444
- <div class="toright2">
445
- <span id="p11power"></span>
446
- <div class="deskareaicon" title="Toggle View Mode" onclick="toggleAspectRatio(1)">⇲</div>
447
- <div class="deskareaicon" title="Rotate Left" onclick="drotate(-1)">↺</div>
448
- <div class="deskareaicon" title="Rotate Right" onclick="drotate(1)">↻</div>
449
- <div id="deskRecordIcon" class="deskareaicon" title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px"></div>
450
- <input id="deskFocusBtn" type="button" title="Toggle focus mode, when active only the region around the mouse is updated" onkeypress="return false" onkeydown="return false" value="Focus All" onclick="deskToggleFocus()" style="margin-right:3px;display:none">
451
- <input id="deskSaveBtn" type="button" title="Save a screenshot of the remote desktop" onkeypress="return false" onkeydown="return false" value="Save..." onclick="deskSaveImage()" class="mR">
452
- <input id="deskActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" class="mR">
453
- <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" class="mR">
454
- <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="display:none">
455
- </div>
456
- <div>
457
- <div id="idx_deskFullBtn2" onclick="deskToggleFull(event)"> ✖</div>
458
- <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none">
459
- <span id="connectbutton1span"><input type="button" id="connectbutton1" value="Connect" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span>
460
- <span id="connectbutton1hspan"> <input type="button" id="connectbutton1h" value="HW Connect" onclick="connectDesktop(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span>
461
- <span id="disconnectbutton1span"> <input type="button" id="disconnectbutton1" value="Disconnect" onclick="connectDesktop(event,0)" onkeypress="return false" onkeydown="return false"></span>
462
- <span id="deskstatus">Disconnected</span>
463
- </div>
464
- </div>
465
- <div id="deskarea2" style="">
466
- <div class="areaProgress"><div id="progressbar" style=""></div></div>
467
- </div>
468
- <div id="deskarea3x">
469
- <div id="DeskFocus" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)"></div>
470
- <div id="DeskParent">
471
- <canvas id="Desk" width="640" height="480" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)" onmousewheel="dmousewheel(event)"></canvas>
472
- </div>
473
- <div id="DeskTools">
474
- <div id="deskToolsAreaTop">
475
- <a id="DeskToolsRefreshButton" style="right:2px" onclick="refreshDeskTools()">Refresh</a>
476
- <div id="deskToolsTopTabProcess" class="deskToolsTopTab" onclick="changeDeskToolTab(0)" style="left:0px;bottom:0px">Processes</div>
477
- <div id="deskToolsTopTabService" class="deskToolsTopTab" onclick="changeDeskToolTab(1)" style="display:none;left:90px;color:gray">Services</div>
478
- </div>
479
- <div id="deskToolsArea">
480
- <div id="DeskToolsProcessTab">
481
- <div id="deskToolsHeader">
482
- <a class="colmn1" title="Sort by process id" onclick="sortProcess(0)">PID</a>
483
- <a class="colmn2" title="Sort by name" onclick="sortProcess(1)">Name</a>
484
- </div>
485
- <div id="DeskToolsProcesses" style=""></div>
486
- </div>
487
- <div id="DeskToolsServiceTab" style="display:none">
488
- <div id="deskToolsServiceHeader">
489
- <a class="colmn1" style="width:70px" title="Sort by state" onclick="sortService(0)">State</a>
490
- <a class="colmn2" title="Sort by name" onclick="sortService(1)">Name</a>
491
- </div>
492
- <div id="DeskToolsServices" style=""></div>
493
- </div>
494
- </div>
495
- </div>
496
- <div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="p11clearConsoleMsg()"></div>
497
- </div>
498
- <div id="deskarea4" class="areaFoot">
499
- <div class="toright2">
500
- <span id="DeskTimer" title="Session time"></span>
501
- <select id="termdisplays" style="display:none" onchange="deskSetDisplay(event)" onkeypress="return false" onkeydown="return false"></select>
502
- <input id="DeskToolsButton" type="button" value="Tools" title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()">
503
- <span id="DeskChatButton" class="deskarea" title="Open chat window to this computer"><img src="images/icon-chat.png" onclick="deviceChat()" height="16" width="16" style="padding-top:2px"></span>
504
- <span id="DeskNotifyButton" title="Display a notification on the remote computer"><img src="images/icon-notify.png" onclick="deviceToastFunction()" height="16" width="16" style="padding-top:2px"></span>
505
- <span id="DeskOpenWebButton" title="Open a web address on remote computer"><img src="images/icon-url2.png" onclick="deviceUrlFunction()" height="16" width="16" style="padding-top:2px"></span>
506
- </div>
507
- <div>
508
- <select id="deskkeys">
509
- <option value="10">Ctrl+Alt+Del</option>
510
- <option value="5">Win</option>
511
- <option value="0">Win+Down</option>
512
- <option value="1">Win+Up</option>
513
- <option value="2">Win+L</option>
514
- <option value="3">Win+M</option>
515
- <option value="4">Shift+Win+M</option>
516
- <option value="6">Win+R</option>
517
- <option value="7">Alt-F4</option>
518
- <option value="8">Ctrl-W</option>
519
- <option value="9">Alt-Tab</option>
520
- <option value="11">Win+Left</option>
521
- <option value="12">Win+Right</option>
522
- </select>
523
- <input id="DeskWD" type="button" value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()">
524
- <input id="DeskClip" style="" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()">
525
- <input id="DeskType" style="" type="button" value="Type" onkeypress="return false" onkeydown="return false" onclick="showDeskType()">
526
- <label><span id="DeskControlSpan" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span></label>
527
- </div>
528
- </div>
529
- </div>
530
- </div>
531
- <div id="p12" style="display:none">
532
- <div id="p12title">
533
- <div id="p12BackButton"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
534
- <h1>Terminal - <span id="p12deviceName"></span></h1>
535
- </div>
536
- <div id="p12warning" onclick="showFeaturesDlg()">
537
- <div class="icon2"></div>
538
- <div class="warningbox">Intel® AMT Redirection port or KVM feature is disabled<span id="p12warninga">, click here to enable it.</span></div>
539
- </div>
540
- <div id="p12warning2" onclick="showPowerActionDlg()">
541
- <div class="icon2"></div>
542
- <div class="warningbox">Remote computer is not powered on, click here to issue a power command.</div>
543
- </div>
544
- <div id="termTable" style="position:relative">
545
- <table style="width:100%" cellpadding="0" cellspacing="0">
546
- <tbody><tr>
547
- <td class="areaHead">
548
- <div class="toright2">
549
- <div id="termRecordIcon" class="deskareaicon" title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px;margin-left:5px"></div>
550
- <input id="termActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()">
551
- </div>
552
- <div>
553
- <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none">
554
- <span id="connectbutton2span"><input type="button" id="connectbutton2" value="Connect" onclick="connectTerminal(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span>
555
- <span id="connectbutton2hspan"> <input type="button" id="connectbutton2h" value="HW Connect" onclick="connectTerminal(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span>
556
- <span id="disconnectbutton2span"> <input type="button" id="disconnectbutton2" value="Disconnect" onclick="connectTerminal(event,0)" onkeypress="return false" onkeydown="return false"></span>
557
- <span id="termstatus">Disconnected</span><span id="termtitle"></span>
558
- </div>
559
- </td>
560
- </tr>
561
- <tr>
562
- <td>
563
- <div class="areaProgress"><div id="termprogressbar" style=""></div></div>
564
- </td>
565
- </tr>
566
- <tr>
567
- <td id="termarea3x">
568
- <pre id="Term"></pre>
569
- </td>
570
- </tr>
571
- <tr>
572
- <td class="areaFoot">
573
- <div class="toright2">
574
- <span id="TermTimer" title="Session time"></span>
575
- <span id="terminalSettingsButtons" style="display:none">
576
- <input id="id_tcrbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="CR+LF" title="Toggle what the return key will send" onclick="termToggleCr()">
577
- <input id="id_tfxkeysbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Intel (F10 = ESC+[OM)" title="Toggle F1 to F10 keys emulation type" onclick="termToggleFx()">
578
- <input id="id_ttypebutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Extended Ascii" title="Toggle terminal emulation type" onclick="termToggleType()">
579
- </span>
580
- <span id="terminalSizeDropDown">
581
- <select id="termSizeList" onkeypress="return false"><option value="1">80x25</option><option value="2">100x30</option><option value="3" selected="">Auto</option></select>
582
- </span>
583
- <select id="specialkeylist" onkeypress="return false"></select>
584
- <input id="specialkeylistinput" type="button" onkeypress="return false" class="bottombutton" value="Send" title="Send the selected special key" onclick="sendSpecialKey()">
585
- </div>
586
- <div>
587
-
588
- <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlcbutton" value="Ctl-C" onclick="termSendKey(3,'ctrlcbutton')">
589
- <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlxbutton" value="Ctl-X" onclick="termSendKey(24,'ctrlxbutton')">
590
- <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="escbutton" value="ESC" onclick="termSendKey(27,'escbutton')">
591
- <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="bsbutton" value="Backspace" onclick="termSendKey(8,'bsbutton')">
592
- <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="pastebutton" value="Paste" title="Paste text into the terminal" onclick="showTermPasteDialog()">
593
- </div>
594
- </td>
595
- </tr>
596
- </tbody></table>
597
- <div id="p12TermConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:45px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="p12clearConsoleMsg()"></div>
598
- </div>
599
- </div>
600
- <div id="p13" style="display:none">
601
- <div id="p13title">
602
- <div id="p13BackButton" style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
603
- <h1>Files - <span id="p13deviceName"></span></h1>
604
- </div>
605
- <table id="p13toolbar" cellpadding="0" cellspacing="0">
606
- <tbody><tr>
607
- <td class="areaHead">
608
- <div class="toright2">
609
- <input id="filesActionsBtn" type="button" title="Perform power actions on the device" value="Actions" onclick="deviceActionFunction()">
610
- <div id="filesRecordIcon" class="deskareaicon" title="Server is recording this session" style="display:none;background-color:red;width:12px;height:12px;border-radius:6px;margin-top:5px;margin-left:5px"></div>
611
- </div>
612
- <div>
613
- <input id="p13AutoConnect" value="AutoConnect" onclick="autoConnectFiles(event)" type="button" style="display:none">
614
- <input id="p13Connect" value="Connect" onclick="connectFiles(event)" type="button">
615
- <span id="p13Status">Disconnected</span>
616
- </div>
617
- </td>
618
- </tr>
619
- <tr>
620
- <td class="areaHead2" valign="bottom">
621
- <div id="p13rightOfButtons" class="toright2"></div>
622
- <div>
623
- <input type="button" id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Up">
624
- <input type="button" id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Select All">
625
- <input type="button" id="p13RenameFileButton" disabled="disabled" value="Rename" onclick="p13renamefile()">
626
- <input type="button" id="p13DeleteFileButton" disabled="disabled" value="Delete" onclick="p13deletefile()">
627
- <input type="button" id="p13ViewFileButton" disabled="disabled" value="Edit" onclick="p13viewfile()">
628
- <input type="button" id="p13NewFolderButton" disabled="disabled" value="New Folder" onclick="p13createfolder()">
629
- <input type="button" id="p13UploadButton" disabled="disabled" value="Upload" onclick="p13uploadFile()">
630
- <input type="button" id="p13CutButton" disabled="disabled" value="Cut" onclick="p13copyFile(1)">
631
- <input type="button" id="p13CopyButton" disabled="disabled" value="Copy" onclick="p13copyFile(0)">
632
- <input type="button" id="p13PasteButton" disabled="disabled" value="Paste" onclick="p13pasteFile()">
633
- <input type="button" id="p13RefreshButton" disabled="disabled" value="Refresh" onclick="p13folderup(9999)">
634
- </div>
635
- </td>
636
- </tr>
637
- <tr>
638
- <td class="areaHead3">
639
- <div class="toright2">
640
- <select id="p13sortdropdown" onchange="p13updateFiles()">
641
- <option value="1" selected="selected">Sort by name</option>
642
- <option value="2">Sort by size</option>
643
- <option value="3">Sort by date</option>
644
- <option value="4">Descend by name</option>
645
- <option value="5">Descend by size</option>
646
- <option value="6">Descend by date</option>
647
- </select>
648
- </div>
649
- <div> <span id="p13currentpath"></span></div>
650
- </td>
651
- </tr>
652
- </tbody></table>
653
- <div id="p13FilesConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:165px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="p13clearConsoleMsg()"></div>
654
- <div id="p13filetable" style="">
655
- <div id="p13bigok" style="display:none"><b>✓</b></div>
656
- <div id="p13bigfail" style="display:none"><b>✗</b></div>
657
- <span id="p13files"></span>
658
- </div>
659
- <table id="p13toolbarBottom" cellpadding="0" cellspacing="0">
660
- <tbody><tr><td class="style6"> <span id="p13bottomstatus"></span></td></tr>
661
- </tbody></table>
662
- </div>
663
- <div id="p14" style="display:none">
664
- <div id="p14title">
665
- <div id="p14BackButton" style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
666
- <div id="devListToolbarViewIcons"><div class="viewSelector" onclick="deskToggleFull(event)" title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div>
667
- <h1>Intel® AMT - <span id="p14deviceName"></span></h1>
668
- </div>
669
- <iframe id="p14iframe" src="{{{domainurl}}}commander.htm"></iframe>
670
- </div>
671
- <div id="p15" style="display:none">
672
- <div id="p15title">
673
- <div id="p15BackButton" style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
674
- <h1><span id="p15deviceName"></span></h1>
675
- </div>
676
- <table id="consoleTable" cellpadding="0" cellspacing="0">
677
- <tbody><tr>
678
- <td class="areaHead">
679
- <div class="toright2">
680
- <div id="p15coreName" title="Information about current core running on this agent"></div>
681
- <input type="button" id="p15uploadCore" value="Agent Action" onclick="p15uploadCore(event)" title="Change the agent Java Script code module">
682
- <img onclick="p15downloadConsoleText()" style="cursor:pointer;margin-top:6px" title="Download console text" src="images/link4.png">
683
- </div>
684
- <div id="p15statetext"></div>
685
- </td>
686
- </tr>
687
- <tr>
688
- <td>
689
- <div class="areaProgress"><div id="consoleprogressbar" style=""></div></div>
690
- </td>
691
- </tr>
692
- <tr>
693
- <td id="p15agentConsole">
694
- <pre id="p15agentConsoleText"></pre>
695
- </td>
696
- </tr>
697
- <tr>
698
- <td class="areaFoot">
699
- <table style="width:100%">
700
- <tbody><tr>
701
- <td style="width:99%">
702
- <input id="p15consoleText" style="width:100%" onkeyup="p15consoleSend(event)" onfocus="onConsoleFocus(1)" onblur="onConsoleFocus(0)">
703
- </td>
704
- <td> </td>
705
- <td id="p15outputselecttd">
706
- <select id="p15outputselect">
707
- <option value="1">Agent</option>
708
- <option value="2">MQTT</option>
709
- </select>
710
- </td>
711
- <td style="width:1%"><input id="id_p15consoleClear" type="button" class="bottombutton" value="Clear" onclick="p15consoleClear()"></td>
712
- </tr>
713
- </tbody></table>
714
- </td>
715
- </tr>
716
- </tbody></table>
717
- </div>
718
- <div id="p16" style="display:none">
719
- <div id="p16title">
720
- <div id="p16BackButton" style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
721
- <h1>Events - <span id="p16deviceName"></span></h1>
722
- </div>
723
- <table class="pTable">
724
- <tbody><tr>
725
- <td class="h1"></td>
726
- <!--<td> <input type=button onclick=refreshDeviceEvents() value="Refresh" /></td>-->
727
- <td class="auto-style1">
728
- Show
729
- <select id="p16limitdropdown" onchange="refreshDeviceEvents()">
730
- <option value="60">Last 60</option>
731
- <option value="120">Last 120</option>
732
- <option value="250">Last 250</option>
733
- <option value="500">Last 500</option>
734
- <option value="1000">Last 1000</option>
735
- </select>
736
- <a href="#" onclick="p3showDownloadEventsDialog(1)"><img src="images/link4.png" height="10" width="10" title="Download Events" style="cursor:pointer"></a>
737
- </td>
738
- <td class="h2"></td>
739
- </tr>
740
- </tbody></table>
741
- <div id="p16events"></div>
742
- </div>
743
- <div id="p17" style="display:none">
744
- <div id="p17title">
745
- <div id="p17BackButton" style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
746
- <h1>Details - <span id="p17deviceName"></span></h1>
747
- </div>
748
- <div id="p17info"></div>
749
- </div>
750
- <div id="p20" style="display:none">
751
- <picture id="MainMeshImage" style="border-width:0px;height:200px;width:200px;float:right">
752
- <source type="image/webp" width="200" height="200" srcset="images/webp/mesh-256.webp">
753
- <img alt="" width="200" height="200" src="images/mesh-256.png">
754
- </picture>
755
- <div style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
756
- <h1>General - <span id="p20meshName"></span></h1>
757
- <p id="p20info"></p>
758
- </div>
759
- <div id="p30" style="display:none">
760
- <table style="width:100%" cellpadding="0" cellspacing="0">
761
- <tbody><tr>
762
- <td style="width:auto" valign="top">
763
- <div id="p30title">
764
- <div style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
765
- <h1>General - <span id="p30userName"></span></h1>
766
- </div>
767
- <div id="p30html"></div>
768
- </td>
769
- <td style="width:20px"></td>
770
- <td style="width:200px">
771
- <picture id="MainUserImage" style="border-width:0px;height:200px;width:200px;float:right">
772
- <source type="image/webp" width="200" height="200" srcset="images/webp/user-256.webp">
773
- <img alt="" width="200" height="200" src="images/user-256.png">
774
- </picture>
775
- <div style="width:100%;text-align:center"><strong><span id="MainUserState"></span></strong></div>
776
- </td>
777
- </tr>
778
- </tbody></table><br>
779
- <div id="p30html2"></div>
780
- <div id="p30html3"></div>
781
- </div>
782
- <div id="p31" style="display:none">
783
- <div style="float:left"><div class="backButton" tabindex="0" onclick="goBack()" title="Back" onkeypress="if (event.key == 'Enter') goBack()"><div class="backButtonEx"></div></div></div>
784
- <h1>Events - <span id="p31userName"></span></h1>
785
- <table class="pTable">
786
- <tbody><tr>
787
- <td class="h1"></td>
788
- <!--<td> <input type=button onclick=refreshUsersEvents() value="Refresh" /></td>-->
789
- <td class="auto-style1">
790
- Show
791
- <select id="p31limitdropdown" onchange="refreshUsersEvents()">
792
- <option value="60">Last 60</option>
793
- <option value="120">Last 120</option>
794
- <option value="250">Last 250</option>
795
- <option value="500">Last 500</option>
796
- <option value="1000">Last 1000</option>
797
- </select>
798
- <a href="#" onclick="p3showDownloadEventsDialog(3)"><img src="images/link4.png" height="10" width="10" title="Download Events" style="cursor:pointer"></a>
799
- </td>
800
- <td class="h2"></td>
801
- </tr>
802
- </tbody></table>
803
- <div id="p31events" style=""></div>
804
- </div>
805
- <div id="p40" style="display:none">
806
- <h1>My Server Stats</h1>
807
- <div class="areaHead">
808
- <div class="toright2">
809
- <select id="p40type" onchange="updateServerTimelineStats()">
810
- <option value="0">Connections</option>
811
- <option value="1">Memory</option>
812
- </select>
813
- <select id="p40time" onchange="updateServerTimelineHours()">
814
- <option value="3">Last 3 hours</option>
815
- <option value="8">Last 8 hours</option>
816
- <option value="24">Last day</option>
817
- <option value="168">Last week</option>
818
- <option value="720">Last 30 days</option>
819
- </select>
820
- <img src="images/link4.png" height="10" width="10" title="Download data points (.csv)" style="cursor:pointer" onclick="p40downloadEvents()">
821
- </div>
822
- <div>
823
- <input value="Refresh" type="button" onclick="refreshServerTimelineStats()">
824
- <label><input id="p40log" type="checkbox" onclick="updateServerTimelineHours()">Log-X</label>
825
- </div>
826
- </div>
827
- <canvas id="serverMainStats" style=""></canvas>
828
- </div>
829
- <div id="p41" style="display:none">
830
- <h1>My Server Tracing</h1>
831
- <div class="areaHead">
832
- <div class="toright2">
833
- Show
834
- <select id="p41limitdropdown" onchange="displayServerTrace()">
835
- <option value="100">Last 100</option>
836
- <option value="250">Last 250</option>
837
- <option value="500">Last 500</option>
838
- <option value="1000">Last 1000</option>
839
- </select>
840
- <input value="Clear" type="button" onclick="clearServerTracing()">
841
- <img src="images/link4.png" height="10" width="10" title="Download trace (.csv)" style="cursor:pointer" onclick="p41downloadServerTrace()">
842
- </div>
843
- <div>
844
- <input value="Tracing" type="button" onclick="setServerTracing()">
845
- <span id="p41traceStatus">None</span>
846
- </div>
847
- </div>
848
- <div id="p41events" style=""></div>
849
- </div>
850
- <div id="p19" style="display:none">
851
- <h1>Plugins - <span id="p19deviceName"></span></h1>
852
- <style>
853
- #p19headers {
854
- padding-right: 7px;
855
- padding-bottom: 10px;
856
- font-weight: bold;
857
- border-bottom: 1px dotted blue;
858
- }
859
-
860
- #p19headers > span:nth-child(n+2) {
861
- border-left: 1px solid black;
862
- }
863
-
864
- #p19headers > span {
865
- padding-left: 4px;
866
- padding-right: 4px;
867
- }
868
- </style>
869
- <div id="p19headers"></div>
870
- <div id="p19pages"></div>
871
- </div>
872
- <br id="column_l_bottomgap">
873
- </div>
874
- <div id="footer">
875
- <div class="footer1">{{{footer}}}</div>
876
- <div class="footer2">
877
- <a id="verifyEmailId2" style="display:none" href="#" onclick="account_showVerifyEmail()">Verify Email</a>
878
- <a href="terms">Terms & Privacy</a>
879
- </div>
880
- </div>
881
- <div id="dialog" class="noselect" style="display:none">
882
- <div id="dialogHeader">
883
- <div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
884
- <div id="id_dialogtitle"></div>
885
- </div>
886
- <div id="dialogBody">
887
- <div id="dialog1">
888
- <div id="id_dialogMessage" style=""></div>
889
- </div>
890
- <div id="dialog2" style="">
891
- <div id="id_dialogOptions"></div>
892
- </div>
893
- <div id="dialog3" style="">
894
- <div id="d3upload">
895
- <div>File Selection</div>
896
- <select id="d3uploadMode" onchange="d3modechange()">
897
- <option value="1">Local file upload</option>
898
- <option value="2">Server file selection</option>
899
- </select>
900
- </div>
901
- <div id="d3localmode" style="display:none">
902
- <div>Upload File</div>
903
- <form id="d3localmodeform" method="post" enctype="multipart/form-data" action="uploadfile.ashx" target="fileUploadFrame">
904
- <input type="text" id="d3auth" name="auth" style="display:none">
905
- <input type="text" id="d3attrib" name="attrib" style="display:none">
906
- <input type="file" id="d3localFile" name="files" onchange="d3setActions()">
907
- <input type="submit" id="d3submit" style="display:none">
908
- </form>
909
- </div>
910
- <div id="d3servermode">
911
- <div id="d3serveraction" valign="bottom">
912
- <input type="button" id="p3FolderUp" disabled="disabled" onclick="d3folderup()" value="Up">
913
- </div>
914
- <div id="d3serverfiles"></div>
915
- </div>
916
- </div>
917
- <div id="dialog7" style="">
918
- <div id="d7meshkvm">
919
- <h4>Agent Remote Desktop</h4>
920
- <div>
921
- <div>Quality</div>
922
- <select id="d7bitmapquality" dir="rtl"></select>
923
- </div>
924
- <div>
925
- <div>Scaling</div>
926
- <select id="d7bitmapscaling" style="" dir="rtl">
927
- <option selected="selected" value="1024">100%</option>
928
- <option value="896">87.5%</option>
929
- <option value="768">75%</option>
930
- <option value="640">62.5%</option>
931
- <option value="512">50%</option>
932
- <option value="384">37.5%</option>
933
- <option value="256">25%</option>
934
- <option value="128">12.5%</option>
935
- </select>
936
- </div>
937
- <div>
938
- <div>Frame rate</div>
939
- <select id="d7framelimiter" dir="rtl">
940
- <option selected="selected" value="50">Fast</option>
941
- <option value="100">Medium</option>
942
- <option value="400">Slow</option>
943
- <option value="1000">Very slow</option>
944
- </select>
945
- </div>
946
- </div>
947
- <div id="d7amtkvm">
948
- <h4>Intel® AMT Hardware KVM</h4>
949
- <div>
950
- <div>Image Encoding</div>
951
- <select id="d7desktopmode">
952
- <option value="1">RLE8, Fastest</option>
953
- <option value="2">RLE16, Recommended</option>
954
- <option value="3">RAW8, Slow</option>
955
- <option value="4">RAW16, Very Slow</option>
956
- </select>
957
- </div>
958
- <div>
959
- <div>Other Settings</div>
960
- <div id="d7otherset" style="display:block">
961
- <label style="display:block"><input type="checkbox" id="d7showfocus">Show Focus Tool</label>
962
- <label style="display:block"><input type="checkbox" id="d7showcursor">Show Local Mouse Cursor</label>
963
- <label style="display:block"><input type="checkbox" id="d7localKeyMap">Local Keyboard Map</label>
964
- </div>
965
- </div>
966
- </div>
967
- </div>
968
- </div>
969
- <div id="idx_dlgButtonBar">
970
- <input id="idx_dlgCancelButton" type="button" value="Cancel" style="" onclick="dialogclose(0)">
971
- <input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
972
- <div><input id="idx_dlgDeleteButton" type="button" value="Delete" style="display:none" onclick="dialogclose(2)"></div>
973
- </div>
974
- </div>
975
- <iframe name="fileUploadFrame" style="display:none"></iframe>
976
- <form style="display:none" method="post" action="uploadfile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p5fileDragName" name="name"><input id="p5fileDragAuthCookie" name="auth"><input id="p5fileDragSize" name="size"><input id="p5fileDragType" name="type"><input id="p5fileDragData" name="data"><input id="p5fileDragLink" name="link"><input type="submit" id="p5loginSubmit2" style="display:none"></form>
977
- <form style="display:none" method="post" action="uploadnodefile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p13fileDragName" name="name"><input id="p13fileDragSize" name="size"><input id="p13fileDragType" name="type"><input id="p13fileDragData" name="data"><input id="p13fileDragLink" name="link"><input type="submit" id="p13loginSubmit2" style="display:none"></form>
978
- <audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3"></audio>
979
- </div>
980
- <script type="text/javascript">
981
- 'use strict';
982
-
983
- // Process server-side web state
984
- var webState = "{{{webstate}}}";
985
- if (webState != "") { webState = JSON.parse(decodeURIComponent(webState)); }
986
- for (var i in webState) { localStorage.setItem(i, webState[i]); }
987
- if (!webState.loctag) { delete localStorage.removeItem('loctag'); }
988
-
989
- var args;
990
- var autoReconnect = true;
991
- var powerStatetable = ['', 'Powered', 'Sleep', 'Sleep', 'Sleep', 'Hibernating', 'Power off', 'Present'];
992
- var StatusStrs = ['Disconnected', 'Connecting...', 'Setup...', 'Connected', 'Intel® AMT Connected'];
993
- var sort = 0;
994
- var searchFocus = 0;
995
- var mapSearchFocus = 0;
996
- var userSearchFocus = 0;
997
- var consoleFocus = 0;
998
- var showRealNames = false;
999
- var meshserver = null;
1000
- var meshes = {};
1001
- var meshcount = 0;
1002
- var nodes = null;
1003
- var filetree = {};
1004
- var userinfo = null;
1005
- var serverinfo = null;
1006
- var events = [];
1007
- var users = null;
1008
- var wssessions = null;
1009
- var nodeShortIdent = 0;
1010
- var desktop;
1011
- var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50, localkeymap: false };
1012
- var multidesktopsettings = { quality: 20, scaling: 128, framerate: 1000 };
1013
- var terminal;
1014
- var files;
1015
- var debugLevel = parseInt("{{{debuglevel}}}");
1016
- var features = parseInt("{{{features}}}");
1017
- var sessionTime = parseInt("{{{sessiontime}}}");
1018
- var domain = "{{{domain}}}";
1019
- var domainUrl = "{{{domainurl}}}";
1020
- var authCookie = "{{{authCookie}}}";
1021
- var authRelayCookie = "{{{authRelayCookie}}}";
1022
- var authCookieRenewTimer = null;
1023
- var multiDesktop = {};
1024
- var multiDesktopFilter = null;
1025
- var serverPublicNamePort = "{{{serverDnsName}}}:{{{serverPublicPort}}}";
1026
- var amtScanResults = null;
1027
- var debugmode = 0;
1028
- var clickOnce = (((features & 256) != 0) && detectClickOnce());
1029
- var attemptWebRTC = ((features & 128) != 0);
1030
- var passRequirements = "{{{passRequirements}}}";
1031
- if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); }
1032
- var deskAspectRatio = 0;
1033
- try { deskAspectRatio = parseInt(getstore('deskAspectRatio', '0')); } catch (ex) { }
1034
- var uiMode = parseInt(getstore('uiMode', 1));
1035
- var webPageStackMenu = false;
1036
- var webPageFullScreen = true;
1037
- var nightMode = (getstore('_nightMode', '0') == '1');
1038
- var sessionActivity = Date.now();
1039
- var updateSessionTimer = null;
1040
- var pluginHandlerBuilder = {{{pluginHandler}}};
1041
- var pluginHandler = null;
1042
- if (pluginHandlerBuilder != null) { pluginHandler = new pluginHandlerBuilder(); }
1043
-
1044
- // Console Message Display Timers
1045
- var p11DeskConsoleMsgTimer = null;
1046
- var p12TermConsoleMsgTimer = null;
1047
- var p13FilesConsoleMsgTimer = null;
1048
-
1049
- function startup() {
1050
- if ((features & 32) == 0) {
1051
- // Guard against other site's top frames (web bugs).
1052
- var loc = null;
1053
- try { loc = top.location.toString().toLowerCase(); } catch (e) { }
1054
- if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
1055
- }
1056
-
1057
- // Check if we are in debug mode
1058
- args = parseUriArgs();
1059
- if (!args.locale) { var x = getstore('loctag', 0); if ((x != null) && (x != '*')) { args.locale = x; } }
1060
- debugmode = args.debug;
1061
- if (args.webrtc != null) { attemptWebRTC = (args.webrtc == 1); }
1062
- QV('p13AutoConnect', debugmode); // Files
1063
- QV('autoconnectbutton2', debugmode); // Terminal
1064
- QV('autoconnectbutton1', debugmode); // Desktop
1065
- //QV('DeskClip', debugmode); // Clipboard feature, not completed so show in in debug mode only.
1066
-
1067
- if (nightMode) { QC('body').add('night'); }
1068
- toggleFullScreen();
1069
-
1070
- // Setup page visuals
1071
- if (args.hide) {
1072
- var hide = parseInt(args.hide);
1073
- QV('masthead', !(hide & 1));
1074
- QV('topbar', !(hide & 2));
1075
- QV('footer', !(hide & 4));
1076
- QV('p10title', !(hide & 8));
1077
- QV('p11title', !(hide & 8));
1078
- QV('p12title', !(hide & 8));
1079
- QV('p13title', !(hide & 8));
1080
- QV('p14title', !(hide & 8));
1081
- QV('p15title', !(hide & 8));
1082
- QV('p16title', !(hide & 8));
1083
- //if (hide & 16) {
1084
- // QV('page_leftbar', false);
1085
- // QS('page_content').left = '0px';
1086
- //}
1087
-
1088
- // Fix the main grid to zero-height elements we want to hide.
1089
- QS('container')['grid-template-rows'] = ((hide & 1) ? '0' : '66') + 'px ' + ((hide & 2) ? '0' : '24') + 'px auto ' + ((hide & 4) ? '0' : '45') + 'px';
1090
- QS('container')['-ms-grid-rows'] = ((hide & 1) ? '0' : '66') + 'px ' + ((hide & 2) ? '0' : '24') + 'px auto ' + ((hide & 4) ? '0' : '45') + 'px';
1091
-
1092
- // Adjust height of remote desktop, files and Intel AMT
1093
- var xh = (((hide & 1) ? 0 : 66) + ((hide & 2) ? 0 : 24) + ((hide & 4) ? 0 : 45) + ((hide & 8) ? 0 : 60)); // 0 to 195
1094
- QS('p3users')['max-height'] = 'calc(100vh - ' + (124 + xh) + 'px)';
1095
- QS('p3events')['height'] = 'calc(100vh - ' + (124 + xh) + 'px)';
1096
- QS('deskarea3x')['height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
1097
- QS('deskarea3x')['max-height'] = 'calc(100vh - ' + (75 + xh) + 'px)';
1098
- QS('p5filetable')['height'] = 'calc(100vh - ' + (160 + xh) + 'px)';
1099
- QS('p13filetable')['height'] = 'calc(100vh - ' + (124 + xh) + 'px)';
1100
- QS('serverMainStats')['height'] = 'calc(100vh - ' + (110 + xh) + 'px)';
1101
- QS('serverMainStats')['max-height'] = 'calc(100vh - ' + (110 + xh) + 'px)';
1102
- QS('xdevices')['max-height'] = 'calc(100vh - ' + (124 + xh) + 'px)';
1103
- QS('xdevicesmap')['max-height'] = 'calc(100vh - ' + (124 + xh) + 'px)';
1104
- QS('p15agentConsole')['height'] = 'calc(100vh - ' + (84 + xh) + 'px)';
1105
- QS('p15agentConsole')['max-height'] = 'calc(100vh - ' + (84 + xh) + 'px)';
1106
- QS('p15agentConsoleText')['height'] = 'calc(100vh - ' + (81 + xh) + 'px)';
1107
- QS('p15agentConsoleText')['max-height'] = 'calc(100vh - ' + (81 + xh) + 'px)';
1108
- }
1109
-
1110
- // We are looking at a single device, remove all the back buttons
1111
- if ('{{currentNode}}' != '') {
1112
- QV('p10BackButton', false);
1113
- QV('p11BackButton', false);
1114
- QV('p12BackButton', false);
1115
- QV('p13BackButton', false);
1116
- QV('p14BackButton', false);
1117
- QV('p15BackButton', false);
1118
- QV('p16BackButton', false);
1119
- }
1120
- p1updateInfo();
1121
-
1122
- // Setup the context menu
1123
- document.onclick = function (e) { hideContextMenu(); }
1124
- document.onkeypress = ondockeypress;
1125
- document.onkeydown = ondockeydown;
1126
- document.onkeyup = ondockeyup;
1127
- //window.addEventListener("focus", ondocfocus, false);
1128
- window.addEventListener("blur", ondocblur, false);
1129
- window.onresize = function () { masterUpdate(512); }
1130
- setTimeout(function() { masterUpdate(512); }, 200);
1131
-
1132
- // Connect to the mesh server
1133
- meshserver = MeshServerCreateControl(domainUrl, authCookie);
1134
- meshserver.onStateChanged = onStateChanged;
1135
- meshserver.onMessage = onMessage;
1136
- meshserver.trace = (args.trace == 1);
1137
- meshserver.Start();
1138
-
1139
- // Setup page controls
1140
- Q('sortselect').selectedIndex = sort = getstore("sort", 0);
1141
- Q('sizeselect').selectedIndex = getstore("_viewsize", 1);
1142
- Q('SearchInput').value = getstore("_search", "");
1143
- showRealNames = (getstore("showRealNames", 0) == 1);
1144
- Q('RealNameCheckBox').checked = showRealNames;
1145
- Q('viewselect').value = getstore("_deviceView", 1);
1146
- Q('DeskControl').checked = (getstore('DeskControl', 1) == 1);
1147
- QV('accountChangeEmailAddressSpan', (features & 0x200000) == 0);
1148
-
1149
- // Display the page devices
1150
- masterUpdate(3)
1151
- for (var j = 1; j < 5; j++) { Q('devViewButton' + j).classList.remove('viewSelectorSel'); }
1152
- Q('devViewButton' + Q('viewselect').value).classList.add('viewSelectorSel');
1153
-
1154
- // Setup upload drag & drop
1155
- Q('p5filetable').addEventListener("drop", p5fileDragDrop, false);
1156
- Q('p5filetable').addEventListener("dragover", p5fileDragOver, false);
1157
- Q('p5filetable').addEventListener("dragleave", p5fileDragLeave, false);
1158
- //Q('p5fileCatchAllInput').addEventListener("drop", p5fileDragDrop, false);
1159
- //Q('p5fileCatchAllInput').addEventListener("dragover", p5fileDragOver, false);
1160
- //Q('p5fileCatchAllInput').addEventListener("dragleave", p5fileDragLeave, false);
1161
-
1162
- // Setup upload drag & drop
1163
- Q('p13filetable').addEventListener("drop", p13fileDragDrop, false);
1164
- Q('p13filetable').addEventListener("dragover", p13fileDragOver, false);
1165
- Q('p13filetable').addEventListener("dragleave", p13fileDragLeave, false);
1166
-
1167
- // Timeline update interval
1168
- setInterval(updateDeviceTimeline, 120000); // Check every 2 minutes
1169
-
1170
- // Load desktop settings
1171
- var t = localStorage.getItem('desktopsettings');
1172
- if (t != null) { desktopsettings = JSON.parse(t); }
1173
- t = localStorage.getItem('multidesktopsettings');
1174
- if (t != null) { multidesktopsettings = JSON.parse(t); }
1175
- applyDesktopSettings();
1176
-
1177
- // Terminal special keys
1178
- var x = '';
1179
- for (var c = 1; c < 27; c++) x += "<option value='" + c + "'>Ctrl-" + String.fromCharCode(64 + c) + " (" + c + ")</option>";
1180
- QH('specialkeylist', x);
1181
-
1182
- // Setup server stats panels
1183
- setupGeneralServerStats();
1184
- setupServerTimelineStats();
1185
-
1186
- // Setup the user interface in the right mode
1187
- userInterfaceSelectMenu();
1188
-
1189
- // If SSPI or LDAP authentication not used, allow batch account creation.
1190
- QV('p4UserBatchCreate', (features & 0x00080000) == 0);
1191
- }
1192
-
1193
- // Toggle the web page to full screen
1194
- function toggleAspectRatio(toggle) {
1195
- if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); putstore('deskAspectRatio', deskAspectRatio); }
1196
- deskAdjust();
1197
- }
1198
-
1199
- // If FullScreen, toggle menu to be horisontal or vertical
1200
- function toggleStackMenu(toggle) {
1201
- if (webPageFullScreen == true) {
1202
- if (toggle === 1) {
1203
- webPageStackMenu = !webPageStackMenu;
1204
- putstore('webPageStackMenu', webPageStackMenu);
1205
- }
1206
- if (webPageStackMenu == false) {
1207
- QC('body').remove("menu_stack");
1208
- } else {
1209
- QC('body').add("menu_stack");
1210
- if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
1211
- }
1212
- deskAdjust();
1213
- }
1214
- }
1215
-
1216
- // Toggle user interface menu
1217
- function showUserInterfaceSelectMenu() {
1218
- Q('uiViewButton1').classList.remove('uiSelectorSel');
1219
- Q('uiViewButton2').classList.remove('uiSelectorSel');
1220
- Q('uiViewButton3').classList.remove('uiSelectorSel');
1221
- Q('uiViewButton4').classList.remove('uiSelectorSel');
1222
- try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
1223
- QV('uiMenu', (QS('uiMenu').display == 'none'));
1224
- //Q('uiViewButton1').focus();
1225
- if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
1226
- }
1227
-
1228
- function userInterfaceSelectMenu(s) {
1229
- if (s) { uiMode = s; putstore('uiMode', uiMode); }
1230
- webPageFullScreen = (uiMode < 3);
1231
- webPageStackMenu = (uiMode > 1);
1232
- toggleFullScreen(0);
1233
- toggleStackMenu(0);
1234
- if (webPageStackMenu && (xxcurrentView >= 10)) { QC('column_l').add('room4submenu'); } else { QC('column_l').remove('room4submenu'); }
1235
- }
1236
-
1237
- function toggleNightMode() {
1238
- nightMode = !nightMode;
1239
- if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
1240
- putstore('_nightMode', nightMode?'1':'0');
1241
- }
1242
-
1243
- // Toggle the web page to full screen
1244
- function toggleFullScreen(toggle) {
1245
- if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
1246
- var hide = 0;
1247
- if (args.hide) { hide = parseInt(args.hide); }
1248
- if (webPageFullScreen == false) {
1249
- QC('body').remove("menu_stack");
1250
- QC('body').remove("fullscreen");
1251
- QC('body').remove("arg_hide");
1252
- if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
1253
- QV('UserDummyMenuSpan', false);
1254
- //QV('page_leftbar', false);
1255
- } else {
1256
- QC('body').add("fullscreen");
1257
- if (hide & 16) QC('body').add("arg_hide"); // This is replacement for QV('page_leftbar', !(hide & 16));
1258
- QV('page_leftbar', !(hide & 16));
1259
- QV('MainMenuSpan', !(hide & 16));
1260
- if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
1261
- QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
1262
- }
1263
- masterUpdate(512);
1264
- QV('body', true);
1265
- }
1266
-
1267
- function getNodeFromId(id) { if (nodes != null) { for (var i in nodes) { if (nodes[i]._id == id) return nodes[i]; } } return null; }
1268
- function reload() {
1269
- var x = window.location.href;
1270
- if (x.endsWith('/#')) { x = x.substring(0, x.length - 2); }
1271
- window.location.href = x;
1272
- }
1273
-
1274
- function onStateChanged(server, state, prevState, errorCode) {
1275
- if (state == 0) {
1276
- // Control web socket disconnected
1277
- setDialogMode(0); // Close any dialog boxes if present
1278
- go(0); // Go to disconnection panel
1279
-
1280
- // Clean up
1281
- powerTimeline = null;
1282
- powerTimelineReq = null;
1283
- powerTimelineNode = null;
1284
- powerTimelineUpdate = null;
1285
- deleteAllNotifications(); // Close and clear notifications if present
1286
- hideContextMenu(); // Hide the context menu if present
1287
- QV('verifyEmailId2', false);
1288
- QV('logoutControl', false);
1289
- if (errorCode == 'noauth') { QH('p0span', 'Unable to perform authentication'); return; }
1290
- if (prevState == 2) { if (autoReconnect) { setTimeout(serverPoll, 5000); } } else { QH('p0span', 'Unable to connect web socket'); }
1291
- if (authCookieRenewTimer != null) { clearInterval(authCookieRenewTimer); authCookieRenewTimer = null; }
1292
- } else if (state == 2) {
1293
- // Fetch list of meshes, nodes, files
1294
- meshserver.send({ action: 'meshes' });
1295
- meshserver.send({ action: 'nodes', id: '{{currentNode}}' });
1296
- if ('{{currentNode}}' == '') { meshserver.send({ action: 'files' }); }
1297
- if ('{{viewmode}}' == '') { go(1); }
1298
- authCookieRenewTimer = setInterval(function () { meshserver.send({ action: 'authcookie' }); }, 1800000); // Request a cookie refresh every 30 minutes.
1299
- }
1300
- }
1301
-
1302
- // Poll the server, if it responds, refresh the page.
1303
- function serverPoll() {
1304
- var xdr = null;
1305
- try { xdr = new XDomainRequest(); } catch (e) { }
1306
- if (!xdr) xdr = new XMLHttpRequest();
1307
- xdr.open("HEAD", window.location.href);
1308
- xdr.timeout = 15000;
1309
- xdr.onload = function () { reload(); };
1310
- xdr.onerror = xdr.ontimeout = function () { setTimeout(serverPoll, 10000); };
1311
- xdr.send();
1312
- }
1313
-
1314
- // Return true if this browser supports clickonce
1315
- function detectClickOnce() {
1316
- for (var i in window.navigator.mimeTypes) { if (window.navigator.mimeTypes[i].type == "application/x-ms-application") { return true; } }
1317
- var userAgent = window.navigator.userAgent.toUpperCase();
1318
- return (userAgent.indexOf('.NET CLR 3.5') >= 0) || (userAgent.indexOf('(WINDOWS NT ') >= 0);
1319
- }
1320
-
1321
- function updateSiteAdmin() {
1322
- var noServerBackup = "{{{noServerBackup}}}";
1323
- var siteRights = userinfo.siteadmin;
1324
- if (noServerBackup == 1) { siteRights &= 0xFFFFFFFA; } // If not server backups allowed, remove server backup and restore permissions
1325
-
1326
- // Update account actions
1327
- QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0)); // Hide Account Security if in single user mode, domain authentication to 2 factor auth not supported.
1328
- QV('p2AccountActions', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide Account Actions if in single user mode or domain authentication
1329
- QV('p2AccountImage', ((features & 4) == 0) && (serverinfo.domainauth == false)); // If account actions are not visible, also remove the image on that panel
1330
- QV('p2ServerActions', siteRights & 21);
1331
- QV('LeftMenuMyServer', siteRights & 21); // 16 + 4 + 1
1332
- QV('MainMenuMyServer', siteRights & 21);
1333
- QV('p2ServerActionsBackup', siteRights & 1);
1334
- QV('p2ServerActionsRestore', siteRights & 4);
1335
- QV('p2ServerActionsVersion', siteRights & 16);
1336
- QV('MainMenuMyFiles', siteRights & 8);
1337
- QV('LeftMenuMyFiles', siteRights & 8);
1338
- if (((siteRights & 8) == 0) && (xxcurrentView == 5)) { setDialogMode(0); go(1); }
1339
- if (currentNode != null) { gotoDevice(currentNode._id, xxcurrentView, true); }
1340
-
1341
- // Update user management state
1342
- if ((userinfo.siteadmin & 2) != 0)
1343
- {
1344
- // We are user administrator
1345
- if (users == null) { meshserver.send({ action: 'users' }); }
1346
- if (wssessions == null) { meshserver.send({ action: 'wssessioncount' }); }
1347
- } else {
1348
- // We are not user administrator
1349
- users = null;
1350
- wssessions = null;
1351
- updateUsers();
1352
- if (xxcurrentView == 4 || ((xxcurrentView >= 30) && (xxcurrentView < 40))) { setDialogMode(0); go(1); currentUser = null; }
1353
- }
1354
- meshserver.send({ action: 'events', limit: parseInt(p3limitdropdown.value) });
1355
- QV('ServerConsole', userinfo.siteadmin === 0xFFFFFFFF);
1356
- QV('ServerTrace', userinfo.siteadmin === 0xFFFFFFFF);
1357
- if ((xxcurrentView == 115) && (userinfo.siteadmin != 0xFFFFFFFF)) { go(6); }
1358
- if ((xxcurrentView == 6) && ((userinfo.siteadmin & 21) == 0)) { go(1); }
1359
-
1360
- // If we are site administrator, register to get server statistics
1361
- if ((siteRights & 21) != 0) { meshserver.send({ action: 'serverstats', interval: 10000 }); }
1362
- }
1363
-
1364
- // To boost the speed of the web page when even floods occur, this method perform a delayed update on the web page.
1365
- var updateNaggleTimer = null;
1366
- var updateNaggleFlags = 0;
1367
- function masterUpdate(flags) {
1368
- updateNaggleFlags |= flags;
1369
- if (updateNaggleTimer == null) {
1370
- updateNaggleTimer = setTimeout(function () {
1371
- if (updateNaggleFlags & 512) { center(); }
1372
- if (updateNaggleFlags & 1) { onSearchInputChanged(); }
1373
- if (updateNaggleFlags & 2) { onSortSelectChange(false); }
1374
- if (updateNaggleFlags & 128) { updateMeshes(); }
1375
- if (updateNaggleFlags & 4) { updateDevices(); }
1376
- if (updateNaggleFlags & 8) { drawNotifications(); }
1377
- if (updateNaggleFlags & 16) { updateMapMarkers(); }
1378
- if (updateNaggleFlags & 32) { eventsUpdate(); }
1379
- if (updateNaggleFlags & 64) { refreshMap(false, true); }
1380
- if (updateNaggleFlags & 256) { drawDeviceTimeline(); }
1381
- if (updateNaggleFlags & 1024) { deviceEventsUpdate(); }
1382
- if (updateNaggleFlags & 2048) { userEventsUpdate(); }
1383
- if (updateNaggleFlags & 4096) { p20updateMesh(); }
1384
- updateNaggleTimer = null;
1385
- updateNaggleFlags = 0;
1386
- }, 150);
1387
- }
1388
- }
1389
-
1390
- var backupCodesWarningDone = false;
1391
- function updateSelf() {
1392
- QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
1393
- QV('verifyEmailId2', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
1394
- QV('manageOtp', (userinfo.otpsecret == 1) || (userinfo.otphkeys > 0));
1395
- QV('authAppSetupCheck', userinfo.otpsecret == 1);
1396
- QV('authKeySetupCheck', userinfo.otphkeys > 0);
1397
- QV('authCodesSetupCheck', userinfo.otpkeys > 0);
1398
- masterUpdate(4 + 128 + 4096);
1399
-
1400
- // Check if backup codes should really be enabled
1401
- if ((backupCodesWarningDone == false) && !(userinfo.otpkeys > 0) && (((userinfo.otpsecret == 1) && !(userinfo.otphkeys > 0)) || ((userinfo.otpsecret != 1) && (userinfo.otphkeys == 1)))) {
1402
- var n = { text: 'Please add two-factor backup codes. If the current factor is lost, there is not way to recover this account.', title: 'Two factor authentication' };
1403
- addNotification(n);
1404
- backupCodesWarningDone = true;
1405
- }
1406
-
1407
- // If we can't create new groups, hide all links that can do that.
1408
- var newGroupsAllowed = ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0));
1409
- QV('p2createMeshLink1', newGroupsAllowed);
1410
- QV('p2createMeshLink2', newGroupsAllowed);
1411
- QV('getStarted1', newGroupsAllowed);
1412
- QV('getStarted2', !newGroupsAllowed);
1413
-
1414
- if (typeof userinfo.passchange == 'number') {
1415
- if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', ' - Reset on next login.'); }
1416
- else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
1417
- var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
1418
- if (seconds < 0) { QH('p2nextPasswordUpdateTime', ' - Reset on next login.'); }
1419
- else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', ' - Reset in ' + Math.floor(seconds / 60) + ' minute' + addLetterS(Math.floor(seconds / 60)) + '.'); }
1420
- else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', ' - Reset in ' + Math.floor(seconds / 3600) + ' hour' + addLetterS(Math.floor(seconds / 3600)) + '.'); }
1421
- else { QH('p2nextPasswordUpdateTime', ' - Reset in ' + Math.floor(seconds / 86400) + ' day' + addLetterS(Math.floor(seconds / 86400)) + '.'); }
1422
- }
1423
- }
1424
- }
1425
-
1426
- function addLetterS(x) { return (x > 1) ? 's' : ''; }
1427
- function setSessionActivity() { sessionActivity = Date.now(); QH('idleTimeoutNotify', ''); }
1428
- function checkIdleSessionTimeout() {
1429
- var delta = (Date.now() - sessionActivity);
1430
- if (delta > serverinfo.timeout) { window.location.href = 'logout'; } else {
1431
- var ds = Math.round((serverinfo.timeout - delta) / 1000);
1432
- if (ds <= 60) {
1433
- QH('idleTimeoutNotify', '<br />' + ds + ' second' + addLetterS(ds) + ' until disconnect');
1434
- } else {
1435
- ds = Math.round(ds / 60);
1436
- if (ds <= 5) { QH('idleTimeoutNotify', '<br />' + ds + ' minute' + addLetterS(ds) + ' until disconnect'); }
1437
- }
1438
- }
1439
- }
1440
-
1441
- function onMessage(server, message) {
1442
- switch (message.action) {
1443
- case 'trace': {
1444
- serverTrace.unshift(message);
1445
- displayServerTrace();
1446
- break;
1447
- }
1448
- case 'traceinfo': {
1449
- if (typeof message.traceSources == 'object') {
1450
- if ((message.traceSources != null) && (message.traceSources.length > 0)) {
1451
- serverTraceSources = message.traceSources;
1452
- QH('p41traceStatus', EscapeHtml(message.traceSources.join(', ')));
1453
- } else {
1454
- serverTraceSources = [];
1455
- QH('p41traceStatus', 'None');
1456
- }
1457
- }
1458
- break;
1459
- }
1460
- case 'serverstats': {
1461
- updateGeneralServerStats(message);
1462
- break;
1463
- }
1464
- case 'servertimelinestats': {
1465
- setServerTimelineStats(message.events);
1466
- break;
1467
- }
1468
- case 'authcookie': {
1469
- // Got an authentication cookie refresh
1470
- authCookie = message.cookie;
1471
- authRelayCookie = message.rcookie;
1472
- break;
1473
- }
1474
- case 'serverinfo': {
1475
- serverinfo = message.serverinfo;
1476
- if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); }
1477
- if (debugmode == 1) { console.log("Server time: ", printDateTime(new Date(serverinfo.serverTime))); }
1478
- break;
1479
- }
1480
- case 'userinfo': {
1481
- userinfo = message.userinfo;
1482
- updateSiteAdmin();
1483
- updateSelf();
1484
- break;
1485
- }
1486
- case 'users': {
1487
- users = {};
1488
- for (var m in message.users) { users[message.users[m]._id] = message.users[m]; }
1489
- updateUsers();
1490
- break;
1491
- }
1492
- case 'wssessioncount': {
1493
- wssessions = message.wssessions;
1494
- updateUsers();
1495
- break;
1496
- }
1497
- case 'meshes': {
1498
- meshes = {};
1499
- for (var m in message.meshes) { meshes[message.meshes[m]._id] = message.meshes[m]; }
1500
- masterUpdate(4 + 128);
1501
- break;
1502
- }
1503
- case 'files': {
1504
- filetree = setupBackPointers(message.filetree);
1505
- updateFiles();
1506
- d3updatefiles();
1507
- break;
1508
- }
1509
- case 'nodes': {
1510
- nodes = [];
1511
- for (var m in message.nodes) {
1512
- if (!meshes[m]) { console.log('Invalid mesh (1): ' + m); continue; }
1513
- for (var n in message.nodes[m]) {
1514
- if (message.nodes[m][n]._id == null) { console.log('Invalid node (' + n + '): ' + JSON.stringify(message.nodes)); continue; }
1515
- message.nodes[m][n].namel = message.nodes[m][n].name.toLowerCase();
1516
- if (message.nodes[m][n].rname) { message.nodes[m][n].rnamel = message.nodes[m][n].rname.toLowerCase(); } else { message.nodes[m][n].rnamel = message.nodes[m][n].namel; }
1517
- message.nodes[m][n].meshnamel = meshes[m].name.toLowerCase();
1518
- message.nodes[m][n].meshid = m;
1519
- message.nodes[m][n].state = (message.nodes[m][n].state)?(message.nodes[m][n].state):0;
1520
- message.nodes[m][n].desc = message.nodes[m][n].desc;
1521
- message.nodes[m][n].ip = message.nodes[m][n].ip;
1522
- if (!message.nodes[m][n].icon) message.nodes[m][n].icon = 1;
1523
- message.nodes[m][n].ident = ++nodeShortIdent;
1524
- nodes.push(message.nodes[m][n]);
1525
- }
1526
- }
1527
- masterUpdate(1 | 2 | 4 | 64);
1528
-
1529
- if (xxcurrentView == -1) { if ('{{viewmode}}' != '') { go(parseInt('{{viewmode}}')); } else { setDialogMode(0); go(1); } }
1530
- if ('{{currentNode}}' != '') { gotoDevice('{{currentNode}}',parseInt('{{viewmode}}'));}
1531
- break;
1532
- }
1533
- case 'powertimeline': {
1534
- if (message.nodeid != powerTimelineReq) break;
1535
- powerTimelineNode = message.nodeid;
1536
- powerTimeline = message.timeline;
1537
- powerTimelineUpdate = Date.now() + 300000; // Update every 5 minutes
1538
- for (var i in powerTimeline) { if (i % 2 == 1) { powerTimeline[i] = powerTimeline[i] * 1000; } } // Decompress time
1539
- if (currentNode._id == message.nodeid) { masterUpdate(256); }
1540
- break;
1541
- }
1542
- case 'getsysinfo': {
1543
- if (message.nodeid != powerTimelineReq) break;
1544
- //console.log('getsysinfo', message); // ***********************
1545
- if (message.noinfo === true) {
1546
- QH('p17info', 'No information for this device.');
1547
- } else {
1548
- var x = '', s = {};
1549
- if (message.hardware) {
1550
- if (message.hardware.identifiers) {
1551
- var ident = message.hardware.identifiers;
1552
- // BIOS
1553
- x += '<div class=DevSt style=margin-bottom:3px><b>BIOS</b></div>';
1554
- if (ident.bios_vendor) { x += addDetailItem('Vendor', ident.bios_vendor, s); }
1555
- if (ident.bios_version) { x += addDetailItem('Version', ident.bios_version, s); }
1556
- x += '<br />';
1557
-
1558
- // Motherboard
1559
- x += '<div class=DevSt style=margin-bottom:3px><b>Motherboard</b></div>';
1560
- if (ident.board_vendor) { x += addDetailItem('Vendor', ident.board_vendor, s); }
1561
- if (ident.board_name) { x += addDetailItem('Name', ident.board_name, s); }
1562
- if (ident.board_serial && (ident.board_serial != '')) { x += addDetailItem('Serial', ident.board_serial, s); }
1563
- if (ident.board_version) { x += addDetailItem('Version', ident.board_version, s); }
1564
- if (ident.product_uuid) { x += addDetailItem('Identifier', ident.product_uuid, s); }
1565
- x += '<br />';
1566
- }
1567
-
1568
- if (message.hardware.windows) {
1569
- if (message.hardware.windows.memory) {
1570
- // Memory
1571
- x += '<div class=DevSt style=margin-bottom:3px><b>Memory</b></div>';
1572
-
1573
- // Sort Memory
1574
- function memorySort(a, b) { if (a.BankLabel > b.BankLabel) return 1; if (a.BankLabel < b.BankLabel) return -1; return 0; }
1575
- message.hardware.windows.memory.sort(memorySort);
1576
-
1577
- x += '<table style=width:100%>';
1578
- for (var i in message.hardware.windows.memory) {
1579
- var m = message.hardware.windows.memory[i];
1580
- x += '<tr><td VALIGN=Top style=width:38px><img src="images/ram2.png" />'
1581
- x += '<td><div style=background-color:lightgray;border-radius:5px;padding:8px>';
1582
- x += '<div><b>' + m.BankLabel + '</b></div>';
1583
- if (m.Capacity) { x += addDetailItem('Capacity / Speed', ( m.Capacity / 1024 / 1024) + ' Mb, ' + m.Speed + ' Mhz', s); }
1584
- if (m.PartNumber) { x += addDetailItem('Part Number', ((m.Manufacturer && m.Manufacturer != 'Undefined')?(m.Manufacturer + ', '):'') + m.PartNumber, s); }
1585
- x += '</div>';
1586
- }
1587
- x += '</table><br />';
1588
- }
1589
-
1590
- if (message.hardware.windows.osinfo) {
1591
- // Operating System
1592
- var m = message.hardware.windows.osinfo;
1593
- x += '<div class=DevSt style=margin-bottom:3px><b>Operating System</b></div>';
1594
- if (m.Caption) { x += addDetailItem('Name', m.Caption, s); }
1595
- if (m.Version) { x += addDetailItem('Version', m.Version, s); }
1596
- if (m.OSArchitecture) { x += addDetailItem('Architecture', m.OSArchitecture, s); }
1597
- x += '<br />';
1598
- }
1599
-
1600
- // Disks
1601
- //x += '<div class=DevSt style=margin-bottom:3px><b>Disks</b></div>';
1602
- //x += '<br />';
1603
- }
1604
- }
1605
-
1606
- QH('p17info', x);
1607
- }
1608
- break;
1609
- }
1610
- case 'lastconnect': {
1611
- var node = getNodeFromId(message.nodeid);
1612
- if (node != null) {
1613
- node.lastconnect = message.time;
1614
- node.lastaddr = message.addr;
1615
- if ((currentNode._id == node._id) && (Q('MainComputerState').innerHTML == '')) {
1616
- QH('MainComputerState', '<span>Last seen:<br />' + printDateTime(new Date(node.lastconnect)) + '</span>');
1617
- }
1618
- }
1619
- break;
1620
- }
1621
- case 'msg': {
1622
- // Check if this is a message from a node
1623
- if (message.nodeid != null) {
1624
- var index = -1;
1625
- if (nodes != null) { for (var i in nodes) { if (nodes[i]._id == message.nodeid) { index = i; break; } } }
1626
- if (index != -1) {
1627
- // Node was found, dispatch the message
1628
- if (message.type == 'console') { p15consoleReceive(nodes[index], message.value, message.source); } // This is a console message.
1629
- else if (message.type == 'notify') { // This is a notification message.
1630
- var n = getstore('notifications', 0);
1631
- if (((n & 8) == 0) && (message.amtMessage != null)) { break; } // Intel AMT desktop & terminal messages should be ignored.
1632
- var n = { text: message.value, title: message.title, icon: message.icon };
1633
- if (message.nodeid != null) { n.nodeid = message.nodeid; }
1634
- if (message.tag != null) { n.tag = message.tag; }
1635
- if (message.username != null) { n.username = message.username; }
1636
- addNotification(n);
1637
- } else if (message.type == 'ps') {
1638
- showDeskToolsProcesses(message);
1639
- } else if (message.type == 'services') {
1640
- showDeskToolsServices(message);
1641
- } else if ((message.type == 'getclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
1642
- Q('d2clipText').value = message.data;
1643
- } else if ((message.type == 'setclip') && (xxdialogTag == 'clipboard') && (currentNode != null) && (currentNode._id == message.nodeid)) {
1644
- // Display success/fail on the clipboard dialog box.
1645
- QH('dlgClipStatus', message.success ? '<span style=color:green>Success</span>' : '<span style=color:red>Failed</span>')
1646
- setTimeout(function () { try { QH('dlgClipStatus', ''); } catch (ex) { } }, 2000);
1647
- }
1648
- }
1649
- } else {
1650
- if (message.type == 'notify') { // This is a notification message.
1651
- var n = { text: message.value, title: message.title, icon: message.icon };
1652
- if (message.tag != null) { n.tag = message.tag; }
1653
- if (message.username != null) { n.username = message.username; }
1654
- addNotification(n);
1655
- }
1656
- }
1657
- break;
1658
- }
1659
- case 'getnetworkinfo': {
1660
- if ((currentNode._id == message.nodeid) && (xxdialogMode == 2) && (xxdialogTag == 'if' + message.nodeid)) {
1661
- if (message.netif == null) {
1662
- QH('d2netinfo', 'No network interface information available for this device.');
1663
- } else {
1664
- var x = '<div class=dialogText>';
1665
-
1666
- if (currentNode.lastconnect) { x += addHtmlValue2('Last agent connection', printDateTime(new Date(currentNode.lastconnect))); }
1667
- if (currentNode.lastaddr) {
1668
- var splitip = currentNode.lastaddr.split(':');
1669
- if (splitip.length > 2) {
1670
- // IPv6
1671
- x += addHtmlValue2('Last agent address', currentNode.lastaddr + ' <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(currentNode.lastaddr) + '\") width=10 height=10>');
1672
- } else {
1673
- // IPv4
1674
- if (isPrivateIP(currentNode.lastaddr)) {
1675
- x += addHtmlValue2('Last agent address', splitip[0] + ' <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(splitip[0]) + '\") width=10 height=10>');
1676
- } else {
1677
- x += addHtmlValue2('Last agent address', '<a href="https://iplocation.com/?ip=' + splitip[0] + '" rel="noreferrer noopener" target="MeshIPLoopup">' + splitip[0] + '</a> <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(splitip[0]) + '\") width=10 height=10>');
1678
- }
1679
- }
1680
- }
1681
-
1682
- x += addHtmlValue2('Last interfaces update', printDateTime(new Date(message.updateTime)));
1683
- for (var i in message.netif) {
1684
- var net = message.netif[i];
1685
- x += '<hr />'
1686
- if (net.name) { x += addHtmlValue2('Name', '<b>' + EscapeHtml(net.name) + '</b>'); }
1687
- if (net.desc) { x += addHtmlValue2('Description', EscapeHtml(net.desc).replace('(R)', '®').replace('(r)', '®')); }
1688
- if (net.dnssuffix) { x += addHtmlValue2('DNS suffix', EscapeHtml(net.dnssuffix) + ' <img src="images/link4.png" title="Copy name to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.dnssuffix) + '\") width=10 height=10>'); }
1689
- if (net.mac) { x += addHtmlValue2('MAC address', '<a href="https://dnslytics.com/mac-address-lookup/' + net.mac.substring(0, 6) + '" rel="noreferrer noopener" target="MeshMACLoopup">' + EscapeHtml(net.mac.toLowerCase()) + '</a> <img src="images/link4.png" title="Copy MAC address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.mac.toLowerCase()) + '\") width=10 height=10>'); }
1690
- if (net.v4addr) { x += addHtmlValue2('IPv4 address', EscapeHtml(net.v4addr) + ' <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.v4addr) + '\") width=10 height=10>'); }
1691
- if (net.v4mask) { x += addHtmlValue2('IPv4 mask', EscapeHtml(net.v4mask) + ' <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.v4mask) + '\") width=10 height=10>'); }
1692
- if (net.v4gateway) { x += addHtmlValue2('IPv4 gateway', EscapeHtml(net.v4gateway) + ' <img src="images/link4.png" title="Copy address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.v4gateway) + '\") width=10 height=10>'); }
1693
- if (net.gatewaymac) { x += addHtmlValue2('Gateway MAC', '<a href="https://dnslytics.com/mac-address-lookup/' + net.gatewaymac.substring(0, 6) + '" rel="noreferrer noopener" target="MeshMACLoopup">' + EscapeHtml(net.gatewaymac.toLowerCase()) + '</a> <img src="images/link4.png" title="Copy MAC address to clipboard" style="cursor:pointer" onclick=copyTextToClip2(\"' + encodeURIComponent(net.gatewaymac.toLowerCase()) + '\") width=10 height=10>'); }
1694
- }
1695
- x += '</div>';
1696
- QH('d2netinfo', x);
1697
- }
1698
- }
1699
- break;
1700
- }
1701
- case 'serverversion': {
1702
- if ((xxdialogMode == 2) && (xxdialogTag == 'MeshCentralServerUpdate')) {
1703
- var x = '<div class=dialogText>';
1704
- if (!message.current) { message.current = 'Unknown'; }
1705
- if (!message.latest) { message.latest = 'Unknown'; }
1706
- x += addHtmlValue2('Current Version', '<b>' + EscapeHtml(message.current) + '</b>');
1707
- x += addHtmlValue2('Latest Version', '<b>' + EscapeHtml(message.latest) + '</b>');
1708
- x += '</div>';
1709
- if ((message.latest.indexOf('.') == -1) || (message.current == message.latest) || ((features & 2048) == 0)) {
1710
- setDialogMode(2, "MeshCentral Version", 1, null, x);
1711
- } else {
1712
- setDialogMode(2, "MeshCentral Version", 3, server_showVersionDlgEx, x + '<br /><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to start server self-update.</label>');
1713
- server_showVersionDlgUpdate();
1714
- }
1715
- }
1716
- break;
1717
- }
1718
- case 'servererrors': {
1719
- if ((xxdialogMode == 2) && (xxdialogTag == 'MeshCentralServerErrors')) {
1720
- if (message.data == null) {
1721
- setDialogMode(2, "MeshCentral Server Errors", 1, null, 'Server has no error log.');
1722
- } else {
1723
- var x = '<div class="dialogText dialogTextLog"><pre id=d2ServerErrorsLogPre>' + message.data + '<pre></div>';
1724
- setDialogMode(2, "MeshCentral Server Errors", 3, server_showErrorsDlgEx, x + '<br /><div style=float:right><img src=images/link4.png height=10 width=10 title="Download error log" style=cursor:pointer onclick=d2CopyServerErrorsToClip()></div><div><label><input id=d2updateCheck type=checkbox onclick=server_showVersionDlgUpdate() /> Check and click OK to clear error log.</label></div>');
1725
- server_showVersionDlgUpdate();
1726
- }
1727
- }
1728
- break;
1729
- }
1730
- case 'serverconsole': {
1731
- p15consoleReceive('serverconsole', message.value);
1732
- break;
1733
- }
1734
- case 'events': {
1735
- if ((message.nodeid != null) && (message.nodeid == currentNode._id)) {
1736
- currentDeviceEvents = message.events;
1737
- masterUpdate(1024);
1738
- } else if ((message.user != null) && (message.user == currentUser.name)) {
1739
- currentUserEvents = message.events;
1740
- masterUpdate(2048);
1741
- } else {
1742
- events = message.events;
1743
- masterUpdate(32);
1744
- }
1745
- break;
1746
- }
1747
- case 'getcookie': {
1748
- if (message.tag == 'clickonce') {
1749
- var basicPort = "{{{serverRedirPort}}}" == "" ? "{{{serverPublicPort}}}" : "{{{serverRedirPort}}}";
1750
- var rdpurl = "http://" + window.location.hostname + ":" + basicPort + "/clickonce/minirouter/MeshMiniRouter.application?WS=wss%3A%2F%2F" + window.location.hostname + "%2Fmeshrelay.ashx%3Fauth=" + message.cookie + "&CH={{{webcerthash}}}&AP=" + message.protocol + ((debugmode == 1) ? "" : "&HOL=1");
1751
- var newWindow = window.open(rdpurl, '_blank');
1752
- newWindow.opener = null;
1753
- }
1754
- break;
1755
- }
1756
- case 'getNotes': {
1757
- var n = Q('d2devNotes');
1758
- if (n && (message.id == decodeURIComponent(n.attributes['noteid'].value))) {
1759
- if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); }
1760
- var ro = (n.attributes['ro'].value == 'true');
1761
- if (ro == false) { // If we have permissions, set read/write on this note.
1762
- n.removeAttribute('readonly');
1763
- QE('idx_dlgOkButton', true);
1764
- QV('idx_dlgOkButton', true);
1765
- focusTextBox('d2devNotes');
1766
- }
1767
- }
1768
- break;
1769
- }
1770
- case 'otpauth-request': {
1771
- if ((xxdialogMode == 2) && (xxdialogTag == 'otpauth-request')) {
1772
- var secret = message.secret;
1773
- if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); }
1774
- else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) }
1775
- QH('d2optinfo', '<table style=width:380px><tr><td style=vertical-align:top>Install <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> or a compatible application and scan the barcode, use <a href=\"' + message.url + '\" rel=\"noreferrer noopener\" target=_blank> this link</a> or enter the secret. Then, enter the current 6 digit token below to activate 2-Step login.<br /><br />Secret<br /><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:12px>' + secret + '</tt><br /><br /></td><td style=width:1px;vertical-align:top><a href=\"' + message.url + '\" rel=\"noreferrer noopener\" target=_blank><div id="qrcode"></div></a></td><tr><td colspan=2 style="text-align:center;border-top:1px solid black"><br />Enter the token here for 2-step login: <input type=text onkeypress=\"return (event.keyCode == 8) || (event.charCode >= 48 && event.charCode <= 57)\" onkeyup=account_addOtpCheck(event) onkeydown=account_addOtpCheck() maxlength=6 id=d2otpauthinput type=text></td></table>');
1776
- new QRCode(Q("qrcode"), { text: message.url, width: 128, height: 128, colorDark: "#000000", colorLight: "#EEE", correctLevel: QRCode.CorrectLevel.H });
1777
- QV('idx_dlgOkButton', true);
1778
- QE('idx_dlgOkButton', false);
1779
- Q('d2otpauthinput').focus();
1780
- }
1781
- break;
1782
- }
1783
- case 'otpauth-setup': {
1784
- if (xxdialogMode) return;
1785
- setDialogMode(2, "Authenticator App", 1, null, message.success ? "<b style=color:green>Authenticator app activation successful</b>. You will now need a valid token to login again." : "<b style=color:red>2-step login activation failed</b>. Clear the secret from the application and try again. You only have a few minutes to enter the proper code.");
1786
- break;
1787
- }
1788
- case 'otpauth-clear': {
1789
- if (xxdialogMode) return;
1790
- setDialogMode(2, "Authenticator App", 1, null, message.success ? "<b>Authenticator application removed</b>. You can reactivate this feature at any time." : "<b style=color:red>2-step login activation removal failed</b>. Try again.");
1791
- break;
1792
- }
1793
- case 'otpauth-getpasswords': {
1794
- if (xxdialogMode) return;
1795
- var x = "One time tokens can be used as secondary authentication. Generate a set, print them and keep them in a safe place.";
1796
- x += "<div style='border-radius:6px;border: 2px dashed #888;width:100%;margin-top:8px'><div style='padding:8px;font-family:Arial, Helvetica, sans-serif;font-size:20px;font-weight:bold'><table class=selecttext style=width:100%;text-align:center>";
1797
- if (message.passwords) {
1798
- var j = 0, clipb = '';
1799
- for (var i in message.passwords) {
1800
- if (++j % 2) { x += '<tr>'; }
1801
- var p = '' + message.passwords[i].p;
1802
- while (p.length < 8) { p = '0' + p; }
1803
- if (message.passwords[i].u === true) {
1804
- x += '<td>' + p.substring(0, 4) + ' ' + p.substring(4);
1805
- if (clipb != '') { clipb += ' '; }
1806
- clipb += p;
1807
- } else {
1808
- x += '<td><strike style=color:#BBB>' + p.substring(0, 4) + ' ' + p.substring(4); + '</strike>';
1809
- }
1810
- }
1811
- } else {
1812
- x += '<tr><td>No Active Tokens';
1813
- }
1814
- x += "</table></div></div><br />";
1815
- x += "<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";
1816
- x += "<input type=button value='Generate New Tokens' onclick='account_manageOtp(1);'></input>";
1817
- if (message.passwords != null) {
1818
- x += "<input type=button value='Clear Tokens' onclick='account_manageOtp(2);'></input>";
1819
- x += ' <img src=images/link4.png height=10 width=10 title="Copy valid codes to clipboard" style=cursor:pointer onclick=copyTextToClip2("' + encodeURIComponent(clipb) + '")>';
1820
- }
1821
- x += "</div><br />";
1822
- setDialogMode(2, "Manage Backup Codes", 8, null, x, 'otpauth-manage');
1823
- break;
1824
- }
1825
- case 'otp-hkey-get': {
1826
- if (xxdialogMode && (xxdialogTag != 'otpauth-hardware-manage')) return;
1827
- var start = "<div style='border-radius:6px;border:2px solid #CCC;background-color:#BBB;width:100%;box-sizing:border-box;margin-bottom:6px'><div style='margin:3px;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:bold'><table style=width:100%;text-align:left>";
1828
- var end = "</table></div></div>";
1829
- var x = "<a href='https://www.yubico.com/' rel='noreferrer noopener' target='_blank'>Hardware keys</a> are used as secondary login authentication.";
1830
- x += "<div style='max-height:150px;overflow-y:auto;overflow-x:hidden;margin-top:6px;margin-bottom:6px'>";
1831
- if (message.keys && message.keys.length > 0) {
1832
- for (var i in message.keys) {
1833
- var key = message.keys[i], type = (key.type == 2)?'OTP':'WebAuthn';
1834
- x += start + '<tr style=margin:5px><td style=width:30px><img width=24 height=18 src="images/hardware-key-' + type + '-24.png" style=margin-top:4px><td style=width:250px>' + key.name + "<td><input type=button value='Remove' onclick=account_removehkey(" + key.i + ")></input>" + end;
1835
- }
1836
- } else {
1837
- x += start + '<tr style=text-align:center><td>No Keys Configured' + end;
1838
- }
1839
- x += "</div>";
1840
- x += "<div><input type=button value='Close' onclick=setDialogMode(0) style=float:right></input>";
1841
- if ((features & 0x00020000) != 0) { x += "<input id=d2addkey3 type=button value='Add Key' onclick='account_addhkey(3);'></input>"; }
1842
- if ((features & 0x00004000) != 0) { x += "<input id=d2addkey2 type=button value='Add YubiKey® OTP' onclick='account_addhkey(2);'></input>"; }
1843
- x += "</div><br />";
1844
- setDialogMode(2, "Manage Security Keys", 8, null, x, 'otpauth-hardware-manage');
1845
- if (u2fSupported() == false) { QE('d2addkey1', false); }
1846
- break;
1847
- }
1848
- case 'otp-hkey-yubikey-add': {
1849
- if (message.result) {
1850
- meshserver.send({ action: 'otp-hkey-get' }); // Success, ask for the full list of keys.
1851
- } else {
1852
- setDialogMode(2, "Add Security Key", 1, null, '<br />Error, Unable to add key.<br /><br />');
1853
- }
1854
- break;
1855
- }
1856
- case 'otp-hkey-setup-response': {
1857
- if (xxdialogMode && (xxdialogTag != 'otpauth-hardware-manage')) return;
1858
- if (message.result == true) {
1859
- meshserver.send({ action: 'otp-hkey-get' }); // Success, ask for the full list of keys.
1860
- } else {
1861
- setDialogMode(2, "Add Security Key", 1, null, '<br />ERROR: Unable to add key.<br /><br />', 'otpauth-hardware-manage');
1862
- }
1863
- break;
1864
- }
1865
- case 'webauthn-startregister': {
1866
- if (xxdialogMode && (xxdialogTag != 'otpauth-hardware-manage')) return;
1867
- var x = "Press the key button now.<br /><br /><div style=width:100%;text-align:center><img width=120 height=117 src='images/hardware-keypress-120.png' /></div><input id=dp1keyname style=display:none value=" + message.name + " />";
1868
- setDialogMode(2, "Add Security Key", 2, null, x);
1869
-
1870
- var publicKey = message.request;
1871
- message.request.challenge = Uint8Array.from(atob(message.request.challenge), function (c) { return c.charCodeAt(0) })
1872
- message.request.user.id = Uint8Array.from(atob(message.request.user.id), function (c) { return c.charCodeAt(0) })
1873
- navigator.credentials.create({ publicKey: publicKey })
1874
- .then(function(newCredentialInfo) {
1875
- // Public key credential
1876
- var r = { rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.rawId))), response: { attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.clientDataJSON))) }, type: newCredentialInfo.type };
1877
- meshserver.send({ action: 'webauthn-endregister', response: r });
1878
- setDialogMode(0);
1879
- }, function(error) {
1880
- // Error
1881
- setDialogMode(2, "Add Security Key", 1, null, "ERROR: " + error);
1882
- });
1883
- break;
1884
- }
1885
- case 'event': {
1886
- if (!message.event.nolog) {
1887
- if (currentNode && (message.event.nodeid == currentNode._id)) {
1888
- // If this event has a nodeid and we are looking at this node, update the log in real time.
1889
- currentDeviceEvents.unshift(message.event);
1890
- var eventLimit = parseInt(p16limitdropdown.value);
1891
- while (currentDeviceEvents.length > eventLimit) { currentDeviceEvents.pop(); } // Remove element(s) at the end
1892
- masterUpdate(1024);
1893
- }
1894
-
1895
- if (currentUser && (message.event.userid == currentUser._id)) {
1896
- // If this event has a userid and we are looking at this user, update the log in real time.
1897
- currentUserEvents.unshift(message.event);
1898
- var eventLimit = parseInt(p31limitdropdown.value);
1899
- while (currentUserEvents.length > eventLimit) { currentUserEvents.pop(); } // Remove element(s) at the end
1900
- masterUpdate(2048);
1901
- }
1902
-
1903
- // Add this event to the master events log.
1904
- events.unshift(message.event);
1905
- var eventLimit = parseInt(p3limitdropdown.value);
1906
- while (events.length > eventLimit) { events.pop(); } // Remove element(s) at the end
1907
- masterUpdate(32);
1908
- }
1909
- if (message.event.noact) break; // Take no action on this event
1910
- switch (message.event.action) {
1911
- case 'userWebState': {
1912
- // New user web state, update the web page as needed
1913
- if (localStorage != null) {
1914
- var oldShowRealNames = localStorage.getItem('showRealNames');
1915
- var oldUiMode = localStorage.getItem('uiMode');
1916
- var oldSort = localStorage.getItem('sort');
1917
- var oldLoctag = localStorage.getItem('loctag');
1918
-
1919
- var webstate = JSON.parse(message.event.state);
1920
- for (var i in webstate) { localStorage.setItem(i, webstate[i]); }
1921
-
1922
- // Update the web page
1923
- if ((webstate.deskAspectRatio != null) && (webstate.deskAspectRatio != deskAspectRatio)) { deskAspectRatio = webstate.deskAspectRatio; deskAdjust(); }
1924
- if ((webstate.showRealNames != null) && (webstate.showRealNames != oldShowRealNames)) { showRealNames = Q('RealNameCheckBox').checked = (webstate.showRealNames == "1"); masterUpdate(6); }
1925
- if ((webstate.uiMode != null) && (webstate.uiMode != oldUiMode)) { userInterfaceSelectMenu(parseInt(webstate.uiMode)); }
1926
- if ((webstate.sort != null) && (webstate.sort != oldSort)) { document.getElementById("sortselect").selectedIndex = sort = parseInt(webstate.sort); masterUpdate(6); }
1927
- if ((webstate.loctag != null) && (webstate.loctag != oldLoctag)) { if (webstate.loctag != null) { args.locale = webstate.loctag; } else { delete args.locale; } masterUpdate(0xFFFFFFFF); }
1928
- }
1929
- break;
1930
- }
1931
- case 'servertimelinestats': { addServerTimelineStats(message.event.data); break; }
1932
- case 'accountcreate':
1933
- case 'accountchange': {
1934
- // An account was created or changed
1935
- if (userinfo.name == message.event.account.name) {
1936
- var newsiteadmin = message.event.account.siteadmin?message.event.account.siteadmin:0;
1937
- var oldsiteadmin = userinfo.siteadmin?userinfo.siteadmin:0;
1938
- if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
1939
- var oldgroups = userinfo.groups;
1940
- userinfo = message.event.account;
1941
- if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
1942
- updateSelf();
1943
-
1944
- if ((userinfo.siteadmin & 2) != 0) {
1945
- // Compare our groups
1946
- var og = oldgroups ? oldgroups : [];
1947
- var ng = userinfo.groups ? userinfo.groups : [];
1948
- if (og.join(',') != ng.join(',')) {
1949
- // Our groups have changed, re-ask for a list of users.
1950
- users = wssessions = null;
1951
- meshserver.send({ action: 'users' });
1952
- meshserver.send({ action: 'wssessioncount' });
1953
- }
1954
- }
1955
- }
1956
- if (users == null) break;
1957
-
1958
- // Check if the account is part of our user group
1959
- if ((userinfo.groups == null) || (userinfo.groups.length == 0) || (findOne(message.event.account.groups, userinfo.groups) == true)) {
1960
- users[message.event.account._id] = message.event.account; // Part of our groups, update this user.
1961
- } else {
1962
- delete users[message.event.account._id]; // No longer part of our groups, remove this user.
1963
- }
1964
-
1965
- updateUsers();
1966
- break;
1967
- }
1968
- case 'accountremove': {
1969
- // An account was removed
1970
- if (users == null) break;
1971
- delete users['user/' + domain + '/' + message.event.username.toLowerCase()];
1972
- updateUsers();
1973
- break;
1974
- }
1975
- case 'createmesh': {
1976
- // A new mesh was created
1977
- if ((meshes[message.event.meshid] == null) && (message.event.links[userinfo._id] != null)) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
1978
- meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
1979
- masterUpdate(4 + 128);
1980
- meshserver.send({ action: 'files' });
1981
- }
1982
- break;
1983
- }
1984
- case 'meshchange': {
1985
- // Update mesh information
1986
- if (meshes[message.event.meshid] == null) {
1987
- // This is a new mesh for us
1988
- meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
1989
- meshserver.send({ action: 'nodes' }); // Request a refresh of all nodes (TODO: We could optimize this to only request nodes for the new mesh).
1990
- } else {
1991
- // This is an existing mesh
1992
- if (message.event.name != null) {
1993
- meshes[message.event.meshid].name = message.event.name;
1994
- for (var i in nodes) { if (nodes[i].meshid == message.event.meshid) { nodes[i].meshnamel = message.event.name.toLowerCase(); } }
1995
- }
1996
- if (message.event.desc != null) { meshes[message.event.meshid].desc = message.event.desc; }
1997
- if (message.event.flags != null) { meshes[message.event.meshid].flags = message.event.flags; }
1998
- if (message.event.consent != null) { meshes[message.event.meshid].consent = message.event.consent; }
1999
- if (message.event.links) { meshes[message.event.meshid].links = message.event.links; }
2000
- if (message.event.amt) { meshes[message.event.meshid].amt = message.event.amt; }
2001
-
2002
- // Check if we lost rights to this mesh in this change.
2003
- if (meshes[message.event.meshid].links[userinfo._id] == null) {
2004
- if ((xxcurrentView == 20) && (currentMesh == meshes[message.event.meshid])) go(2);
2005
- delete meshes[message.event.meshid];
2006
-
2007
- // Delete all nodes in that mesh
2008
- var newnodes = [];
2009
- for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } }
2010
- nodes = newnodes;
2011
-
2012
- // If we are looking at a node in the deleted mesh, move back to "My Devices"
2013
- if (xxcurrentView >= 10 && xxcurrentView < 20 && currentNode && currentNode.meshid == message.event.meshid) { setDialogMode(0); go(1); }
2014
- }
2015
- }
2016
- masterUpdate(4 + 128);
2017
- if (currentNode && (currentNode.meshid == message.event.meshid)) { currentNode = null; if ((xxcurrentView >= 10) && (xxcurrentView < 20)) { go(1); } }
2018
- //meshserver.send({ action: 'files' }); // TODO: Why do we need to do this??
2019
-
2020
- // If we are looking at a mesh that is now deleted, move back to "My Account"
2021
- if (xxcurrentView == 20 && currentMesh._id == message.event.meshid) { masterUpdate(4096); }
2022
- break;
2023
- }
2024
- case 'deletemesh': {
2025
- // Delete the mesh
2026
- if (meshes[message.event.meshid]) {
2027
- delete meshes[message.event.meshid];
2028
- masterUpdate(128);
2029
- meshserver.send({ action: 'files' });
2030
- }
2031
-
2032
- // Delete all nodes in that mesh
2033
- var newnodes = [];
2034
- if (nodes != null) { for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } } }
2035
- nodes = newnodes;
2036
- masterUpdate(4);
2037
-
2038
- // If we are looking at a mesh that is now deleted, move back to "My Account"
2039
- if (xxcurrentView >= 20 && xxcurrentView < 30 && currentMesh._id == message.event.meshid) { setDialogMode(0); go(2); }
2040
- // If we are looking at a node in the deleted mesh, move back to "My Devices"
2041
- if (xxcurrentView >= 10 && xxcurrentView < 20 && currentNode && currentNode.meshid == message.event.meshid) { setDialogMode(0); go(1); }
2042
-
2043
- break;
2044
- }
2045
- case 'addnode': {
2046
- var node = message.event.node;
2047
- if (!meshes[node.meshid]) break; // This is a node for a mesh we don't know. Happens when we are site administrator, we get all messages.
2048
- if (getNodeFromId(node._id) != null) break; // This node is already known.
2049
- node.namel = node.name.toLowerCase();
2050
- if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
2051
- node.meshnamel = meshes[node.meshid].name.toLowerCase();
2052
- node.state = 0;
2053
- if (!node.icon) node.icon = 1;
2054
- node.ident = ++nodeShortIdent;
2055
- if (nodes == null) { }
2056
- nodes.push(node);
2057
-
2058
- // Web page update
2059
- masterUpdate(1 | 2 | 4 | 16);
2060
-
2061
- break;
2062
- }
2063
- case 'removenode': {
2064
- var index = -1;
2065
- for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
2066
- if (index != -1) {
2067
- var node = nodes[index];
2068
- if (currentNode == node) {
2069
- if (xxcurrentView >= 10 && xxcurrentView < 20) { setDialogMode(0); go(1); }
2070
- currentNode = null;
2071
- // TODO: Correctly disconnect from this node (Desktop/Terminal/Files...)
2072
- }
2073
- nodes.splice(index, 1);
2074
-
2075
- // Web page update
2076
- masterUpdate(4 | 16);
2077
- }
2078
- break;
2079
- }
2080
- case 'changenode': {
2081
- var index = -1;
2082
- for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
2083
- if (index != -1) {
2084
- var node = nodes[index];
2085
-
2086
- // Change the node
2087
- node.name = message.event.node.name;
2088
- node.rname = message.event.node.rname;
2089
- node.users = message.event.node.users;
2090
- node.host = message.event.node.host;
2091
- node.desc = message.event.node.desc;
2092
- node.ip = message.event.node.ip;
2093
- node.osdesc = message.event.node.osdesc;
2094
- node.publicip = message.event.node.publicip;
2095
- node.iploc = message.event.node.iploc;
2096
- node.wifiloc = message.event.node.wifiloc;
2097
- node.gpsloc = message.event.node.gpsloc;
2098
- node.tags = message.event.node.tags;
2099
- node.userloc = message.event.node.userloc;
2100
- if (message.event.node.agent != null) {
2101
- if (node.agent == null) node.agent = {};
2102
- if (message.event.node.agent.ver != null) { node.agent.ver = message.event.node.agent.ver; }
2103
- if (message.event.node.agent.id != null) { node.agent.id = message.event.node.agent.id; }
2104
- if (message.event.node.agent.caps != null) { node.agent.caps = message.event.node.agent.caps; }
2105
- if (message.event.node.agent.core != null) { node.agent.core = message.event.node.agent.core; } else { if (node.agent.core) { delete node.agent.core; } }
2106
- node.agent.tag = message.event.node.agent.tag;
2107
- }
2108
- if (message.event.node.intelamt != null) {
2109
- if (node.intelamt == null) node.intelamt = {};
2110
- if (message.event.node.intelamt.state != null) { node.intelamt.state = message.event.node.intelamt.state; }
2111
- if (message.event.node.intelamt.host != null) { node.intelamt.user = message.event.node.intelamt.host; }
2112
- if (message.event.node.intelamt.user != null) { node.intelamt.user = message.event.node.intelamt.user; }
2113
- if (message.event.node.intelamt.tls != null) { node.intelamt.tls = message.event.node.intelamt.tls; }
2114
- if (message.event.node.intelamt.ver != null) { node.intelamt.ver = message.event.node.intelamt.ver; }
2115
- if (message.event.node.intelamt.tag != null) { node.intelamt.tag = message.event.node.intelamt.tag; }
2116
- if (message.event.node.intelamt.uuid != null) { node.intelamt.uuid = message.event.node.intelamt.uuid; }
2117
- if (message.event.node.intelamt.realm != null) { node.intelamt.realm = message.event.node.intelamt.realm; }
2118
- }
2119
- if (message.event.node.av != null) { node.av = message.event.node.av; }
2120
- node.namel = node.name.toLowerCase();
2121
- if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
2122
- if (message.event.node.icon) { node.icon = message.event.node.icon; }
2123
-
2124
- // Web page update
2125
- masterUpdate(2 | 4 | 8 | 16);
2126
- refreshDevice(node._id);
2127
-
2128
- if ((currentNode == node) && (xxdialogMode != null) && (xxdialogTag == '@xxmap')) { p10showNodeLocationDialog(); }
2129
- }
2130
- break;
2131
- }
2132
- case 'nodemeshchange': {
2133
- var index = -1;
2134
- for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
2135
- if (index != -1) {
2136
- var node = nodes[index];
2137
- if (meshes[message.event.newMeshId] == null) {
2138
- // We don't see the new mesh, remove this device
2139
-
2140
- // TODO: Correctly disconnect from this node (Desktop/Terminal/Files...)
2141
- if (currentNode == node) { if (xxcurrentView >= 10 && xxcurrentView < 20) { setDialogMode(0); go(1); } currentNode = null; }
2142
- nodes.splice(index, 1);
2143
- masterUpdate(4 | 16);
2144
- } else {
2145
- // We see the new mesh, move this device
2146
- node.meshid = message.event.newMeshId;
2147
- node.meshnamel = meshes[message.event.newMeshId].name.toLowerCase();
2148
- masterUpdate(1 | 2 | 4);
2149
- }
2150
- refreshDevice(message.event.nodeid);
2151
- } else {
2152
- // This is a new device, add it.
2153
- var node = message.event.node;
2154
- if (!meshes[node.meshid]) break; // This is a node for a mesh we don't know. Happens when we are site administrator, we get all messages.
2155
- node.namel = node.name.toLowerCase();
2156
- if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
2157
- node.meshnamel = meshes[node.meshid].name.toLowerCase();
2158
- node.state = 0;
2159
- if (!node.icon) node.icon = 1;
2160
- node.ident = ++nodeShortIdent;
2161
- if (nodes == null) { }
2162
- nodes.push(node);
2163
-
2164
- // Web page update
2165
- masterUpdate(1 | 2 | 4 | 16);
2166
- }
2167
- break;
2168
- }
2169
- case 'nodeconnect': {
2170
- // Indicated a node has changed connectivity state
2171
- var index = -1;
2172
- for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
2173
- if (index != -1) {
2174
- var node = nodes[index];
2175
-
2176
- // Event the connection change if needed
2177
- var n = getstore('notifications', 0); // Account notification settings
2178
-
2179
- // Per-group notification settings
2180
- if (message.event.meshid && userinfo.links && userinfo.links[message.event.meshid] && userinfo.links[message.event.meshid].notify) {
2181
- n &= userinfo.links[message.event.meshid].notify;
2182
- } else {
2183
- n = 0;
2184
- }
2185
-
2186
- // Show the notification
2187
- if (n & 2) {
2188
- if (((node.conn & 1) == 0) && ((message.event.conn & 1) != 0)) { addNotification({ text: 'Agent connected', title: node.name, icon: node.icon, nodeid: node._id }); }
2189
- if (((node.conn & 2) == 0) && ((message.event.conn & 2) != 0)) { addNotification({ text: 'Intel AMT detected', title: node.name, icon: node.icon, nodeid: node._id }); }
2190
- if (((node.conn & 4) == 0) && ((message.event.conn & 4) != 0)) { addNotification({ text: 'Intel AMT CIRA connected', title: node.name, icon: node.icon, nodeid: node._id }); }
2191
- if (((node.conn & 16) == 0) && ((message.event.conn & 16) != 0)) { addNotification({ text: 'MQTT connected', title: node.name, icon: node.icon, nodeid: node._id }); }
2192
- }
2193
- if (n & 4) {
2194
- if (((node.conn & 1) != 0) && ((message.event.conn & 1) == 0)) { addNotification({ text: 'Agent disconnected', title: node.name, icon: node.icon, nodeid: node._id }); }
2195
- if (((node.conn & 2) != 0) && ((message.event.conn & 2) == 0)) { addNotification({ text: 'Intel AMT not detected', title: node.name, icon: node.icon, nodeid: node._id }); }
2196
- if (((node.conn & 4) != 0) && ((message.event.conn & 4) == 0)) { addNotification({ text: 'Intel AMT CIRA disconnected', title: node.name, icon: node.icon, nodeid: node._id }); }
2197
- if (((node.conn & 16) != 0) && ((message.event.conn & 16) == 0)) { addNotification({ text: 'MQTT disconnected', title: node.name, icon: node.icon, nodeid: node._id }); }
2198
- }
2199
-
2200
- // Change the node connection state
2201
- node.conn = message.event.conn;
2202
- node.pwr = message.event.pwr;
2203
-
2204
- // Web page update
2205
- masterUpdate(4 | 16);
2206
- refreshDevice(node._id);
2207
- }
2208
- break;
2209
- }
2210
- case 'wssessioncount': {
2211
- // Update the active web socket session count for a user
2212
- if (wssessions != null) {
2213
- if (message.event.count == 0 && wssessions['user/' + domain + '/' + message.event.username.toLowerCase()]) {
2214
- delete wssessions['user/' + domain + '/' + message.event.username.toLowerCase()];
2215
- } else {
2216
- wssessions['user/' + domain + '/' + message.event.username.toLowerCase()] = message.event.count;
2217
- }
2218
- updateUsers();
2219
- }
2220
- break;
2221
- }
2222
- case 'login': {
2223
- // Update the last login time
2224
- if (users != null && users['user/' + domain + '/' + message.event.username.toLowerCase()]) {
2225
- users['user/' + domain + '/' + message.event.username.toLowerCase()].login = Math.floor(new Date(message.event.time).getTime() / 1000);
2226
- }
2227
- break;
2228
- }
2229
- case 'scanamtdevice': {
2230
- // Populate the Intel AMT scan dialog box with the result of the RMCP scan
2231
- if ((xxdialogMode == null) || (!Q('dp1range')) || (Q('dp1range').value != message.event.range)) return;
2232
- var x = '';
2233
- if (message.event.results == null) {
2234
- // The scan could not occur because of an error. Likely the user range was invalid.
2235
- x = '<div style=width:100%;text-align:center;margin-top:12px>Unable to scan this address range.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>';
2236
- } else {
2237
- // Go thru all the results and populate the dialog box
2238
- amtScanResults = message.event.results;
2239
- for (var i in message.event.results) {
2240
- var r = message.event.results[i], shortname = r.hostname;
2241
- if (shortname.length > 20) { shortname = shortname.substring(0, 20) + '...'; }
2242
- var str = '<b title="' + EscapeHtml(r.hostname) + '">' + EscapeHtml(shortname) + '</b> - v' + r.ver;
2243
- if (r.state == 2) { if (r.tls == 1) { str += ' with TLS.'; } else { str += ' without TLS.'; } } else { str += ' not activated.'; }
2244
- x += '<div style=width:100%;margin-bottom:2px;background-color:lightgray><div style=padding:4px><div style=display:inline-block;margin-right:5px><input class=DevScanCheckbox name=dp1checkbox tag="' + EscapeHtml(i) + '" type=checkbox onclick=addAmtScanToMeshCheckbox() /></div><div class=j1 style=display:inline-block></div><div style=display:inline-block;margin-left:5px;overflow-x:auto;white-space:nowrap>' + str + '</div></div></div>';
2245
- }
2246
- // If no results where found, display a nice message
2247
- if (x == '') { x = '<div style=width:100%;text-align:center;margin-top:12px>Scan returned no results.</div><div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>'; }
2248
- }
2249
- // Set the html in the dialog box and re-enable the scan button
2250
- QH('dp1results', x);
2251
- QE('dp1range', true);
2252
- QE('dp1rangebutton', true);
2253
- break;
2254
- }
2255
- case 'notify': {
2256
- var n = { text: message.event.value, title: message.event.title, icon: message.event.icon };
2257
- if (message.event.tag != null) { n.tag = message.event.tag; }
2258
- addNotification(n);
2259
- break;
2260
- }
2261
- case 'traceinfo': {
2262
- if (typeof message.event.traceSources == 'object') {
2263
- if ((message.event.traceSources != null) && (message.event.traceSources.length > 0)) {
2264
- serverTraceSources = message.event.traceSources;
2265
- QH('p41traceStatus', EscapeHtml(message.event.traceSources.join(', ')));
2266
- } else {
2267
- serverTraceSources = [];
2268
- QH('p41traceStatus', 'None');
2269
- }
2270
- }
2271
- break;
2272
- }
2273
- case 'sysinfohash': {
2274
- // If the sysinfo document has changed and we are looking at it, request an update.
2275
- if ((currentNode != null) && (message.event.nodeid == powerTimelineReq)) {
2276
- meshserver.send({ action: 'getsysinfo', nodeid: message.event.nodeid });
2277
- }
2278
- break;
2279
- }
2280
- case 'stopped': { // Server is stopping.
2281
- // Disconnect
2282
- //console.log(message.msg);
2283
- break;
2284
- }
2285
- default:
2286
- //console.log('Unknown message.event.action', message.event.action);
2287
- break;
2288
- }
2289
- break;
2290
- }
2291
- case 'createInviteLink': { // Agent installation invitation link
2292
- if (xxdialogTag != message.meshid) break;
2293
- var servername = serverinfo.name;
2294
- if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
2295
- var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
2296
- var url;
2297
- if (serverinfo.https == true) {
2298
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
2299
- url = "https://" + servername + portStr + domainUrl + "agentinvite?c=" + message.cookie;
2300
- } else {
2301
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
2302
- url = "http://" + servername + portStr + domainUrl + "agentinvite?c=" + message.cookie;
2303
- }
2304
- Q('agentInvitationLink').href = url;
2305
- var t = message.expire + ' hour' + addLetterS(message.expire);
2306
- if (message.expire == 24) { t = '1 day'; }
2307
- if (message.expire == 168) { t = '1 week'; }
2308
- if (message.expire == 5040) { t = '1 month'; }
2309
- if (message.expire == 0) { t = 'Unlimited'; }
2310
- QH('agentInvitationLink', 'Invitation Link (' + t + ')');
2311
- QV('agentInvitationLinkDiv', true);
2312
- break;
2313
- }
2314
- case 'getmqttlogin': {
2315
- if ((currentNode == null) || (currentNode._id != message.nodeid) || (xxdialogMode != null)) return;
2316
- var x = "These settings can be used to connect MQTT for this device.<br /><br />";
2317
- delete message.action;
2318
- delete message.nodeid;
2319
- x += '<textarea readonly=readonly style=width:100%;resize:none;height:100px;overflow:auto;font-size:12px readonly>' + JSON.stringify(message) + '</textarea>';
2320
- /*
2321
- x += addHtmlValue('Username', '<input style=width:230px readonly value="' + message.user + '" />');
2322
- x += addHtmlValue('Password', '<input style=width:230px readonly value="' + message.pass + '" />');
2323
- x += addHtmlValue('WS URL', '<input style=width:230px readonly value="' + message.wsUrl + '" />');
2324
- if (message.mpsUrl && message.mpsCertHash) {
2325
- x += addHtmlValue('MPS URL', '<input style=width:230px readonly value="' + message.mpsUrl + '" />');
2326
- x += addHtmlValue('MPS Cert Hash', '<input style=width:230px readonly value="' + message.mpsCertHash + '" />');
2327
- }
2328
- */
2329
- setDialogMode(2, "MQTT Credentials", 1, null, x);
2330
- break;
2331
- }
2332
- case 'stopped': { // Server is stopping.
2333
- // Disconnect
2334
- autoReconnect = false;
2335
- QH('p0span', message.msg);
2336
- break;
2337
- }
2338
- case 'plugin': {
2339
- if ((pluginHandler == null) || (typeof message.plugin != 'string')) break;
2340
- try { pluginHandler[message.plugin][message.method](server, message); } catch (e) { console.log('Error loading plugin handler ('+ e + ')'); }
2341
- break;
2342
- }
2343
- default:
2344
- //console.log('Unknown message.action', message.action);
2345
- break;
2346
- }
2347
- }
2348
-
2349
- //
2350
- // MY DEVICES
2351
- //
2352
-
2353
- function onRealNameCheckBox() {
2354
- showRealNames = Q('RealNameCheckBox').checked;
2355
- putstore("showRealNames", showRealNames ? 1 : 0);
2356
- masterUpdate(6);
2357
- return;
2358
- }
2359
-
2360
- function onDeviceViewChange(i) {
2361
- if (i != null) { Q('viewselect').value = i; }
2362
- for (var j = 1; j < 5; j++) { Q('devViewButton' + j).classList.remove('viewSelectorSel'); }
2363
- Q('devViewButton' + Q('viewselect').value).classList.add('viewSelectorSel');
2364
- putstore("_deviceView", Q('viewselect').value);
2365
- putstore("_viewsize", Q('sizeselect').value);
2366
- masterUpdate(4);
2367
- setTimeout(function () { masterUpdate(512); }, 200);
2368
- }
2369
-
2370
- function ondockeypress(e) {
2371
- setSessionActivity();
2372
- if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
2373
- // Check what keys we are allows to send
2374
- if (currentNode != null) {
2375
- var mesh = meshes[currentNode.meshid];
2376
- var meshrights = mesh.links[userinfo._id].rights;
2377
- var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
2378
- if (inputAllowed == false) return false;
2379
- var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
2380
- if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
2381
- }
2382
- return desktop.m.handleKeys(e);
2383
- }
2384
- if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeys(e); }
2385
- if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) return agentConsoleHandleKeys(e);
2386
- if (!xxdialogMode && xxcurrentView == 4) {
2387
- if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
2388
- var processed = 0;
2389
- if (e.key) {
2390
- if (e.key.length === 1 && userSearchFocus == 0) { Q('UserSearchInput').value = ((Q('UserSearchInput').value + e.key)); processed = 1; }
2391
- if (e.keyCode == 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = x.substring(0, x.length - 1); processed = 1; }
2392
- if (e.keyCode == 27) { Q('UserSearchInput').value = ''; processed = 1; }
2393
- } else {
2394
- if (e.charCode != 0 && userSearchFocus == 0) { Q('UserSearchInput').value = ((Q('UserSearchInput').value + String.fromCharCode(e.charCode))); processed = 1; }
2395
- }
2396
- if (processed > 0) { if (processed == 1) { onUserSearchInputChanged(); } return haltEvent(e); }
2397
- }
2398
- if (xxdialogMode || xxcurrentView != 1) return;
2399
- if (e.ctrlKey == true && e.charCode == 96) {
2400
- showRealNames = !showRealNames;
2401
- Q('RealNameCheckBox').value = showRealNames;
2402
- putstore("showRealNames", showRealNames ? 1 : 0);
2403
- masterUpdate(6)
2404
- return;
2405
- }
2406
- if (e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
2407
- if (Q('viewselect').value < 3) {
2408
- var processed = 0;
2409
- if (e.key) {
2410
- if (e.key.length === 1 && searchFocus == 0) { Q('SearchInput').value = ((Q('SearchInput').value + e.key)); processed = 1; }
2411
- if (e.keyCode == 8 && searchFocus == 0) { var x = Q('SearchInput').value; Q('SearchInput').value = x.substring(0, x.length - 1); processed = 1; }
2412
- if (e.keyCode == 27) { Q('SearchInput').value = ''; processed = 1; }
2413
- } else {
2414
- if (e.charCode != 0 && searchFocus == 0) { Q('SearchInput').value = ((Q('SearchInput').value + String.fromCharCode(e.charCode))); processed = 1; }
2415
- }
2416
- if (processed > 0) { if (processed == 1) { masterUpdate(5); } return haltEvent(e); }
2417
- }
2418
- if (Q('viewselect').value == 3) {
2419
- if (e.key) {
2420
- if (e.key.length === 1 && mapSearchFocus == 0) { Q('mapSearchLocation').value = ((Q('mapSearchLocation').value + e.key)); processed = 1; }
2421
- //if (e.keyCode == 8 && mapSearchFocus == 0) { var x = Q('mapSearchLocation').value; Q('mapSearchLocation').value = x.substring(0, x.length - 1); processed = 1; }
2422
- if (e.keyCode == 27) { Q('mapSearchLocation').value = ''; mapCloseSearchWindow(); processed = 1; }
2423
- if (e.keyCode == 13) { getSearchLocation(); }
2424
- } else {
2425
- if (e.charCode != 0 && mapSearchFocus == 0) { Q('mapSearchLocation').value = ((Q('mapSearchLocation').value + String.fromCharCode(e.charCode))); processed = 1; }
2426
- }
2427
- }
2428
- }
2429
-
2430
- function ondockeydown(e) {
2431
- setSessionActivity();
2432
- if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
2433
- // Check what keys we are allows to send
2434
- if (currentNode != null) {
2435
- var mesh = meshes[currentNode.meshid];
2436
- var meshrights = mesh.links[userinfo._id].rights;
2437
- var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
2438
- if (inputAllowed == false) return false;
2439
- var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
2440
- if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
2441
- }
2442
- return desktop.m.handleKeyDown(e);
2443
- }
2444
- if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { terminal.m.TermHandleKeyDown(e); if ((e.keyCode >= 37) && (e.keyCode <= 40)) { haltEvent(e); } }
2445
- if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
2446
- if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) { return agentConsoleHandleKeys(e); }
2447
- if (!xxdialogMode && xxcurrentView == 4) {
2448
- if (e.keyCode === 8 && userSearchFocus == 0) { var x = Q('UserSearchInput').value; Q('UserSearchInput').value = (x.substring(0, x.length - 1)); processed = 1; }
2449
- if (e.keyCode === 27) { Q('UserSearchInput').value = ''; processed = 1; }
2450
- if (processed > 0) { if (processed == 1) { masterUpdate(5); } return haltEvent(e); }
2451
- }
2452
- if (xxdialogMode || xxcurrentView != 1 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
2453
- var processed = 0;
2454
- if (Q('viewselect').value < 3) {
2455
- if (e.keyCode === 8 && searchFocus == 0) { var x = Q('SearchInput').value; Q('SearchInput').value = (x.substring(0, x.length - 1)); processed = 1; }
2456
- if (e.keyCode === 27) { Q('SearchInput').value = ''; processed = 1; }
2457
- if (processed > 0) { if (processed == 1) { masterUpdate(5); } return haltEvent(e); }
2458
- }
2459
- if (Q('viewselect').value == 3) {
2460
- if (e.keyCode === 8 && mapSearchFocus == 0) { var x = Q('mapSearchLocation').value; Q('mapSearchLocation').value = (x.substring(0, x.length - 1)); processed = 1; }
2461
- if (e.keyCode === 27) { Q('mapSearchLocation').value = ''; mapCloseSearchWindow(); processed = 1; }
2462
- }
2463
- }
2464
-
2465
- function ondockeyup(e) {
2466
- setSessionActivity();
2467
- if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
2468
- // Check what keys we are allows to send
2469
- if (currentNode != null) {
2470
- var mesh = meshes[currentNode.meshid];
2471
- var meshrights = mesh.links[userinfo._id].rights;
2472
- var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
2473
- if (inputAllowed == false) return false;
2474
- var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
2475
- if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
2476
- }
2477
- return desktop.m.handleKeyUp(e);
2478
- }
2479
- if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyUp(e); }
2480
- if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { p13folderup(9999); haltEvent(e); return false; } // F5 Refresh on files
2481
- if (!xxdialogMode && xxcurrentView == 4) { if ((e.keyCode === 8 && searchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
2482
- if (xxdialogMode && e.keyCode == 27) { dialogclose(0); }
2483
- if (xxdialogMode || xxcurrentView != 0 || e.ctrlKey == true || e.altKey == true || e.metaKey == true) return;
2484
- if (Q('viewselect').value < 3) { if ((e.keyCode === 8 && searchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
2485
- if (Q('viewselect').value == 3) { if ((e.keyCode === 8 && mapSearchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
2486
- }
2487
-
2488
- //function ondocfocus() { }
2489
- // TODO: Add handleReleaseKeys() for Intel AMT.
2490
- function ondocblur() { if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked && desktop.m.handleReleaseKeys) { return desktop.m.handleReleaseKeys(); } }
2491
-
2492
- // Highlights the device being hovered
2493
- function devMouseHover(element, over) {
2494
- setSessionActivity();
2495
- var view = Q('viewselect').value;
2496
- if (view == 1) {
2497
- var e = element.children[1].children[1];
2498
- e.children[0].classList.remove('g1s');
2499
- e.children[1].classList.remove('e2s');
2500
- e.children[2].classList.remove('g2s');
2501
- if (over == 1) {
2502
- e.children[0].classList.add('g1s');
2503
- e.children[1].classList.add('e2s');
2504
- e.children[2].classList.add('g2s');
2505
- }
2506
- } else if (view == 2) {
2507
- var e = element;
2508
- e.children[2].classList.remove('g1s');
2509
- e.children[4].classList.remove('e2s');
2510
- e.children[3].classList.remove('g2s');
2511
- if (over == 1) {
2512
- e.children[2].classList.add('g1s');
2513
- e.children[4].classList.add('e2s');
2514
- e.children[3].classList.add('g2s');
2515
- }
2516
- }
2517
- }
2518
-
2519
- var deviceHeaderId = 0;
2520
- var deviceHeaderTotal = 0;
2521
- var deviceHeadersTitles = {};
2522
- var deviceHeaderCount;
2523
- var deviceHeaders = {};
2524
- var oldviewmode = 0;
2525
- function updateDevices() {
2526
- if (nodes == null) { return; }
2527
- var r = '', c = 0, current = null, count = 0, displayedMeshes = {}, view = Q('viewselect').value, groups = {}, groupCount = {};
2528
- QV('xdevices', view < 4);
2529
- QV('xdevicesmap', view == 4);
2530
- QV('devListToolbar', view < 3);
2531
- QV('kvmListToolbar', view == 3);
2532
- QV('devMapToolbar', view == 4);
2533
- QV('devListToolbarSize', view == 3);
2534
- QV('NoMeshesPanel', meshcount == 0);
2535
- //QV('devListToolbarView', (meshcount != 0) && (nodes.length > 0));
2536
- QV('devListToolbarViewIcons', (meshcount != 0) && (nodes.length > 0));
2537
- QV('devListToolbarSort', (meshcount != 0) && (nodes.length > 0) && (view < 4));
2538
- if ((meshcount == 0) || (nodes.length == 0)) { view = 1; sort = 0; }
2539
- if (view == 4) {
2540
- setTimeout( function() { if (xxmap.map != null) { xxmap.map.updateSize(); } }, 200);
2541
- // TODO
2542
- } else {
2543
- // 3 wide, list view or desktop view
2544
- deviceHeaderId = 0;
2545
- deviceHeaderCount = {};
2546
- deviceHeaderTotal = 0;
2547
- deviceHeaders = {};
2548
- deviceHeadersTitles = {};
2549
- var kvmDivs = [];
2550
-
2551
- // Perform node sort
2552
- if (sort == 0) { nodes.sort(meshSort); }
2553
- else if (sort == 1) { nodes.sort(powerSort); }
2554
- else if (sort == 2) { if (showRealNames == true) { nodes.sort(deviceHostSort); } else { nodes.sort(deviceSort); } }
2555
-
2556
- // Save the list of currently checked nodeid's
2557
- var checkedNodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
2558
- for (var i=0;i<elements.length;i++) { if (elements[i].checked) { checkedNodeids.push(elements[i].value); } }
2559
- if ((oldviewmode < 3) && (view == 3)) { multiDesktopFilter = checkedNodeids; }
2560
- else if ((oldviewmode == 3) && (view < 3)) { checkedNodeids = multiDesktopFilter; }
2561
-
2562
- // Compute the width of the device view.
2563
- var totalDeviceViewWidth = Q('column_l').clientWidth - 60;
2564
- var deviceBoxWidth = Math.floor(totalDeviceViewWidth / 301);
2565
- deviceBoxWidth = 301 + Math.floor((totalDeviceViewWidth - (deviceBoxWidth * 301)) / deviceBoxWidth);
2566
-
2567
- if ((view == 2) && (sort != 3)) {
2568
- r += '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity'; //<th style=color:gray;width:100px>State';
2569
- }
2570
-
2571
- // Go thru the list of nodes and display them
2572
- for (var i in nodes) {
2573
- var node = nodes[i];
2574
- if (node.v == false) continue;
2575
- var mesh2 = meshes[node.meshid], meshlinks = mesh2.links[userinfo._id];
2576
- if (meshlinks == null) continue;
2577
- var meshrights = meshlinks.rights;
2578
- if ((view == 3) && (mesh2.mtype == 1)) continue;
2579
- if (sort == 0) {
2580
- // Mesh header
2581
- if (node.meshid != current) {
2582
- deviceHeaderSet();
2583
- var extra = '';
2584
- if (view == 2) { r += '<tr><td colspan=5>'; }
2585
- if (meshes[node.meshid].mtype == 1) { extra = '<span class=devHeaderx>, Intel® AMT only</span>'; }
2586
- if ((view == 1) && (current != null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
2587
- if (view == 2) { r += '<div>'; }
2588
- r += '<div class=DevSt style=width:100%;padding-top:4px><span style=float:right>';
2589
- r += '<span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx></span>' + extra;
2590
- r += '</span><span id=MxMESH tabindex=0 style=cursor:pointer onclick=gotoMesh("' + node.meshid + '") onkeypress="if (event.key==\'Enter\') gotoMesh(\'' + node.meshid + '\')">' + EscapeHtml(meshes[node.meshid].name) + '</span>' + getMeshActions(mesh2, meshrights) + '</div>';
2591
- if (view == 2) { r += '</div>'; }
2592
- current = node.meshid;
2593
- displayedMeshes[current] = 1;
2594
- c = 0;
2595
- }
2596
- } else if (sort == 1) {
2597
- // Power header
2598
- var pwr = node.pwr?node.pwr:0;
2599
- if (pwr !== current) {
2600
- deviceHeaderSet();
2601
- if ((view == 1) && (current !== null)) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
2602
-
2603
- if (view == 2) { r += '<tr><td>'; }
2604
- r += '<div class=DevSt style=width:100%;padding-top:4px><span id=DevxHeader' + deviceHeaderId + ' class=devHeaderx style=float:right></span><span>' + PowerStateStr2(node.pwr) + '</span></div>';
2605
-
2606
- current = pwr;
2607
- c = 0;
2608
- }
2609
- } else if (sort == 2) {
2610
- // Device header
2611
- if (current == null) { current = '1'; }
2612
- }
2613
-
2614
- count++;
2615
- var title = EscapeHtml(node.name);
2616
- if (title.length == 0) { title = '<i>None</i>'; }
2617
- if ((node.rname != null) && (node.rname.length > 0)) { title += " / " + EscapeHtml(node.rname); }
2618
- var name = EscapeHtml(node.name);
2619
- if (showRealNames == true && node.rname != null) name = EscapeHtml(node.rname);
2620
- if (name.length == 0) { name = '<i>None</i>'; }
2621
-
2622
- // Node
2623
- var icon = node.icon;
2624
- if ((!node.conn) || (node.conn == 0)) { icon += ' gray'; }
2625
- if (view == 1) {
2626
- r += '<div id=devs onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=display:inline-block;width:' + deviceBoxWidth + 'px;height:50px;padding-top:1px;padding-bottom:1px><div style=width:22px;height:50%;float:left;padding-top:12px><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div><div style=height:100%;cursor:pointer tabindex=0 onclick=gotoDevice(\'' + node._id + '\',null,null,event) onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)"><div class="i' + icon + '" style=width:50px;float:left></div><div style=height:100%><div class=g1></div><div class=e2><div class=e1 style=width:' + (deviceBoxWidth - 100) + 'px title="' + title + '">' + name + '</div><div>' + NodeStateStr(node) + '</div></div><div class=g2></div></div></div></div>';
2627
- } else if (view == 2) {
2628
- var states = [];
2629
- if (node.conn) {
2630
- if ((node.conn & 1) != 0) { states.push('<span title="Mesh agent is connected and ready for use.">Agent</span>'); }
2631
- if ((node.conn & 2) != 0) { states.push('<span title="Intel® AMT CIRA is connected and ready for use.">CIRA</span>'); }
2632
- else if ((node.conn & 4) != 0) { states.push('<span title="Intel® AMT is routable.">AMT</span>'); }
2633
- if ((node.conn & 8) != 0) { states.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>'); }
2634
- if ((node.conn & 16) != 0) { states.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
2635
- }
2636
- r += '<tr><td><div id=devs class=bar18 tabindex=0 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)">';
2637
- r += '<div class=deviceBarCheckbox><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div>';
2638
- r += '<div class=deviceBarIcon onclick=gotoDevice(\'' + node._id + '\',null,null,event)><div class=\"j' + icon + '\" style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
2639
- r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
2640
- r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + node._id + '\',null,null,event)><span style=width:300px>' + name + '</span></div></div></td>';
2641
- r += '<td style=text-align:center>' + getUserShortStr(node);
2642
- r += '<td style=text-align:center>' + (node.ip != null ? node.ip : '');
2643
- r += '<td style=text-align:center>' + states.join(' + ');
2644
- //r += '<td style=text-align:center>' + (node.pwr != null ? powerStateStrings[node.pwr] : '');
2645
- r += '</tr>';
2646
- } else if ((view == 3) && (node.conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((node.agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM.
2647
- if ((multiDesktopFilter) && ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + node._id) >= 0))) {
2648
- r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div tabindex=0 style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + node._id + '\',11,null,event) onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',11,null,event)">';
2649
- //r += '<input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox style=float:left>';
2650
- r += '<div class="j' + icon + '" style=width:16px;float:left></div> ' + name + '</div>';
2651
- r += '<span onclick=gotoDevice(\'' + node._id + '\',null,null,event)></span><div id=xkvmid_' + node._id.split('/')[2] + '><div id=skvmid_' + node._id.split('/')[2] + ' tabindex=0 style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + node._id + '\') onkeypress="if (event.key==\'Enter\') toggleKvmDevice(\'' + node._id + '\')">Disconnected</div></div>';
2652
- r += '</div>';
2653
- kvmDivs.push(node._id);
2654
- }
2655
- }
2656
-
2657
- // If we are displaying devices by group, put the device in the right group.
2658
- if ((sort == 3) && (r != '')) {
2659
- if (node.tags) {
2660
- for (var j in node.tags) {
2661
- var tag = node.tags[j];
2662
- if (groups[tag] == null) { groups[tag] = r; groupCount[tag] = 1; } else { groups[tag] += r; groupCount[tag] += 1; }
2663
- if (view == 3) break;
2664
- }
2665
- }
2666
- r = '';
2667
- }
2668
-
2669
- deviceHeaderTotal++;
2670
- if (typeof deviceHeaderCount[node.state] == 'undefined') { deviceHeaderCount[node.state] = 1; } else { deviceHeaderCount[node.state]++; }
2671
- }
2672
-
2673
- // Display "connect all" and "auto"
2674
- QV('kvmMultiConnectButtonSpan', (kvmDivs.length < 16));
2675
- QV('kvmAutoConnectButtonSpan', (kvmDivs.length < 16));
2676
- if (kvmDivs.length >= 16) { Q('autoConnectDesktopCheckbox').checked = false; }
2677
-
2678
- // If displaying devices by groups, sort the group names and display the devices.
2679
- if (sort == 3) {
2680
- if (view == 2) { r = '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity'; }
2681
-
2682
- var groupNames = [];
2683
- for (var i in groups) { groupNames.push(i); }
2684
- groupNames.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); });
2685
- for (var j in groupNames) {
2686
- var i = groupNames[j];
2687
- if (view == 2) {
2688
- r += '<tr><td colspan=4><div class=DevSt style=width:100%;padding-top:4px><span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span><span>' + i + '</span></div>' + groups[i];
2689
- } else {
2690
- r += '<div class=DevSt style=width:100%;padding-top:4px><span class=devHeaderx style=float:right>' + groupCount[i] + ' node' + ((groupCount[i] > 1) ? 's' : '') + '</span><span>' + i + '</span></div>' + groups[i];
2691
- }
2692
- }
2693
- }
2694
-
2695
- // If there is nothing to display, explain the problem
2696
- if ((r == '') && (meshcount > 0) && (Q('SearchInput').value != '')) {
2697
- if (sort == 3) {
2698
- r = '<div style="margin:30px">No devices are included in any groups, click on a device\'s \"Groups\" to add to a group.</div>';
2699
- } else {
2700
- r = '<div style="margin:30px">No devices matching this search.</div>';
2701
- }
2702
- }
2703
-
2704
- if ((view == 1) && (c == 2)) r += '<td><div style=width:301px></div></td>'; // Adds device padding
2705
-
2706
- // Display all empty device groups, we need to do this because users can add devices to these at any time.
2707
- if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) {
2708
- for (var i in meshes) {
2709
- var mesh = meshes[i], meshlink = mesh.links[userinfo._id];
2710
- if (meshlink != null) {
2711
- var meshrights = meshlink.rights;
2712
- if (displayedMeshes[mesh._id] == null) {
2713
- if ((current != '') && (r != '')) { r += '</tr></table>'; }
2714
- r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt><span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>';
2715
- r += getMeshActions(mesh, meshrights);
2716
- r += '</span></td></tr><tr>';
2717
- if (mesh.mtype == 1) {
2718
- r += '<td><div style=padding:10px><i>No Intel® AMT devices in this mesh';
2719
- if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>add one</a>'; }
2720
- }
2721
- if (mesh.mtype == 2) {
2722
- r += '<td><div style=padding:10px><i>No devices in this mesh';
2723
- if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>add one</a>'; }
2724
- }
2725
- r += '.</i></div></td>';
2726
- current = mesh._id;
2727
- count++;
2728
- }
2729
- }
2730
- }
2731
- }
2732
- r += '</tr></table><div style=height:1px></div>'; // This height of 1 div fixes a problem in Linux firefox browsers
2733
-
2734
- // Add a "Add Device Group" option
2735
- r += '<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px>';
2736
- if ((view < 3) && (sort == 0) && (meshcount > 0) && ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0))) {
2737
- r += '<a href=# onclick="return account_createMesh()" title="Create a new group of devices." style=cursor:pointer>Add Device Group</a> ';
2738
- }
2739
- if ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 128) == 0)) {
2740
- r += '<a href=# onclick=\'return p10showMeshCmdDialog(0)\' style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a> ';
2741
- if (navigator.platform.toLowerCase() == 'win32') { r += '<a href=# onclick=\'return p10showMeshRouterDialog()\' style=cursor:pointer title="Download MeshCentral Router, a TCP port mapping tool.">Router</a> '; }
2742
- }
2743
- r += '</div><br/>';
2744
-
2745
- QH('xdevices', r);
2746
- deviceHeaderSet();
2747
-
2748
- // Re-check nodeid's
2749
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
2750
- if (checkedNodeids) { for (var i=0;i<elements.length;i++) { elements[i].checked = (checkedNodeids.indexOf(elements[i].value) >= 0); } }
2751
-
2752
- for (var i in deviceHeaders) { QH(i, deviceHeaders[i]); }
2753
- for (var i in deviceHeadersTitles) { Q(i).title = deviceHeadersTitles[i]; }
2754
- p1updateInfo();
2755
-
2756
- // Take care of KVM surfaces in desktop view mode
2757
- if (view == 3) {
2758
- // Figure out and adjust the size to fill the width of the div
2759
- var vsize = [{ x: 180, y: 101 }, { x: 302, y: 169 }, { x: 454, y: 255 }][Q('sizeselect').selectedIndex];
2760
- //var realw = vsize.x + 2, tw = Q('xdevices').clientWidth - 30, xw = Math.floor(tw / realw);
2761
- var realw = vsize.x + 2, tw = totalDeviceViewWidth - 5, xw = Math.floor(tw / realw);
2762
- xw = realw + Math.floor((tw - (xw * realw)) / xw);
2763
- vsize.y = vsize.y * (xw / vsize.x);
2764
- vsize.x = xw;
2765
-
2766
- for (var i in multiDesktop) { multiDesktop[i].xxdelete = true; }
2767
- for (var i in kvmDivs) {
2768
- var id = kvmDivs[i], shortid = id.split('/')[2], desk = multiDesktop[id];
2769
- if (desk != null) {
2770
- // This device already has a canvas, use it.
2771
- desk.m.CanvasId.setAttribute('style', 'background-color:black;width:' + vsize.x + 'px;height:' + vsize.y + 'px');
2772
- Q('xkvmid_' + shortid).appendChild(desk.m.CanvasId);
2773
- delete desk.xxdelete;
2774
- QH('skvmid_' + shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][((desk.m.State == null)?desk.m.state:desk.m.State)]);
2775
- } else {
2776
- var node = getNodeFromId(id);
2777
- if ((desktopNode == node) && (desktop != null)) { // Check if the main desktop is this device, if it is, use that.
2778
- // This device already has a canvas, use it.
2779
- var c = desktop.m.CanvasId;
2780
- c.setAttribute('id', 'kvmid_' + shortid);
2781
- c.setAttribute('style', 'background-color:black;width:' + vsize.x + 'px;height:' + vsize.y + 'px');
2782
- c.setAttribute('onclick', 'toggleKvmDevice(\'' + id + '\')');
2783
- c.removeAttribute('onmousedown');
2784
- c.removeAttribute('onmouseup');
2785
- c.removeAttribute('onmousemove');
2786
- Q('xkvmid_' + shortid).appendChild(c);
2787
- QH('skvmid_' + shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][((desktop.m.State == null)?desktop.m.state:desktop.m.State)]);
2788
- if (desktop.m.SendCompressionLevel) { desktop.m.SendCompressionLevel(1, multidesktopsettings.quality, multidesktopsettings.scaling, multidesktopsettings.framerate); }
2789
- desktop.shortid = shortid;
2790
- desktop.onStateChanged = onMultiDesktopStateChange;
2791
- multiDesktop[id] = desktop;
2792
- desktop = desktopNode = currentNode = null;
2793
- // Setup a replacement desktop
2794
- QH('DeskParent', '<canvas id="Desk" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
2795
- } else {
2796
- // This is a new device, create a canvas for it.
2797
- var c = document.createElement('canvas');
2798
- c.setAttribute('id', 'kvmid_' + shortid);
2799
- c.setAttribute('width', 640);
2800
- c.setAttribute('height', 480);
2801
- c.setAttribute('oncontextmenu', 'return false');
2802
- c.setAttribute('style', 'background-color:black;width:' + vsize.x + 'px;height:' + vsize.y + 'px');
2803
- c.setAttribute('onclick', 'toggleKvmDevice(\'' + id + '\')');
2804
- try { Q('xkvmid_' + shortid).appendChild(c); } catch (ex) {}
2805
- // Check if we need to auto-connect
2806
- if (Q('autoConnectDesktopCheckbox').checked == true) { setTimeout(function() { connectMultiDesktop(node, 1); }, 100); }
2807
- }
2808
- }
2809
- }
2810
- for (var i in multiDesktop) {
2811
- // If a device is no longer viewed, disconnect it.
2812
- if (multiDesktop[i].xxdelete == true) { multiDesktop[i].Stop(); delete multiDesktop[i]; }
2813
- else if (debugmode && multiDesktop[i].m && multiDesktop[i].m.onScreenSizeChange) {
2814
- mdeskAdjust(multiDesktop[i].m, multiDesktop[i].m.ScreenWidth, multiDesktop[i].m.ScreenHeight, multiDesktop[i].m.CanvasId); // Adjust screen size change
2815
- }
2816
- }
2817
- deskAdjust();
2818
- } else {
2819
- disconnectAllKvmFunction();
2820
- Q('autoConnectDesktopCheckbox').checked = false;
2821
- }
2822
- }
2823
- oldviewmode = view;
2824
- }
2825
-
2826
- function toggleKvmDevice(nodeid) {
2827
- var node = getNodeFromId(nodeid), mesh = meshes[node.meshid], meshrights = mesh.links[userinfo._id].rights;
2828
- if ((meshrights & 8) || (meshrights & 256)) { // Requires remote control rights or desktop view only rights
2829
- //var conn = 0;
2830
- //if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT)
2831
- if (node.conn & 1) { connectMultiDesktop(node, 1); }
2832
- }
2833
- }
2834
-
2835
- function getUserShortStr(node) {
2836
- if (node == null || node.users == null || node.users.length == 0) return '';
2837
- if (node.users.length > 1) { return '<span title="' + EscapeHtml(node.users.join(', ')) + '">' + node.users.length + ' users</span>'; }
2838
- var u = node.users[0], su = u, i = u.indexOf('\\');
2839
- if (i > 0) { su = u.substring(i + 1); }
2840
- su = EscapeHtml(su);
2841
- if (su.length > 15) { su = su.substring(0, 14) + '…'; }
2842
- return '<span title="' + EscapeHtml(u) + '">' + su + '</span>';
2843
- }
2844
-
2845
- function autoConnectDesktops() { if (Q('autoConnectDesktopCheckbox').checked == true) { connectAllKvmFunction(); } }
2846
- function connectAllKvmFunction() { for (var i in nodes) { if (multiDesktop[nodes[i]._id] == null) { toggleKvmDevice(nodes[i]._id); } } }
2847
- function disconnectAllKvmFunction() { for (var nodeid in multiDesktop) { multiDesktop[nodeid].Stop(); } multiDesktop = {}; }
2848
- function onMultiDesktopStateChange(desk, state) { try { QH('skvmid_' + desk.shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][state]); } catch (ex) {} }
2849
-
2850
- function showMultiDesktopSettings() {
2851
- QV('d7amtkvm', false);
2852
- QV('d7meshkvm', true);
2853
- d7bitmapquality.value = multidesktopsettings.quality;
2854
- d7bitmapscaling.value = multidesktopsettings.scaling;
2855
- if (multidesktopsettings.framerate) { d7framelimiter.value = multidesktopsettings.framerate; } else { d7framelimiter.value = 1000; }
2856
- setDialogMode(7, "Remote Desktop Settings", 3, showMultiDesktopSettingsChanged);
2857
- }
2858
-
2859
- function showMultiDesktopSettingsChanged() {
2860
- multidesktopsettings.quality = d7bitmapquality.value;
2861
- multidesktopsettings.scaling = d7bitmapscaling.value;
2862
- multidesktopsettings.framerate = d7framelimiter.value;
2863
- localStorage.setItem('multidesktopsettings', JSON.stringify(multidesktopsettings));
2864
- // Make changes to all current connections
2865
- for (var i in multiDesktop) { multiDesktop[i].m.SendCompressionLevel(1, multidesktopsettings.quality, multidesktopsettings.scaling, multidesktopsettings.framerate); }
2866
- }
2867
-
2868
- function connectMultiDesktop(node, contype) {
2869
- var nodeid = node._id, shortid = nodeid.split('/')[2];
2870
- var desk = multiDesktop[nodeid];
2871
- if (desk == null) {
2872
- if (Q('kvmid_' + shortid) == null) return; // Check if this device is being displayed, if not, exit now.
2873
- if (contype == 2) {
2874
- // Setup the Intel AMT remote desktop
2875
- if ((node.intelamt.user == null) || (node.intelamt.user == '')) { return; }
2876
- desk = CreateAmtRedirect(CreateAmtRemoteDesktop('kvmid_' + shortid), authCookie);
2877
- desk.shortid = shortid;
2878
- //desk.debugmode = debugmode;
2879
- desk.onStateChanged = onMultiDesktopStateChange;
2880
- desk.m.bpp = 1;
2881
- desk.m.useZRLE = true;
2882
- desk.m.showmouse = true;
2883
- desk.m.onKvmData = function (data) { console.log('KVM Data received in multi-desktop mode, this is not supported.'); }; // KVM Data Channel not supported in multi-desktop right now.
2884
- //desk.m.onScreenSizeChange = deskAdjust;
2885
- if (debugmode > 0) { desk.m.onScreenSizeChange = mdeskAdjust; } // Multi-Desktop Adjust
2886
- desk.Start(nodeid, 16994, '*', '*', 0);
2887
- desk.contype = 2;
2888
- multiDesktop[nodeid] = desk;
2889
- } else if (contype == 1) {
2890
- // Setup the Mesh Agent remote desktop
2891
- desk = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('kvmid_' + shortid), serverPublicNamePort, authCookie, authRelayCookie, domainUrl);
2892
- desk.shortid = shortid;
2893
- desk.attemptWebRTC = attemptWebRTC;
2894
- desk.onStateChanged = onMultiDesktopStateChange;
2895
- //desk.onConsoleMessageChange = function () { console.log('CONSOLEMSG:', desk.consoleMessage); }
2896
- desk.m.CompressionLevel = multidesktopsettings.quality;
2897
- desk.m.ScalingLevel = multidesktopsettings.scaling;
2898
- desk.m.FrameRateTimer = multidesktopsettings.framerate;
2899
- //desk.m.onDisplayinfo = deskDisplayInfo;
2900
- //desk.m.onScreenSizeChange = deskAdjust;
2901
- if (debugmode > 0) { desk.m.onScreenSizeChange = mdeskAdjust; } // Multi-Desktop Adjust
2902
- desk.Start(nodeid);
2903
- desk.contype = 1;
2904
- multiDesktop[nodeid] = desk;
2905
- }
2906
- } else {
2907
- // Disconnect and clean up the remote desktop
2908
- desk.Stop();
2909
- delete multiDesktop[nodeid];
2910
- }
2911
- }
2912
-
2913
- function getMeshActions(mesh, meshrights) {
2914
- if ((meshrights & 4) == 0) return '';
2915
- var r = '';
2916
- if ((features & 1024) == 0) { // If CIRA is allowed
2917
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the internet." onclick=\'return addCiraDeviceToMesh(\"' + mesh._id + '\")\'>Add CIRA</a>';
2918
- }
2919
- if (mesh.mtype == 1) {
2920
- if ((features & 1) == 0) { // If not WAN-Only
2921
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the local network." onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>Add Local</a>';
2922
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer by scanning the local network." onclick=\'return addAmtScanToMesh(\"' + mesh._id + '\")\'>Scan Network</a>';
2923
- }
2924
- if (mesh.amt && (mesh.amt.type == 2)) { // CCM activation
2925
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Perform Intel AMT client control mode (CCM) activation." onclick=\'return showCcmActivation(\"' + mesh._id + '\")\'>Activation</a>';
2926
- } else if (mesh.amt && (mesh.amt.type == 3) && ((features & 0x00100000) != 0)) { // ACM activation
2927
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Perform Intel AMT admin control mode (ACM) activation." onclick=\'return showAcmActivation(\"' + mesh._id + '\")\'>Activation</a>';
2928
- }
2929
- }
2930
- if (mesh.mtype == 2) {
2931
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>Add Agent</a>';
2932
- if ((features & 2) == 0) { r += ' <a href=# style=cursor:pointer;font-size:10px title="Invite someone to install the mesh agent on this mesh." onclick=\'return inviteAgentToMesh(\"' + mesh._id + '\")\'>Invite</a>'; }
2933
- }
2934
- return r;
2935
- }
2936
-
2937
- function addDeviceToMesh(meshid) {
2938
- if (xxdialogMode) return false;
2939
- var mesh = meshes[meshid];
2940
- var x = "Add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\".<br /><br />";
2941
- x += addHtmlValue('Device Name', '<input id=dp1devicename style=width:230px maxlength=32 autocomplete=off onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2942
- x += addHtmlValue('Hostname', '<input id=dp1hostname style=width:230px maxlength=32 autocomplete=off placeholder="Same as device name" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2943
- x += addHtmlValue('Username', '<input id=dp1username style=width:230px maxlength=32 autocomplete=off placeholder="admin" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2944
- x += addHtmlValue('Password', '<input id=dp1password type=password style=width:230px autocomplete=off maxlength=32 onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2945
- x += addHtmlValue('Security', '<select id=dp1tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>');
2946
- setDialogMode(2, "Add Intel® AMT device", 3, addDeviceToMeshEx, x, meshid);
2947
- validateDeviceToMesh();
2948
- Q('dp1devicename').focus();
2949
- return false;
2950
- }
2951
-
2952
- // Intel AMT CCM Activation
2953
- function showCcmActivation(meshid) {
2954
- if (xxdialogMode) return false;
2955
- var servername = serverinfo.name, mesh = meshes[meshid];
2956
- if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
2957
- var url, domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
2958
- if (serverinfo.https == true) {
2959
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
2960
- url = "wss://" + servername + portStr + domainUrl;
2961
- } else {
2962
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
2963
- url = "ws://" + servername + portStr + domainUrl;
2964
- }
2965
- var x = "Perform Intel AMT client control mode (CCM) activation to group \"" + EscapeHtml(mesh.name) + "\" by downloading the MeshCMD tool and running it like this:<br /><br />";
2966
- x += '<textarea readonly=readonly style=width:100%;resize:none;height:100px;overflow:auto;font-size:12px readonly>meshcmd amtccm --url ' + url + 'amtactivate?id=' + meshid.split('/')[2] + ' --serverhttpshash ' + serverinfo.tlshash + '</textarea>';
2967
- setDialogMode(2, "Intel® AMT activation", 9, null, x);
2968
- Q('idx_dlgOkButton').focus();
2969
- return false;
2970
- }
2971
-
2972
- // Intel AMT ACM Activation
2973
- function showAcmActivation(meshid) {
2974
- if (xxdialogMode) return false;
2975
- var servername = serverinfo.name, mesh = meshes[meshid];
2976
- if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
2977
- var url, domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
2978
- if (serverinfo.https == true) {
2979
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
2980
- url = "wss://" + servername + portStr + domainUrl;
2981
- } else {
2982
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
2983
- url = "ws://" + servername + portStr + domainUrl;
2984
- }
2985
- var x = "Perform Intel AMT admin control mode (ACM) activation to group \"" + EscapeHtml(mesh.name) + "\" by downloading the MeshCMD tool and running it like this:<br /><br />";
2986
- x += '<textarea readonly=readonly style=width:100%;resize:none;height:100px;overflow:auto;font-size:12px readonly>meshcmd amtacm --url ' + url + 'amtactivate?id=' + meshid.split('/')[2] + ' --serverhttpshash ' + serverinfo.tlshash + '</textarea>';
2987
- if (serverinfo.amtAcmFqdn != null) {
2988
- x += '<div style=margin-top:8px>Intel AMT will need to be set with a Trusted FQDN in MEBx or have a wired LAN on the network: <b>' + serverinfo.amtAcmFqdn.join(', ') + '</b></div>';
2989
- }
2990
- setDialogMode(2, "Intel® AMT activation", 9, null, x);
2991
- Q('idx_dlgOkButton').focus();
2992
- return false;
2993
- }
2994
-
2995
- // Display the Intel AMT scanning dialog box
2996
- function addAmtScanToMesh(meshid) {
2997
- if (xxdialogMode) return false;
2998
- var x = "Enter a range of IP addresses to scan for Intel AMT devices.<br /><br />";
2999
- x += addHtmlValue('IP Range', '<input id=dp1range style=width:184px value="192.168.1.0/24" onkeyup=addAmtScanToMeshKeyUp(event) /><input id=dp1rangebutton type=button value=Scan onclick=addAmtScanToMeshButton()></input>');
3000
- x += '<div id=dp1results style="width:100%;height:200px;background-color:white;border:1px gray solid;overflow-y:scroll"></div>';
3001
- setDialogMode(2, "Scan for Intel® AMT devices", 3, addAmtScanToMeshEx, x, meshid);
3002
- QE('idx_dlgOkButton', false);
3003
- QH('dp1results', '<div style=width:100%;text-align:center;margin-top:12px;color:gray;line-height:1.5>Sample IP range values<br />192.168.0.100<br />192.168.1.0/24<br />192.167.0.1-192.168.0.100</div>');
3004
- focusTextBox('dp1range');
3005
- return false;
3006
- }
3007
-
3008
- function addAmtScanToMeshKeyUp(e) {
3009
- if (e.keyCode == 13) { haltEvent(e); addAmtScanToMeshButton(); }
3010
- }
3011
-
3012
- // Called when OK is pressed on the Intel AMT scanning box
3013
- function addAmtScanToMeshEx(button, meshid) {
3014
- var elements = document.getElementsByClassName("DevScanCheckbox"), checkcount = 0;
3015
- for (var i=0;i<elements.length;i++) {
3016
- if (elements[i].checked) {
3017
- var ipaddr = elements[i].getAttribute('tag');
3018
- var amtinfo = amtScanResults[ipaddr];
3019
- meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: ipaddr, hostname: amtinfo.hostname, amtusername: '', amtpassword: '', amttls: amtinfo.tls });
3020
- }
3021
- }
3022
- }
3023
-
3024
- // If the user presses the "Scan" button on the Intel AMT scanning dialog box, start a scan.
3025
- function addAmtScanToMeshButton() {
3026
- QE('dp1range', false);
3027
- QE('dp1rangebutton', false);
3028
- QH('dp1results', '<div style=width:100%;text-align:center;margin-top:12px>Scanning...</div>');
3029
- meshserver.send({ action: 'scanamtdevice', range: Q('dp1range').value });
3030
- }
3031
-
3032
- // Called when a scanned computer is checked or unchecked.
3033
- function addAmtScanToMeshCheckbox() {
3034
- var elements = document.getElementsByClassName("DevScanCheckbox"), checkcount = 0;
3035
- for (var i=0;i<elements.length;i++) { if (elements[i].checked) checkcount++; }
3036
- QE('idx_dlgOkButton', checkcount > 0);
3037
- }
3038
-
3039
- function addCiraDeviceToMesh(meshid) {
3040
- if (xxdialogMode) return false;
3041
- var mesh = meshes[meshid];
3042
-
3043
- // Replace non alphabetic characters (@ and $) with 'X' because MPS username cannot accept it.
3044
- var meshidx = meshid.split('/')[2].replace(/\@/g, 'X').replace(/\$/g, 'X');
3045
-
3046
- var y = '<select id=dlgAddCiraSel onclick=dlgAddCiraSelClick() style=width:230px><option value=0>MeshCommander Script</option><option value=1>Manual Username/Password</option>';
3047
- if ((features & 16) == 0) { y += '<option value=2>Manual Certificate</option></select>'; } // Only display this option if Intel AMT CIRA with Mutual-Auth is allowed.
3048
-
3049
- var x = '';
3050
- x += addHtmlValue('Setup Method', y);
3051
- x += '<hr>';
3052
-
3053
- // Setup CIRA using a MeshCommander script (Pretty Simple)
3054
- x += "<div id=dlgAddCira0>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.<br /><br />";
3055
- //x += addHtmlValue('Setup CIRA', '<a href="mescript.ashx?type=1&meshid=' + meshidx.substring(0, 16) + '" download>cira_setup.mescript</a>');
3056
- x += addHtmlValue('Setup CIRA', '<a href="mescript.ashx?type=1&meshid=' + meshid + '" download>cira_setup.mescript</a>');
3057
- x += addHtmlValue('Cleanup CIRA', '<a href="mescript.ashx?type=2" download>cira_clean.mescript</a>');
3058
- x += "</div>";
3059
-
3060
- // Setup CIRA with user/pass authentication (Somewhat difficult)
3061
- x += "<div id=dlgAddCira1 style=display:none>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, load the following certificate as trusted root within Intel AMT";
3062
- if (serverinfo.mpspass) { x += " and authenticate to the server using this username and password.<br /><br />"; } else { x += " and authenticate to the server using this username and any password.<br /><br />"; }
3063
- x += addHtmlValue('Root Certificate', '<a href="MeshServerRootCert.cer" download>Root Certificate File</a>');
3064
- x += addHtmlValue('Username', '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
3065
- if (serverinfo.mpspass) { x += addHtmlValue('Password', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
3066
- if (serverinfo != null) { x += addHtmlValue('MPS Server', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3067
- x += "</div>";
3068
-
3069
- // Setup CIRA with certificate authentication (Really difficult, only if TLS offload is not used)
3070
- if ((features & 16) == 0) {
3071
- x += "<div id=dlgAddCira2 style=display:none>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, load the following certificate as trusted root within Intel AMT, authenticate using a client certificate with the following common name and connect to the following server.<br /><br />";
3072
- x += addHtmlValue('Root Certificate', '<a href="MeshServerRootCert.cer" download>Root Certificate File</a>');
3073
- x += addHtmlValue('Organization', '<input style=width:230px readonly value="' + meshidx + '" />');
3074
- if (serverinfo != null) { x += addHtmlValue('MPS Server', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3075
- x += "</div>";
3076
- }
3077
-
3078
- setDialogMode(2, "Add Intel® AMT CIRA device", 2, null, x, 'fileDownload');
3079
- Q('dlgAddCiraSel').focus();
3080
- return false;
3081
- }
3082
-
3083
- function dlgAddCiraSelClick() {
3084
- var val = Q('dlgAddCiraSel').value;
3085
- QV('dlgAddCira0', val == 0);
3086
- QV('dlgAddCira1', val == 1);
3087
- QV('dlgAddCira2', val == 2);
3088
- }
3089
-
3090
- // Return true is the input string looks like an email address
3091
- function checkEmail(str) {
3092
- var x = str.split('@');
3093
- var ok = ((x.length == 2) && (x[0].length > 0) && (x[1].split('.').length > 1) && (x[1].length > 2));
3094
- if (ok == true) { var y = x[1].split('.'); for (var i in y) { if (y[i].length == 0) { ok = false; } } }
3095
- return ok;
3096
- }
3097
-
3098
- function inviteAgentToMesh(meshid) {
3099
- if (xxdialogMode) return false;
3100
- var x = '', mesh = meshes[meshid];
3101
- if (features & 64) {
3102
- x += addHtmlValue('Invitation Type', '<select id=d2InviteType onchange=d2ChangedInviteType() style=width:236px><option value=0>Link invitation</option><option value=1>Email invitation</option></select>') + "<hr />";
3103
- x += "<div id=emailInviteDiv style=display:none>Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for the \"" + EscapeHtml(mesh.name) + "\" device group.<br /><br />";
3104
- x += addHtmlValue('Name (optional)', '<input id=agentInviteName value="" style=width:230px maxlength=64 />');
3105
- x += addHtmlValue('Email', '<input id=agentInviteEmail style=width:230px placeholder="example@email.com" onkeyup=validateAgentInvite()></input>');
3106
- x += addHtmlValue('Operating System', '<select id=agentInviteNameOs onchange=d2ChangedInviteType() style=width:236px><option value=4>Send installation link</option><option value=0 selected>Any supported</option><option value=1>Windows only</option><option value=3>Apple MacOS only</option><option value=2>Linux only</option></select>');
3107
- x += '<div id=d2agentexpirediv>';
3108
- x += addHtmlValue('Link Expiration', '<select id=agentInviteExpire style=width:236px><option value=1>1 hour</option><option value=8>8 hours</option><option value=24>1 day</option><option value=168>1 week</option><option value=5040>1 month</option><option value=0>Unlimited</option></select>');
3109
- x += '</div>';
3110
- x += addHtmlValue('Installation Type', '<select id=agentInviteType style=width:236px><option value=0>Background and interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>');
3111
- x += addHtmlValue('Message<br />(optional)', '<textarea id=agentInviteMessage value="" style=width:230px;height:100px;resize:none maxlength=1024 /></textarea>');
3112
- x += '</div>';
3113
- }
3114
- x += '<div id=urlInviteDiv>Invite someone to install the mesh agent by sharing an invitation link. This link points the user to installation instructions for the \"' + EscapeHtml(mesh.name) + '\" device group. The link is public and no account for this server is needed.<br /><br />';
3115
- x += addHtmlValue('Link Expiration', '<select id=d2inviteExpire style=width:236px onchange=d2RequestInvitationLink()><option value=1>1 hour</option><option value=8>8 hours</option><option value=24>1 day</option><option value=168>1 week</option><option value=5040>1 month</option><option value=0>Unlimited</option></select>');
3116
- x += '<div id=agentInvitationLinkDiv style="text-align:center;font-size:large;margin:16px;display:none"><a href=# id=agentInvitationLink target="_blank" style=cursor:pointer></a> <img src=images/link4.png height=10 width=10 title="Copy link to clipboard" style=cursor:pointer onclick=d2CopyInviteToClip()></div></div>';
3117
- setDialogMode(2, "Invite", 3, performAgentInvite, x, meshid);
3118
- if (features & 64) { Q('d2InviteType').focus(); d2ChangedInviteType(); } else { Q('d2inviteExpire').focus(); validateAgentInvite(); }
3119
- d2RequestInvitationLink();
3120
- return false;
3121
- }
3122
-
3123
- function d2RequestInvitationLink() {
3124
- meshserver.send({ action: 'createInviteLink', meshid: xxdialogTag, expire: parseInt(Q('d2inviteExpire').value), flags: 0 });
3125
- }
3126
-
3127
- function d2ChangedInviteType() {
3128
- QV('urlInviteDiv', Q('d2InviteType').value == 0);
3129
- QV('d2agentexpirediv', Q('agentInviteNameOs').value == 4);
3130
- QV('emailInviteDiv', Q('d2InviteType').value == 1);
3131
- validateAgentInvite();
3132
- }
3133
-
3134
- function d2CopyInviteToClip() { copyTextToClip(Q('agentInvitationLink').href); }
3135
-
3136
- function validateAgentInvite() {
3137
- if ((features & 64) && (Q('d2InviteType').value == 1)) {
3138
- QE('idx_dlgOkButton', checkEmail(Q('agentInviteEmail').value));
3139
- QV('idx_dlgCancelButton', true);
3140
- } else {
3141
- QE('idx_dlgOkButton', true);
3142
- QV('idx_dlgCancelButton', false);
3143
- }
3144
- }
3145
-
3146
- function performAgentInvite(button, meshid) {
3147
- if ((features & 64) && (Q('d2InviteType').value == 1)) {
3148
- meshserver.send({ action: 'inviteAgent', meshid: meshid, email: Q('agentInviteEmail').value, name: Q('agentInviteName').value, os: Q('agentInviteNameOs').value, flags: Q('agentInviteType').value, msg: Q('agentInviteMessage').value, expire: parseInt(Q('agentInviteExpire').value) });
3149
- }
3150
- }
3151
-
3152
- function addAgentToMesh(meshid) {
3153
- if (xxdialogMode) return false;
3154
- var mesh = meshes[meshid], x = '', installType = 0;
3155
- x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux / BSD</option><option value=2>Apple MacOS</option><option value=3>Windows (UnInstall)</option><option value=4>Linux / BSD (UnInstall)</option></select>');
3156
- x += '<div id=aginsTypeDiv>';
3157
- x += addHtmlValue('Installation Type', '<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>Background & interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>');
3158
- x += '</div><hr>';
3159
-
3160
- // \/:*?"<>|
3161
- var meshfilename = mesh.name
3162
- meshfilename = meshfilename.split('\\').join('').split('/').join('').split(':').join('').split('*').join('').split('?').join('').split('"').join('').split('<').join('').split('>').join('').split('|').join('').split(' ').join('').split('\'').join('');
3163
-
3164
- // Windows agent install
3165
- //x += "<div id=agins_windows>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and configuration file and install the agent on the computer to manage.<br /><br />";
3166
- x += "<div id=agins_windows>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and install it the computer to manage. This agent has server and device group information embedded within it.<br /><br />";
3167
- x += addHtmlValue('Mesh Agent', '<a id=aginsw32lnk href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title="32bit version of the MeshAgent">Windows (.exe)</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 32bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3168
- x += addHtmlValue('Mesh Agent', '<a id=aginsw64lnk href="meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title="64bit version of the MeshAgent">Windows x64 (.exe)</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 64bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3169
- if (debugmode > 0) { x += addHtmlValue('Settings File', '<a id=aginswmshlnk href="meshsettings?id=' + meshid.split('/')[2] + '&installflags=0" rel="noreferrer noopener" target="_blank">' + EscapeHtml(mesh.name) + ' settings (.msh)</a>'); }
3170
- x += "</div>";
3171
-
3172
- // Linux agent install
3173
- x += "<div id=agins_linux style=display:none>To add a computer to " + EscapeHtml(mesh.name) + " run the following command. Root credentials will be needed.<br />";
3174
- x += '<textarea id=agins_linux_area rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
3175
- x += "<div style='font-size:x-small'>* For BSD, run \"pkg install wget sudo bash\" first.</div></div>";
3176
-
3177
- // MacOS agent install
3178
- x += "<div id=agins_osx style=display:none>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and install it the computer to manage. This agent installer has server and device group information embedded within it.<br /><br />";
3179
- x += addHtmlValue('Mesh Agent', '<a href="meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '" rel="noreferrer noopener" target="_blank" title="64bit version of MacOS Mesh Agent">MacOS Agent (64bit)</a> <img src=images/link4.png height=10 width=10 title="Copy MacOS agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '",0)>');
3180
- x += "</div>";
3181
-
3182
- // Windows agent uninstall
3183
- x += "<div id=agins_windows_un style=display:none>To remove a mesh agent, download the file below, run it and click \"uninstall\".<br /><br />";
3184
- x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=3" download onclick="setDialogMode(0)" title="32bit version of the MeshAgent">Windows (.exe)</a>');
3185
- x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=4" download onclick="setDialogMode(0)" title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');
3186
- x += "</div>";
3187
-
3188
- // Linux agent uninstall
3189
- x += "<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentials will be needed.<br />";
3190
- x += '<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
3191
- x += "</div>";
3192
-
3193
- setDialogMode(2, "Add Mesh Agent", 2, null, x, 'fileDownload');
3194
- var servername = serverinfo.name;
3195
- if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
3196
- var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
3197
-
3198
- if (serverinfo.https == true)
3199
- {
3200
- var portStr = (serverinfo.port == 443)?'':(":" + serverinfo.port);
3201
- if ((features & 0x2000) == 0)
3202
- {
3203
- Q('agins_linux_area').value = "(wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh https://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3204
- Q('agins_linux_area_un').value = "(wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3205
- }
3206
- else
3207
- {
3208
- // Server asked that agent be installed to preferably not use a HTTP proxy.
3209
- Q('agins_linux_area').value = "wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3210
- Q('agins_linux_area_un').value = "wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3211
- }
3212
- }
3213
- else
3214
- {
3215
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
3216
- if ((features & 0x2000) == 0)
3217
- {
3218
- Q('agins_linux_area').value = "(wget http://" + servername + portStr + domainUrl + "meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh http://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3219
- Q('agins_linux_area_un').value = "(wget http://" + servername + portStr + domainUrl + "meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3220
- }
3221
- else
3222
- {
3223
- // Server asked that agent be installed to preferably not use a HTTP proxy.
3224
- Q('agins_linux_area').value = "wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3225
- Q('agins_linux_area_un').value = "wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3226
- }
3227
- }
3228
- Q('aginsSelect').focus();
3229
- addAgentToMeshClick();
3230
- return false;
3231
- }
3232
-
3233
- function copyAgentUrl(url,addflag) {
3234
- var servername = serverinfo.name;
3235
- if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
3236
- var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
3237
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
3238
- var c = "https://" + servername + portStr + domainUrl + url;
3239
- if (addflag == 1) c += Q('aginsType').value;
3240
- copyTextToClip(c);
3241
- }
3242
-
3243
- function addAgentToMeshClick() {
3244
- var v = Q('aginsSelect').value;
3245
- QV('agins_windows', v == 0);
3246
- QV('agins_linux', v == 1);
3247
- QV('agins_osx', v == 2);
3248
- QV('agins_windows_un', v == 3);
3249
- QV('agins_linux_un', v == 4);
3250
- QV('aginsTypeDiv', v == 0);
3251
-
3252
- // Fix the links if needed
3253
- Q('aginsw32lnk').href = (Q('aginsw32lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value;
3254
- Q('aginsw64lnk').href = (Q('aginsw64lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value;
3255
- if (debugmode > 0) { Q('aginswmshlnk').href = (Q('aginswmshlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value; }
3256
- }
3257
-
3258
- function validateDeviceToMesh() {
3259
- QE('idx_dlgOkButton', (Q('dp1devicename').value.length > 0) && (passwordcheck(Q('dp1password').value)));
3260
- }
3261
-
3262
- function addDeviceToMeshEx(button, meshid) {
3263
- var amtuser = Q('dp1username').value;
3264
- if (amtuser == '') amtuser = 'admin';
3265
- var host = Q('dp1hostname').value;
3266
- if (host == '') host = Q('dp1devicename').value;
3267
- meshserver.send({ action: 'addamtdevice', meshid: meshid, devicename: Q('dp1devicename').value, hostname: host, amtusername: amtuser, amtpassword: Q('dp1password').value, amttls: Q('dp1tls').value });
3268
- }
3269
-
3270
- function deviceHeaderSet() {
3271
- if (deviceHeaderId == 0) { deviceHeaderId = 1; return; }
3272
- deviceHeaders["DevxHeader" + deviceHeaderId] = deviceHeaderTotal + ((deviceHeaderTotal == 1) ? ' node' : ' nodes');
3273
- //var title = '';
3274
- //for (x in deviceHeaderCount) { if (title.length > 0) title += ', '; title += deviceHeaderCount[x] + ' ' + PowerStateStr2(x); }
3275
- //deviceHeadersTitles["DevxHeader" + deviceHeaderId] = title;
3276
- deviceHeaderId++;
3277
- deviceHeaderCount = {};
3278
- deviceHeaderTotal = 0;
3279
- }
3280
-
3281
- var powerStateStrings = ['', '<span title="Device is powered on.">Powered</span>', '<span title="Device is in sleep state (S1).">Sleeping</span>', '<span title="Device is in sleep state (S2).">Sleeping</span>', '<span title="Device is in deep sleep state (S3).">Deep Sleep</span>', '<span title="Device is in hibernating state (S4).">Hibernating</span>', '<span title="Device is in powered off state (S5).">Soft-Off</span>', '<span title="Device is detected but power state could not be obtained.">Present</span>'];
3282
- var powerStateStrings2 = ['', 'Device is powered', 'Device is in sleep state (S1)', 'Device is in sleep state (S2)', 'Device is in deep sleep state (S3)', 'Device is hibernating (S4)', 'Device is in soft-off state (S5)', 'Device is present, but power state cannot be determined'];
3283
- var powerColorTable = ['pwsTransparent', 'pwsBlack', 'pwsBlue', 'pwsBlue2', 'pwsLightblue', 'pwsBlueviolet', 'pwsDarkgreen', 'pwsLightseagreen', 'pwsLightseagreen2'];
3284
- function NodeStateStr(node) {
3285
- var states = [];
3286
- if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]);
3287
- if (node.conn) {
3288
- if ((node.conn & 1) != 0) { states.push('<span title="Mesh agent is connected and ready for use.">Agent</span>'); }
3289
- if ((node.conn & 2) != 0) { states.push('<span title="Intel® AMT CIRA is connected and ready for use.">CIRA</span>'); }
3290
- else if ((node.conn & 4) != 0) { states.push('<span title="Intel® AMT is routable.">AMT</span>'); }
3291
- if ((node.conn & 8) != 0) { states.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>'); }
3292
- if ((node.conn & 16) != 0) { states.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
3293
- }
3294
- if ((node.pwr != null) && (node.pwr != 0)) { states.push(powerStateStrings[node.pwr]); }
3295
- return states.join(', ');
3296
- }
3297
-
3298
- function PowerStateStr(x) {
3299
- if (x < powerStatetable.length) return powerStatetable[x];
3300
- return '';
3301
- }
3302
-
3303
- function PowerStateStr2(x) {
3304
- if ((x != 0) && (x < powerStatetable.length)) return powerStatetable[x];
3305
- return 'Unknown';
3306
- }
3307
-
3308
- function selectallButtonFunction() {
3309
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
3310
- for (var i=0;i<elements.length;i++) { if (elements[i].checked === true) checkcount++; }
3311
- for (var i=0;i<elements.length;i++) { elements[i].checked = (checkcount == 0); }
3312
- p1updateInfo();
3313
- }
3314
-
3315
- function p1updateInfo() {
3316
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
3317
- for (var i=0;i<elements.length;i++) { if (elements[i].checked === true) { checkcount++; } }
3318
- if (checkcount > 0) {
3319
- QE('GroupActionButton', true);
3320
- Q('SelectAllButton').value = 'Select None';
3321
- QV('cxmgroupsplit', true);
3322
- QV('cxmdesktop', true);
3323
- } else {
3324
- QE('GroupActionButton', false);
3325
- Q('SelectAllButton').value = 'Select All';
3326
- QV('cxmgroupsplit', false);
3327
- QV('cxmdesktop', false);
3328
- }
3329
- }
3330
-
3331
- function groupActionFunction() {
3332
- var mqttx = '';
3333
- if (features & 0x00400000) { // Check if any of the selected devices have a MQTT connection active
3334
- var nodeids = getCheckedDevices();
3335
- for (var i in nodeids) { if ((getNodeFromId(nodeids[i]).conn & 16) != 0) { mqttx = '<option value=103>Send MQTT Message</option>'; } }
3336
- }
3337
- var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights.<br /><br />";
3338
- x += addHtmlValue('Operation', '<select id=d2groupop><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=102>Move to device group</option>' + mqttx + '<option value=101>Delete devices</option></select>');
3339
- setDialogMode(2, "Group Action", 3, groupActionFunctionEx, x);
3340
- }
3341
-
3342
- // Get the list of checked devices, removes any duplicates.
3343
- function getCheckedDevices() {
3344
- var nodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
3345
- for (var i=0;i<elements.length;i++) { if (elements[i].checked) { if (elements[i].value) { var nid = elements[i].value.substring(6); if (nodeids.indexOf(nid) == -1) { nodeids.push(nid); } } } }
3346
- return nodeids;
3347
- }
3348
-
3349
- function groupActionFunctionEx() {
3350
- var op = Q('d2groupop').value;
3351
- if (op == 100) {
3352
- // Group wake
3353
- meshserver.send({ action: 'wakedevices', nodeids: getCheckedDevices() });
3354
- } else if (op == 101) {
3355
- // Group delete, ask for confirmation
3356
- var x = "Confirm delete selected devices(s)?<br /><br />";
3357
- x += "<label><input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />Confirm</label>";
3358
- setDialogMode(2, "Delete Nodes", 3, groupActionFunctionDelEx, x);
3359
- QE('idx_dlgOkButton', false);
3360
- } else if (op == 102) {
3361
- // Move computers to a different group
3362
- p10showChangeGroupDialog(getCheckedDevices());
3363
- } else if (op == 103) {
3364
- // Send MQTT Message
3365
- p10showSendMqttMsgDialog(getCheckedDevices());
3366
- } else {
3367
- // Power operation
3368
- meshserver.send({ action: 'poweraction', nodeids: getCheckedDevices(), actiontype: parseInt(op) });
3369
- }
3370
- }
3371
-
3372
- function d2groupActionFunctionDelEx() { QE('idx_dlgOkButton', Q('d2check').checked); }
3373
- function groupActionFunctionDelEx() { meshserver.send({ action: 'removedevices', nodeids: getCheckedDevices() }); }
3374
-
3375
- function onSortSelectChange(skipsave) {
3376
- sort = document.getElementById("sortselect").selectedIndex;
3377
- if (!skipsave) { putstore("sort", sort); }
3378
- }
3379
-
3380
- function meshSort(a, b) { if (a.meshnamel > b.meshnamel) return 1; if (a.meshnamel < b.meshnamel) return -1; if (a.meshid == b.meshid) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } return 0; }
3381
- function powerSort(a, b) { var ap = a.pwr?a.pwr:0; var bp = b.pwr?b.pwr:0; if (ap > bp) return -1; if (ap < bp) return 1; if (ap == bp) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } return 0; }
3382
- function deviceSort(a, b) { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; }
3383
- function deviceHostSort(a, b) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; }
3384
- function onSearchFocus(x) { searchFocus = x; }
3385
- function onMapSearchFocus(x) { mapSearchFocus = x; }
3386
- function onUserSearchFocus(x) { userSearchFocus = x; }
3387
- function onConsoleFocus(x) { consoleFocus = x; }
3388
-
3389
- function onSearchInputChanged() {
3390
- var x = Q('SearchInput').value.toLowerCase().trim(); putstore("_search", x);
3391
- var userSearch = null, ipSearch = null, groupSearch = null;
3392
- if (x.startsWith('user:')) { userSearch = x.substring(5); }
3393
- else if (x.startsWith('u:')) { userSearch = x.substring(2); }
3394
- else if (x.startsWith('ip:')) { ipSearch = x.substring(3); }
3395
- else if (x.startsWith('group:')) { groupSearch = x.substring(6); }
3396
- else if (x.startsWith('g:')) { groupSearch = x.substring(2); }
3397
-
3398
- if (x == '') {
3399
- // No search
3400
- for (var d in nodes) { nodes[d].v = true; }
3401
- } else if (ipSearch != null) {
3402
- // IP address search
3403
- for (var d in nodes) { nodes[d].v = ((nodes[d].ip != null) && (nodes[d].ip.indexOf(ipSearch) >= 0)); }
3404
- } else if (groupSearch != null) {
3405
- // Group filter
3406
- for (var d in nodes) { nodes[d].v = (meshes[nodes[d].meshid].name.toLowerCase().indexOf(groupSearch) >= 0); }
3407
- } else if (userSearch != null) {
3408
- // User search
3409
- for (var d in nodes) {
3410
- nodes[d].v = false;
3411
- if (nodes[d].users && nodes[d].users.length > 0) { for (var i in nodes[d].users) { if (nodes[d].users[i].toLowerCase().indexOf(userSearch) >= 0) { nodes[d].v = true; } } }
3412
- }
3413
- } else {
3414
- // Device name search
3415
- try {
3416
- var rs = x.split(/\s+/).join('|'), rx = new RegExp(rs); // In some cases (like +), this can throw an exception.
3417
- for (var d in nodes) {
3418
- nodes[d].v = (rx.test(nodes[d].name.toLowerCase())) || (nodes[d].rnamel != null && rx.test(nodes[d].rnamel.toLowerCase()));
3419
- if ((nodes[d].v == false) && nodes[d].tags) {
3420
- for (var s in nodes[d].tags) {
3421
- if (rx.test(nodes[d].tags[s].toLowerCase())) {
3422
- nodes[d].v = true;
3423
- break;
3424
- } else {
3425
- nodes[d].v = false;
3426
- }
3427
- }
3428
- }
3429
- }
3430
- } catch (ex) { for (var d in nodes) { nodes[d].v = true; } }
3431
- }
3432
- }
3433
-
3434
- var contextelement = null;
3435
- function handleContextMenu(event) {
3436
- hideContextMenu();
3437
- var scrollLeft = (window.pageXOffset !== null) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
3438
- var scrollTop = (window.pageYOffset !== null) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
3439
- var elem = document.elementFromPoint(event.pageX - scrollLeft, event.pageY - scrollTop);
3440
- if (elem && elem != null && elem.id == "connectbutton2" && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3441
- contextelement = elem;
3442
- var contextmenudiv = document.getElementById("termShellContextMenu");
3443
- contextmenudiv.style.left = event.pageX + "px";
3444
- contextmenudiv.style.top = event.pageY + "px";
3445
- contextmenudiv.style.display = "block";
3446
- } else if (elem && elem != null && elem.id == "MxMESH") {
3447
- contextelement = elem;
3448
- var contextmenudiv = document.getElementById("meshContextMenu");
3449
- contextmenudiv.style.left = event.pageX + "px";
3450
- contextmenudiv.style.top = event.pageY + "px";
3451
- contextmenudiv.style.display = "block";
3452
- } else {
3453
- while (elem && elem != null && elem.id != "devs") { elem = elem.parentElement; }
3454
- if (!elem || elem == null) return true;
3455
- contextelement = elem;
3456
- var contextmenudiv = document.getElementById("contextMenu");
3457
- contextmenudiv.style.left = event.pageX + "px";
3458
- contextmenudiv.style.top = event.pageY + "px";
3459
- contextmenudiv.style.display = "block";
3460
-
3461
- // Get the node and set the menu options
3462
- var nodeid = contextelement.children[1].attributes.onclick.value;
3463
- var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18));
3464
- var mesh = meshes[node.meshid];
3465
- var meshlinks = mesh.links[userinfo._id];
3466
- var meshrights = meshlinks.rights;
3467
- var consoleRights = ((meshrights & 16) != 0);
3468
-
3469
- // Check if we have terminal and file access
3470
- var terminalAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 512) == 0));
3471
- var fileAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0));
3472
-
3473
- QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((meshrights & 8) || (meshrights & 256)));
3474
- QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8) && terminalAccess);
3475
- QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8) && fileAccess);
3476
- QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8));
3477
- QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (meshrights & 8));
3478
- }
3479
-
3480
- return haltEvent(event);
3481
- }
3482
-
3483
- function cmaction(action,event) {
3484
- var nodeid = contextelement.children[1].attributes.onclick.value;
3485
- nodeid = nodeid.substring(12, nodeid.length - 18);
3486
- if (action == 7) { Q('viewselect').value = 3; Q('viewselect').onchange(); Q('autoConnectDesktopCheckbox').checked = true; Q('autoConnectDesktopCheckbox').onclick(); } // Multi-Desktop
3487
- if ((action > 0) && (action < 7)) {
3488
- var panel = [0, 10, 12, 11, 13, 16, 15][action]; // (invalid), General, Desktop, Terminal, Files, Events, Console
3489
- if (event && (event.shiftKey == true)) {
3490
- // Open the device in a different tab
3491
- window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=' + panel + '&hide=16', 'meshcentral:' + nodeid);
3492
- } else {
3493
- // Go to the right panel
3494
- gotoDevice(nodeid, panel);
3495
-
3496
- // If possible, connect...
3497
- var mesh = meshes[currentNode.meshid];
3498
- if ((currentNode.conn & 1) && (mesh.mtype == 2)) {
3499
- if ((panel == 11) && (desktop == null) && (currentNode.agent.caps & 1)) { connectDesktop(null, 1); } // Desktop
3500
- if ((panel == 12) && (terminal == null) && (currentNode.agent.caps & 2)) { connectTerminal(null, 1); } // Terminal
3501
- if ((panel == 13) && (files == null)) { connectFiles(null); } // files
3502
- }
3503
- }
3504
- }
3505
- }
3506
-
3507
- function cmmeshaction(action) {
3508
- var meshid = contextelement.attributes.onclick.value.substring(10, contextelement.attributes.onclick.value.length - 2);
3509
- var elements = document.getElementsByClassName("DeviceCheckbox");
3510
- if ((action == 1) || (action == 2)) {
3511
- for (var i = 0; i < elements.length; i++) {
3512
- if ((elements[i].attributes) && (elements[i].attributes['class']['value'].split(' ')[0] == meshid)) { elements[i].checked = (action == 1); }
3513
- }
3514
- }
3515
- //if (action == 3) { window.location = "multidesktop.aspx?mesh=" + meshid + "&auto=1"; }
3516
- p1updateInfo();
3517
- }
3518
-
3519
- function cmtermaction(action) {
3520
- connectTerminal(null, 1, { powershell: (action == 2) });
3521
- }
3522
-
3523
- function hideContextMenu() {
3524
- QV('contextMenu', false);
3525
- QV('meshContextMenu', false);
3526
- QV('termShellContextMenu', false);
3527
- contextelement = null;
3528
- }
3529
-
3530
- //
3531
- // DEVICES MAP
3532
- //
3533
-
3534
- // Maps code starts from here. Initialize all the variables
3535
- var xxmap = {
3536
- map: null,
3537
- contextmenu: null,
3538
- activeInteractions: [], // Save Modified features in this list
3539
- showindex: 0,
3540
- markersSource: null, // Initialize a Source Vector
3541
- markersLayer: null,
3542
- mapLayer: null, // Create a tile and use OSM source
3543
- mapView: null, // Sets the initial view
3544
- }
3545
-
3546
- // Add a feature for every Node and change style if connection status changes
3547
- function updateMapMarkers(selectedMesh) {
3548
- if ((xxmap != null) && (xxmap.map == null)) { try { loadmap(); } catch (ex) { console.error('loadmap() exception', ex); } }
3549
- if (xxmap == null) return;
3550
- var boundingBox = null;
3551
- for (var i in nodes) {
3552
- try {
3553
- var loc = map_parseNodeLoc(nodes[i]), feature = xxmap.markersSource.getFeatureById(nodes[i]._id);
3554
- if ((loc != null) && ((nodes[i].meshid == selectedMesh) || (selectedMesh == null))) { // Draw markers for devices with locations
3555
- var lat = loc[0], lon = loc[1], type = loc[2];
3556
- if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } }
3557
- if (feature == null) { addFeature(nodes[i]); boundingBox[4] = 1; } else { updateFeature(nodes[i], feature); feature.setStyle(markerStyle(nodes[i], loc[2])); } // Update Feature
3558
- } else {
3559
- if (feature) { xxmap.markersSource.removeFeature(feature); }
3560
- }
3561
- } catch (ex) { console.error('updateMapMarkers() exception', ex, JSON.stringify(nodes[i])); }
3562
- }
3563
- return boundingBox;
3564
- }
3565
-
3566
- // Show node details on hovering over a feature
3567
- var map_cm_popup = new ol.Overlay({ element: Q('xmap-info-window'), positioning: 'bottom-center', stopEvent: false });
3568
-
3569
- // Edit Marker item
3570
- var map_cm_editMarker = { text: "Modify node location", callback: function (obj) { modifyMarkerloc(obj.data); } };
3571
-
3572
- // Clear Marker item
3573
- var map_cm_clearMarker = { text: "Remove node location", callback: function (obj) {
3574
- meshserver.send({ action: 'changedevice', nodeid: obj.data.a, userloc: [] }); // Clear the user position marker
3575
- }};
3576
-
3577
- // Save Marker item
3578
- var map_cm_saveMarker = { text: "Save node location", callback: function (obj) { saveMarkerloc(obj.data); } };
3579
-
3580
- // Build a context menu for a feature
3581
- var map_cm_nodemenu_items = [
3582
- { text: "General information", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 10); } } },
3583
- { text: "Desktop", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 11); } } },
3584
- { text: "Terminal", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 12); } } },
3585
- { text: "Intel® AMT", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 14); } } },
3586
- '-',
3587
- { text: 'Zoom-in to extent', callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 19); } },
3588
- { text: 'Zoom-out to extent', callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 2); } }
3589
- ];
3590
-
3591
- // Context menu for clicks other than on feature
3592
- var contextmenu_items = [
3593
- { text: 'Refresh', callback: function () { refreshMap(true, true); } },
3594
- { text: 'Zoom to fit extent', callback: function () { zoomToFitExtent(); } },
3595
- { text: 'Center map here', callback: function(obj) { xxmap.mapView.animate({ center: obj.coordinate } ); } },
3596
- { text: 'Place node here', callback: function(obj) { placeNode(obj.coordinate); } }
3597
- ];
3598
-
3599
- function stringToIntHash(str) {
3600
- var hash = 0, i;
3601
- for (i = 0; i < str.length; i++) { hash = ((hash << 5) - hash) + str.charCodeAt(i); hash |= 0; }
3602
- return hash;
3603
- };
3604
-
3605
- // Get the lat/lon from a node
3606
- function map_parseNodeLoc(node) {
3607
- var loc = null, t = 0;
3608
- if (node.iploc) { loc = node.iploc; t = 1; }
3609
- if (node.wifiloc) { loc = node.wifiloc; t = 2; }
3610
- if (node.gpsloc) { loc = node.gpsloc; t = 3; }
3611
- if (node.userloc) { loc = node.userloc; t = 4; }
3612
- if ((loc == null) || (typeof loc != 'string')) return null;
3613
- loc = loc.split(',');
3614
- if (t == 1) {
3615
- // If this is IP location, randomize the position a little.
3616
- return [ parseFloat(loc[0]) + (stringToIntHash(node._id.substring(0, 20)) / 100000000000), parseFloat(loc[1]) + (stringToIntHash(node._id.substring(20)) / 100000000000), t ];
3617
- } else {
3618
- // Return the real position
3619
- return [ parseFloat(loc[0]), parseFloat(loc[1]), t ];
3620
- }
3621
- }
3622
-
3623
- // Load the entire map
3624
- function loadmap() {
3625
- if (xxmap == null) return;
3626
- if ((features & 0x8000) == 0) { QV('viewselectmapoption', false); QV('devViewButton4', false); xxmap = null; return; } // Geolocation not supported
3627
- try {
3628
- // Initialize a Source Vector
3629
- xxmap.markersSource = new ol.source.Vector();
3630
-
3631
- xxmap.markersLayer = new ol.layer.Vector({
3632
- source: xxmap.markersSource
3633
- });
3634
-
3635
- // Create a tile and use OSM source
3636
- xxmap.mapLayer = new ol.layer.Tile({ source: new ol.source.OSM() });
3637
-
3638
- xxmap.mapView = new ol.View({ // Set the initial view
3639
- center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'),
3640
- zoom: 2,
3641
- minZoom: 2,
3642
- maxZoom: 20,
3643
- extent: ol.proj.transformExtent([-100000, -69.55, 100000, 69.55], 'EPSG:4326', 'EPSG:3857')
3644
- });
3645
-
3646
- xxmap.map = new ol.Map({
3647
- target: 'xdevicesmap',
3648
- layers: [xxmap.mapLayer, xxmap.markersLayer],
3649
- view: xxmap.mapView
3650
- });
3651
-
3652
- xxmap.map.addOverlay(map_cm_popup);
3653
-
3654
- // Goto information tab if a user clicks on a feature
3655
- xxmap.map.on('click', function(evt) {
3656
- var feature = xxmap.map.forEachFeatureAtPixel(evt.pixel, function(feat, layer) { return feat; });
3657
- if (feature) {
3658
- var nodeid = feature.getId();
3659
- if (nodeid != null) { gotoDevice(nodeid, 10); } // Goto general info tab
3660
- else { // For pointer
3661
- var nodeFeatgoto = getCorrespondingFeature(feature); gotoDevice(nodeFeatgoto.getId(), 10);
3662
- }
3663
- }
3664
- });
3665
-
3666
- // On hover feature show the name of the node. Also add pointer style
3667
- xxmap.map.on('pointermove', function(evt) {
3668
- var feature = xxmap.map.forEachFeatureAtPixel(evt.pixel, function(feat, layer) { return feat; });
3669
- if (feature) {
3670
- xxmap.map.getTargetElement().style.cursor = 'pointer';
3671
- var coord = feature.getGeometry().getCoordinates();
3672
- // map_cm_popup.setPosition(evt.coordinate);
3673
- map_cm_popup.setPosition(coord);
3674
- var featid = feature.getId();
3675
- if (featid) {
3676
- QH('xmap-info-window', feature.get('name'));
3677
- } else {
3678
- var nodeFeat = getCorrespondingFeature(feature); // Return the node feature associated to pointer.
3679
- QH('xmap-info-window', nodeFeat.get('name'));
3680
- }
3681
- } else {
3682
- xxmap.map.getTargetElement().style.cursor = '';
3683
- QH('xmap-info-window', '');
3684
- }
3685
- });
3686
-
3687
- // Initialize context menu for openlayers
3688
- var contextmenu = new ContextMenu({
3689
- width: 160,
3690
- defaultItems: false, // defaultItems are Zoom In/Zoom Out
3691
- items: contextmenu_items
3692
- });
3693
-
3694
- // On right click open the context menu
3695
- contextmenu.on("open", function (evt) {
3696
- var feature = xxmap.map.forEachFeatureAtPixel(evt.pixel, function(ft, l){ return ft; });
3697
- xxmap.contextmenu.clear(); //Clear the context menu
3698
- if (feature) {
3699
- var featId = feature.getId();
3700
- if (featId) { addContextMenuItems(feature); } // Node feature will have an id
3701
- else { // If the feature is a pointer, Get its corresponding Node feature
3702
- var nodeFeature = getCorrespondingFeature(feature); //return the node feature associated to pointer.
3703
- if (nodeFeature) { addContextMenuItems(nodeFeature); }
3704
- else{ xxmap.contextmenu.extend(contextmenu_items); }
3705
- }
3706
- }
3707
- else { xxmap.contextmenu.extend(contextmenu_items); }
3708
- });
3709
- if (xxmap.contextmenu == null) { xxmap.contextmenu = contextmenu; }
3710
- xxmap.map.addControl(xxmap.contextmenu);
3711
- //addMeshOptions(); // Adds Mesh names to mesh dropdown
3712
- } catch (ex) {
3713
- console.log(ex);
3714
- QV('viewselectmapoption', false);
3715
- QV('devViewButton4', false);
3716
- xxmap = null;
3717
- }
3718
- }
3719
-
3720
- // Add feature on to Map for a Node
3721
- function addFeature(node, lat, lon) {
3722
- var existingfeature = getModifiedFeature(node._id); // Check if Corresponding feature was Modified ( Modifed feature are in active interactions list)
3723
- if (existingfeature) { xxmap.markersSource.addFeature(existingfeature); } // Add that existing feature
3724
- else { // Add new feature for this node
3725
- if (!lat && !lon) { var loc = map_parseNodeLoc(node); lat = loc[0]; lon = loc[1]; }
3726
-
3727
- // Fix the longiture and send an event to patch the db to correct coordinate format. It will cause second unnecessary updateFeature on this node to the map.
3728
- if (lon > 180) { lon = 180 - lon; meshserver.send({ action: 'changedevice', nodeid: node._id, userloc: [ lat, lon ] }); }
3729
-
3730
- if ((lat < 90) && (lat > -90) && (lon < 180) && (lon > -180)) { // Check valid lat/lon
3731
- var feature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326','EPSG:3857')), name: node.name, status: node.conn, lat: lat, lon: lon });
3732
- feature.setId(node._id); // Set id for the device as nodeid
3733
- feature.setStyle(markerStyle(node));
3734
- xxmap.markersSource.addFeature(feature); // Add the feature to Marker Source
3735
- }
3736
- }
3737
- }
3738
-
3739
- // Removing any feature from map
3740
- function removeFeature(node) {
3741
- var feature = xxmap.markersSource.getFeatureById(node._id);
3742
- if (feature) { xxmap.markersSource.removeFeature(feature); }
3743
- }
3744
-
3745
- // Update feature
3746
- function updateFeature(node, feature) {
3747
- if (node.conn != feature.get('status') ) { // Update status if changed
3748
- feature.set('status',node.conn)
3749
- feature.setStyle(markerStyle(node));
3750
- }
3751
-
3752
- // Since this is IP address location, add some fixed randomness to the location. Avoid pin pile-up.
3753
- var loc = map_parseNodeLoc(node);
3754
- if (loc != null) {
3755
- var lat = loc[0], lon = loc[1];
3756
- if ((lat != feature.get('lat')) || (lon != feature.get('lon'))) { // Update lat and lon if changed
3757
- feature.set('lat', lat); feature.set('lon', lon);
3758
- var modifiedCoordinates = ol.proj.transform([parseFloat(lon), parseFloat(lat)], 'EPSG:4326', 'EPSG:3857');
3759
- feature.getGeometry().setCoordinates(modifiedCoordinates);
3760
- }
3761
- }
3762
-
3763
- if (node.name != feature.get('name') ) { feature.set('name', node.name); } // Update name
3764
- }
3765
-
3766
- // Enable dragging of a marker after edit option is clicked in context menu
3767
- function modifyMarkerloc(ft){
3768
- var featid = ft.getId();
3769
- if (featid) {
3770
- ft.setStyle(markerStyle(getNodeFromId(ft.a), 4)); // Switch to a user marker
3771
- if ( !getActiveInteractions(ft)) {
3772
- var dragInteration = new ol.interaction.Modify({
3773
- features: new ol.Collection([ft]),
3774
- pixelTolerance: 10
3775
- });
3776
- xxmap.activeInteractions.push({ featureid: featid, feature:ft, interaction: dragInteration }); // Also keep track of Interactions
3777
- xxmap.map.addInteraction(dragInteration);
3778
- }
3779
- }
3780
- }
3781
-
3782
- // This will be called when save location option is clicked in context menu
3783
- function saveMarkerloc(ft){
3784
- var featid = ft.getId()
3785
- if (featid) {
3786
- var actInteraction = getActiveInteractions(ft);
3787
- if (actInteraction) { // Check if the interaction exists
3788
- xxmap.map.removeInteraction(actInteraction); //Clear Interaction for that node
3789
- removeInteraction(featid);
3790
- var coord = ft.getGeometry().getCoordinates();
3791
- var v = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
3792
- if (v[0] > 180) { v[0] = 180 - v[0]; }
3793
- var vx = [ v[1], v[0] ]; // Flip the coordinates around, lat/long
3794
- meshserver.send({ action: 'changedevice', nodeid: featid, userloc: vx }); // Send them to server to save changes
3795
- }
3796
- }
3797
- }
3798
-
3799
- // Style the Markers
3800
- function markerStyle(node, type) {
3801
- if (type == null) {
3802
- type = 0;
3803
- if (node.iploc) { type = 1; }
3804
- if (node.wifiloc) { type = 2; }
3805
- if (node.gpsloc) { type = 3; }
3806
- if (node.userloc) { type = 4; }
3807
- }
3808
- var types = ['', '-ip','-wifi','-gps','-user'];
3809
- var color = connStateColor(node);
3810
- var style = new ol.style.Style({
3811
- image: new ol.style.Icon({ color: color, anchor: [0.5, 1], src: 'images/mapmarker' + types[type] + '.png' })
3812
- //stroke: new ol.style.Stroke({ color: '#000', width: 20 })
3813
- //text: new ol.style.Text({ text: 'bob!', textAlign: 'right', offsetX: -10, fill: new ol.style.Fill({ color: '#000' }), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }) })
3814
- });
3815
-
3816
- /*
3817
- deviceMark.setStyle(new ol.style.Style({
3818
- text: new ol.style.Text({
3819
- //font: '12px helvetica,sans-serif',
3820
- text: currentNode.name,
3821
- textAlign: 'right',
3822
- offsetX: -10,
3823
- fill: new ol.style.Fill({ color: '#000' }),
3824
- stroke: new ol.style.Stroke({ color: '#fff', width: 2 })
3825
- }),
3826
- image: new ol.style.Icon(({ color: [113, 140, 0], src: 'images/dot.png' })) }));
3827
- */
3828
-
3829
- return [ style ];
3830
- }
3831
-
3832
- // TODO: Add more connection status types. Currently we only change color if connection status changes
3833
- function connStateColor(nodeConn){
3834
- if (nodeConn.conn == 1 || nodeConn.conn == 3 || nodeConn.conn == 5) { return '#00ffdd'; } // Green for connected devices
3835
- return '#C70039'; // Red if the Agent is not connected
3836
- }
3837
-
3838
- // Add save/edit option to context menu
3839
- function addContextMenuItems(feature) {
3840
- if (getActiveInteractions(feature)) { // If this feature is modified then display save option in contextmenu
3841
- map_cm_saveMarker.data = feature;
3842
- xxmap.contextmenu.push(map_cm_saveMarker);
3843
- } else {
3844
- map_cm_editMarker.data = feature;
3845
- xxmap.contextmenu.push(map_cm_editMarker);
3846
- var node = getNodeFromId(feature.a);
3847
- if (node.userloc) {
3848
- map_cm_clearMarker.data = feature;
3849
- xxmap.contextmenu.push(map_cm_clearMarker);
3850
- }
3851
- }
3852
- map_cm_nodemenu_items.forEach(function (item){
3853
- if (item.text == 'Zoom-in to extent' || item.text == 'Zoom-out to extent') { item.data = feature; }
3854
- else { if (item != "-") { item.data = feature.getId(); } }
3855
- });
3856
- xxmap.contextmenu.extend(map_cm_nodemenu_items);
3857
- }
3858
-
3859
- // Return a active Interaction if it exists in activeInteractions list
3860
- function getActiveInteractions(feature) {
3861
- var featid = feature.getId();
3862
- for (var i = 0; i < xxmap.activeInteractions.length; i++) {
3863
- if (xxmap.activeInteractions[i].featureid == featid) { return xxmap.activeInteractions[i].interaction; }
3864
- }
3865
- return false;
3866
- }
3867
-
3868
- // Return Modified feature based on Id
3869
- function getModifiedFeature(featid) {
3870
- if (featid) {
3871
- for (var i = 0; i < xxmap.activeInteractions.length; i++) {
3872
- if (xxmap.activeInteractions[i].featureid == featid) { return xxmap.activeInteractions[i].feature; }
3873
- }
3874
- }
3875
- return null;
3876
- }
3877
-
3878
- // Remove Interaction
3879
- function removeInteraction(ftid) {
3880
- var index = -1;
3881
- for (var i = 0; i < xxmap.activeInteractions.length; i++) {
3882
- if (xxmap.activeInteractions[i].featureid === ftid) { index = i; break; }
3883
- }
3884
- if (index >= 0) { xxmap.activeInteractions.splice(index, 1); }
3885
- }
3886
-
3887
- // Check if pointer coordinates are equal to features and return node feature
3888
- function getCorrespondingFeature(pointerFeat) {
3889
- var pointerCoord = pointerFeat.getGeometry().getCoordinates();
3890
- for (var i = 0; i < xxmap.activeInteractions.length ; i++) {
3891
- var modifiedFeatures = xxmap.activeInteractions[i].feature;
3892
- var fearCoord = modifiedFeatures.getGeometry().getCoordinates();
3893
- if (fearCoord[0].toFixed(5) == pointerCoord[0].toFixed(5) && fearCoord[1].toFixed(5) == pointerCoord[1].toFixed(5) ) { return modifiedFeatures; }
3894
- }
3895
- return null;
3896
- }
3897
-
3898
- // Refresh the map and clear list
3899
- function refreshMap(reset, rebound){
3900
- if (reset) {
3901
- xxmap.map.setTarget(null);
3902
- xxmap.map = null;
3903
- xxmap.markersSource = null;
3904
- xxmap.mapView = null;
3905
- xxmap.mapLayer = null;
3906
- xxmap.activeInteractions = []; // Clear Active Interaction list
3907
- }
3908
- //clearMeshOptions();
3909
- //onSelectMeshChange();
3910
- var box = updateMapMarkers();
3911
- if ((box != null) && (rebound || (box[4] == 1))) {
3912
- var clat = (box[0] + box[2]) / 2;
3913
- var clon = (box[1] + box[3]) / 2;
3914
- var cscale = Math.max(Math.abs(box[0] - box[2]), Math.abs(box[1] - box[3]));
3915
- var view = xxmap.map.getView();
3916
- view.setCenter(ol.proj.transform([clon, clat], 'EPSG:4326', 'EPSG:3857'));
3917
- var i = 360, j = -2;
3918
- while (i > cscale) { j++; i = i / 2; }
3919
- view.setZoom(j);
3920
- }
3921
- }
3922
-
3923
- // Called When Place a node option is clicked from context menu
3924
- function placeNode(coords) {
3925
- if (xxdialogMode) return;
3926
- var x = '<div style=margin-bottom:6px><label for=selectnode-search>Search</label>  <input type=text placeholder="Device name" id="selectnode-search" onchange=onPlaceNodeInputChange() onkeyup=onPlaceNodeInputChange() autocomplete=off style=width:120px></div><div id=placenode style="height:254px;overflow-y:auto;width:100%;margin:12px 1px 4px 1px;"><div id=noNodesMapPlace style=text-align:center;width:100%;display:none>No devices found.</div>';
3927
- for (var i in nodes) {
3928
- x += '<div class=noselect id=' + nodes[i]._id + '-rowid onclick=selectNodeToPlace(event,\''+ nodes[i]._id +'\') style=background-color:lightgray;margin-bottom:4px;border-radius:2px><input name=PlaceMapDeviceCheckbox id=' + nodes[i]._id + '-checkid type=checkbox style=width:16px;display:inline />';
3929
- x += '<div class=j' + nodes[i].icon + ' style=width:16px;height:16px;margin-top:2px;margin-right:4px;display:inline-block></div><div style=width:16px;display:inline>' + nodes[i].name + '</div></div>';
3930
- }
3931
- setDialogMode(2, "Select a node to place", 3, placeNodeEx, x + '</div>', coords);
3932
- onPlaceNodeInputChange();
3933
- }
3934
-
3935
- function placeNodeEx(button, coords) {
3936
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox");
3937
- for (var i in elements) {
3938
- if (elements[i].checked) {
3939
- var node = getNodeFromId(elements[i].id.substring(0, elements[i].id.length - 8));
3940
- if (node) {
3941
- var feature = xxmap.markersSource.getFeatureById(i);
3942
- var v = ol.proj.transform(coords, 'EPSG:3857', 'EPSG:4326');
3943
- var vx = [ v[1], v[0] ]; // Flip the coordinates around, lat/long
3944
- if (feature) {
3945
- feature.getGeometry().setCoordinates(coords);
3946
- var activeInteraction = getActiveInteractions(feature);
3947
- if (activeInteraction) {
3948
- saveMarkerloc(feature);
3949
- } else { // If this feature is not saved after its location is changed, then send updated coords to server.
3950
- meshserver.send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // Send them to server to save changes
3951
- }
3952
- } else {
3953
- meshserver.send({ action: 'changedevice', nodeid: node._id, userloc: vx }); // This Node is not yet added to maps.
3954
- }
3955
- }
3956
- }
3957
- }
3958
- }
3959
-
3960
- // Called when the user changes the search box
3961
- function onPlaceNodeInputChange() {
3962
- updatePlaceNodeTable(Q('selectnode-search').value.trim().toLowerCase());
3963
- }
3964
-
3965
- // Update the list of devices in the "place on map" table
3966
- function updatePlaceNodeTable(inputSearch) {
3967
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox"), count = 0;
3968
- for (var i in nodes) {
3969
- var visible = ((nodes[i].namel.indexOf(inputSearch) >= 0 || inputSearch == '') || (nodes[i].rnamel != null && nodes[i].rnamel.indexOf(inputSearch) >= 0));
3970
- if (visible) { count++; }
3971
- QV(nodes[i]._id + '-rowid', visible);
3972
- }
3973
- QV('noNodesMapPlace', count == 0);
3974
- /*
3975
- console.log(selected);
3976
- for (var i in nodes) {
3977
- if ((nodes[i].name.toLowerCase().indexOf(inputSearch) >= 0 || inputSearch == '') || (nodes[i].rnamel != null && nodes[i].rnamel.toLowerCase().indexOf(inputSearch) >= 0)) {
3978
- console.log(selected.indexOf(nodes[i]._id));
3979
- x += '<div class=noselect id=' + nodes[i]._id + '-rowid onclick=selectNodeToPlace(event,\''+ nodes[i]._id +'\') style=background-color:lightgray;margin-bottom:4px;border-radius:2px><input name=PlaceMapDeviceCheckbox id=' + nodes[i]._id + '-checkid type=checkbox style=width:16px;display:inline ' + ((selected.indexOf(nodes[i]._id) >= 0)?'checked':'') + ' />';
3980
- x += '<div class=j' + nodes[i].icon + ' style=width:16px;height:16px;margin-top:2px;margin-right:4px;display:inline-block></div><div style=width:16px;display:inline>' + nodes[i].name + '</div></div>';
3981
- }
3982
- }
3983
- if (x == '') { x = '<div style=text-align:center;width:100%>No devices found.</div>'; }
3984
- QH('placenode', '');
3985
- */
3986
- }
3987
-
3988
- // Called when a user clicks on a device to toggle selection for placement on map.
3989
- function selectNodeToPlace(e, id) {
3990
- // Toggle checkbox if needed
3991
- if (e.target.name != 'PlaceMapDeviceCheckbox') { var inputElement = Q(id + '-checkid'); inputElement.checked = !inputElement.checked; }
3992
-
3993
- // Check button state
3994
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox"), checkcount = 0;
3995
- for (var i in elements) { if (elements[i].checked) checkcount++; }
3996
- QE('idx_dlgOkButton', checkcount > 0);
3997
- }
3998
-
3999
- // Add option for available meshes in mesh Dropdown
4000
- function addMeshOptions(addMeshid, meshName) {
4001
- /*
4002
- var meshOptions = Q('select-mesh');
4003
- if (addMeshid && meshName) {
4004
- var option = document.createElement('option');
4005
- option.value =addMeshid;
4006
- option.text = meshName;
4007
- meshOptions.add(option); // Add specific option
4008
- }
4009
- else {
4010
- for (var i in meshes) { // Add all options
4011
- var option = document.createElement('option');
4012
- option.value = i;
4013
- option.text = meshes[i].name;
4014
- meshOptions.add(option);
4015
- }
4016
- }
4017
- */
4018
- }
4019
-
4020
- // Remove/Modify options in Mesh dropdown (if modMeshname is defined then Modify else Remove)
4021
- function meshOptionRmvMod(delMeshid, modMeshname){
4022
- /*
4023
- var meshOptions = Q('select-mesh');
4024
- if (delMeshid) {
4025
- var index=-1;
4026
- for (var i = 1; i < meshOptions.options.length; i++) {
4027
- if (meshOptions[i].value === delMeshid) { index=i; }
4028
- }
4029
- if (index > 0) {
4030
- if (modMeshname) {
4031
- meshOptions[index].innerHTML=modMeshname; // If Mesh name is Modified
4032
- }
4033
- else { meshOptions.remove(index); }
4034
- }
4035
- }
4036
- */
4037
- }
4038
-
4039
- //Check if there is any mesh created
4040
- function meshExists() {
4041
- for (var i in meshes) { if (meshes[i]) { return true; } }
4042
- return false;
4043
- }
4044
-
4045
- // Reset Mesh dropdown option to 'All' when a current view mesh is deleted.
4046
- function setMeshView(emeshid) {
4047
- var selectMeshElement=Q("select-mesh");
4048
- var selectedIndex = selectMeshElement.selectedIndex;
4049
- if (selectMeshElement[selectedIndex].value == emeshid) { selectMeshElement[0].selected = true; onSelectMeshChange(); }
4050
- }
4051
-
4052
- // Clear all mesh options except 'All'
4053
- function clearMeshOptions() {
4054
- /*
4055
- var meshOptions=Q('select-mesh');
4056
- for(var i = meshOptions.options.length - 1 ; i > 0 ; i--) { meshOptions.remove(i); }
4057
- */
4058
- }
4059
-
4060
- // Make a http get call- Replace this with AJAX get if jquery is used
4061
- function getSearchLocation() {
4062
- try {
4063
- var searchdata = Q('mapSearchLocation').value.trim();
4064
- if (searchdata.length > 0) {
4065
- var xmlhttp = new XMLHttpRequest(); // Compatible with Chrome, Opera, Safari, IE7+, Firefox.
4066
- xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { formatSearchData(xmlhttp.responseText); } }
4067
- xmlhttp.open("GET", 'https://nominatim.openstreetmap.org/search?q=' + searchdata + '&format=json', true); // Get request
4068
- xmlhttp.send();
4069
- }
4070
- } catch (e) {}
4071
- }
4072
-
4073
- // Format data recieved from nominatim API and display it on content window
4074
- function formatSearchData(data) {
4075
- try {
4076
- QH('xmapSearchResults','');
4077
- var dataInfo = JSON.parse(data), count = 0, x = '<div class="xmapItem">';
4078
- for (var i = 0; i < dataInfo.length; i++) {
4079
- if (dataInfo[i].display_name && dataInfo[i].boundingbox[0] && dataInfo[i].boundingbox[1] && dataInfo[i].boundingbox[2] && dataInfo[i].boundingbox[3]) {
4080
- count++;
4081
- var itemclass = (i % 2 == 0)?'xmapItemSel1':'xmapItemSel1';
4082
- x += '<div class="' + itemclass + '" onclick=mapGotoSelectedLocation(this)><div>' + dataInfo[i].display_name + '</div><div style=display:none>' + dataInfo[i].boundingbox[0] + '!#!' + dataInfo[i].boundingbox[1] + '!#!' + dataInfo[i].boundingbox[2] + '!#!' + dataInfo[i].boundingbox[3] + '</div></div>';
4083
- }
4084
- }
4085
- x += '</div>';
4086
- if (count == 1) {
4087
- // If only one result is returned then zoom to that location
4088
- var extent = [ parseFloat(dataInfo[0].boundingbox[2]), parseFloat(dataInfo[0].boundingbox[0]), parseFloat(dataInfo[0].boundingbox[3]), parseFloat(dataInfo[0].boundingbox[1]) ];
4089
- zoomToExtent(extent);
4090
- } else {
4091
- if (count == 0) { x = '<div style=width:200px>No location found.<div>'; }
4092
- QV('xmapSearchResultsDlg', true);
4093
- }
4094
- QH('xmapSearchResults', x);
4095
- }
4096
- catch (e) {}
4097
- }
4098
-
4099
- // Zoom into the bounding box
4100
- function mapGotoSelectedLocation(obj) {
4101
- var objchildren = obj.children;
4102
- var boundingBox = objchildren[1].innerHTML.split('!#!');
4103
- var extent = [parseFloat(boundingBox[2]), parseFloat(boundingBox[0]), parseFloat(boundingBox[3]), parseFloat(boundingBox[1])];
4104
- //Q('search-location').value = objchildren[0].innerHTML;
4105
- zoomToExtent(extent);
4106
- mapCloseSearchWindow();
4107
- }
4108
-
4109
- // Close the search window
4110
- function mapCloseSearchWindow() {
4111
- QH('xmapSearchResults', '');
4112
- QV('xmapSearchResultsDlg', false);
4113
- }
4114
-
4115
- // Zoom to specific cordinates
4116
- function zoomToLocation(coordinates, zoomVal) {
4117
- var view = xxmap.map.getView();
4118
- view.setCenter(coordinates);
4119
- view.setZoom(zoomVal);
4120
- }
4121
-
4122
- function zoomToFitExtent() {
4123
- var features = xxmap.markersSource.getFeatures();
4124
- if (features.length > 0) {
4125
- var extent = xxmap.markersSource.getExtent();
4126
- xxmap.map.getView().fit(extent, xxmap.map.getSize());
4127
- }
4128
- }
4129
-
4130
- function zoomToExtent(extent){
4131
- var boundingExtent = ol.proj.transformExtent(extent, ol.proj.get('EPSG:4326'), ol.proj.get('EPSG:3857'));
4132
- xxmap.map.getView().fit(boundingExtent, xxmap.map.getSize());
4133
- }
4134
-
4135
-
4136
- //
4137
- // MY DEVICE
4138
- //
4139
- function refreshDevice(nodeid) {
4140
- if (!currentNode || currentNode._id != nodeid) return;
4141
- gotoDevice(nodeid, xxcurrentView, true);
4142
- }
4143
-
4144
- function getNodeRights(nodeid) {
4145
- var node = getNodeFromId(nodeid), mesh = meshes[node.meshid];
4146
- return mesh.links[userinfo._id].rights;
4147
- }
4148
-
4149
- var currentNode;
4150
- var powerTimelineNode = null;
4151
- var powerTimelineReq = null;
4152
- var powerTimelineUpdate = null;
4153
- var powerTimeline = null;
4154
- function getCurrentNode() { return currentNode; };
4155
- function gotoDevice(nodeid, panel, refresh, event) {
4156
- // Remind the user to verify the email address
4157
- if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "Account Security", 1, null, "Unable to access a device until a email address is verified. This is required for password recovery. Go to the \"My Account\" tab to change and verify an email address."); return; }
4158
-
4159
- // Remind the user to add two factor authentication
4160
- if ((features & 0x00040000) && !((userinfo.otpsecret == 1) || (userinfo.otphkeys > 0) || (userinfo.otpkeys > 0))) { setDialogMode(2, "Account Security", 1, null, "Unable to access a device until two-factor authentication is enabled. This is required for extra security. Go to the \"My Account\" tab and look at the \"Account Security\" section."); return; }
4161
-
4162
- if (event && (event.shiftKey == true)) {
4163
- // Open the device in a different tab
4164
- window.open(window.location.origin + '?node=' + nodeid.split('/')[2] + '&viewmode=10&hide=16', 'meshcentral:' + nodeid);
4165
- return;
4166
- }
4167
-
4168
- //disconnectAllKvmFunction();
4169
- var node = getNodeFromId(nodeid);
4170
- var mesh = meshes[node.meshid];
4171
- var meshrights = mesh.links[userinfo._id].rights;
4172
- if (!currentNode || currentNode._id != node._id || refresh == true) {
4173
- currentNode = node;
4174
-
4175
- // Add node name
4176
- var nname = EscapeHtml(node.name);
4177
- if (nname.length == 0) { nname = '<i>None</i>'; }
4178
- if (((meshrights & 4) != 0) && ((!mesh.flags) || ((mesh.flags & 2) == 0))) { nname = '<span tabindex=0 title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) onkeyup="if (event.key == \'Enter\') showEditNodeValueDialog(0)" style=cursor:pointer>' + nname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
4179
- nname += '<span style=color:#AAA;font-size:small> - ' + EscapeHtml(mesh.name) + '</span>';
4180
- QH('p10deviceName', nname);
4181
- QH('p11deviceName', nname);
4182
- QH('p12deviceName', nname);
4183
- QH('p13deviceName', nname);
4184
- QH('p14deviceName', nname);
4185
- QH('p15deviceName', 'Console - ' + nname);
4186
- QH('p16deviceName', nname);
4187
- QH('p17deviceName', nname);
4188
- QH('p19deviceName', nname);
4189
-
4190
- // Node attributes
4191
- var x = '<table style=width:100%>';
4192
-
4193
- // Attribute: Mesh
4194
- x += addDeviceAttribute('<span title="The name of the device group this computer belong to.">Group</span>', '<a href=# title="The name of the device group this computer belong to" onclick=gotoMesh("' + node.meshid + '") style=cursor:pointer>' + EscapeHtml(meshes[node.meshid].name) + '</a>');
4195
-
4196
- // Attribute: Name
4197
- if ((node.rname != null) && (node.name != node.rname)) { x += addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>', '<span title="The name of this computer as set in the operating system">' + EscapeHtml(node.rname) + '</span>'); }
4198
-
4199
- // Attribute: Host
4200
- if ((features & 1) == 0) { // If not WAN-only, local hostname is in use
4201
- if ((meshrights & 4) != 0) {
4202
- if (node.host) {
4203
- x += addDeviceAttribute('Hostname', '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
4204
- } else {
4205
- x += addDeviceAttribute('Hostname', '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>None</i></span>');
4206
- }
4207
- } else {
4208
- x += addDeviceAttribute('Hostname', EscapeHtml(node.host));
4209
- }
4210
- }
4211
-
4212
- // Attribute: Description
4213
- var description = node.desc?EscapeHtml(node.desc):"<i>None</i>";
4214
- if ((meshrights & 4) != 0) {
4215
- x += addDeviceAttribute('Description', '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + ' <img class=hoverButton src="images/link5.png" /></span>');
4216
- } else {
4217
- x += addDeviceAttribute('Description', description);
4218
- }
4219
-
4220
- // Attribute: Mesh Agent
4221
- var agentsStr = ['Unknown', 'Windows 32bit console', 'Windows 64bit console', 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'MacOS 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'MacOS 64bit', 'ChromeOS', 'Linux Poky x86-64bit', 'Linux NoKVM x86-32bit', 'Linux NoKVM x86-64bit', 'Windows MinCore console', 'Windows MinCore service', 'NodeJS', 'ARM-Linaro', 'ARMv6l / ARMv7l', 'ARMv8 64bit', 'ARMv6l / ARMv7l / NoKVM', 'Unknown', 'Unknown', 'FreeBSD x86-64'];
4222
- if ((node.agent != null) && (node.agent.id != null) && (node.agent.ver != null)) {
4223
- var str = '';
4224
- if (node.agent.id <= agentsStr.length) { str = agentsStr[node.agent.id]; } else { str = agentsStr[0]; }
4225
- if (node.agent.ver != 0) { str += ' v' + node.agent.ver; }
4226
- x += addDeviceAttribute('Mesh Agent', str);
4227
- }
4228
-
4229
- // Attribute: Intel AMT
4230
- if (node.intelamt != null) {
4231
- var str = '';
4232
- var provisioningStates = { 0: 'Not Activated (Pre)', 1: 'Not Activated (In)', 2: 'Activated' };
4233
- if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>Unknown State</i>, v' + node.intelamt.ver; } else
4234
-
4235
- if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>Activated</i>'; }
4236
- else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>Unknown Version & State</i>'; }
4237
- else {
4238
- str += provisioningStates[node.intelamt.state];
4239
- if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { str += ' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'; } else if (node.intelamt.flags & 4) { str += ' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'; } }
4240
- str += (', v' + node.intelamt.ver);
4241
- }
4242
-
4243
- if (node.intelamt.tls == 1) { str += ', <span title="Intel AMT is setup with TLS network security">TLS</span>'; }
4244
- if (node.intelamt.state == 2) {
4245
- if (node.intelamt.user == null || node.intelamt.user == '') {
4246
- if ((meshrights & 4) != 0) {
4247
- str += ', <i style=color:#FF0000;cursor:pointer title="Edit Intel® AMT credentials" onclick=editDeviceAmtSettings("' + node._id + '")>No Credentials</i>';
4248
- } else {
4249
- str += ', <i style=color:#FF0000>No Credentials</i>';
4250
- }
4251
- }
4252
- str += ' ';
4253
- if ((meshrights & 4) != 0) {
4254
- str += '<img src=images/link4.png height=10 width=10 title="Edit Intel® AMT credentials" style=cursor:pointer onclick=editDeviceAmtSettings("' + node._id + '")>';
4255
- }
4256
- }
4257
-
4258
- var meName = '<span title="Intel® Manageability Engine">Intel® ME<span>';
4259
- if (typeof node.intelamt.sku == 'number') {
4260
- if ((node.intelamt.sku & 8) != 0) { meName = '<span title="Intel® Active Management Technology">Intel® AMT<span>'; }
4261
- else if ((node.intelamt.sku & 16) != 0) { meName = '<span title="Intel® Standard Manageability">Intel® SM<span>'; }
4262
- }
4263
- x += addDeviceAttribute(meName, str);
4264
- }
4265
-
4266
- if (mesh.mtype == 2) {
4267
- // Attribute: Mesh Agent Tag
4268
- if ((node.agent != null) && (node.agent.tag != null)) {
4269
- var tag = EscapeHtml(node.agent.tag);
4270
- if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
4271
- x += addDeviceAttribute('Agent Tag', tag);
4272
- }
4273
- } else {
4274
- // Attribute: Intel AMT Tag
4275
- if ((node.intelamt != null) && (node.intelamt.tag != null)) {
4276
- var tag = EscapeHtml(node.intelamt.tag);
4277
- if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
4278
- x += addDeviceAttribute('Intel® AMT Tag', tag);
4279
- }
4280
- }
4281
-
4282
- // Attribute: Intel AMT
4283
- //if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
4284
-
4285
- // Operating system description
4286
- if (node.osdesc) { x += addDeviceAttribute('Operating System', node.osdesc); }
4287
-
4288
- // Antivirus
4289
- if (node.av && node.av.length > 0) {
4290
- var y = [];
4291
- for (var i in node.av) {
4292
- if (node.av[i].product) {
4293
- var avx = EscapeHtml(node.av[i].product);
4294
- if (node.av[i].enabled !== true) { avx += ' - <span style=color:red>Disabled</span>'; }
4295
- if (node.av[i].updated !== true) { avx += ' - <span style=color:red>Out of date</span>'; }
4296
- if ((node.av[i].enabled == true) && (node.av[i].updated == true)) { avx += ' - <span style=color:green>OK</span>'; }
4297
- y.push(avx);
4298
- }
4299
- }
4300
- x += addDeviceAttribute('Antivirus', y.join('<br />'));
4301
- }
4302
-
4303
- // Active Users
4304
- if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute('Active User' + ((node.users.length > 1)?'s':''), node.users.join(', ')); }
4305
-
4306
- // Attribute: Connectivity (Only show this if more than just the agent is connected).
4307
- var connectivity = node.conn;
4308
- if (connectivity && connectivity > 1) {
4309
- var cstate = [];
4310
- if ((node.conn & 1) != 0) cstate.push('<span title="Mesh agent is connected and ready for use.">Mesh Agent</span>');
4311
- if ((node.conn & 2) != 0) cstate.push('<span title="Intel® AMT CIRA is connected and ready for use.">Intel® AMT CIRA</span>');
4312
- else if ((node.conn & 4) != 0) cstate.push('<span title="Intel® AMT is routable and ready for use.">Intel® AMT</span>');
4313
- if ((node.conn & 8) != 0) cstate.push('<span title="Mesh agent is reachable using another agent as relay.">Mesh Relay</span>');
4314
- if ((node.conn & 16) != 0) { cstate.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
4315
- x += addDeviceAttribute('Connectivity', cstate.join(', '));
4316
- }
4317
-
4318
- // Node grouping tags
4319
- var groupingTags = '<i>None</i>';
4320
- if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '<span class="tagSpan">' + node.tags[i] + '</span>'; } }
4321
- if ((meshrights & 4) != 0) {
4322
- x += addDeviceAttribute('Tags', '<span onclick=showEditNodeValueDialog(3) style=cursor:pointer>' + groupingTags + ' <img class=hoverButton src="images/link5.png" /></span>');
4323
- } else {
4324
- x += addDeviceAttribute('Tags', groupingTags);
4325
- }
4326
-
4327
- x += '</table><br />';
4328
- // Show action button, only show if we have permissions 4, 8, 64
4329
- if ((meshrights & 76) != 0) { x += '<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'; }
4330
- x += '<input type=button value=Notes title="View notes about this device" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponent(node._id) + '") />';
4331
- x += '<input type=button value="Log Event" title="Write an event for this device" onclick=writeDeviceEvent("' + encodeURIComponent(node._id) + '") />';
4332
- //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="Display a text message of the remote device" onclick=deviceToastFunction() />'; }
4333
- QH('p10html', x);
4334
-
4335
- // Show node last 7 days timeline
4336
- masterUpdate(256);
4337
-
4338
- // Show bottom buttons
4339
- x = '<div class="p10html3right">';
4340
- if ((meshrights & 4) != 0) {
4341
- // TODO: Show change group only if there is another mesh of the same type.
4342
- x += ' <a href=# onclick=p10showChangeGroupDialog(["' + node._id + '"]) title="Move this device to a different device group">Change Group</a>';
4343
- x += ' <a href=# onclick=p10showDeleteNodeDialog("' + node._id + '") title="Remove this device">Delete Device</a>';
4344
- }
4345
- x += '</div><div class="p10html3left">';
4346
- if (mesh.mtype == 2) x += '<a href=# onclick=p10showNodeNetInfoDialog("' + node._id + '") title="Show device network interface information">Interfaces</a> ';
4347
- if (xxmap != null) x += '<a href=# onclick=p10showNodeLocationDialog("' + node._id + '") title="Show device locations information">Location</a> ';
4348
- if (((meshrights & 8) != 0) && (mesh.mtype == 2)) x += '<a href=# onclick=p10showMeshCmdDialog(1,"' + node._id + '") title="Traffic router used to connect to a device thru this server.">Router</a> ';
4349
-
4350
- // RDP link, show this link only of the remote machine is Windows.
4351
- if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
4352
- if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# onclick=p10clickOnce("' + node._id + '","RDP2",3389) title="Requires Microsoft ClickOnce support in your browser.">RDP</a> '; }
4353
- if (node.agent.id > 4) {
4354
- x += '<a href=# onclick=p10clickOnce("' + node._id + '","PSSH",22) title="Requires Microsoft ClickOnce support in your browser.">Putty</a> ';
4355
- x += '<a href=# onclick=p10clickOnce("' + node._id + '","WSCP",22) title="Requires Microsoft ClickOnce support in your browser.">WinSCP</a> ';
4356
- }
4357
- }
4358
-
4359
- // MQTT options
4360
- if ((meshrights == 0xFFFFFFFF) && (features & 0x00400000)) { x += '<a href=# onclick=p10showMqttLoginDialog("' + node._id + '") title="Get MQTT login credentials for this device.">MQTT Login</a> '; }
4361
- x += '</div><br>'
4362
-
4363
- QH('p10html3', x);
4364
-
4365
- // Set the node power state
4366
- var powerstate = PowerStateStr(node.state);
4367
- //if (node.state == 0) { powerstate = 'Unknown State'; }
4368
- if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Agent connected">Agent connected</span>'; }
4369
- if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Intel® AMT connected">Intel® AMT connected</span>'; }
4370
- else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Intel® AMT detected">Intel® AMT detected</span>'; }
4371
- if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="MQTT connected">MQTT channel connected</span>'; }
4372
- if ((powerstate == '') && node.lastconnect) { powerstate = '<span style=font-size:12px>Last seen:<br />' + printDateTime(new Date(node.lastconnect)) + '</span>'; }
4373
- QH('MainComputerState', powerstate);
4374
-
4375
- // Set the node icon
4376
- Q('MainComputerImage').setAttribute("src", "images/icons256-" + node.icon + "-1.png");
4377
- Q('MainComputerImage').className = ((!node.conn) || (node.conn == 0)?'gray':'');
4378
-
4379
- // Check if we have terminal and file access
4380
- var terminalAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 512) == 0));
4381
- var fileAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0));
4382
- var amtAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 2048) == 0));
4383
-
4384
- // Setup/Refresh the desktop tab
4385
- if (terminalAccess) { setupTerminal(); }
4386
- if (fileAccess) { setupFiles(); }
4387
- var consoleRights = ((meshrights & 16) != 0);
4388
- if (consoleRights) { setupConsole(); } else { if (panel == 15) { panel = 10; } }
4389
-
4390
- // Show or hide the tabs
4391
- // mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent
4392
- // node.agent.caps (bitmask): 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console
4393
- QV('MainDevDesktop', (((mesh.mtype == 1) && ((typeof node.intelamt.sku !== 'number') || ((node.intelamt.sku & 8) != 0)))
4394
- || ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2)))))
4395
- && ((meshrights & 8) || (meshrights & 256))
4396
- );
4397
- QV('MainDevTerminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8) && terminalAccess);
4398
- QV('MainDevFiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8) && fileAccess);
4399
- QV('MainDevAmt', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8) && amtAccess);
4400
- QV('MainDevConsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (meshrights & 8));
4401
- QV('MainDevPlugins', pluginHandler != null);
4402
- QV('p15uploadCore', (node.agent != null) && (node.agent.caps != null) && ((node.agent.caps & 16) != 0));
4403
- QH('p15coreName', ((node.agent != null) && (node.agent.core != null))?node.agent.core:'');
4404
-
4405
- // Setup/Refresh Intel AMT tab
4406
- var amtFrameNode = Q('p14iframe').contentWindow.getCurrentMeshNode();
4407
- if ((amtFrameNode != null) && (amtFrameNode._id != currentNode._id)) { Q('p14iframe').contentWindow.disconnect(); }
4408
- var online = ((node.conn & 6) != 0)?true:false; // If CIRA (2) or AMT (4) connected, enable Commander
4409
- Q('p14iframe').contentWindow.setConnectionState(online);
4410
- Q('p14iframe').contentWindow.setFrameHeight('650px');
4411
- Q('p14iframe').contentWindow.setAuthCallback(updateAmtCredentials);
4412
-
4413
- // Display "action" button on desktop/terminal/files
4414
- QV('deskActionsBtn', (meshrights & 72) != 0); // 72 = Wake-up + Remote Control permissions
4415
- QV('termActionsBtn', (meshrights & 72) != 0);
4416
- QV('filesActionsBtn', (meshrights & 72) != 0);
4417
-
4418
- // Request the power timeline
4419
- if ((powerTimelineNode != currentNode._id) && (powerTimelineReq != currentNode._id)) {
4420
- QH('p10html2', '');
4421
- powerTimelineReq = currentNode._id;
4422
- meshserver.send({ action: 'powertimeline', nodeid: currentNode._id });
4423
- meshserver.send({ action: 'lastconnect', nodeid: currentNode._id });
4424
- meshserver.send({ action: 'getsysinfo', nodeid: currentNode._id });
4425
- QH('p17info', '');
4426
- }
4427
-
4428
- // Reset the desktop tools
4429
- QV('DeskTools', false);
4430
- showDeskToolsProcesses();
4431
-
4432
- // Ask for device events
4433
- refreshDeviceEvents();
4434
-
4435
- // Update the web page title
4436
- if ((currentNode) && (xxcurrentView >= 10) && (xxcurrentView < 20)) {
4437
- document.title = decodeURIComponent("{{{extitle}}}") + ' - ' + currentNode.name + ' - ' + mesh.name;
4438
- } else {
4439
- document.title = decodeURIComponent("{{{extitle}}}");
4440
- }
4441
-
4442
- // Clear user consent status if present
4443
- p11clearConsoleMsg();
4444
- p12clearConsoleMsg();
4445
- p13clearConsoleMsg();
4446
-
4447
- // Device refresh plugin handler
4448
- if (pluginHandler != null) { pluginHandler.onDeviceRefeshEnd(nodeid, panel, refresh, event); }
4449
- }
4450
- setupDesktop(); // Always refresh the desktop, even if we are on the same device, we need to do some canvas switching.
4451
- if (!panel) panel = 10;
4452
- go(panel);
4453
- }
4454
-
4455
- function writeDeviceEvent(nodeid) {
4456
- if (xxdialogMode) return;
4457
- setDialogMode(2, "Add Device Event", 3, writeDeviceEventEx, '<textarea id=d2devEvent style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>This will add an entry to this device\'s event log.<span>', nodeid);
4458
- }
4459
-
4460
- function writeDeviceEventEx(buttons, tag) { meshserver.send({ action: 'setDeviceEvent', nodeid: decodeURIComponent(tag), msg: encodeURIComponent(Q('d2devEvent').value) }); }
4461
-
4462
- function showNotes(readonly, noteid) {
4463
- if (xxdialogMode) return;
4464
- setDialogMode(2, "Notes", 2, showNotesEx, '<textarea id=d2devNotes ro=' + readonly + ' noteid=' + noteid + ' readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>Device group notes can be viewed and changed by other device group administrators.<span>', noteid);
4465
- meshserver.send({ action: 'getNotes', id: decodeURIComponent(noteid) });
4466
- }
4467
-
4468
- function showNotesEx(buttons, tag) { meshserver.send({ action: 'setNotes', id: decodeURIComponent(tag), notes: encodeURIComponent(Q('d2devNotes').value) }); }
4469
-
4470
- function deviceChat() {
4471
- if (xxdialogMode) return;
4472
- var url = '/messenger?id=meshmessenger/' + encodeURIComponent(currentNode._id) + '/' + encodeURIComponent(userinfo._id) + '&title=' + currentNode.name;
4473
- if ((authCookie != null) && (authCookie != '')) { url += '&auth=' + authCookie; }
4474
- window.open(url, 'meshmessenger:' + currentNode._id);
4475
- meshserver.send({ action: 'meshmessenger', nodeid: decodeURIComponent(currentNode._id) });
4476
- }
4477
-
4478
- function deviceUrlFunction() {
4479
- if (xxdialogMode) return;
4480
- setDialogMode(2, "Open Page on Device", 3, deviceUrlFunctionEx, '<input id=d2devurl placeholder="http://server.com" style=width:100%;overflow-y:scroll></input>');
4481
- Q('d2devurl').focus();
4482
- }
4483
-
4484
- function deviceUrlFunctionEx() {
4485
- meshserver.send({ action: 'msg', type: 'openUrl', nodeid: currentNode._id, url: Q('d2devurl').value });
4486
- }
4487
-
4488
- function deviceToastFunction() {
4489
- if (xxdialogMode) return;
4490
- setDialogMode(2, "Device Notification", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
4491
- Q('d2devToast').focus();
4492
- }
4493
-
4494
- function deviceToastFunctionEx() {
4495
- meshserver.send({ action: 'toast', nodeids: [ currentNode._id ], title: 'MeshCentral', msg: Q('d2devToast').value });
4496
- }
4497
-
4498
- function deviceActionFunction() {
4499
- if (xxdialogMode) return;
4500
- var meshrights = meshes[currentNode.meshid].links[userinfo._id].rights;
4501
- var x = "Select an operation to perform on this device.<br /><br />";
4502
- var y = '<select id=d2deviceop style=float:right;width:250px>';
4503
- if ((meshrights & 64) != 0) { y += '<option value=100>Wake-up</option>'; } // Wake-up permission
4504
- if ((meshrights & 8) != 0) { y += '<option value=4>Sleep</option><option value=3>Reset</option><option value=2>Power off</option>'; } // Remote control permission
4505
- if ((currentNode.conn & 16) != 0) { y += '<option value=103>Send MQTT Message</option>'; }
4506
- y += '</select>';
4507
- x += addHtmlValue('Operation', y);
4508
- setDialogMode(2, "Device Action", 3, deviceActionFunctionEx, x);
4509
- }
4510
-
4511
- function deviceActionFunctionEx() {
4512
- var op = Q('d2deviceop').value;
4513
- if (op == 100) {
4514
- // Device wake
4515
- meshserver.send({ action: 'wakedevices', nodeids: [currentNode._id] });
4516
- } else if (op == 103) {
4517
- // Send MQTT Message
4518
- p10showSendMqttMsgDialog([currentNode._id]);
4519
- } else {
4520
- // Power operation
4521
- meshserver.send({ action: 'poweraction', nodeids: [ currentNode._id ], actiontype: parseInt(op) });
4522
- }
4523
- }
4524
-
4525
- // Called when MeshCommander needs new credentials or updated credentials.
4526
- function updateAmtCredentials(forceDialog) {
4527
- var node = getNodeFromId(currentNode._id);
4528
- if ((forceDialog == true) || (node.intelamt.user == null) || (node.intelamt.user == '')) {
4529
- editDeviceAmtSettings(currentNode._id, updateAmtCredentialsEx);
4530
- } else {
4531
- Q('p14iframe').contentWindow.connectButtonfunctionEx();
4532
- }
4533
- }
4534
-
4535
- function updateAmtCredentialsEx(button, tag) {
4536
- Q('p14iframe').contentWindow.connectButtonfunctionEx();
4537
- }
4538
-
4539
- // Look to see if we need to update the device timeline
4540
- function updateDeviceTimeline() {
4541
- if ((meshserver.State != 2) || (powerTimelineNode == null) || (powerTimelineUpdate == null) || (currentNode == null)) return;
4542
- if ((powerTimelineNode == powerTimelineReq) && (currentNode._id == powerTimelineNode) && (powerTimelineUpdate < Date.now())) {
4543
- powerTimelineUpdate = null;
4544
- meshserver.send({ action: 'powertimeline', nodeid: currentNode._id });
4545
- meshserver.send({ action: 'lastconnect', nodeid: currentNode._id });
4546
- }
4547
- }
4548
-
4549
- // Draw device power bars. The bars are 766px wide.
4550
- function drawDeviceTimeline() {
4551
- if ((currentNode == null) || (xxcurrentView < 10) || (xxcurrentView > 19)) return;
4552
- var timeline = null, now = Date.now();
4553
- if (currentNode._id == powerTimelineNode) { timeline = powerTimeline; }
4554
-
4555
- // Calculate when the timeline starts
4556
- var d = new Date();
4557
- d.setHours(0, 0, 0, 0);
4558
- d = new Date(d.getTime() - (1000 * 60 * 60 * 24 * 6));
4559
- var timelineStart = d.getTime();
4560
-
4561
- // De-compact the timeline
4562
- var timeline2 = [];
4563
- if (timeline != null && timeline.length > 1) {
4564
- timeline2.push([ 0, timeline[1], timeline[0] ]); // Start, End, Power
4565
- var ct = timeline[1];
4566
- for (var i = 2; i < timeline.length; i += 2) {
4567
- var power = timeline[i], dt = now;
4568
- if (timeline.length > (i + 1)) { dt = timeline[i + 1]; }
4569
- timeline2.push([ ct, ct + dt, power ]); // Start, End, Power
4570
- ct = ct + dt;
4571
- }
4572
- }
4573
-
4574
- // Draw the timeline
4575
- var x = '', count = 1, date = new Date();
4576
- var totalWidth = Q('masthead').offsetWidth - (160 + 9 + 9 + 14); // Compute the total width of the power bar
4577
- date.setHours(0, 0, 0, 0);
4578
- for (var i = 0; i < 7; i++) {
4579
- var datavalue = '', start = date.getTime(), end = start + (1000 * 60 * 60 * 24);
4580
- for (var j in timeline2) {
4581
- var block = timeline2[j];
4582
- if (isTimeBlockInside(start, end, block[0], block[1]) == true) {
4583
- var ts = Math.max(start, block[0]);
4584
- var te = Math.min(Math.min(end, block[1]), now);
4585
- var width = Math.round(((te - ts) * totalWidth) / 86400000);
4586
- if (width > 0) {
4587
- var title = powerStateStrings2[block[2]] + ' from ' + printTime(new Date(ts)) + ' to ' + printTime(new Date(te)) + '.';
4588
- datavalue += '<div class="pwState ' + powerColor(block[2]) + '" title="' + title + '" style="width:' + width + 'px;"></div>';
4589
- }
4590
- }
4591
- }
4592
- x += '<tr class=' + (((count % 2) == 0)?'altBack':'') + '><td><div> ' + printDate(date) + '<div></div></div></td><td><div>' + datavalue + '</div></td></tr>';
4593
- ++count;
4594
- date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day
4595
- }
4596
- QH('p10html2', '<table cellpadding=2 cellspacing=0><thead><tr style=><th scope=col style=text-align:center;width:150px>Day</th><th scope=col style=text-align:center><a download href="devicepowerevents.ashx?id=' + currentNode._id + '" onclick="setDialogMode(0)"><img title="Download power events" src="images/link4.png" /></a>7 Day Power State</th></tr></thead><tbody>' + x + '</tbody></table>');
4597
- }
4598
-
4599
- // Return a color for the given power state
4600
- function powerColor(x) { if (x < powerColorTable.length) { return powerColorTable[x]; } return 'pwsYellow'; }
4601
-
4602
- // Return true if the time block is visible within the start/end period
4603
- function isTimeBlockInside(start, end, blockStart, blockEnd) {
4604
- if ((blockStart < start) && (blockEnd > end)) return true; // Block is wider than timespan
4605
- if ((blockStart > start) && (blockStart < end)) return true;
4606
- if ((blockEnd > start) && (blockEnd < end)) return true;
4607
- return false;
4608
- }
4609
-
4610
- function addDeviceAttribute(name, value) { return '<tr><td class=style7>' + name + '</td><td class=style9>' + value + '</td></tr>'; }
4611
-
4612
- function editDeviceAmtSettings(nodeid, func, arg) {
4613
- if (xxdialogMode) return;
4614
- var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = getNodeRights(nodeid);
4615
- if ((meshrights & 4) == 0) return;
4616
- x += addHtmlValue('Username', '<input id=dp10username style=width:230px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
4617
- x += addHtmlValue('Password', '<input id=dp10password type=password style=width:230px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
4618
- x += addHtmlValue('Security', '<select id=dp10tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>');
4619
- if ((node.intelamt.user != null) && (node.intelamt.user != '')) { buttons = 7; }
4620
- setDialogMode(2, "Edit Intel® AMT credentials", buttons, editDeviceAmtSettingsEx, x, { node: node, func: func, arg: arg });
4621
- if ((node.intelamt.user != null) && (node.intelamt.user != '')) { Q('dp10username').value = node.intelamt.user; } else { Q('dp10username').value = 'admin'; }
4622
- Q('dp10tls').value = node.intelamt.tls;
4623
- validateDeviceAmtSettings();
4624
- }
4625
-
4626
- function validateDeviceAmtSettings() {
4627
- QE('idx_dlgOkButton', passwordcheck(Q('dp10password').value));
4628
- }
4629
-
4630
- function editDeviceAmtSettingsEx(button, tag) {
4631
- if (button == 2) {
4632
- // Delete button pressed, remove credentials
4633
- meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: '', pass: '' } });
4634
- } else {
4635
- // Change Intel AMT credentials
4636
- var amtuser = Q('dp10username').value;
4637
- if (amtuser == '') amtuser = 'admin';
4638
- var amtpass = Q('dp10password').value;
4639
- if (amtpass == '') amtuser = '';
4640
- meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: amtuser, pass: amtpass, tls: Q('dp10tls').value } });
4641
- tag.node.intelamt.user = amtuser;
4642
- tag.node.intelamt.tls = Q('dp10tls').value;
4643
- if (tag.func) { setTimeout(function () { tag.func(null, tag.arg); }, 300); }
4644
- }
4645
- }
4646
-
4647
- function p10showSendMqttMsgDialog(nodeids) {
4648
- if (xxdialogMode) return false;
4649
- var x = addHtmlValue('Topic', '<input id=dp2topic style=width:230px maxlength=64 onchange=p10validateSendMqttMsgDialog() onkeyup=p10validateSendMqttMsgDialog(event,1) />');
4650
- x += addHtmlValue('Message', '<div style=width:230px;margin:0;padding:0><textarea id=dp2msg maxlength=4096 style=width:100%;height:150px;resize:none onchange=p10validateSendMqttMsgDialog() onkeyup=p10validateSendMqttMsgDialog(event,1)></textarea></div>');
4651
- setDialogMode(2, "Send MQTT message", 3, p10showSendMqttMsgDialogEx, x, nodeids);
4652
- p10validateSendMqttMsgDialog();
4653
- Q('dp2topic').focus();
4654
- return false;
4655
- }
4656
-
4657
- function p10validateSendMqttMsgDialog() {
4658
- QE('idx_dlgOkButton', (Q('dp2topic').value.length > 0) && (Q('dp2msg').value.length > 0));
4659
- }
4660
-
4661
- function p10showSendMqttMsgDialogEx(b, nodeids) {
4662
- meshserver.send({ action: 'sendmqttmsg', nodeids: nodeids, topic: Q('dp2topic').value, msg: Q('dp2msg').value });
4663
- }
4664
-
4665
- function p10showChangeGroupDialog(nodeids) {
4666
- if (xxdialogMode) return false;
4667
- var targetMeshId = null;
4668
- if (nodeids.length == 1) { try { targetMeshId = meshes[getNodeFromId(nodeids[0])]._id; } catch (ex) { } }
4669
-
4670
- // List all available alternative groups
4671
- var y = "<select id=p10newGroup style=width:236px>", count = 0;
4672
- for (var i in meshes) {
4673
- var meshrights = meshes[i].links[userinfo._id].rights;
4674
- if ((meshes[i]._id != targetMeshId) && (meshrights & 4)) { count++; y += "<option value='" + meshes[i]._id + "'>" + meshes[i].name + "</option>"; }
4675
- }
4676
- y += "</select>";
4677
-
4678
- if (count > 0) {
4679
- var x = (nodeids.length == 1) ? "Select a new group for this device<br /><br />" : "Select a new group for selected devices<br /><br />";
4680
- x += addHtmlValue('New Device Group', y);
4681
- setDialogMode(2, "Change Group", 3, p10showChangeGroupDialogEx, x, nodeids);
4682
- } else {
4683
- setDialogMode(2, "Change Group", 1, null, "No other device group of same type exists.");
4684
- }
4685
- return false;
4686
- }
4687
-
4688
- function p10showChangeGroupDialogEx(b, nodeids) {
4689
- meshserver.send({ action: 'changeDeviceMesh', nodeids: nodeids, meshid: Q('p10newGroup').value });
4690
- }
4691
-
4692
- function p10showDeleteNodeDialog(nodeid) {
4693
- if (xxdialogMode) return false;
4694
- var x = "Are you sure you want to delete node \"" + EscapeHtml(currentNode.name) + "\"?<br /><br />";
4695
- x += "<label><input id=p10check type=checkbox onchange=p10validateDeleteNodeDialog() />Confirm</label>";
4696
- setDialogMode(2, "Delete Node", 3, p10showDeleteNodeDialogEx, x, nodeid);
4697
- p10validateDeleteNodeDialog();
4698
- return false;
4699
- }
4700
-
4701
- function p10validateDeleteNodeDialog() {
4702
- QE('idx_dlgOkButton', Q('p10check').checked);
4703
- }
4704
-
4705
- function p10showDeleteNodeDialogEx(buttons, nodeid) {
4706
- meshserver.send({ action: 'removedevices', nodeids: [ nodeid ] });
4707
- }
4708
-
4709
- function p10clickOnce(nodeid, protocol, port) {
4710
- meshserver.send({ action: 'getcookie', nodeid: nodeid, tcpport: port, tag: 'clickonce', protocol: protocol });
4711
- return false;
4712
- }
4713
-
4714
- // Show current location
4715
- var d2map = null;
4716
- function p10showNodeLocationDialog() {
4717
- if ((xxdialogMode != null) && (xxdialogTag == '@xxmap')) { setDialogMode(0); } else { if (xxdialogMode) return false; }
4718
- var markers = [], types = ['iploc', 'wifiloc', 'gpsloc', 'userloc'], boundingBox = null;
4719
-
4720
- for (var loctype in types) {
4721
- if (currentNode[types[loctype]] != null) {
4722
- var loc = currentNode[types[loctype]].split(','), lat = parseFloat(loc[0]), lon = parseFloat(loc[1]);
4723
- if ((lat < 90) && (lat > -90) && (lon < 180) && (lon > -180)) { // Check valid lat/lon
4724
- var deviceMark = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat])) });
4725
- deviceMark.setStyle(markerStyle(currentNode, parseInt(loctype) + 1));
4726
- markers.push(deviceMark);
4727
-
4728
- if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } }
4729
- }
4730
- }
4731
- }
4732
-
4733
- // Setup the device mark layer
4734
- var vectorSource = new ol.source.Vector({ features: markers });
4735
- var vectorLayer = new ol.layer.Vector({ source: vectorSource });
4736
-
4737
- //var x = '<div><a href="https://www.google.com/maps/preview/@' + lat + ',' + lng + ',12z" rel="noreferrer noopener" target=_blank>Open in Google maps</a></div>';
4738
- var x = '<div id=d2map style=width:100%;height:300px></div>';
4739
- setDialogMode(2, "Device Location", 1, null, x, '@xxmap');
4740
-
4741
- var clng = 0, clat = 0, zoom = 8;
4742
- if (boundingBox != null) {
4743
- var clat = (boundingBox[0] + boundingBox[2]) / 2;
4744
- var clng = (boundingBox[1] + boundingBox[3]) / 2;
4745
- var cscale = Math.max(Math.abs(boundingBox[0] - boundingBox[2]), Math.abs(boundingBox[1] - boundingBox[3]));
4746
- var i = 360, zoom = -2;
4747
- while (i > cscale) { zoom++; i = i / 2; }
4748
- }
4749
-
4750
- if (markers.length == 1) { zoom = 8; }
4751
-
4752
- // Setup the map
4753
- d2map = new ol.Map({
4754
- target: 'd2map',
4755
- interactions: ol.interaction.defaults({dragPan:false, mouseWheelZoom:false}),
4756
- layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer ],
4757
- view: new ol.View({ center: ol.proj.fromLonLat([clng, clat]), zoom: zoom })
4758
- });
4759
- return false;
4760
- }
4761
-
4762
- // Show network interfaces
4763
- function p10showNodeNetInfoDialog() {
4764
- if (xxdialogMode) return false;
4765
- setDialogMode(2, "Network Interfaces", 1, null, "<div id=d2netinfo>Loading...</div>", 'if' + currentNode._id );
4766
- meshserver.send({ action: 'getnetworkinfo', nodeid: currentNode._id });
4767
- return false;
4768
- }
4769
-
4770
- // Show MeshCentral Router dialog
4771
- function p10showMeshRouterDialog() {
4772
- if (xxdialogMode) return;
4773
- var x = "<div>MeshCentral Router is a Windows tool for TCP port mapping. You can, for example, RDP into a remote device thru this server.</div><br />";
4774
- x += addHtmlValue('Win32 Executable', '<a style=cursor:pointer download href="meshagents?meshaction=winrouter" onclick="setDialogMode(0)">MeshCentralRouter.exe</a>');
4775
- setDialogMode(2, "MeshCentral Router", 1, null, x, "fileDownload");
4776
- }
4777
-
4778
- // Request MQTT login credentials
4779
- function p10showMqttLoginDialog(nodeid) { meshserver.send({ action: 'getmqttlogin', nodeid: nodeid }); }
4780
-
4781
- // Show MeshCmd dialog
4782
- function p10showMeshCmdDialog(mode, nodeid) {
4783
- if (xxdialogMode) return;
4784
- var y = "<select id=aginsSelect onclick=meshCmdOsClick() style=width:236px>";
4785
- y += "<option value=3>Windows (32bit)</option>";
4786
- y += "<option value=4>Windows (64bit)</option>";
4787
- y += "<option value=5>Linux x86 (32bit)</option>";
4788
- y += "<option value=6>Linux x86 (64bit)</option>";
4789
- y += "<option value=16>MacOS (64bit)</option>";
4790
- y += "<option value=25>Linux ARM, Raspberry Pi (32bit)</option>";
4791
- y += "</select>";
4792
-
4793
- var x = "";
4794
- if (mode == 0) { x += '<div>MeshCmd is a command line tool that performs lots of different operations. The action file can optionally be downloaded and edited to provide server information and credentials.<br /><br />'; }
4795
- if (mode == 1) { x += '<div>Download "meshcmd" with an action file to route traffic thru this server to this device. Make sure to edit meshaction.txt and add your account password or make any changes needed.<br /><br />'; }
4796
- x += addHtmlValue('Operating System', y);
4797
- x += addHtmlValue('MeshCmd', '<a id=meshcmddownloadid href="meshagents?meshcmd=3" download></a>');
4798
- if (mode == 0) { x += addHtmlValue('Action File', '<a href="meshagents?meshaction=generic" download>MeshAction (.txt)</a>'); }
4799
- if (mode == 1) { x += addHtmlValue('Action File', '<a href="meshagents?meshaction=route&nodeid=' + nodeid + '" download>MeshAction (.txt)</a>'); }
4800
- x += "</div>";
4801
- setDialogMode(2, ["Download MeshCmd","Network Router"][mode], 9, null, x, "fileDownload");
4802
- meshCmdOsClick();
4803
- }
4804
-
4805
- function meshCmdOsClick() {
4806
- var os = Q('aginsSelect').value, osn = '', osurl = '';
4807
- //Q('meshcmddownloadid').href = "meshagents?meshcmd=" + os;
4808
- if (os == 3) { osn = 'MeshCmd (Win32 executable)'; }
4809
- if (os == 4) { osn = 'MeshCmd (Win64 executable)'; }
4810
- if (os == 5) { osn = 'MeshCmd (Linux x86, 32bit)'; }
4811
- if (os == 6) { osn = 'MeshCmd (Linux x86, 64bit)'; }
4812
- if (os == 16) { osn = 'MeshCmd (MacOS, 64bit)'; }
4813
- if (os == 25) { osn = 'MeshCmd (Linux ARM, 32bit)'; }
4814
- QH('meshcmddownloadid', osn);
4815
- Q('meshcmddownloadid').setAttribute('href', 'meshagents?meshcmd=' + os);
4816
- }
4817
-
4818
- function p10showiconselector() {
4819
- if (xxdialogMode) return;
4820
- var mesh = meshes[currentNode.meshid];
4821
- var meshrights = mesh.links[userinfo._id].rights;
4822
- if ((meshrights & 4) == 0) return;
4823
-
4824
- var x = '<br><div style=display:inline-block;width:40px></div>';
4825
- x += '<div tabindex=0 style=display:inline-block class=i1 onclick=p10setIcon(1) onkeypress="if (event.key==\'Enter\') p10setIcon(1)"></div>';
4826
- x += '<div tabindex=0 style=display:inline-block class=i2 onclick=p10setIcon(2) onkeypress="if (event.key==\'Enter\') p10setIcon(2)"></div>';
4827
- x += '<div tabindex=0 style=display:inline-block class=i3 onclick=p10setIcon(3) onkeypress="if (event.key==\'Enter\') p10setIcon(3)"></div>';
4828
- x += '<div tabindex=0 style=display:inline-block class=i4 onclick=p10setIcon(4) onkeypress="if (event.key==\'Enter\') p10setIcon(4)"></div>';
4829
- x += '<div tabindex=0 style=display:inline-block class=i5 onclick=p10setIcon(5) onkeypress="if (event.key==\'Enter\') p10setIcon(5)"></div>';
4830
- x += '<div tabindex=0 style=display:inline-block class=i6 onclick=p10setIcon(6) onkeypress="if (event.key==\'Enter\') p10setIcon(6)"></div><br><br>';
4831
- setDialogMode(2, "Icon Selection", 0, null, x);
4832
- QV('id_dialogclose', true);
4833
- }
4834
-
4835
- function p10setIcon(icon) {
4836
- setDialogMode(0);
4837
- meshserver.send({ action: 'changedevice', nodeid: currentNode._id, icon: icon });
4838
- }
4839
-
4840
- var showEditNodeValueDialog_modes = ['Device Name', 'Hostname', 'Description', 'Tags'];
4841
- var showEditNodeValueDialog_modes2 = ['name', 'host', 'desc', 'tags'];
4842
- var showEditNodeValueDialog_modes3 = ['', '', '', 'Tag1, Tag2, Tag3'];
4843
- function showEditNodeValueDialog(mode) {
4844
- if (xxdialogMode) return;
4845
- var x = addHtmlValue(showEditNodeValueDialog_modes[mode], '<input id=dp10devicevalue maxlength=64 placeholder="' + showEditNodeValueDialog_modes3[mode] + '" onchange=p10editdevicevalueValidate(' + mode + ',event) onkeyup=p10editdevicevalueValidate(' + mode + ',event) />');
4846
- setDialogMode(2, "Edit Device", 3, showEditNodeValueDialogEx, x, mode);
4847
- var v = currentNode[showEditNodeValueDialog_modes2[mode]];
4848
- if (v == null) v = '';
4849
- if (Array.isArray(v)) { v = v.join(', '); }
4850
- Q('dp10devicevalue').value = v;
4851
- p10editdevicevalueValidate();
4852
- Q('dp10devicevalue').focus();
4853
- }
4854
-
4855
- function showEditNodeValueDialogEx(button, mode) {
4856
- var x = { action: 'changedevice', nodeid: currentNode._id };
4857
- x[showEditNodeValueDialog_modes2[mode]] = Q('dp10devicevalue').value;
4858
- meshserver.send(x);
4859
- }
4860
-
4861
- function p10editdevicevalueValidate(mode, e) {
4862
- var x = ((mode > 1) || (Q('dp10devicevalue').value.length > 0));
4863
- QE('idx_dlgOkButton', x);
4864
- if ((e != null) && (x == true) && (e.keyCode == 13)) { dialogclose(1); }
4865
- }
4866
-
4867
- //
4868
- // DESKTOP
4869
- //
4870
-
4871
- var desktopNode;
4872
- function setupDesktop() {
4873
- // Setup the remote desktop
4874
- if ((desktopNode != currentNode) && (desktop != null)) { desktop.Stop(); desktopNode = null; desktop = null; }
4875
-
4876
- // If the device desktop is already connected in multi-desktop, use that.
4877
- if ((desktopNode != currentNode) || (desktop == null)) {
4878
- var xdesk = multiDesktop[currentNode._id];
4879
- if (xdesk != null) {
4880
- // This device already has a canvas, use it.
4881
- QH('DeskParent', '');
4882
- var c = xdesk.m.CanvasId;
4883
- c.setAttribute('id', 'Desk');
4884
- c.setAttribute('onmousedown', 'dmousedown(event)');
4885
- c.setAttribute('onmouseup', 'dmouseup(event)');
4886
- c.setAttribute('onmousemove', 'dmousemove(event)');
4887
- c.removeAttribute('onclick');
4888
- Q('DeskParent').appendChild(c);
4889
- desktop = xdesk;
4890
- if (desktop.m.SendCompressionLevel) { desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); }
4891
- desktop.onStateChanged = onDesktopStateChange;
4892
- desktopNode = currentNode;
4893
- onDesktopStateChange(desktop, desktop.State);
4894
- delete multiDesktop[currentNode._id];
4895
- } else {
4896
- // Device is not already connected, just setup a blank canvas
4897
- QH('DeskParent', '<canvas id=Desk oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
4898
- desktopNode = currentNode;
4899
- }
4900
- // Setup the mouse wheel
4901
- Q('Desk').addEventListener('DOMMouseScroll', function (e) { return dmousewheel(e); });
4902
- Q('Desk').addEventListener('mousewheel', function (e) { return dmousewheel(e); });
4903
- }
4904
- desktopNode = currentNode;
4905
- updateDesktopButtons();
4906
- deskAdjust();
4907
-
4908
- // On some browsers like IE, we can't save screen shots. Hide the scheenshot/capture buttons.
4909
- if (!Q('Desk')['toBlob']) { QV('deskSaveBtn', false); }
4910
- }
4911
-
4912
- // Show and enable the right buttons
4913
- function updateDesktopButtons() {
4914
- var mesh = meshes[currentNode.meshid];
4915
- var deskState = 0;
4916
- if (desktop != null) { deskState = desktop.State; }
4917
- var meshrights = mesh.links[userinfo._id].rights;
4918
-
4919
- // Show the right buttons
4920
- QV('disconnectbutton1span', (deskState != 0));
4921
- QV('connectbutton1span', (deskState == 0) && ((meshrights & 8) || (meshrights & 256)) && (mesh.mtype == 2) && (currentNode.agent.caps & 1));
4922
- QV('connectbutton1hspan',
4923
- (deskState == 0) &&
4924
- (meshrights & 8) &&
4925
- ((mesh.mtype == 1) ||
4926
- ((currentNode.intelamt != null) &&
4927
- (currentNode.intelamt.state == 2) &&
4928
- (currentNode.intelamt.ver != null) &&
4929
- (typeof currentNode.intelamt.sku == 'number') &&
4930
- ((currentNode.intelamt.sku & 8) != 0))
4931
- )
4932
- );
4933
-
4934
- // Show the right settings
4935
- QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
4936
- QV('d7meshkvm', (webRtcDesktop) || ((mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1))));
4937
-
4938
- // Enable buttons
4939
- var inputAllowed = (meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) == 0));
4940
- var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
4941
- QE('connectbutton1', online);
4942
- var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
4943
- QE('connectbutton1h', hwonline);
4944
- QE('deskSaveBtn', deskState == 3);
4945
- QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus));
4946
- QV('DeskClip', (currentNode.agent) && (currentNode.agent.id != 11) && (currentNode.agent.id != 16) && ((desktop == null) || (desktop.contype != 2))); // Clipboard not supported on MacOS
4947
- QE('DeskClip', deskState == 3);
4948
- QE('DeskType', deskState == 3);
4949
- QV('DeskWD', inputAllowed);
4950
- QE('DeskWD', deskState == 3);
4951
- QV('deskkeys', inputAllowed);
4952
- QE('deskkeys', deskState == 3);
4953
-
4954
- // Display this only if we have Chat & Notify permissions
4955
- QV('DeskChatButton', ((meshrights & 16384) != 0) && (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
4956
- QV('DeskNotifyButton', ((meshrights & 16384) != 0) && (browserfullscreen == false) && (currentNode.agent) && (currentNode.agent.id < 5) && (inputAllowed) && (mesh.mtype == 2) && online);
4957
-
4958
- QV('DeskToolsButton', (inputAllowed) && (mesh.mtype == 2) && online);
4959
- QV('DeskOpenWebButton', (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
4960
- QV('DeskControlSpan', inputAllowed)
4961
- QV('deskActionsBtn', (browserfullscreen == false));
4962
- QV('deskActionsSettings', (browserfullscreen == false));
4963
- if (meshrights & 8) { Q('DeskControl').checked = (getstore('DeskControl', 1) == 1); } else { Q('DeskControl').checked = false; }
4964
- if (online == false) QV('DeskTools', false);
4965
- }
4966
-
4967
- // Debug
4968
- var autoConnectDesktopTimer = null;
4969
- function autoConnectDesktop(e) { if (autoConnectDesktopTimer == null) { autoConnectDesktopTimer = setInterval(connectDesktop, 100); } else { clearInterval(autoConnectDesktopTimer); autoConnectDesktopTimer = null; } }
4970
-
4971
- function connectDesktop(e, contype) {
4972
- p11clearConsoleMsg();
4973
- if (desktop == null) {
4974
- desktopNode = currentNode;
4975
- if (contype == 2) {
4976
- // Setup the Intel AMT remote desktop
4977
- if ((desktopNode.intelamt.user == null) || (desktopNode.intelamt.user == '')) { editDeviceAmtSettings(desktopNode._id, connectDesktop, 2); return; }
4978
- desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'), authCookie);
4979
- desktop.debugmode = debugmode;
4980
- desktop.onStateChanged = onDesktopStateChange;
4981
- desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
4982
- desktop.m.useZRLE = (desktopsettings.encoding < 3);
4983
- desktop.m.localKeyMap = desktopsettings.localkeymap;
4984
- desktop.m.showmouse = desktopsettings.showmouse;
4985
- desktop.m.onScreenSizeChange = deskAdjust;
4986
- desktop.m.onKvmData = function (x) {
4987
- //console.log('onKvmData (' + x.length + '): ' + x);
4988
- // Send the presense probe only once if needed.
4989
- if (x.length == 0) { if (!desktop.m._sentPresence) { desktop.m._sentPresence = true; desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 })); } return; }
4990
- var data = null;
4991
- try { data = JSON.parse(x); } catch (e) { }
4992
- if ((data != null) && (data.action != null)) {
4993
- if (data.action == 'restart') {
4994
- // Clear WebRTC channel
4995
- webRtcDesktopReset();
4996
- desktop.m.sendKvmData(JSON.stringify({ action: 'present', ver: 1 }));
4997
- } else if ((data.action == 'present') && (webRtcDesktop == null)) {
4998
- // Setup WebRTC channel
4999
- webRtcDesktop = { platform: data.platform };
This file is too large to show in full.
views/default-mobile.handlebars
+5
-5
@@ -1172,7 +1172,7 @@
1172
1173
function account_showVerifyEmail() {
1174
if (xxdialogMode || (userinfo.emailVerified == true) || (serverinfo.emailcheck != true)) return;
1175
- var x = "Click ok to send a verification mail to:<br /><div style=padding:8px><b>" + EscapeHtml(userinfo.email) + "</b></div>Please wait a few minute to receive the verification.";
1175
+ var x = "Click ok to send a verification mail to:" + '<br /><div style=padding:8px><b>' + EscapeHtml(userinfo.email) + "</b></div>Please wait a few minute to receive the verification.";
1176
setDialogMode(2, "Email Verification", 3, account_showVerifyEmailEx, x);
1177
}
1178
@@ -1182,7 +1182,7 @@
1182
1183
function account_showChangeEmail() {
1184
if (xxdialogMode) return;
1185
- var x = addHtmlValue('Email', '<input id=dp3email style=width:170px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />');
1185
+ var x = addHtmlValue("Email", '<input id=dp3email style=width:170px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />');
1186
setDialogMode(2, "Email Address Change", 3, account_changeEmail, x);
1187
if (userinfo.email != null) { Q('dp3email').value = userinfo.email; }
1188
account_validateEmail();
@@ -1887,15 +1887,15 @@
1887
}
1888
1889
// Attribute: Description
1890
- var description = node.desc ? EscapeHtml(node.desc) : "<i>None</i>";
1890
+ var description = node.desc ? EscapeHtml(node.desc) : '<i>' + "None" + '</i>';
1891
if ((meshrights & 4) != 0) {
1892
x += addDeviceAttribute('Description', '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + '</span>');
1893
} else {
1894
- x += addDeviceAttribute('Description', description);
1894
+ x += addDeviceAttribute("Description", description);
1895
}
1896
1897
// Attribute: Mesh Agent
1898
- var agentsStr = ['Unknown', 'Windows 32bit console', 'Windows 64bit console', 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'MacOS 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'MacOS 64bit', 'ChromeOS', 'Linux Poky x86-64bit', 'Linux NoKVM x86-32bit', 'Linux NoKVM x86-64bit', 'Windows MinCore console', 'Windows MinCore service', 'NodeJS', 'ARM-Linaro', 'ARMv6l / ARMv7l', 'ARMv8 64bit', 'ARMv6l / ARMv7l / NoKVM', 'Unknown', 'Unknown', 'FreeBSD x86-64'];
1898
+ var agentsStr = ["Unknown", "Windows 32bit console", "Windows 64bit console", 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'MacOS 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'MacOS 64bit', 'ChromeOS', 'Linux Poky x86-64bit', 'Linux NoKVM x86-32bit', 'Linux NoKVM x86-64bit', 'Windows MinCore console', 'Windows MinCore service', 'NodeJS', 'ARM-Linaro', 'ARMv6l / ARMv7l', 'ARMv8 64bit', 'ARMv6l / ARMv7l / NoKVM', 'Unknown', 'Unknown', 'FreeBSD x86-64'];
1899
if ((node.agent != null) && (node.agent.id != null) && (node.agent.ver != null)) {
1900
var str = '';
1901
if (node.agent.id <= agentsStr.length) { str = agentsStr[node.agent.id]; } else { str = agentsStr[0]; }
views/default.handlebars
+293
-262
@@ -1784,12 +1784,12 @@
1784
}
1785
case 'otpauth-setup': {
1786
if (xxdialogMode) return;
1787
- setDialogMode(2, "Authenticator App", 1, null, message.success ? "<b style=color:green>Authenticator app activation successful</b>. You will now need a valid token to login again." : "<b style=color:red>2-step login activation failed</b>. Clear the secret from the application and try again. You only have a few minutes to enter the proper code.");
1787
+ setDialogMode(2, "Authenticator App", 1, null, message.success ? ('<b style=color:green>' + "Authenticator app activation successful." + '</b> ' + "You will now need a valid token to login again.") : ('<b style=color:red>' + "2-step login activation failed." + '</b> ' + "Clear the secret from the application and try again. You only have a few minutes to enter the proper code."));
1788
break;
1789
}
1790
case 'otpauth-clear': {
1791
if (xxdialogMode) return;
1792
- setDialogMode(2, "Authenticator App", 1, null, message.success ? "<b>Authenticator application removed</b>. You can reactivate this feature at any time." : "<b style=color:red>2-step login activation removal failed</b>. Try again.");
1792
+ setDialogMode(2, "Authenticator App", 1, null, message.success ? ('<b>' + "Authenticator application removed." + '</b> ' + "You can reactivate this feature at any time.") : ('<b style=color:red>' + "2-step login activation removal failed." + '</b> ' + "Try again."));
1793
break;
1794
}
1795
case 'otpauth-getpasswords': {
@@ -2556,7 +2556,7 @@
2556
else if (sort == 2) { if (showRealNames == true) { nodes.sort(deviceHostSort); } else { nodes.sort(deviceSort); } }
2557
2558
// Save the list of currently checked nodeid's
2559
- var checkedNodeids = [], elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
2559
+ var checkedNodeids = [], elements = document.getElementsByClassName('DeviceCheckbox'), checkcount = 0;
2560
for (var i=0;i<elements.length;i++) { if (elements[i].checked) { checkedNodeids.push(elements[i].value); } }
2561
if ((oldviewmode < 3) && (view == 3)) { multiDesktopFilter = checkedNodeids; }
2562
else if ((oldviewmode == 3) && (view < 3)) { checkedNodeids = multiDesktopFilter; }
@@ -2567,7 +2567,7 @@
2567
deviceBoxWidth = 301 + Math.floor((totalDeviceViewWidth - (deviceBoxWidth * 301)) / deviceBoxWidth);
2568
2569
if ((view == 2) && (sort != 3)) {
2570
- r += '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity'; //<th style=color:gray;width:100px>State';
2570
+ r += '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>' + "User" + '<th style=color:gray;width:120px>' + "Address" + '<th style=color:gray;width:100px>' + "Connectivity"; //<th style=color:gray;width:100px>State';
2571
}
2572
2573
// Go thru the list of nodes and display them
@@ -2615,11 +2615,11 @@
2615
2616
count++;
2617
var title = EscapeHtml(node.name);
2618
- if (title.length == 0) { title = '<i>None</i>'; }
2619
- if ((node.rname != null) && (node.rname.length > 0)) { title += " / " + EscapeHtml(node.rname); }
2618
+ if (title.length == 0) { title = '<i>' + "None" + '</i>'; }
2619
+ if ((node.rname != null) && (node.rname.length > 0)) { title += ' / ' + EscapeHtml(node.rname); }
2620
var name = EscapeHtml(node.name);
2621
if (showRealNames == true && node.rname != null) name = EscapeHtml(node.rname);
2622
- if (name.length == 0) { name = '<i>None</i>'; }
2622
+ if (name.length == 0) { name = '<i>' + "None" + '</i>'; }
2623
2624
// Node
2625
var icon = node.icon;
@@ -2629,11 +2629,11 @@
2629
} else if (view == 2) {
2630
var states = [];
2631
if (node.conn) {
2632
- if ((node.conn & 1) != 0) { states.push('<span title="Mesh agent is connected and ready for use.">Agent</span>'); }
2633
- if ((node.conn & 2) != 0) { states.push('<span title="Intel® AMT CIRA is connected and ready for use.">CIRA</span>'); }
2634
- else if ((node.conn & 4) != 0) { states.push('<span title="Intel® AMT is routable.">AMT</span>'); }
2635
- if ((node.conn & 8) != 0) { states.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>'); }
2636
- if ((node.conn & 16) != 0) { states.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
2632
+ if ((node.conn & 1) != 0) { states.push('<span title=\"' + "Mesh agent is connected and ready for use." + '\">' + "Agent" + '</span>'); }
2633
+ if ((node.conn & 2) != 0) { states.push('<span title=\"' + "Intel® AMT CIRA is connected and ready for use." + '\">' + "CIRA" + '</span>'); }
2634
+ else if ((node.conn & 4) != 0) { states.push('<span title=\"' + "Intel® AMT is routable." + '\">' + "AMT" + '</span>'); }
2635
+ if ((node.conn & 8) != 0) { states.push('<span title=\"' + "Mesh agent is reachable using another agent as relay." + '\">' + "Relay" + '</span>'); }
2636
+ if ((node.conn & 16) != 0) { states.push('<span title=\"' + "MQTT connection to the device is active." + '\">' + "MQTT" + '</span>'); }
2637
}
2638
r += '<tr><td><div id=devs class=bar18 tabindex=0 onmouseover=devMouseHover(this,1) onmouseout=devMouseHover(this,0) style=height:18px;width:100%;font-size:medium onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',null,null,event)">';
2639
r += '<div class=deviceBarCheckbox><input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox></div>';
@@ -2650,7 +2650,7 @@
2650
r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div tabindex=0 style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + node._id + '\',11,null,event) onkeypress="if (event.key==\'Enter\') gotoDevice(\'' + node._id + '\',11,null,event)">';
2651
//r += '<input class="' + node.meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + node._id + ' type=checkbox style=float:left>';
2652
r += '<div class="j' + icon + '" style=width:16px;float:left></div> ' + name + '</div>';
2653
- r += '<span onclick=gotoDevice(\'' + node._id + '\',null,null,event)></span><div id=xkvmid_' + node._id.split('/')[2] + '><div id=skvmid_' + node._id.split('/')[2] + ' tabindex=0 style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + node._id + '\') onkeypress="if (event.key==\'Enter\') toggleKvmDevice(\'' + node._id + '\')">Disconnected</div></div>';
2653
+ r += '<span onclick=gotoDevice(\'' + node._id + '\',null,null,event)></span><div id=xkvmid_' + node._id.split('/')[2] + '><div id=skvmid_' + node._id.split('/')[2] + ' tabindex=0 style="position:absolute;color:white;left:5px;top:27px;text-shadow:0px 0px 5px #000;z-index:1000;cursor:default" onclick=toggleKvmDevice(\'' + node._id + '\') onkeypress="if (event.key==\'Enter\') toggleKvmDevice(\'' + node._id + '\')">' + "Disconnected" + '</div></div>';
2654
r += '</div>';
2655
kvmDivs.push(node._id);
2656
}
@@ -2679,7 +2679,7 @@
2679
2680
// If displaying devices by groups, sort the group names and display the devices.
2681
if (sort == 3) {
2682
- if (view == 2) { r = '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>User<th style=color:gray;width:120px>Address<th style=color:gray;width:100px>Connectivity'; }
2682
+ if (view == 2) { r = '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray><th style=color:gray;width:120px>' + "User" + '<th style=color:gray;width:120px>' + "Address" + '<th style=color:gray;width:100px>' + "Connectivity"; }
2683
2684
var groupNames = [];
2685
for (var i in groups) { groupNames.push(i); }
@@ -2697,9 +2697,9 @@
2697
// If there is nothing to display, explain the problem
2698
if ((r == '') && (meshcount > 0) && (Q('SearchInput').value != '')) {
2699
if (sort == 3) {
2700
- r = '<div style="margin:30px">No devices are included in any groups, click on a device\'s \"Groups\" to add to a group.</div>';
2700
+ r = '<div style="margin:30px">' + "No devices are included in any groups, click on a device\'s \"Groups\" to add to a group." + '</div>';
2701
} else {
2702
- r = '<div style="margin:30px">No devices matching this search.</div>';
2702
+ r = '<div style="margin:30px">' + "No devices matching this search." + '</div>';
2703
}
2704
}
2705
@@ -2717,12 +2717,12 @@
2717
r += getMeshActions(mesh, meshrights);
2718
r += '</span></td></tr><tr>';
2719
if (mesh.mtype == 1) {
2720
- r += '<td><div style=padding:10px><i>No Intel® AMT devices in this mesh';
2721
- if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>add one</a>'; }
2720
+ r += '<td><div style=padding:10px><i>' + "No Intel® AMT devices in this mesh";
2721
+ if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
2722
}
2723
if (mesh.mtype == 2) {
2724
- r += '<td><div style=padding:10px><i>No devices in this mesh';
2725
- if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>add one</a>'; }
2724
+ r += '<td><div style=padding:10px><i>' + "No devices in this mesh";
2725
+ if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
2726
}
2727
r += '.</i></div></td>';
2728
current = mesh._id;
@@ -2736,11 +2736,11 @@
2736
// Add a "Add Device Group" option
2737
r += '<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px>';
2738
if ((view < 3) && (sort == 0) && (meshcount > 0) && ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0))) {
2739
- r += '<a href=# onclick="return account_createMesh()" title="Create a new group of devices." style=cursor:pointer>Add Device Group</a> ';
2739
+ r += '<a href=# onclick="return account_createMesh()" title=\"' + "Create a new group of devices." + '\" style=cursor:pointer>' + "Add Device Group" + '</a> ';
2740
}
2741
if ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 128) == 0)) {
2742
- r += '<a href=# onclick=\'return p10showMeshCmdDialog(0)\' style=cursor:pointer title="Download MeshCmd, a command line tool that performs many functions.">MeshCmd</a> ';
2743
- if (navigator.platform.toLowerCase() == 'win32') { r += '<a href=# onclick=\'return p10showMeshRouterDialog()\' style=cursor:pointer title="Download MeshCentral Router, a TCP port mapping tool.">Router</a> '; }
2742
+ r += '<a href=# onclick=\'return p10showMeshCmdDialog(0)\' style=cursor:pointer title=\"' + "Download MeshCmd, a command line tool that performs many functions." + '\">' + "MeshCmd" + '</a> ';
2743
+ if (navigator.platform.toLowerCase() == 'win32') { r += '<a href=# onclick=\'return p10showMeshRouterDialog()\' style=cursor:pointer title=\"' + "Download MeshCentral Router, a TCP port mapping tool." + '\">' + "Router" + '</a> '; }
2744
}
2745
r += '</div><br/>';
2746
@@ -2748,7 +2748,7 @@
2748
deviceHeaderSet();
2749
2750
// Re-check nodeid's
2751
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
2751
+ var elements = document.getElementsByClassName('DeviceCheckbox'), checkcount = 0;
2752
if (checkedNodeids) { for (var i=0;i<elements.length;i++) { elements[i].checked = (checkedNodeids.indexOf(elements[i].value) >= 0); } }
2753
2754
for (var i in deviceHeaders) { QH(i, deviceHeaders[i]); }
@@ -2773,7 +2773,7 @@
2773
desk.m.CanvasId.setAttribute('style', 'background-color:black;width:' + vsize.x + 'px;height:' + vsize.y + 'px');
2774
Q('xkvmid_' + shortid).appendChild(desk.m.CanvasId);
2775
delete desk.xxdelete;
2776
- QH('skvmid_' + shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][((desk.m.State == null)?desk.m.state:desk.m.State)]);
2776
+ QH('skvmid_' + shortid, ["Disconnected", "Connecting...", "Setup...", '', ''][((desk.m.State == null)?desk.m.state:desk.m.State)]);
2777
} else {
2778
var node = getNodeFromId(id);
2779
if ((desktopNode == node) && (desktop != null)) { // Check if the main desktop is this device, if it is, use that.
@@ -2786,7 +2786,7 @@
2786
c.removeAttribute('onmouseup');
2787
c.removeAttribute('onmousemove');
2788
Q('xkvmid_' + shortid).appendChild(c);
2789
- QH('skvmid_' + shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][((desktop.m.State == null)?desktop.m.state:desktop.m.State)]);
2789
+ QH('skvmid_' + shortid, ["Disconnected", "Connecting...", "Setup...", '', ''][((desktop.m.State == null)?desktop.m.state:desktop.m.State)]);
2790
if (desktop.m.SendCompressionLevel) { desktop.m.SendCompressionLevel(1, multidesktopsettings.quality, multidesktopsettings.scaling, multidesktopsettings.framerate); }
2791
desktop.shortid = shortid;
2792
desktop.onStateChanged = onMultiDesktopStateChange;
@@ -2836,7 +2836,7 @@
2836
2837
function getUserShortStr(node) {
2838
if (node == null || node.users == null || node.users.length == 0) return '';
2839
- if (node.users.length > 1) { return '<span title="' + EscapeHtml(node.users.join(', ')) + '">' + node.users.length + ' users</span>'; }
2839
+ if (node.users.length > 1) { return '<span title="' + EscapeHtml(node.users.join(', ')) + '">' + format("{0} users", node.users.length) + '</span>'; }
2840
var u = node.users[0], su = u, i = u.indexOf('\\');
2841
if (i > 0) { su = u.substring(i + 1); }
2842
su = EscapeHtml(su);
@@ -2847,7 +2847,7 @@
2847
function autoConnectDesktops() { if (Q('autoConnectDesktopCheckbox').checked == true) { connectAllKvmFunction(); } }
2848
function connectAllKvmFunction() { for (var i in nodes) { if (multiDesktop[nodes[i]._id] == null) { toggleKvmDevice(nodes[i]._id); } } }
2849
function disconnectAllKvmFunction() { for (var nodeid in multiDesktop) { multiDesktop[nodeid].Stop(); } multiDesktop = {}; }
2850
- function onMultiDesktopStateChange(desk, state) { try { QH('skvmid_' + desk.shortid, ['Disconnected', 'Connecting...', 'Setup...', '', ''][state]); } catch (ex) {} }
2850
+ function onMultiDesktopStateChange(desk, state) { try { QH('skvmid_' + desk.shortid, ["Disconnected", "Connecting...", "Setup...", '', ''][state]); } catch (ex) {} }
2851
2852
function showMultiDesktopSettings() {
2853
QV('d7amtkvm', false);
@@ -2916,22 +2916,22 @@
2916
if ((meshrights & 4) == 0) return '';
2917
var r = '';
2918
if ((features & 1024) == 0) { // If CIRA is allowed
2919
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the internet." onclick=\'return addCiraDeviceToMesh(\"' + mesh._id + '\")\'>Add CIRA</a>';
2919
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Add a new Intel® AMT computer that is located on the internet." + '\" onclick=\'return addCiraDeviceToMesh(\"' + mesh._id + '\")\'>' + "Add CIRA" + '</a>';
2920
}
2921
if (mesh.mtype == 1) {
2922
if ((features & 1) == 0) { // If not WAN-Only
2923
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the local network." onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>Add Local</a>';
2924
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer by scanning the local network." onclick=\'return addAmtScanToMesh(\"' + mesh._id + '\")\'>Scan Network</a>';
2923
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Add a new Intel® AMT computer that is located on the local network." + '\" onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "Add Local" + '</a>';
2924
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Add a new Intel® AMT computer by scanning the local network." + '\" onclick=\'return addAmtScanToMesh(\"' + mesh._id + '\")\'>' + "Scan Network" + '</a>';
2925
}
2926
if (mesh.amt && (mesh.amt.type == 2)) { // CCM activation
2927
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Perform Intel AMT client control mode (CCM) activation." onclick=\'return showCcmActivation(\"' + mesh._id + '\")\'>Activation</a>';
2927
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Perform Intel AMT client control mode (CCM) activation." + '\" onclick=\'return showCcmActivation(\"' + mesh._id + '\")\'>' + "Activation" + '</a>';
2928
} else if (mesh.amt && (mesh.amt.type == 3) && ((features & 0x00100000) != 0)) { // ACM activation
2929
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Perform Intel AMT admin control mode (ACM) activation." onclick=\'return showAcmActivation(\"' + mesh._id + '\")\'>Activation</a>';
2929
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Perform Intel AMT admin control mode (ACM) activation." + '\" onclick=\'return showAcmActivation(\"' + mesh._id + '\")\'>' + "Activation" + '</a>';
2930
}
2931
}
2932
if (mesh.mtype == 2) {
2933
- r += ' <a href=# style=cursor:pointer;font-size:10px title="Add a new computer to this mesh by installing the mesh agent." onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>Add Agent</a>';
2934
- if ((features & 2) == 0) { r += ' <a href=# style=cursor:pointer;font-size:10px title="Invite someone to install the mesh agent on this mesh." onclick=\'return inviteAgentToMesh(\"' + mesh._id + '\")\'>Invite</a>'; }
2933
+ r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Add a new computer to this mesh by installing the mesh agent." + '\" onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "Add Agent" + '</a>';
2934
+ if ((features & 2) == 0) { r += ' <a href=# style=cursor:pointer;font-size:10px title=\"' + "Invite someone to install the mesh agent on this mesh." + '\" onclick=\'return inviteAgentToMesh(\"' + mesh._id + '\")\'>' + "Invite" + '</a>'; }
2935
}
2936
return r;
2937
}
@@ -2939,12 +2939,12 @@
2939
function addDeviceToMesh(meshid) {
2940
if (xxdialogMode) return false;
2941
var mesh = meshes[meshid];
2942
- var x = "Add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\".<br /><br />";
2943
- x += addHtmlValue('Device Name', '<input id=dp1devicename style=width:230px maxlength=32 autocomplete=off onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2944
- x += addHtmlValue('Hostname', '<input id=dp1hostname style=width:230px maxlength=32 autocomplete=off placeholder="Same as device name" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2945
- x += addHtmlValue('Username', '<input id=dp1username style=width:230px maxlength=32 autocomplete=off placeholder="admin" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2946
- x += addHtmlValue('Password', '<input id=dp1password type=password style=width:230px autocomplete=off maxlength=32 onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2947
- x += addHtmlValue('Security', '<select id=dp1tls style=width:236px><option value=0>No TLS security</option><option value=1>TLS security required</option></select>');
2942
+ var x = format("Add a new Intel® AMT device to device group \"{0}\".", EscapeHtml(mesh.name)) + '<br /><br />';
2943
+ x += addHtmlValue("Device Name", '<input id=dp1devicename style=width:230px maxlength=32 autocomplete=off onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2944
+ x += addHtmlValue("Hostname", '<input id=dp1hostname style=width:230px maxlength=32 autocomplete=off placeholder=\"' + "Same as device name" + '\" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2945
+ x += addHtmlValue("Username", '<input id=dp1username style=width:230px maxlength=32 autocomplete=off placeholder=\"' + "admin" + '\" onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2946
+ x += addHtmlValue("Password", '<input id=dp1password type=password style=width:230px autocomplete=off maxlength=32 onchange=validateDeviceToMesh() onkeyup=validateDeviceToMesh() />');
2947
+ x += addHtmlValue("Security", '<select id=dp1tls style=width:236px><option value=0>' + "No TLS security" + '</option><option value=1>' + "TLS security required" + '</option></select>');
2948
setDialogMode(2, "Add Intel® AMT device", 3, addDeviceToMeshEx, x, meshid);
2949
validateDeviceToMesh();
2950
Q('dp1devicename').focus();
@@ -2958,13 +2958,13 @@
2958
if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
2959
var url, domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
2960
if (serverinfo.https == true) {
2961
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
2962
- url = "wss://" + servername + portStr + domainUrl;
2961
+ var portStr = (serverinfo.port == 443) ? '' : (':' + serverinfo.port);
2962
+ url = 'wss://' + servername + portStr + domainUrl;
2963
} else {
2964
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
2965
- url = "ws://" + servername + portStr + domainUrl;
2964
+ var portStr = (serverinfo.port == 80) ? '' : (':' + serverinfo.port);
2965
+ url = 'ws://' + servername + portStr + domainUrl;
2966
}
2967
- var x = "Perform Intel AMT client control mode (CCM) activation to group \"" + EscapeHtml(mesh.name) + "\" by downloading the MeshCMD tool and running it like this:<br /><br />";
2967
+ var x = format("Perform Intel AMT client control mode (CCM) activation to group \"{0}\" by downloading the MeshCMD tool and running it like this:", EscapeHtml(mesh.name)) + '<br /><br />';
2968
x += '<textarea readonly=readonly style=width:100%;resize:none;height:100px;overflow:auto;font-size:12px readonly>meshcmd amtccm --url ' + url + 'amtactivate?id=' + meshid.split('/')[2] + ' --serverhttpshash ' + serverinfo.tlshash + '</textarea>';
2969
setDialogMode(2, "Intel® AMT activation", 9, null, x);
2970
Q('idx_dlgOkButton').focus();
@@ -2978,16 +2978,16 @@
2978
if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
2979
var url, domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
2980
if (serverinfo.https == true) {
2981
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
2982
- url = "wss://" + servername + portStr + domainUrl;
2981
+ var portStr = (serverinfo.port == 443) ? '' : (':' + serverinfo.port);
2982
+ url = 'wss://' + servername + portStr + domainUrl;
2983
} else {
2984
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
2985
- url = "ws://" + servername + portStr + domainUrl;
2984
+ var portStr = (serverinfo.port == 80) ? '' : (':' + serverinfo.port);
2985
+ url = 'ws://' + servername + portStr + domainUrl;
2986
}
2987
- var x = "Perform Intel AMT admin control mode (ACM) activation to group \"" + EscapeHtml(mesh.name) + "\" by downloading the MeshCMD tool and running it like this:<br /><br />";
2987
+ var x = format("Perform Intel AMT admin control mode (ACM) activation to group \"{0}\" by downloading the MeshCMD tool and running it like this:", EscapeHtml(mesh.name)) + '<br /><br />';
2988
x += '<textarea readonly=readonly style=width:100%;resize:none;height:100px;overflow:auto;font-size:12px readonly>meshcmd amtacm --url ' + url + 'amtactivate?id=' + meshid.split('/')[2] + ' --serverhttpshash ' + serverinfo.tlshash + '</textarea>';
2989
if (serverinfo.amtAcmFqdn != null) {
2990
- x += '<div style=margin-top:8px>Intel AMT will need to be set with a Trusted FQDN in MEBx or have a wired LAN on the network: <b>' + serverinfo.amtAcmFqdn.join(', ') + '</b></div>';
2990
+ x += ('<div style=margin-top:8px>' + "Intel AMT will need to be set with a Trusted FQDN in MEBx or have a wired LAN on the network:" + ' <b>' + serverinfo.amtAcmFqdn.join(', ') + '</b></div>');
2991
}
2992
setDialogMode(2, "Intel® AMT activation", 9, null, x);
2993
Q('idx_dlgOkButton').focus();
@@ -2997,8 +2997,8 @@
2997
// Display the Intel AMT scanning dialog box
2998
function addAmtScanToMesh(meshid) {
2999
if (xxdialogMode) return false;
3000
- var x = "Enter a range of IP addresses to scan for Intel AMT devices.<br /><br />";
3001
- x += addHtmlValue('IP Range', '<input id=dp1range style=width:184px value="192.168.1.0/24" onkeyup=addAmtScanToMeshKeyUp(event) /><input id=dp1rangebutton type=button value=Scan onclick=addAmtScanToMeshButton()></input>');
3000
+ var x = "Enter a range of IP addresses to scan for Intel AMT devices." + '<br /><br />';
3001
+ x += addHtmlValue("IP Range", '<input id=dp1range style=width:184px value="192.168.1.0/24" onkeyup=addAmtScanToMeshKeyUp(event) /><input id=dp1rangebutton type=button value=\"' + "Scan" + '\" onclick=addAmtScanToMeshButton()></input>');
3002
x += '<div id=dp1results style="width:100%;height:200px;background-color:white;border:1px gray solid;overflow-y:scroll"></div>';
3003
setDialogMode(2, "Scan for Intel® AMT devices", 3, addAmtScanToMeshEx, x, meshid);
3004
QE('idx_dlgOkButton', false);
@@ -3013,7 +3013,7 @@
3013
3014
// Called when OK is pressed on the Intel AMT scanning box
3015
function addAmtScanToMeshEx(button, meshid) {
3016
- var elements = document.getElementsByClassName("DevScanCheckbox"), checkcount = 0;
3016
+ var elements = document.getElementsByClassName('DevScanCheckbox'), checkcount = 0;
3017
for (var i=0;i<elements.length;i++) {
3018
if (elements[i].checked) {
3019
var ipaddr = elements[i].getAttribute('tag');
@@ -3027,13 +3027,13 @@
3027
function addAmtScanToMeshButton() {
3028
QE('dp1range', false);
3029
QE('dp1rangebutton', false);
3030
- QH('dp1results', '<div style=width:100%;text-align:center;margin-top:12px>Scanning...</div>');
3030
+ QH('dp1results', '<div style=width:100%;text-align:center;margin-top:12px>' + "Scanning..." + '</div>');
3031
meshserver.send({ action: 'scanamtdevice', range: Q('dp1range').value });
3032
}
3033
3034
// Called when a scanned computer is checked or unchecked.
3035
function addAmtScanToMeshCheckbox() {
3036
- var elements = document.getElementsByClassName("DevScanCheckbox"), checkcount = 0;
3036
+ var elements = document.getElementsByClassName('DevScanCheckbox'), checkcount = 0;
3037
for (var i=0;i<elements.length;i++) { if (elements[i].checked) checkcount++; }
3038
QE('idx_dlgOkButton', checkcount > 0);
3039
}
@@ -3045,36 +3045,36 @@
3045
// Replace non alphabetic characters (@ and $) with 'X' because MPS username cannot accept it.
3046
var meshidx = meshid.split('/')[2].replace(/\@/g, 'X').replace(/\$/g, 'X');
3047
3048
- var y = '<select id=dlgAddCiraSel onclick=dlgAddCiraSelClick() style=width:230px><option value=0>MeshCommander Script</option><option value=1>Manual Username/Password</option>';
3049
- if ((features & 16) == 0) { y += '<option value=2>Manual Certificate</option></select>'; } // Only display this option if Intel AMT CIRA with Mutual-Auth is allowed.
3048
+ var y = '<select id=dlgAddCiraSel onclick=dlgAddCiraSelClick() style=width:230px><option value=0>' + "MeshCommander Script" + '</option><option value=1>' + "Manual Username/Password" + '</option>';
3049
+ if ((features & 16) == 0) { y += ('<option value=2>' + "Manual Certificate" + '</option></select>'); } // Only display this option if Intel AMT CIRA with Mutual-Auth is allowed.
3050
3051
var x = '';
3052
- x += addHtmlValue('Setup Method', y);
3052
+ x += addHtmlValue("Setup Method", y);
3053
x += '<hr>';
3054
3055
// Setup CIRA using a MeshCommander script (Pretty Simple)
3056
- x += "<div id=dlgAddCira0>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.<br /><br />";
3056
+ x += '<div id=dlgAddCira0>' + format("To add a new Intel® AMT device to device group \"{0}\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.", EscapeHtml(mesh.name)) + '<br /><br />';
3057
//x += addHtmlValue('Setup CIRA', '<a href="mescript.ashx?type=1&meshid=' + meshidx.substring(0, 16) + '" download>cira_setup.mescript</a>');
3058
- x += addHtmlValue('Setup CIRA', '<a href="mescript.ashx?type=1&meshid=' + meshid + '" download>cira_setup.mescript</a>');
3059
- x += addHtmlValue('Cleanup CIRA', '<a href="mescript.ashx?type=2" download>cira_clean.mescript</a>');
3060
- x += "</div>";
3058
+ x += addHtmlValue("Setup CIRA", '<a href="mescript.ashx?type=1&meshid=' + meshid + '" download>cira_setup.mescript</a>');
3059
+ x += addHtmlValue("Cleanup CIRA", '<a href="mescript.ashx?type=2" download>cira_clean.mescript</a>');
3060
+ x += '</div>';
3061
3062
// Setup CIRA with user/pass authentication (Somewhat difficult)
3063
- x += "<div id=dlgAddCira1 style=display:none>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, load the following certificate as trusted root within Intel AMT";
3064
- if (serverinfo.mpspass) { x += " and authenticate to the server using this username and password.<br /><br />"; } else { x += " and authenticate to the server using this username and any password.<br /><br />"; }
3065
- x += addHtmlValue('Root Certificate', '<a href="MeshServerRootCert.cer" download>Root Certificate File</a>');
3066
- x += addHtmlValue('Username', '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
3067
- if (serverinfo.mpspass) { x += addHtmlValue('Password', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
3068
- if (serverinfo != null) { x += addHtmlValue('MPS Server', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3069
- x += "</div>";
3063
+ x += '<div id=dlgAddCira1 style=display:none>' + format("To add a new Intel® AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel AMT", EscapeHtml(mesh.name));
3064
+ if (serverinfo.mpspass) { x += (" and authenticate to the server using this username and password." + '<br /><br />'); } else { x += (" and authenticate to the server using this username and any password." + '<br /><br />'); }
3065
+ x += addHtmlValue("Root Certificate", '<a href=\"' + "MeshServerRootCert.cer" + '\" download>' + "Root Certificate File" + '</a>');
3066
+ x += addHtmlValue("Username", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
3067
+ if (serverinfo.mpspass) { x += addHtmlValue("Password", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
3068
+ if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3069
+ x += '</div>';
3070
3071
// Setup CIRA with certificate authentication (Really difficult, only if TLS offload is not used)
3072
if ((features & 16) == 0) {
3073
- x += "<div id=dlgAddCira2 style=display:none>To add a new Intel® AMT device to device group \"" + EscapeHtml(mesh.name) + "\" with CIRA, load the following certificate as trusted root within Intel AMT, authenticate using a client certificate with the following common name and connect to the following server.<br /><br />";
3074
- x += addHtmlValue('Root Certificate', '<a href="MeshServerRootCert.cer" download>Root Certificate File</a>');
3075
- x += addHtmlValue('Organization', '<input style=width:230px readonly value="' + meshidx + '" />');
3076
- if (serverinfo != null) { x += addHtmlValue('MPS Server', '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3077
- x += "</div>";
3073
+ x += '<div id=dlgAddCira2 style=display:none>' + format("To add a new Intel® AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel AMT, authenticate using a client certificate with the following common name and connect to the following server.", EscapeHtml(mesh.name)) + '<br /><br />';
3074
+ x += addHtmlValue("Root Certificate", '<a href="MeshServerRootCert.cer" download>' + "Root Certificate File" + '</a>');
3075
+ x += addHtmlValue("Organization", '<input style=width:230px readonly value="' + meshidx + '" />');
3076
+ if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
3077
+ x += '</div>';
3078
}
3079
3080
setDialogMode(2, "Add Intel® AMT CIRA device", 2, null, x, 'fileDownload');
@@ -3101,21 +3101,21 @@
3101
if (xxdialogMode) return false;
3102
var x = '', mesh = meshes[meshid];
3103
if (features & 64) {
3104
- x += addHtmlValue('Invitation Type', '<select id=d2InviteType onchange=d2ChangedInviteType() style=width:236px><option value=0>Link invitation</option><option value=1>Email invitation</option></select>') + "<hr />";
3105
- x += "<div id=emailInviteDiv style=display:none>Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for the \"" + EscapeHtml(mesh.name) + "\" device group.<br /><br />";
3106
- x += addHtmlValue('Name (optional)', '<input id=agentInviteName value="" style=width:230px maxlength=64 />');
3107
- x += addHtmlValue('Email', '<input id=agentInviteEmail style=width:230px placeholder="example@email.com" onkeyup=validateAgentInvite()></input>');
3108
- x += addHtmlValue('Operating System', '<select id=agentInviteNameOs onchange=d2ChangedInviteType() style=width:236px><option value=4>Send installation link</option><option value=0 selected>Any supported</option><option value=1>Windows only</option><option value=3>Apple MacOS only</option><option value=2>Linux only</option></select>');
3104
+ x += addHtmlValue("Invitation Type", '<select id=d2InviteType onchange=d2ChangedInviteType() style=width:236px><option value=0>Link invitation</option><option value=1>Email invitation</option></select>') + '<hr />';
3105
+ x += '<div id=emailInviteDiv style=display:none>' + format("Invite someone to install the mesh agent. An email with be sent with the link to the mesh agent installation for the \"{0}\" device group.", EscapeHtml(mesh.name)) + '<br /><br />';
3106
+ x += addHtmlValue("Name (optional)", '<input id=agentInviteName value="" style=width:230px maxlength=64 />');
3107
+ x += addHtmlValue("Email", '<input id=agentInviteEmail style=width:230px placeholder=\"' + "example@email.com" + '\" onkeyup=validateAgentInvite()></input>');
3108
+ x += addHtmlValue("Operating System", '<select id=agentInviteNameOs onchange=d2ChangedInviteType() style=width:236px><option value=4>' + "Send installation link" + '</option><option value=0 selected>' + "Any supported" + '</option><option value=1>' + "Windows only" + '</option><option value=3>' + "Apple MacOS only" + '</option><option value=2>' + "Linux only" + '</option></select>');
3109
x += '<div id=d2agentexpirediv>';
3110
- x += addHtmlValue('Link Expiration', '<select id=agentInviteExpire style=width:236px><option value=1>1 hour</option><option value=8>8 hours</option><option value=24>1 day</option><option value=168>1 week</option><option value=5040>1 month</option><option value=0>Unlimited</option></select>');
3110
+ x += addHtmlValue("Link Expiration", '<select id=agentInviteExpire style=width:236px><option value=1>' + "1 hour" + '</option><option value=8>' + "8 hours" + '</option><option value=24>' + "1 day" + '</option><option value=168>' + "1 week" + '</option><option value=5040>' + "1 month" + '</option><option value=0>' + "Unlimited" + '</option></select>');
3111
x += '</div>';
3112
- x += addHtmlValue('Installation Type', '<select id=agentInviteType style=width:236px><option value=0>Background and interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>');
3113
- x += addHtmlValue('Message<br />(optional)', '<textarea id=agentInviteMessage value="" style=width:230px;height:100px;resize:none maxlength=1024 /></textarea>');
3112
+ x += addHtmlValue("Installation Type", '<select id=agentInviteType style=width:236px><option value=0>' + "Background and interactive" + '</option><option value=2>' + "Background only" + '</option><option value=1>' + "Interactive only" + '</option></select>');
3113
+ x += addHtmlValue("Message" + '<br />' + "(optional)", '<textarea id=agentInviteMessage value="" style=width:230px;height:100px;resize:none maxlength=1024 /></textarea>');
3114
x += '</div>';
3115
}
3116
- x += '<div id=urlInviteDiv>Invite someone to install the mesh agent by sharing an invitation link. This link points the user to installation instructions for the \"' + EscapeHtml(mesh.name) + '\" device group. The link is public and no account for this server is needed.<br /><br />';
3117
- x += addHtmlValue('Link Expiration', '<select id=d2inviteExpire style=width:236px onchange=d2RequestInvitationLink()><option value=1>1 hour</option><option value=8>8 hours</option><option value=24>1 day</option><option value=168>1 week</option><option value=5040>1 month</option><option value=0>Unlimited</option></select>');
3118
- x += '<div id=agentInvitationLinkDiv style="text-align:center;font-size:large;margin:16px;display:none"><a href=# id=agentInvitationLink target="_blank" style=cursor:pointer></a> <img src=images/link4.png height=10 width=10 title="Copy link to clipboard" style=cursor:pointer onclick=d2CopyInviteToClip()></div></div>';
3116
+ x += '<div id=urlInviteDiv>' + format("Invite someone to install the mesh agent by sharing an invitation link. This link points the user to installation instructions for the \"{0}\" device group. The link is public and no account for this server is needed.", EscapeHtml(mesh.name)) + '<br /><br />';
3117
+ x += addHtmlValue("Link Expiration", '<select id=d2inviteExpire style=width:236px onchange=d2RequestInvitationLink()><option value=1>' + "1 hour" + '</option><option value=8>' + "8 hours" + '</option><option value=24>' + "1 day" + '</option><option value=168>' + "1 week" + '</option><option value=5040>' + "1 month" + '</option><option value=0>' + "Unlimited" + '</option></select>');
3118
+ x += '<div id=agentInvitationLinkDiv style="text-align:center;font-size:large;margin:16px;display:none"><a href=# id=agentInvitationLink target="_blank" style=cursor:pointer></a> <img src=images/link4.png height=10 width=10 title=\"' + "Copy link to clipboard" + '\" style=cursor:pointer onclick=d2CopyInviteToClip()></div></div>';
3119
setDialogMode(2, "Invite", 3, performAgentInvite, x, meshid);
3120
if (features & 64) { Q('d2InviteType').focus(); d2ChangedInviteType(); } else { Q('d2inviteExpire').focus(); validateAgentInvite(); }
3121
d2RequestInvitationLink();
@@ -3154,9 +3154,9 @@
3154
function addAgentToMesh(meshid) {
3155
if (xxdialogMode) return false;
3156
var mesh = meshes[meshid], x = '', installType = 0;
3157
- x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux / BSD</option><option value=2>Apple MacOS</option><option value=3>Windows (UnInstall)</option><option value=4>Linux / BSD (UnInstall)</option></select>');
3157
+ x += addHtmlValue("Operating System", '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>' + "Windows" + '</option><option value=1>' + "Linux / BSD" + '</option><option value=2>' + "Apple MacOS" + '</option><option value=3>' + "Windows (UnInstall)" + '</option><option value=4>' + "Linux / BSD (UnInstall)" + '</option></select>');
3158
x += '<div id=aginsTypeDiv>';
3159
- x += addHtmlValue('Installation Type', '<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>Background & interactive</option><option value=2>Background only</option><option value=1>Interactive only</option></select>');
3159
+ x += addHtmlValue("Installation Type", '<select id=aginsType onchange=addAgentToMeshClick() style=width:236px><option value=0>' + "Background & interactive" + '</option><option value=2>' + "Background only" + '</option><option value=1>' + "Interactive only" + '</option></select>');
3160
x += '</div><hr>';
3161
3162
// \/:*?"<>|
@@ -3165,32 +3165,32 @@
3165
3166
// Windows agent install
3167
//x += "<div id=agins_windows>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and configuration file and install the agent on the computer to manage.<br /><br />";
3168
- x += "<div id=agins_windows>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and install it the computer to manage. This agent has server and device group information embedded within it.<br /><br />";
3169
- x += addHtmlValue('Mesh Agent', '<a id=aginsw32lnk href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title="32bit version of the MeshAgent">Windows (.exe)</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 32bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3170
- x += addHtmlValue('Mesh Agent', '<a id=aginsw64lnk href="meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title="64bit version of the MeshAgent">Windows x64 (.exe)</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 64bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3171
- if (debugmode > 0) { x += addHtmlValue('Settings File', '<a id=aginswmshlnk href="meshsettings?id=' + meshid.split('/')[2] + '&installflags=0" rel="noreferrer noopener" target="_blank">' + EscapeHtml(mesh.name) + ' settings (.msh)</a>'); }
3172
- x += "</div>";
3168
+ x += '<div id=agins_windows>' + format("To add a new computer to device group \"{0}\", download the mesh agent and install it the computer to manage. This agent has server and device group information embedded within it.", EscapeHtml(mesh.name)) + '<br /><br />';
3169
+ x += addHtmlValue("Mesh Agent", '<a id=aginsw32lnk href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title=\"' + "32bit version of the MeshAgent" + '\">' + "Windows (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 32bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3170
+ x += addHtmlValue("Mesh Agent", '<a id=aginsw64lnk href="meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=0" download onclick="setDialogMode(0)" title=\"' + "64bit version of the MeshAgent" + '\">' + "Windows x64 (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="Copy Windows 64bit agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
3171
+ if (debugmode > 0) { x += addHtmlValue("Settings File", '<a id=aginswmshlnk href="meshsettings?id=' + meshid.split('/')[2] + '&installflags=0" rel="noreferrer noopener" target="_blank">' + format("{0} settings (.msh)", EscapeHtml(mesh.name)) + '</a>'); }
3172
+ x += '</div>';
3173
3174
// Linux agent install
3175
- x += "<div id=agins_linux style=display:none>To add a computer to " + EscapeHtml(mesh.name) + " run the following command. Root credentials will be needed.<br />";
3175
+ x += '<div id=agins_linux style=display:none>' + format("To add a computer to {0} run the following command. Root credentials will be needed.", EscapeHtml(mesh.name)) + '<br />';
3176
x += '<textarea id=agins_linux_area rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
3177
- x += "<div style='font-size:x-small'>* For BSD, run \"pkg install wget sudo bash\" first.</div></div>";
3177
+ x += '<div style=\'font-size:x-small\'>' + "* For BSD, run \"pkg install wget sudo bash\" first." + '</div></div>';
3178
3179
// MacOS agent install
3180
- x += "<div id=agins_osx style=display:none>To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and install it the computer to manage. This agent installer has server and device group information embedded within it.<br /><br />";
3181
- x += addHtmlValue('Mesh Agent', '<a href="meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '" rel="noreferrer noopener" target="_blank" title="64bit version of MacOS Mesh Agent">MacOS Agent (64bit)</a> <img src=images/link4.png height=10 width=10 title="Copy MacOS agent URL to clipboard" style=cursor:pointer onclick=copyAgentUrl("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '",0)>');
3182
- x += "</div>";
3180
+ x += '<div id=agins_osx style=display:none>' + format("To add a new computer to device group \"{0}\", download the mesh agent and install it the computer to manage. This agent installer has server and device group information embedded within it.", EscapeHtml(mesh.name)) + '<br /><br />';
3181
+ x += addHtmlValue("Mesh Agent", '<a href="meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '" rel="noreferrer noopener" target="_blank" title="64bit version of MacOS Mesh Agent">MacOS Agent (64bit)</a> <img src=images/link4.png height=10 width=10 title="' + "Copy MacOS agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '",0)>');
3182
+ x += '</div>';
3183
3184
// Windows agent uninstall
3185
- x += "<div id=agins_windows_un style=display:none>To remove a mesh agent, download the file below, run it and click \"uninstall\".<br /><br />";
3186
- x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=3" download onclick="setDialogMode(0)" title="32bit version of the MeshAgent">Windows (.exe)</a>');
3187
- x += addHtmlValue('Mesh Agent', '<a href="meshagents?id=4" download onclick="setDialogMode(0)" title="64bit version of the MeshAgent">Windows x64 (.exe)</a>');
3188
- x += "</div>";
3185
+ x += '<div id=agins_windows_un style=display:none>' + "To remove a mesh agent, download the file below, run it and click \"uninstall\"." + '<br /><br />';
3186
+ x += addHtmlValue("Mesh Agent", '<a href="meshagents?id=3" download onclick="setDialogMode(0)" title="' + "32bit version of the MeshAgent" + '">' + "Windows (.exe)" + '</a>');
3187
+ x += addHtmlValue("Mesh Agent", '<a href="meshagents?id=4" download onclick="setDialogMode(0)" title="' + "64bit version of the MeshAgent" + '">' + "Windows x64 (.exe)" + '</a>');
3188
+ x += '</div>';
3189
3190
// Linux agent uninstall
3191
- x += "<div id=agins_linux_un style=display:none>To remove a mesh agent, run the following command. Root credentials will be needed.<br />";
3191
+ x += '<div id=agins_linux_un style=display:none>' + "To remove a mesh agent, run the following command. Root credentials will be needed." + '<br />';
3192
x += '<textarea id=agins_linux_area_un rows=2 cols=20 readonly=readonly style=width:100%;resize:none;height:120px;overflow:scroll;font-size:12px readonly></textarea>';
3193
- x += "</div>";
3193
+ x += '</div>';
3194
3195
setDialogMode(2, "Add Mesh Agent", 2, null, x, 'fileDownload');
3196
var servername = serverinfo.name;
@@ -3199,32 +3199,32 @@
3199
3200
if (serverinfo.https == true)
3201
{
3202
- var portStr = (serverinfo.port == 443)?'':(":" + serverinfo.port);
3202
+ var portStr = (serverinfo.port == 443)?'':(':' + serverinfo.port);
3203
if ((features & 0x2000) == 0)
3204
{
3205
- Q('agins_linux_area').value = "(wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh https://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3206
- Q('agins_linux_area_un').value = "(wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3205
+ Q('agins_linux_area').value = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid.split('/')[2] + '\'\r\n';
3206
+ Q('agins_linux_area_un').value = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
3207
}
3208
else
3209
{
3210
// Server asked that agent be installed to preferably not use a HTTP proxy.
3211
- Q('agins_linux_area').value = "wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3212
- Q('agins_linux_area_un').value = "wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3211
+ Q('agins_linux_area').value = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid.split('/')[2] + '\'\r\n';
3212
+ Q('agins_linux_area_un').value = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
3213
}
3214
}
3215
else
3216
{
3217
- var portStr = (serverinfo.port == 80) ? '' : (":" + serverinfo.port);
3217
+ var portStr = (serverinfo.port == 80) ? '' : (':' + serverinfo.port);
3218
if ((features & 0x2000) == 0)
3219
{
3220
- Q('agins_linux_area').value = "(wget http://" + servername + portStr + domainUrl + "meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh http://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3221
- Q('agins_linux_area_un').value = "(wget http://" + servername + portStr + domainUrl + "meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3220
+ Q('agins_linux_area').value = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo -E ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid.split('/')[2] + '\'\r\n';
3221
+ Q('agins_linux_area_un').value = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
3222
}
3223
else
3224
{
3225
// Server asked that agent be installed to preferably not use a HTTP proxy.
3226
- Q('agins_linux_area').value = "wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://" + servername + portStr + domainUrlNoSlash + " '" + meshid.split('/')[2] + "'\r\n";
3227
- Q('agins_linux_area_un').value = "wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
3226
+ Q('agins_linux_area').value = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid.split('/')[2] + '\'\r\n';
3227
+ Q('agins_linux_area_un').value = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
3228
}
3229
}
3230
Q('aginsSelect').focus();
@@ -3236,8 +3236,8 @@
3236
var servername = serverinfo.name;
3237
if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
3238
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
3239
- var portStr = (serverinfo.port == 443) ? '' : (":" + serverinfo.port);
3240
- var c = "https://" + servername + portStr + domainUrl + url;
3239
+ var portStr = (serverinfo.port == 443) ? '' : (':' + serverinfo.port);
3240
+ var c = 'https://' + servername + portStr + domainUrl + url;
3241
if (addflag == 1) c += Q('aginsType').value;
3242
copyTextToClip(c);
3243
}
@@ -3271,7 +3271,7 @@
3271
3272
function deviceHeaderSet() {
3273
if (deviceHeaderId == 0) { deviceHeaderId = 1; return; }
3274
- deviceHeaders["DevxHeader" + deviceHeaderId] = deviceHeaderTotal + ((deviceHeaderTotal == 1) ? ' node' : ' nodes');
3274
+ deviceHeaders['DevxHeader' + deviceHeaderId] = deviceHeaderTotal + ((deviceHeaderTotal == 1) ? " node" : " nodes");
3275
//var title = '';
3276
//for (x in deviceHeaderCount) { if (title.length > 0) title += ', '; title += deviceHeaderCount[x] + ' ' + PowerStateStr2(x); }
3277
//deviceHeadersTitles["DevxHeader" + deviceHeaderId] = title;
@@ -3280,18 +3280,18 @@
3280
deviceHeaderTotal = 0;
3281
}
3282
3283
- var powerStateStrings = ['', '<span title="Device is powered on.">Powered</span>', '<span title="Device is in sleep state (S1).">Sleeping</span>', '<span title="Device is in sleep state (S2).">Sleeping</span>', '<span title="Device is in deep sleep state (S3).">Deep Sleep</span>', '<span title="Device is in hibernating state (S4).">Hibernating</span>', '<span title="Device is in powered off state (S5).">Soft-Off</span>', '<span title="Device is detected but power state could not be obtained.">Present</span>'];
3284
- var powerStateStrings2 = ['', 'Device is powered', 'Device is in sleep state (S1)', 'Device is in sleep state (S2)', 'Device is in deep sleep state (S3)', 'Device is hibernating (S4)', 'Device is in soft-off state (S5)', 'Device is present, but power state cannot be determined'];
3283
+ var powerStateStrings = ['', '<span title=\"' + "Device is powered on." + '\">' + "Powered" + '</span>', '<span title=\"' + "Device is in sleep state (S1)." + '\">' + "Sleeping" + '</span>', '<span title=\"' + "Device is in sleep state (S2)." + '\">' + "Sleeping" + '</span>', '<span title=\"' + "Device is in deep sleep state (S3)." + '\">' + "Deep Sleep" + '</span>', '<span title=\"' + "Device is in hibernating state (S4)." + '\">' + "Hibernating" + '</span>', '<span title=\"' + "Device is in powered off state (S5)." + '\">' + "Soft-Off" + '</span>', '<span title=\"' + "Device is detected but power state could not be obtained." + '\">' + "Present" + '</span>'];
3284
+ var powerStateStrings2 = ['', "Device is powered", "Device is in sleep state (S1)", "Device is in sleep state (S2)", "Device is in deep sleep state (S3)", "Device is hibernating (S4)", "Device is in soft-off state (S5)", "Device is present, but power state cannot be determined"];
3285
var powerColorTable = ['pwsTransparent', 'pwsBlack', 'pwsBlue', 'pwsBlue2', 'pwsLightblue', 'pwsBlueviolet', 'pwsDarkgreen', 'pwsLightseagreen', 'pwsLightseagreen2'];
3286
function NodeStateStr(node) {
3287
var states = [];
3288
if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]);
3289
if (node.conn) {
3290
- if ((node.conn & 1) != 0) { states.push('<span title="Mesh agent is connected and ready for use.">Agent</span>'); }
3291
- if ((node.conn & 2) != 0) { states.push('<span title="Intel® AMT CIRA is connected and ready for use.">CIRA</span>'); }
3292
- else if ((node.conn & 4) != 0) { states.push('<span title="Intel® AMT is routable.">AMT</span>'); }
3293
- if ((node.conn & 8) != 0) { states.push('<span title="Mesh agent is reachable using another agent as relay.">Relay</span>'); }
3294
- if ((node.conn & 16) != 0) { states.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
3290
+ if ((node.conn & 1) != 0) { states.push('<span title=\"' + "Mesh agent is connected and ready for use." + '\">' + "Agent" + '</span>'); }
3291
+ if ((node.conn & 2) != 0) { states.push('<span title=\"' + "Intel® AMT CIRA is connected and ready for use." + '\">' + "CIRA" + '</span>'); }
3292
+ else if ((node.conn & 4) != 0) { states.push('<span title=\"' + "Intel® AMT is routable." + '\">' + "AMT" + '</span>'); }
3293
+ if ((node.conn & 8) != 0) { states.push('<span title=\"' + "Mesh agent is reachable using another agent as relay." + '\">' + "Relay" + '</span>'); }
3294
+ if ((node.conn & 16) != 0) { states.push('<span title=\"' + "MQTT connection to the device is active." + '\">' + "MQTT" + '</span>'); }
3295
}
3296
if ((node.pwr != null) && (node.pwr != 0)) { states.push(powerStateStrings[node.pwr]); }
3297
return states.join(', ');
@@ -3304,27 +3304,27 @@
3304
3305
function PowerStateStr2(x) {
3306
if ((x != 0) && (x < powerStatetable.length)) return powerStatetable[x];
3307
- return 'Unknown';
3307
+ return "Unknown";
3308
}
3309
3310
function selectallButtonFunction() {
3311
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
3311
+ var elements = document.getElementsByClassName('DeviceCheckbox'), checkcount = 0;
3312
for (var i=0;i<elements.length;i++) { if (elements[i].checked === true) checkcount++; }
3313
for (var i=0;i<elements.length;i++) { elements[i].checked = (checkcount == 0); }
3314
p1updateInfo();
3315
}
3316
3317
function p1updateInfo() {
3318
- var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
3318
+ var elements = document.getElementsByClassName('DeviceCheckbox'), checkcount = 0;
3319
for (var i=0;i<elements.length;i++) { if (elements[i].checked === true) { checkcount++; } }
3320
if (checkcount > 0) {
3321
QE('GroupActionButton', true);
3322
- Q('SelectAllButton').value = 'Select None';
3322
+ Q('SelectAllButton').value = "Select None";
3323
QV('cxmgroupsplit', true);
3324
QV('cxmdesktop', true);
3325
} else {
3326
QE('GroupActionButton', false);
3327
- Q('SelectAllButton').value = 'Select All';
3327
+ Q('SelectAllButton').value = "Select All";
3328
QV('cxmgroupsplit', false);
3329
QV('cxmdesktop', false);
3330
}
@@ -3334,10 +3334,10 @@
3334
var mqttx = '';
3335
if (features & 0x00400000) { // Check if any of the selected devices have a MQTT connection active
3336
var nodeids = getCheckedDevices();
3337
- for (var i in nodeids) { if ((getNodeFromId(nodeids[i]).conn & 16) != 0) { mqttx = '<option value=103>Send MQTT Message</option>'; } }
3337
+ for (var i in nodeids) { if ((getNodeFromId(nodeids[i]).conn & 16) != 0) { mqttx = '<option value=103>' + "Send MQTT Message" + '</option>'; } }
3338
}
3339
- var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights.<br /><br />";
3340
- x += addHtmlValue('Operation', '<select id=d2groupop><option value=100>Wake-up devices</option><option value=4>Sleep devices</option><option value=3>Reset devices</option><option value=2>Power off devices</option><option value=102>Move to device group</option>' + mqttx + '<option value=101>Delete devices</option></select>');
3339
+ var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights." + '<br /><br />';
3340
+ x += addHtmlValue("Operation", '<select id=d2groupop><option value=100>' + "Wake-up devices" + '</option><option value=4>' + "Sleep devices" + '</option><option value=3>' + "Reset devices" + '</option><option value=2>' + "Power off devices" + '</option><option value=102>' + "Move to device group" + '</option>' + mqttx + '<option value=101>' + "Delete devices" + '</option></select>');
3341
setDialogMode(2, "Group Action", 3, groupActionFunctionEx, x);
3342
}
3343
@@ -3355,8 +3355,8 @@
3355
meshserver.send({ action: 'wakedevices', nodeids: getCheckedDevices() });
3356
} else if (op == 101) {
3357
// Group delete, ask for confirmation
3358
- var x = "Confirm delete selected devices(s)?<br /><br />";
3359
- x += "<label><input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />Confirm</label>";
3358
+ var x = "Confirm delete selected devices(s)?" + '<br /><br />';
3359
+ x += '<label><input id=d2check type=checkbox onchange=d2groupActionFunctionDelEx() />' + "Confirm" + '</label>';
3360
setDialogMode(2, "Delete Nodes", 3, groupActionFunctionDelEx, x);
3361
QE('idx_dlgOkButton', false);
3362
} else if (op == 102) {
@@ -3375,8 +3375,8 @@
3375
function groupActionFunctionDelEx() { meshserver.send({ action: 'removedevices', nodeids: getCheckedDevices() }); }
3376
3377
function onSortSelectChange(skipsave) {
3378
- sort = document.getElementById("sortselect").selectedIndex;
3379
- if (!skipsave) { putstore("sort", sort); }
3378
+ sort = document.getElementById('sortselect').selectedIndex;
3379
+ if (!skipsave) { putstore('sort', sort); }
3380
}
3381
3382
function meshSort(a, b) { if (a.meshnamel > b.meshnamel) return 1; if (a.meshnamel < b.meshnamel) return -1; if (a.meshid == b.meshid) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } return 0; }
@@ -3389,7 +3389,7 @@
3389
function onConsoleFocus(x) { consoleFocus = x; }
3390
3391
function onSearchInputChanged() {
3392
- var x = Q('SearchInput').value.toLowerCase().trim(); putstore("_search", x);
3392
+ var x = Q('SearchInput').value.toLowerCase().trim(); putstore('_search', x);
3393
var userSearch = null, ipSearch = null, groupSearch = null;
3394
if (x.startsWith('user:')) { userSearch = x.substring(5); }
3395
else if (x.startsWith('u:')) { userSearch = x.substring(2); }
@@ -3439,26 +3439,26 @@
3439
var scrollLeft = (window.pageXOffset !== null) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
3440
var scrollTop = (window.pageYOffset !== null) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
3441
var elem = document.elementFromPoint(event.pageX - scrollLeft, event.pageY - scrollTop);
3442
- if (elem && elem != null && elem.id == "connectbutton2" && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3442
+ if (elem && elem != null && elem.id == 'connectbutton2' && currentNode && currentNode.agent && (currentNode.agent.id > 0) && (currentNode.agent.id < 5)) {
3443
contextelement = elem;
3444
- var contextmenudiv = document.getElementById("termShellContextMenu");
3445
- contextmenudiv.style.left = event.pageX + "px";
3446
- contextmenudiv.style.top = event.pageY + "px";
3447
- contextmenudiv.style.display = "block";
3448
- } else if (elem && elem != null && elem.id == "MxMESH") {
3444
+ var contextmenudiv = document.getElementById('termShellContextMenu');
3445
+ contextmenudiv.style.left = event.pageX + 'px';
3446
+ contextmenudiv.style.top = event.pageY + 'px';
3447
+ contextmenudiv.style.display = 'block';
3448
+ } else if (elem && elem != null && elem.id == 'MxMESH') {
3449
contextelement = elem;
3450
- var contextmenudiv = document.getElementById("meshContextMenu");
3451
- contextmenudiv.style.left = event.pageX + "px";
3452
- contextmenudiv.style.top = event.pageY + "px";
3453
- contextmenudiv.style.display = "block";
3450
+ var contextmenudiv = document.getElementById('meshContextMenu');
3451
+ contextmenudiv.style.left = event.pageX + 'px';
3452
+ contextmenudiv.style.top = event.pageY + 'px';
3453
+ contextmenudiv.style.display = 'block';
3454
} else {
3455
- while (elem && elem != null && elem.id != "devs") { elem = elem.parentElement; }
3455
+ while (elem && elem != null && elem.id != 'devs') { elem = elem.parentElement; }
3456
if (!elem || elem == null) return true;
3457
contextelement = elem;
3458
- var contextmenudiv = document.getElementById("contextMenu");
3459
- contextmenudiv.style.left = event.pageX + "px";
3460
- contextmenudiv.style.top = event.pageY + "px";
3461
- contextmenudiv.style.display = "block";
3458
+ var contextmenudiv = document.getElementById('contextMenu');
3459
+ contextmenudiv.style.left = event.pageX + 'px';
3460
+ contextmenudiv.style.top = event.pageY + 'px';
3461
+ contextmenudiv.style.display = 'block';
3462
3463
// Get the node and set the menu options
3464
var nodeid = contextelement.children[1].attributes.onclick.value;
@@ -3508,7 +3508,7 @@
3508
3509
function cmmeshaction(action) {
3510
var meshid = contextelement.attributes.onclick.value.substring(10, contextelement.attributes.onclick.value.length - 2);
3511
- var elements = document.getElementsByClassName("DeviceCheckbox");
3511
+ var elements = document.getElementsByClassName('DeviceCheckbox');
3512
if ((action == 1) || (action == 2)) {
3513
for (var i = 0; i < elements.length; i++) {
3514
if ((elements[i].attributes) && (elements[i].attributes['class']['value'].split(' ')[0] == meshid)) { elements[i].checked = (action == 1); }
@@ -3586,16 +3586,16 @@
3586
{ text: "Terminal", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 12); } } },
3587
{ text: "Intel® AMT", callback: function (obj) { if (obj.data !=null) { gotoDevice(obj.data, 14); } } },
3588
'-',
3589
- { text: 'Zoom-in to extent', callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 19); } },
3590
- { text: 'Zoom-out to extent', callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 2); } }
3589
+ { text: "Zoom-in to extent", callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 19); } },
3590
+ { text: "Zoom-out to extent", callback: function(obj) { var coords = obj.data.getGeometry().getCoordinates(); zoomToLocation(coords, 2); } }
3591
];
3592
3593
// Context menu for clicks other than on feature
3594
var contextmenu_items = [
3595
- { text: 'Refresh', callback: function () { refreshMap(true, true); } },
3596
- { text: 'Zoom to fit extent', callback: function () { zoomToFitExtent(); } },
3597
- { text: 'Center map here', callback: function(obj) { xxmap.mapView.animate({ center: obj.coordinate } ); } },
3598
- { text: 'Place node here', callback: function(obj) { placeNode(obj.coordinate); } }
3595
+ { text: "Refresh", callback: function () { refreshMap(true, true); } },
3596
+ { text: "Zoom to fit extent", callback: function () { zoomToFitExtent(); } },
3597
+ { text: "Center map here", callback: function(obj) { xxmap.mapView.animate({ center: obj.coordinate } ); } },
3598
+ { text: "Place node here", callback: function(obj) { placeNode(obj.coordinate); } }
3599
];
3600
3601
function stringToIntHash(str) {
@@ -3852,7 +3852,7 @@
3852
}
3853
}
3854
map_cm_nodemenu_items.forEach(function (item){
3855
- if (item.text == 'Zoom-in to extent' || item.text == 'Zoom-out to extent') { item.data = feature; }
3855
+ if (item.text == "Zoom-in to extent" || item.text == "Zoom-out to extent") { item.data = feature; }
3856
else { if (item != '-') { item.data = feature.getId(); } }
3857
});
3858
xxmap.contextmenu.extend(map_cm_nodemenu_items);
@@ -3925,7 +3925,7 @@
3925
// Called When Place a node option is clicked from context menu
3926
function placeNode(coords) {
3927
if (xxdialogMode) return;
3928
- var x = '<div style=margin-bottom:6px><label for=selectnode-search>Search</label>  <input type=text placeholder="Device name" id="selectnode-search" onchange=onPlaceNodeInputChange() onkeyup=onPlaceNodeInputChange() autocomplete=off style=width:120px></div><div id=placenode style="height:254px;overflow-y:auto;width:100%;margin:12px 1px 4px 1px;"><div id=noNodesMapPlace style=text-align:center;width:100%;display:none>No devices found.</div>';
3928
+ var x = '<div style=margin-bottom:6px><label for=selectnode-search>Search</label>  <input type=text placeholder="' + "Device name" + '" id="selectnode-search" onchange=onPlaceNodeInputChange() onkeyup=onPlaceNodeInputChange() autocomplete=off style=width:120px></div><div id=placenode style="height:254px;overflow-y:auto;width:100%;margin:12px 1px 4px 1px;"><div id=noNodesMapPlace style=text-align:center;width:100%;display:none>' + "No devices found." + '</div>';
3929
for (var i in nodes) {
3930
x += '<div class=noselect id=' + nodes[i]._id + '-rowid onclick=selectNodeToPlace(event,\''+ nodes[i]._id +'\') style=background-color:lightgray;margin-bottom:4px;border-radius:2px><input name=PlaceMapDeviceCheckbox id=' + nodes[i]._id + '-checkid type=checkbox style=width:16px;display:inline />';
3931
x += '<div class=j' + nodes[i].icon + ' style=width:16px;height:16px;margin-top:2px;margin-right:4px;display:inline-block></div><div style=width:16px;display:inline>' + nodes[i].name + '</div></div>';
@@ -3935,7 +3935,7 @@
3935
}
3936
3937
function placeNodeEx(button, coords) {
3938
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox");
3938
+ var elements = document.getElementsByName('PlaceMapDeviceCheckbox');
3939
for (var i in elements) {
3940
if (elements[i].checked) {
3941
var node = getNodeFromId(elements[i].id.substring(0, elements[i].id.length - 8));
@@ -3966,7 +3966,7 @@
3966
3967
// Update the list of devices in the "place on map" table
3968
function updatePlaceNodeTable(inputSearch) {
3969
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox"), count = 0;
3969
+ var elements = document.getElementsByName('PlaceMapDeviceCheckbox'), count = 0;
3970
for (var i in nodes) {
3971
var visible = ((nodes[i].namel.indexOf(inputSearch) >= 0 || inputSearch == '') || (nodes[i].rnamel != null && nodes[i].rnamel.indexOf(inputSearch) >= 0));
3972
if (visible) { count++; }
@@ -3993,7 +3993,7 @@
3993
if (e.target.name != 'PlaceMapDeviceCheckbox') { var inputElement = Q(id + '-checkid'); inputElement.checked = !inputElement.checked; }
3994
3995
// Check button state
3996
- var elements = document.getElementsByName("PlaceMapDeviceCheckbox"), checkcount = 0;
3996
+ var elements = document.getElementsByName('PlaceMapDeviceCheckbox'), checkcount = 0;
3997
for (var i in elements) { if (elements[i].checked) checkcount++; }
3998
QE('idx_dlgOkButton', checkcount > 0);
3999
}
@@ -4046,7 +4046,7 @@
4046
4047
// Reset Mesh dropdown option to 'All' when a current view mesh is deleted.
4048
function setMeshView(emeshid) {
4049
- var selectMeshElement=Q("select-mesh");
4049
+ var selectMeshElement=Q('select-mesh');
4050
var selectedIndex = selectMeshElement.selectedIndex;
4051
if (selectMeshElement[selectedIndex].value == emeshid) { selectMeshElement[0].selected = true; onSelectMeshChange(); }
4052
}
@@ -4066,7 +4066,7 @@
4066
if (searchdata.length > 0) {
4067
var xmlhttp = new XMLHttpRequest(); // Compatible with Chrome, Opera, Safari, IE7+, Firefox.
4068
xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { formatSearchData(xmlhttp.responseText); } }
4069
- xmlhttp.open("GET", 'https://nominatim.openstreetmap.org/search?q=' + searchdata + '&format=json', true); // Get request
4069
+ xmlhttp.open('GET', 'https://nominatim.openstreetmap.org/search?q=' + searchdata + '&format=json', true); // Get request
4070
xmlhttp.send();
4071
}
4072
} catch (e) {}
@@ -4090,7 +4090,7 @@
4090
var extent = [ parseFloat(dataInfo[0].boundingbox[2]), parseFloat(dataInfo[0].boundingbox[0]), parseFloat(dataInfo[0].boundingbox[3]), parseFloat(dataInfo[0].boundingbox[1]) ];
4091
zoomToExtent(extent);
4092
} else {
4093
- if (count == 0) { x = '<div style=width:200px>No location found.<div>'; }
4093
+ if (count == 0) { x = '<div style=width:200px>' + "No location found." + '<div>'; }
4094
QV('xmapSearchResultsDlg', true);
4095
}
4096
QH('xmapSearchResults', x);
@@ -4176,15 +4176,15 @@
4176
4177
// Add node name
4178
var nname = EscapeHtml(node.name);
4179
- if (nname.length == 0) { nname = '<i>None</i>'; }
4180
- if (((meshrights & 4) != 0) && ((!mesh.flags) || ((mesh.flags & 2) == 0))) { nname = '<span tabindex=0 title="Click here to edit the server-side device name" onclick=showEditNodeValueDialog(0) onkeyup="if (event.key == \'Enter\') showEditNodeValueDialog(0)" style=cursor:pointer>' + nname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
4179
+ if (nname.length == 0) { nname = '<i>' + "None" + '</i>'; }
4180
+ if (((meshrights & 4) != 0) && ((!mesh.flags) || ((mesh.flags & 2) == 0))) { nname = '<span tabindex=0 title=\"' + "Click here to edit the server-side device name" + '\" onclick=showEditNodeValueDialog(0) onkeyup="if (event.key == \'Enter\') showEditNodeValueDialog(0)" style=cursor:pointer>' + nname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
4181
nname += '<span style=color:#AAA;font-size:small> - ' + EscapeHtml(mesh.name) + '</span>';
4182
QH('p10deviceName', nname);
4183
QH('p11deviceName', nname);
4184
QH('p12deviceName', nname);
4185
QH('p13deviceName', nname);
4186
QH('p14deviceName', nname);
4187
- QH('p15deviceName', 'Console - ' + nname);
4187
+ QH('p15deviceName', "Console - " + nname);
4188
QH('p16deviceName', nname);
4189
QH('p17deviceName', nname);
4190
QH('p19deviceName', nname);
@@ -4193,7 +4193,7 @@
4193
var x = '<table style=width:100%>';
4194
4195
// Attribute: Mesh
4196
- x += addDeviceAttribute('<span title="The name of the device group this computer belong to.">Group</span>', '<a href=# title="The name of the device group this computer belong to" onclick=gotoMesh("' + node.meshid + '") style=cursor:pointer>' + EscapeHtml(meshes[node.meshid].name) + '</a>');
4196
+ x += addDeviceAttribute('<span title=\"' + "The name of the device group this computer belong to." + '\">' + "Group" + '</span>', '<a href=# title=\"' + "The name of the device group this computer belong to" + '\" onclick=gotoMesh("' + node.meshid + '") style=cursor:pointer>' + EscapeHtml(meshes[node.meshid].name) + '</a>');
4197
4198
// Attribute: Name
4199
if ((node.rname != null) && (node.name != node.rname)) { x += addDeviceAttribute('<span title="The name of this computer as set in the operating system">Name</span>', '<span title="The name of this computer as set in the operating system">' + EscapeHtml(node.rname) + '</span>'); }
@@ -4202,65 +4202,65 @@
4202
if ((features & 1) == 0) { // If not WAN-only, local hostname is in use
4203
if ((meshrights & 4) != 0) {
4204
if (node.host) {
4205
- x += addDeviceAttribute('Hostname', '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
4205
+ x += addDeviceAttribute("Hostname", '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
4206
} else {
4207
- x += addDeviceAttribute('Hostname', '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>None</i></span>');
4207
+ x += addDeviceAttribute("Hostname", '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>' + "None" + '</i></span>');
4208
}
4209
} else {
4210
- x += addDeviceAttribute('Hostname', EscapeHtml(node.host));
4210
+ x += addDeviceAttribute("Hostname", EscapeHtml(node.host));
4211
}
4212
}
4213
4214
// Attribute: Description
4215
- var description = node.desc?EscapeHtml(node.desc):"<i>None</i>";
4215
+ var description = node.desc?EscapeHtml(node.desc):('<i>' + "None" + '</i>');
4216
if ((meshrights & 4) != 0) {
4217
- x += addDeviceAttribute('Description', '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + ' <img class=hoverButton src="images/link5.png" /></span>');
4217
+ x += addDeviceAttribute("Description", '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + ' <img class=hoverButton src="images/link5.png" /></span>');
4218
} else {
4219
- x += addDeviceAttribute('Description', description);
4219
+ x += addDeviceAttribute("Description", description);
4220
}
4221
4222
// Attribute: Mesh Agent
4223
- var agentsStr = ['Unknown', 'Windows 32bit console', 'Windows 64bit console', 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'MacOS 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'MacOS 64bit', 'ChromeOS', 'Linux Poky x86-64bit', 'Linux NoKVM x86-32bit', 'Linux NoKVM x86-64bit', 'Windows MinCore console', 'Windows MinCore service', 'NodeJS', 'ARM-Linaro', 'ARMv6l / ARMv7l', 'ARMv8 64bit', 'ARMv6l / ARMv7l / NoKVM', 'Unknown', 'Unknown', 'FreeBSD x86-64'];
4223
+ var agentsStr = ["Unknown", "Windows 32bit console", "Windows 64bit console", "Windows 32bit service", "Windows 64bit service", "Linux 32bit", "Linux 64bit", "MIPS", "XENx86", "Android ARM", "Linux ARM", "MacOS 32bit", "Android x86", "PogoPlug ARM", "Android APK", "Linux Poky x86-32bit", "MacOS 64bit", "ChromeOS", "Linux Poky x86-64bit", "Linux NoKVM x86-32bit", "Linux NoKVM x86-64bit", "Windows MinCore console", "Windows MinCore service", "NodeJS", "ARM-Linaro", "ARMv6l / ARMv7l", "ARMv8 64bit", "ARMv6l / ARMv7l / NoKVM", "Unknown", "Unknown", "FreeBSD x86-64"];
4224
if ((node.agent != null) && (node.agent.id != null) && (node.agent.ver != null)) {
4225
var str = '';
4226
if (node.agent.id <= agentsStr.length) { str = agentsStr[node.agent.id]; } else { str = agentsStr[0]; }
4227
if (node.agent.ver != 0) { str += ' v' + node.agent.ver; }
4228
- x += addDeviceAttribute('Mesh Agent', str);
4228
+ x += addDeviceAttribute("Mesh Agent", str);
4229
}
4230
4231
// Attribute: Intel AMT
4232
if (node.intelamt != null) {
4233
var str = '';
4234
- var provisioningStates = { 0: 'Not Activated (Pre)', 1: 'Not Activated (In)', 2: 'Activated' };
4235
- if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>Unknown State</i>, v' + node.intelamt.ver; } else
4234
+ var provisioningStates = { 0: "Not Activated (Pre)", 1: "Not Activated (In)", 2: "Activated" };
4235
+ if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + "Unknown State" + '</i>, v' + node.intelamt.ver; } else
4236
4237
- if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>Activated</i>'; }
4238
- else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>Unknown Version & State</i>'; }
4237
+ if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>' + "Activated" + '</i>'; }
4238
+ else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>' + "Unknown Version & State" + '</i>'; }
4239
else {
4240
str += provisioningStates[node.intelamt.state];
4241
- if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { str += ' <span title="Intel AMT is activated in Client Control Mode">CCM</span>'; } else if (node.intelamt.flags & 4) { str += ' <span title="Intel AMT is activated in Admin Control Mode">ACM</span>'; } }
4241
+ if ((node.intelamt.state == 2) && node.intelamt.flags) { if (node.intelamt.flags & 2) { str += ' <span title=\"' + "Intel AMT is activated in Client Control Mode" + '\">' + "CCM" + '</span>'; } else if (node.intelamt.flags & 4) { str += ' <span title=\"' + "Intel AMT is activated in Admin Control Mode" + '\">' + "ACM" + '</span>'; } }
4242
str += (', v' + node.intelamt.ver);
4243
}
4244
4245
- if (node.intelamt.tls == 1) { str += ', <span title="Intel AMT is setup with TLS network security">TLS</span>'; }
4245
+ if (node.intelamt.tls == 1) { str += ', <span title=\"' + "Intel AMT is setup with TLS network security" + '\">' + "TLS" + '</span>'; }
4246
if (node.intelamt.state == 2) {
4247
if (node.intelamt.user == null || node.intelamt.user == '') {
4248
if ((meshrights & 4) != 0) {
4249
- str += ', <i style=color:#FF0000;cursor:pointer title="Edit Intel® AMT credentials" onclick=editDeviceAmtSettings("' + node._id + '")>No Credentials</i>';
4249
+ str += ', <i style=color:#FF0000;cursor:pointer title=\"' + "Edit Intel® AMT credentials" + '\" onclick=editDeviceAmtSettings("' + node._id + '")>' + "No Credentials" + '</i>';
4250
} else {
4251
- str += ', <i style=color:#FF0000>No Credentials</i>';
4251
+ str += ', <i style=color:#FF0000>' + "No Credentials" + '</i>';
4252
}
4253
}
4254
str += ' ';
4255
if ((meshrights & 4) != 0) {
4256
- str += '<img src=images/link4.png height=10 width=10 title="Edit Intel® AMT credentials" style=cursor:pointer onclick=editDeviceAmtSettings("' + node._id + '")>';
4256
+ str += '<img src=images/link4.png height=10 width=10 title=\"' + "Edit Intel® AMT credentials" + '\" style=cursor:pointer onclick=editDeviceAmtSettings("' + node._id + '")>';
4257
}
4258
}
4259
4260
- var meName = '<span title="Intel® Manageability Engine">Intel® ME<span>';
4260
+ var meName = '<span title=\"Intel® Manageability Engine\">' + "Intel® ME" + '<span>';
4261
if (typeof node.intelamt.sku == 'number') {
4262
- if ((node.intelamt.sku & 8) != 0) { meName = '<span title="Intel® Active Management Technology">Intel® AMT<span>'; }
4263
- else if ((node.intelamt.sku & 16) != 0) { meName = '<span title="Intel® Standard Manageability">Intel® SM<span>'; }
4262
+ if ((node.intelamt.sku & 8) != 0) { meName = '<span title=\"' + "Intel® Active Management Technology" + '\">' + "Intel® AMT" + '<span>'; }
4263
+ else if ((node.intelamt.sku & 16) != 0) { meName = '<span title=\"' + "Intel® Standard Manageability" + '\">' + "Intel® SM" + '<span>'; }
4264
}
4265
x += addDeviceAttribute(meName, str);
4266
}
@@ -4270,14 +4270,14 @@
4270
if ((node.agent != null) && (node.agent.tag != null)) {
4271
var tag = EscapeHtml(node.agent.tag);
4272
if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
4273
- x += addDeviceAttribute('Agent Tag', tag);
4273
+ x += addDeviceAttribute("Agent Tag", tag);
4274
}
4275
} else {
4276
// Attribute: Intel AMT Tag
4277
if ((node.intelamt != null) && (node.intelamt.tag != null)) {
4278
var tag = EscapeHtml(node.intelamt.tag);
4279
if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
4280
- x += addDeviceAttribute('Intel® AMT Tag', tag);
4280
+ x += addDeviceAttribute("Intel® AMT Tag", tag);
4281
}
4282
}
4283
@@ -4285,7 +4285,7 @@
4285
//if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
4286
4287
// Operating system description
4288
- if (node.osdesc) { x += addDeviceAttribute('Operating System', node.osdesc); }
4288
+ if (node.osdesc) { x += addDeviceAttribute("Operating System", node.osdesc); }
4289
4290
// Antivirus
4291
if (node.av && node.av.length > 0) {
@@ -4293,32 +4293,32 @@
4293
for (var i in node.av) {
4294
if (node.av[i].product) {
4295
var avx = EscapeHtml(node.av[i].product);
4296
- if (node.av[i].enabled !== true) { avx += ' - <span style=color:red>Disabled</span>'; }
4297
- if (node.av[i].updated !== true) { avx += ' - <span style=color:red>Out of date</span>'; }
4298
- if ((node.av[i].enabled == true) && (node.av[i].updated == true)) { avx += ' - <span style=color:green>OK</span>'; }
4296
+ if (node.av[i].enabled !== true) { avx += ' - <span style=color:red>' + "Disabled" + '</span>'; }
4297
+ if (node.av[i].updated !== true) { avx += ' - <span style=color:red>' + "Out of date" + '</span>'; }
4298
+ if ((node.av[i].enabled == true) && (node.av[i].updated == true)) { avx += ' - <span style=color:green>' + "OK" + '</span>'; }
4299
y.push(avx);
4300
}
4301
}
4302
- x += addDeviceAttribute('Antivirus', y.join('<br />'));
4302
+ x += addDeviceAttribute("Antivirus", y.join('<br />'));
4303
}
4304
4305
// Active Users
4306
- if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute('Active User' + ((node.users.length > 1)?'s':''), node.users.join(', ')); }
4306
+ if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute(format("Active User{0}", ((node.users.length > 1)?'s':'')), node.users.join(', ')); }
4307
4308
// Attribute: Connectivity (Only show this if more than just the agent is connected).
4309
var connectivity = node.conn;
4310
if (connectivity && connectivity > 1) {
4311
var cstate = [];
4312
- if ((node.conn & 1) != 0) cstate.push('<span title="Mesh agent is connected and ready for use.">Mesh Agent</span>');
4313
- if ((node.conn & 2) != 0) cstate.push('<span title="Intel® AMT CIRA is connected and ready for use.">Intel® AMT CIRA</span>');
4314
- else if ((node.conn & 4) != 0) cstate.push('<span title="Intel® AMT is routable and ready for use.">Intel® AMT</span>');
4315
- if ((node.conn & 8) != 0) cstate.push('<span title="Mesh agent is reachable using another agent as relay.">Mesh Relay</span>');
4316
- if ((node.conn & 16) != 0) { cstate.push('<span title="MQTT connection to the device is active.">MQTT</span>'); }
4317
- x += addDeviceAttribute('Connectivity', cstate.join(', '));
4312
+ if ((node.conn & 1) != 0) cstate.push('<span title=\"' + "Mesh agent is connected and ready for use." + '\">' + "Mesh Agent" + '</span>');
4313
+ if ((node.conn & 2) != 0) cstate.push('<span title=\"' + "Intel® AMT CIRA is connected and ready for use." + '\">' + "Intel® AMT CIRA" + '</span>');
4314
+ else if ((node.conn & 4) != 0) cstate.push('<span title=\"' + "Intel® AMT is routable and ready for use." + '\">' + "Intel® AMT" + '</span>');
4315
+ if ((node.conn & 8) != 0) cstate.push('<span title=\"' + "Mesh agent is reachable using another agent as relay." + '\">' + "Mesh Relay" + '</span>');
4316
+ if ((node.conn & 16) != 0) { cstate.push('<span title=\"' + "MQTT connection to the device is active." + '\">' + "MQTT" + '</span>'); }
4317
+ x += addDeviceAttribute("Connectivity", cstate.join(', '));
4318
}
4319
4320
// Node grouping tags
4321
- var groupingTags = '<i>None</i>';
4321
+ var groupingTags = '<i>' + "None" + '</i>';
4322
if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '<span class="tagSpan">' + node.tags[i] + '</span>'; } }
4323
if ((meshrights & 4) != 0) {
4324
x += addDeviceAttribute('Tags', '<span onclick=showEditNodeValueDialog(3) style=cursor:pointer>' + groupingTags + ' <img class=hoverButton src="images/link5.png" /></span>');
@@ -4328,9 +4328,9 @@
4328
4329
x += '</table><br />';
4330
// Show action button, only show if we have permissions 4, 8, 64
4331
- if ((meshrights & 76) != 0) { x += '<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'; }
4332
- x += '<input type=button value=Notes title="View notes about this device" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponent(node._id) + '") />';
4333
- x += '<input type=button value="Log Event" title="Write an event for this device" onclick=writeDeviceEvent("' + encodeURIComponent(node._id) + '") />';
4331
+ if ((meshrights & 76) != 0) { x += '<input type=button value=\"' + "Actions" + '\" title=\"' + "Perform power actions on the device" + '\" onclick=deviceActionFunction() />'; }
4332
+ x += '<input type=button value=\"' + "Notes" + '\" title=\"' + "View notes about this device" + '\" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponent(node._id) + '") />';
4333
+ x += '<input type=button value=\"' + "Log Event" + '\" title=\"' + "Write an event for this device" + '\" onclick=writeDeviceEvent("' + encodeURIComponent(node._id) + '") />';
4334
//if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="Display a text message of the remote device" onclick=deviceToastFunction() />'; }
4335
QH('p10html', x);
4336
@@ -4341,25 +4341,25 @@
4341
x = '<div class="p10html3right">';
4342
if ((meshrights & 4) != 0) {
4343
// TODO: Show change group only if there is another mesh of the same type.
4344
- x += ' <a href=# onclick=p10showChangeGroupDialog(["' + node._id + '"]) title="Move this device to a different device group">Change Group</a>';
4345
- x += ' <a href=# onclick=p10showDeleteNodeDialog("' + node._id + '") title="Remove this device">Delete Device</a>';
4344
+ x += ' <a href=# onclick=p10showChangeGroupDialog(["' + node._id + '"]) title=\"' + "Move this device to a different device group" + '\">' + "Change Group" + '</a>';
4345
+ x += ' <a href=# onclick=p10showDeleteNodeDialog("' + node._id + '") title=\"' + "Remove this device" + '\">' + "Delete Device" + '</a>';
4346
}
4347
x += '</div><div class="p10html3left">';
4348
- if (mesh.mtype == 2) x += '<a href=# onclick=p10showNodeNetInfoDialog("' + node._id + '") title="Show device network interface information">Interfaces</a> ';
4349
- if (xxmap != null) x += '<a href=# onclick=p10showNodeLocationDialog("' + node._id + '") title="Show device locations information">Location</a> ';
4350
- if (((meshrights & 8) != 0) && (mesh.mtype == 2)) x += '<a href=# onclick=p10showMeshCmdDialog(1,"' + node._id + '") title="Traffic router used to connect to a device thru this server.">Router</a> ';
4348
+ if (mesh.mtype == 2) x += '<a href=# onclick=p10showNodeNetInfoDialog("' + node._id + '") title=\"' + "Show device network interface information" + '\">' + "Interfaces" + '</a> ';
4349
+ if (xxmap != null) x += '<a href=# onclick=p10showNodeLocationDialog("' + node._id + '") title=\"' + "Show device locations information" + '\">' + "Location" + '</a> ';
4350
+ if (((meshrights & 8) != 0) && (mesh.mtype == 2)) x += '<a href=# onclick=p10showMeshCmdDialog(1,"' + node._id + '") title=\"' + "Traffic router used to connect to a device thru this server" + '.\">' + "Router" + '</a> ';
4351
4352
// RDP link, show this link only of the remote machine is Windows.
4353
if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
4354
- if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# onclick=p10clickOnce("' + node._id + '","RDP2",3389) title="Requires Microsoft ClickOnce support in your browser.">RDP</a> '; }
4354
+ if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a href=# onclick=p10clickOnce("' + node._id + '","RDP2",3389) title=\"' + "Requires Microsoft ClickOnce support in your browser" + '.\">' + "RDP" + '</a> '; }
4355
if (node.agent.id > 4) {
4356
- x += '<a href=# onclick=p10clickOnce("' + node._id + '","PSSH",22) title="Requires Microsoft ClickOnce support in your browser.">Putty</a> ';
4357
- x += '<a href=# onclick=p10clickOnce("' + node._id + '","WSCP",22) title="Requires Microsoft ClickOnce support in your browser.">WinSCP</a> ';
4356
+ x += '<a href=# onclick=p10clickOnce("' + node._id + '","PSSH",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "Putty" + '</a> ';
4357
+ x += '<a href=# onclick=p10clickOnce("' + node._id + '","WSCP",22) title=\"' + "Requires Microsoft ClickOnce support in your browser." + '\">' + "WinSCP" + '</a> ';
4358
}
4359
}
4360
4361
// MQTT options
4362
- if ((meshrights == 0xFFFFFFFF) && (features & 0x00400000)) { x += '<a href=# onclick=p10showMqttLoginDialog("' + node._id + '") title="Get MQTT login credentials for this device.">MQTT Login</a> '; }
4362
+ if ((meshrights == 0xFFFFFFFF) && (features & 0x00400000)) { x += '<a href=# onclick=p10showMqttLoginDialog("' + node._id + '") title=\"' + "Get MQTT login credentials for this device." + '\">' + "MQTT Login" + '</a> '; }
4363
x += '</div><br>'
4364
4365
QH('p10html3', x);
@@ -4367,15 +4367,15 @@
4367
// Set the node power state
4368
var powerstate = PowerStateStr(node.state);
4369
//if (node.state == 0) { powerstate = 'Unknown State'; }
4370
- if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Agent connected">Agent connected</span>'; }
4371
- if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Intel® AMT connected">Intel® AMT connected</span>'; }
4372
- else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="Intel® AMT detected">Intel® AMT detected</span>'; }
4373
- if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title="MQTT connected">MQTT channel connected</span>'; }
4374
- if ((powerstate == '') && node.lastconnect) { powerstate = '<span style=font-size:12px>Last seen:<br />' + printDateTime(new Date(node.lastconnect)) + '</span>'; }
4370
+ if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title=\"' + "Agent connected" + '\">' + "Agent connected" + '</span>'; }
4371
+ if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title=\"' + "Intel® AMT connected" + '\">' + "Intel® AMT connected" + '</span>'; }
4372
+ else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title=\"' + "Intel® AMT detected" + '\">' + "Intel® AMT detected" + '</span>'; }
4373
+ if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px title=\"' + "MQTT connected" + '\">' + "MQTT channel connected" + '</span>'; }
4374
+ if ((powerstate == '') && node.lastconnect) { powerstate = '<span style=font-size:12px>' + "Last seen:" + '<br />' + printDateTime(new Date(node.lastconnect)) + '</span>'; }
4375
QH('MainComputerState', powerstate);
4376
4377
// Set the node icon
4378
- Q('MainComputerImage').setAttribute("src", "images/icons256-" + node.icon + "-1.png");
4378
+ Q('MainComputerImage').setAttribute('src', 'images/icons256-' + node.icon + '-1.png');
4379
Q('MainComputerImage').className = ((!node.conn) || (node.conn == 0)?'gray':'');
4380
4381
// Check if we have terminal and file access
@@ -4675,7 +4675,7 @@
4675
var meshrights = meshes[i].links[userinfo._id].rights;
4676
if ((meshes[i]._id != targetMeshId) && (meshrights & 4)) { count++; y += '<option value=\'' + meshes[i]._id + '\'>' + meshes[i].name + '</option>'; }
4677
}
4678
- y += "</select>";
4678
+ y += '</select>';
4679
4680
if (count > 0) {
4681
var x = (nodeids.length == 1) ? ("Select a new group for this device" + '<br /><br />') : ("Select a new group for selected devices" + '<br /><br />');
@@ -4792,14 +4792,14 @@
4792
y += '<option value=25>' + "Linux ARM, Raspberry Pi (32bit)" + '</option>';
4793
y += '</select>';
4794
4795
- var x = "";
4795
+ var x = '';
4796
if (mode == 0) { x += '<div>MeshCmd is a command line tool that performs lots of different operations. The action file can optionally be downloaded and edited to provide server information and credentials.<br /><br />'; }
4797
if (mode == 1) { x += '<div>Download "meshcmd" with an action file to route traffic thru this server to this device. Make sure to edit meshaction.txt and add your account password or make any changes needed.<br /><br />'; }
4798
x += addHtmlValue('Operating System', y);
4799
x += addHtmlValue('MeshCmd', '<a id=meshcmddownloadid href="meshagents?meshcmd=3" download></a>');
4800
if (mode == 0) { x += addHtmlValue('Action File', '<a href="meshagents?meshaction=generic" download>MeshAction (.txt)</a>'); }
4801
if (mode == 1) { x += addHtmlValue('Action File', '<a href="meshagents?meshaction=route&nodeid=' + nodeid + '" download>MeshAction (.txt)</a>'); }
4802
- x += "</div>";
4802
+ x += '</div>';
4803
setDialogMode(2, [ "Download MeshCmd", "Network Router" ][mode], 9, null, x, 'fileDownload');
4804
meshCmdOsClick();
4805
}
@@ -5039,7 +5039,7 @@
5039
if (e.candidate == null) {
5040
desktop.m.sendKvmData(JSON.stringify({ action: 'offer', ver: 1, sdp: webRtcDesktop.webrtcoffer.sdp }));
5041
} else {
5042
- webRtcDesktop.webrtcoffer.sdp += ("a=" + e.candidate.candidate + "\r\n"); // New candidate, add it to the SDP
5042
+ webRtcDesktop.webrtcoffer.sdp += ('a=' + e.candidate.candidate + '\r\n'); // New candidate, add it to the SDP
5043
}
5044
}
5045
webRtcDesktop.webrtc.oniceconnectionstatechange = function () {
@@ -5944,7 +5944,7 @@
5944
//console.log('p13gotFiles', data);
5945
data = JSON.parse(decode_utf8(data));
5946
if (data.action == 'download') { p13gotDownloadCommand(data); return; }
5947
- data.path = data.path.replace(/\//g, "\\");
5947
+ data.path = data.path.replace(/\//g, '\\');
5948
if ((p13filetree != null) && (data.path == p13filetree.path)) {
5949
// This is an update to the same folder
5950
var checkedNames = p13getCheckedNames();
@@ -5952,7 +5952,7 @@
5952
p13updateFiles(checkedNames);
5953
} else {
5954
// Make both paths use the same seperator not start with /
5955
- var x1 = data.path.replace(/\//g, "\\"), x2 = p13targetpath.replace(/\//g, "\\");
5955
+ var x1 = data.path.replace(/\//g, '\\'), x2 = p13targetpath.replace(/\//g, '\\');
5956
while ((x1.length > 0) && (x1[0] == '\\')) { x1 = x1.substring(1); }
5957
while ((x2.length > 0) && (x2[0] == '\\')) { x2 = x2.substring(1); }
5958
if ((x1 == x2) || ((data.path == '\\') && (p13targetpath == ''))) {
@@ -5988,7 +5988,7 @@
5988
// Figure out the name and shortname
5989
var f = filetreexx[i], name = f.n, shortname;
5990
shortname = name;
5991
- if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + "...</span>"; } else { shortname = EscapeHtml(name); }
5991
+ if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + ("..." + '</span>'); } else { shortname = EscapeHtml(name); }
5992
name = EscapeHtml(name);
5993
5994
// Figure out the date
@@ -6082,8 +6082,8 @@
6082
}
6083
}
6084
6085
- function p13getFileSelCount(includeDirs) { var cc = 0; var checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == "3"))) cc++; } return cc; }
6086
- function p13getFileSelDirCount() { var cc = 0, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "999")) cc++; } return cc; }
6085
+ function p13getFileSelCount(includeDirs) { var cc = 0; var checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == '3'))) cc++; } return cc; }
6086
+ function p13getFileSelDirCount() { var cc = 0, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '999')) cc++; } return cc; }
6087
function p13getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fd'); return checkboxes.length; }
6088
function p13selectallfile() { var nv = (p13getFileSelCount() == 0), checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p13setActions(); }
6089
function p13createfolder() { setDialogMode(2, "New Folder", 3, p13createfolderEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />'); focusTextBox('p13renameinput'); p13fileNameCheck(); }
@@ -6108,10 +6108,39 @@
6108
}
6109
6110
var p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0;
6111
- function p13copyFile(cut) { var checkboxes = document.getElementsByName('fd'); p13clipboard = []; p13clipboardCut = cut, p13clipboardFolder = p13targetpath; for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "3")) { p13clipboard.push(p13filetree.dir[checkboxes[i].value].n); } } p13updateClipview(); }
6112
- function p13pasteFile() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Confim ' + (p13clipboardCut == 0?'copy':'move') + ' of ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1)?'s':'') + ' to this location?' } setDialogMode(2, "Paste", 3, p13pasteFileEx, x); }
6111
+ function p13copyFile(cut) { var checkboxes = document.getElementsByName('fd'); p13clipboard = []; p13clipboardCut = cut, p13clipboardFolder = p13targetpath; for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '3')) { p13clipboard.push(p13filetree.dir[checkboxes[i].value].n); } } p13updateClipview(); }
6112
+ function p13pasteFile() {
6113
+ var x = '';
6114
+ if ((p13clipboard != null) && (p13clipboard.length > 0)) {
6115
+ if (p13clipboardCut == 0) {
6116
+ if (p13clipboard.length > 1) { x = format("Confirm copy of {0} entries's to this location?", p13clipboard.length); } else { x = format("Confirm copy of 1 entrie to this location?"); }
6117
+ } else {
6118
+ if (p13clipboard.length > 1) { x = format("Confirm move of {0} entries's to this location?", p13clipboard.length); } else { x = format("Confirm move of 1 entrie to this location?"); }
6119
+ }
6120
+ }
6121
+ setDialogMode(2, "Paste", 3, p13pasteFileEx, x);
6122
+ }
6123
function p13pasteFileEx() { files.sendText({ action: (p13clipboardCut == 0?'copy':'move'), reqid: 1, scpath: p13clipboardFolder, dspath: p13targetpath, names: p13clipboard }); p13folderup(999); if (p13clipboardCut == 1) { p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0; p13updateClipview(); } }
6114
- function p13updateClipview() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Holding ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1)?'s':'') + ' for ' + (p13clipboardCut == 0?'copy':'move') + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>Clear</a>.' } QH('p13bottomstatus', x); p13setActions(); }
6124
+ function p13updateClipview() {
6125
+ var x = '';
6126
+ if ((p13clipboard != null) && (p13clipboard.length > 0)) {
6127
+ if (p13clipboardCut == 0) {
6128
+ if (p13clipboard.length > 1) {
6129
+ x = format("Holding {0} entries for copy" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.', p13clipboard.length);
6130
+ } else {
6131
+ x = format("Holding 1 entrie for copy" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.');
6132
+ }
6133
+ } else {
6134
+ if (p13clipboard.length > 1) {
6135
+ x = format("Holding {0} entries for move" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.', p13clipboard.length);
6136
+ } else {
6137
+ x = format("Holding 1 entrie for move" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Clear" + '</a>.');
6138
+ }
6139
+ }
6140
+ }
6141
+ QH('p13bottomstatus', x);
6142
+ p13setActions();
6143
+ }
6144
function p13clearClip() { p13clipboard = null; p13clipboardFolder = null; p13clipboardCut = 0; p13updateClipview(); return false; }
6145
6146
function p13fileDragDrop(e) {
@@ -6683,7 +6712,7 @@
6712
6713
function account_addOtp() {
6714
if (xxdialogMode || (userinfo.otpsecret == 1) || ((features & 4096) == 0)) return;
6686
- setDialogMode(2, "Authenticator App", 2, function () { meshserver.send({ action: 'otpauth-setup', secret: Q('d2optsecret').attributes.secret.value, token: Q('d2otpauthinput').value }); }, "<div id=d2optinfo>Loading...</div>", 'otpauth-request');
6715
+ setDialogMode(2, "Authenticator App", 2, function () { meshserver.send({ action: 'otpauth-setup', secret: Q('d2optsecret').attributes.secret.value, token: Q('d2otpauthinput').value }); }, ('<div id=d2optinfo>' + "Loading..." + '</div>'), 'otpauth-request');
6716
meshserver.send({ action: 'otpauth-request' });
6717
}
6718
@@ -6749,7 +6778,7 @@
6778
function account_showLocalizationSettings() {
6779
if (xxdialogMode) return false;
6780
var n = getstore('loctag', 0);
6752
- var x = '<select id=d2locselect style=width:100%><option value="*">' + "User browser value" + '</option>';
6781
+ var x = '<select id=d2locselect style=width:100%><option value=\"*\">' + "User browser value" + '</option>';
6782
for (var i in loclist) { x += '<option value="' + i + '"' + ((n == i)?' selected':'') + '>' + i + ' - ' + loclist[i] + '</option>'; }
6783
x += '</select>';
6784
var y = addHtmlValue("Localization", x);
@@ -6768,7 +6797,7 @@
6797
}
6798
6799
function account_enableNotifications() {
6771
- if (Notification) { Notification.requestPermission().then(function (permission) { QV('accountEnableNotificationsSpan', permission != "granted"); }); }
6800
+ if (Notification) { Notification.requestPermission().then(function (permission) { QV('accountEnableNotificationsSpan', permission != 'granted'); }); }
6801
return false;
6802
}
6803
@@ -7273,15 +7302,15 @@
7302
if (xxdialogMode) return;
7303
var x = '', consent = (currentMesh.consent) ? currentMesh.consent : 0;
7304
x += '<div style="width:100%;border-bottom:1px solid gray;margin-bottom:5px"><b>' + "Desktop" + '</b></div>';
7276
- x += "<div><label><input type=checkbox id=d20flag1 " + ((consent & 0x0001) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7277
- x += "<div><label><input type=checkbox id=d20flag2 " + ((consent & 0x0008) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7278
- if (debugmode) { x += "<div><label><input type=checkbox id=d20flag7 " + ((consent & 0x0040) ? 'checked' : '') + '>' + "Show connection toolbar" + '</label></div>'; }
7305
+ x += '<div><label><input type=checkbox id=d20flag1 ' + ((consent & 0x0001) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7306
+ x += '<div><label><input type=checkbox id=d20flag2 ' + ((consent & 0x0008) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7307
+ if (debugmode) { x += '<div><label><input type=checkbox id=d20flag7 ' + ((consent & 0x0040) ? 'checked' : '') + '>' + "Show connection toolbar" + '</label></div>'; }
7308
x += '<div style="width:100%;border-bottom:1px solid gray;margin-bottom:5px;margin-top:8px"><b>' + "Terminal" + '</b></div>';
7280
- x += "<div><label><input type=checkbox id=d20flag3 " + ((consent & 0x0002) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7281
- x += "<div><label><input type=checkbox id=d20flag4 " + ((consent & 0x0010) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7309
+ x += '<div><label><input type=checkbox id=d20flag3 ' + ((consent & 0x0002) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7310
+ x += '<div><label><input type=checkbox id=d20flag4 ' + ((consent & 0x0010) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7311
x += '<div style="width:100%;border-bottom:1px solid gray;margin-bottom:5px;margin-top:8px"><b>' + "Files" + '</b></div>';
7283
- x += "<div><label><input type=checkbox id=d20flag5 " + ((consent & 0x0004) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7284
- x += "<div><label><input type=checkbox id=d20flag6 " + ((consent & 0x0020) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7312
+ x += '<div><label><input type=checkbox id=d20flag5 ' + ((consent & 0x0004) ? 'checked' : '') + '>' + "Notify user" + '</label></div>';
7313
+ x += '<div><label><input type=checkbox id=d20flag6 ' + ((consent & 0x0020) ? 'checked' : '') + '>' + "Prompt for user consent" + '</label></div>';
7314
setDialogMode(2, "Edit Device Group User Consent", 3, p20editmeshconsentEx, x);
7315
if (serverinfo.consent) {
7316
if (serverinfo.consent & 0x0001) { Q('d20flag1').checked = true; }
@@ -7605,7 +7634,7 @@
7634
// Figure out the name and shortname
7635
var f = filetreexx[i], name = f.n, shortname;
7636
shortname = name;
7608
- if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + "...</span>"; } else { shortname = EscapeHtml(name); }
7637
+ if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + "..." + '</span>'; } else { shortname = EscapeHtml(name); }
7638
name = EscapeHtml(name);
7639
7640
// Figure out the date
@@ -7667,7 +7696,9 @@
7696
while (f.t > 1 && f.t != 4) { f = f.parent; }
7697
if ((f.t != 1 && f.t != 4) || (f.maxbytes == null)) return '';
7698
var tf = Math.floor(f.s / 1024), tq = (f.maxbytes - f.s);
7670
- return '<span title="' + tf + "k in " + f.c + " file" + (f.c > 1 ? 's' : '') + ". " + (Math.floor(f.maxbytes / 1024 / 1024)) + 'k maxinum">' + getNiceSize(tq) + ' <progress style=height:10px;width:100px value=' + f.s + ' max=' + f.maxbytes + ' /></span>';
7699
+ var title;
7700
+ if (f.c > 1) { title = format("{0}k in {1} files. {2}k maximum", tf, f.c, (Math.floor(f.maxbytes / 1024 / 1024))); } else { title = format("{0}k in 1 file. {1}k maximum", tf, (Math.floor(f.maxbytes / 1024 / 1024))); }
7701
+ return '<span title="' + title + '">' + getNiceSize(tq) + ' <progress style=height:10px;width:100px value=' + f.s + ' max=' + f.maxbytes + ' /></span>';
7702
}
7703
7704
function p5showPublicLink(u) { setDialogMode(2, "Public Link", 1, null, '<input type=text style=width:100% value="' + u + '" readonly />'); return false; }
@@ -7702,8 +7733,8 @@
7733
QE('p5PasteButton', (p5clipboard != null) && (p5clipboard.length > 0) && (filetreelocation.length > 0));
7734
}
7735
7705
- function getFileSelCount(includeDirs) { var cc = 0, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == "3"))) cc++; } return cc; }
7706
- function getFileSelDirCount() { var cc = 0, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "999")) cc++; } return cc; }
7736
+ function getFileSelCount(includeDirs) { var cc = 0, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == '3'))) cc++; } return cc; }
7737
+ function getFileSelDirCount() { var cc = 0, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '999')) cc++; } return cc; }
7738
function getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fc'); return checkboxes.length; }
7739
function p5selectallfile() { var nv = (getFileSelCount() == 0), checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p5setActions(); }
7740
function setupBackPointers(x) { if (x.f != null) { var fs = 0, fc = 0; for (var i in x.f) { setupBackPointers(x.f[i]); x.f[i].parent = x; if (x.f[i].s) { fs += x.f[i].s; } if (x.f[i].c) { fc += x.f[i].c; } if (x.f[i].t == 3) { fc++; } } x.s = fs; x.c = fc; } return x; }
@@ -7734,7 +7765,7 @@
7765
*/
7766
7767
var p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0;
7737
- function p5copyFile(cut) { var checkboxes = document.getElementsByName('fc'); p5clipboard = []; p5clipboardCut = cut, p5clipboardFolder = Clone(filetreelocation); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "3")) { p5clipboard.push(checkboxes[i].value); } } p5updateClipview(); }
7768
+ function p5copyFile(cut) { var checkboxes = document.getElementsByName('fc'); p5clipboard = []; p5clipboardCut = cut, p5clipboardFolder = Clone(filetreelocation); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == '3')) { p5clipboard.push(checkboxes[i].value); } } p5updateClipview(); }
7769
function p5pasteFile() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = format("Confim {0} of {1} entrie{2} to this location?", (p5clipboardCut == 0?'copy':'move'), p5clipboard.length, ((p5clipboard.length > 1)?'s':'')) } setDialogMode(2, "Paste", 3, p5pasteFileEx, x); }
7770
function p5pasteFileEx() { meshserver.send({ action: 'fileoperation', fileop: (p5clipboardCut == 0?'copy':'move'), scpath: p5clipboardFolder, path: filetreelocation, names: p5clipboard }); p5folderup(999); if (p5clipboardCut == 1) { p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0; p5updateClipview(); } }
7771
function p5updateClipview() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = format("Holding {0} entrie{1} for {2}", p5clipboard.length, ((p5clipboard.length > 1)?'s':''), (p5clipboardCut == 0?"copy":"move")) + ', <a href=# onclick="return p5clearClip()" style=cursor:pointer>' + "Clear" + '</a>.' } QH('p5bottomstatus', x); p5setActions(); }
@@ -8010,7 +8041,7 @@
8041
} else {
8042
if (user.login) { lastAccess += '<span title=\"' + format("Last login: {0}", printDateTime(new Date(user.login * 1000))) + '\">' + printDate(new Date(user.login * 1000)) + '</span>'; }
8043
}
8013
- if (self) { permissions += "<a href=# style=cursor:pointer onclick='return showUserAdminDialog(event,\"" + encodeURIComponent(user._id) + "\")'>"; }
8044
+ if (self) { permissions += '<a href=# style=cursor:pointer onclick=\'return showUserAdminDialog(event,\"' + encodeURIComponent(user._id) + '\")\'>'; }
8045
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { permissions += "Locked" + ', '; }
8046
permissions += '<span title=\'' + "Server Permissions" + '\'>';
8047
@@ -8026,10 +8057,10 @@
8057
} else {
8058
permissions += "Partial";
8059
}
8029
- if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128)) != 0)) { permissions += "*"; }
8030
- permissions += "</span>";
8060
+ if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128)) != 0)) { permissions += '*'; }
8061
+ permissions += '</span>';
8062
//if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; }
8032
- if (self) { permissions += "</a>"; }
8063
+ if (self) { permissions += '</a>'; }
8064
8065
var groups = 0
8066
if (user.links) { for (var i in user.links) { groups++; } }
@@ -8353,11 +8384,11 @@
8384
if (serverinfo.emailcheck) { everify = ((user.emailVerified == true) ? '<b style=color:green;cursor:pointer title=\"' + "Email is verified" + '\">✓</b> ' : '<b style=color:red;cursor:pointer title=\"' + "Email not verified" + '\">✗</b> '); }
8385
if (user.name.toLowerCase() != user._id.split('/')[2]) { x += addDeviceAttribute("User Identifier", user._id.split('/')[2]); }
8386
if (((features & 0x200000) == 0) && ((user.siteadmin != 0xFFFFFFFF) || (userinfo.siteadmin == 0xFFFFFFFF))) { // If we are not site admin, we can't change a admin email.
8356
- x += addDeviceAttribute("Email", everify + "<a href=# style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,\"" + userid + "\")>" + email + '</a> <a href=# style=cursor:pointer onclick=\'return doemail(event,\"' + user.email + '\")\'><img class=hoverButton src="images/link1.png" /></a>');
8387
+ x += addDeviceAttribute("Email", everify + '<a href=# style=cursor:pointer onclick=p30showUserEmailChangeDialog(event,\"' + userid + '\")>' + email + '</a> <a href=# style=cursor:pointer onclick=\'return doemail(event,\"' + user.email + '\")\'><img class=hoverButton src="images/link1.png" /></a>');
8388
} else {
8389
x += addDeviceAttribute("Email", everify + email + ' <a href=# style=cursor:pointer onclick=\'return doemail(event,\"' + user.email + '\")\'><img class=hoverButton src="images/link1.png" /></a>');
8390
}
8360
- x += addDeviceAttribute("Server Rights", premsg + "<a href=# style=cursor:pointer onclick=\'return showUserAdminDialog(event,\"" + userid + "\")\'>" + msg.join(', ') + "</a>");
8391
+ x += addDeviceAttribute("Server Rights", premsg + '<a href=# style=cursor:pointer onclick=\'return showUserAdminDialog(event,\"' + userid + '\")\'>' + msg.join(', ') + '</a>');
8392
if (user.quota) x += addDeviceAttribute("Server Quota", EscapeHtml(parseInt(user.quota) / 1024) + ' k');
8393
x += addDeviceAttribute("Creation", printDateTime(new Date(user.creation * 1000)));
8394
if (user.login) x += addDeviceAttribute("Last Login", printDateTime(new Date(user.login * 1000)));
@@ -8416,7 +8447,7 @@
8447
8448
// Update user's connection state
8449
x = '';
8419
- if (activeSessions == 1) { x = "1 active session"; } else if (activeSessions > 1) { x = format(" active sessions", activeSessions); }
8450
+ if (activeSessions == 1) { x = "1 active session"; } else if (activeSessions > 1) { x = format("{0} active sessions", activeSessions); }
8451
QH('MainUserState', x);
8452
8453
go(30);
@@ -8656,7 +8687,7 @@
8687
// Figure out the name and shortname
8688
var f = filetreexx[i], name = f.n, shortname;
8689
shortname = name;
8659
- if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + "...</span>"; } else { shortname = EscapeHtml(name); }
8690
+ if (name.length > 70) { shortname = '<span title="' + EscapeHtml(name) + '">' + EscapeHtml(name.substring(0, 70)) + ("..." + '</span>'); } else { shortname = EscapeHtml(name); }
8691
name = EscapeHtml(name);
8692
8693
// Figure out the size
@@ -9240,7 +9271,7 @@
9271
function methodcheck(r) { if (r && r != null && r.Body && r.Body.ReturnValueStr != 'SUCCESS') { messagebox("Call Error", r.Header.Method + ': ' + r.Body.ReturnValueStr.replace('_', ' ')); return true; } return false; }
9272
function TableStart() { return '<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td width=200px><p><td>'; }
9273
function TableStart2() { return '<table cellpadding=0 cellspacing=0 style=width:100%;border-radius:8px><tr><td><p><td>'; }
9243
- function TableEntry(n, v) { return "<tr><td><p>" + n + "<td>" + v; }
9274
+ function TableEntry(n, v) { return '<tr><td><p>' + n + '<td>' + v; }
9275
function FullTable(x, e) { var r = TableStart(); for (i in x) { if (i && x[i]) r += TableEntry(i, x[i]); } return r + TableEnd(e); }
9276
function TableEnd(n) { return '<tr><td colspan=2><p>' + (n?n:'') + '</table>'; }
9277
function AddButton(v, f) { return '<input type=button value="' + v + '" onclick="' + f + '" style=margin:4px>'; }
@@ -9272,7 +9303,7 @@
9303
function printDateTime(d) { return d.toLocaleString(args.locale); }
9304
function addDetailItem(title, value, state) { return '<div><span style=float:right>' + value + '</span><span>' + title + '</span></div>'; }
9305
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; }); };
9275
-
9306
+
9307
</script>
9308
</body>
9309
</html>