mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-26 23:25:53 -05:00
3391 lines
216 KiB
Handlebars
3391 lines
216 KiB
Handlebars
<!DOCTYPE html><html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"><head>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
<meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="format-detection" content="telephone=no">
|
|
<link rel="shortcut icon" type="image/x-icon" href="{{{domainurl}}}favicon.ico">
|
|
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
|
<script type="text/javascript" src="scripts/meshcentral.js"></script>
|
|
<script type="text/javascript" src="scripts/agent-redir-ws-0.1.1.js"></script>
|
|
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-0.2.0.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-redir-ws-0.1.0.js"></script>
|
|
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-inflate.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-adler32.js"></script>
|
|
<script type="text/javascript" src="scripts/zlib-crc32.js"></script>
|
|
<script keeplink="1" type="text/javascript" src="scripts/filesaver.js"></script>
|
|
<title>{{{title}}}</title>
|
|
<style>
|
|
a {
|
|
color: #036;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
#footer a {
|
|
color: #fff;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
#footer a:hover {
|
|
color: #fff;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.i1 {
|
|
background: url(../images/icons50.png) 0px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.i2 {
|
|
background: url(../images/icons50.png) -50px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.i3 {
|
|
background: url(../images/icons50.png) -100px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.i4 {
|
|
background: url(../images/icons50.png) -150px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.i5 {
|
|
background: url(../images/icons50.png) -200px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.i6 {
|
|
background: url(../images/icons50.png) -250px 0px;
|
|
height: 50px;
|
|
width: 50px;
|
|
border: none;
|
|
}
|
|
|
|
.m0 {
|
|
background: url(../images/images16.png) -32px 0px;
|
|
height: 16px;
|
|
width: 16px;
|
|
border: none;
|
|
float: left;
|
|
}
|
|
|
|
.m1 {
|
|
background: url(../images/images16.png) -16px 0px;
|
|
height: 16px;
|
|
width: 16px;
|
|
border: none;
|
|
float: left;
|
|
}
|
|
|
|
.m2 {
|
|
background: url(../images/images16.png) -96px 0px;
|
|
height: 16px;
|
|
width: 16px;
|
|
border: none;
|
|
float: left;
|
|
}
|
|
|
|
.m3 {
|
|
background: url(../images/images16.png) -112px 0px;
|
|
height: 16px;
|
|
width: 16px;
|
|
border: none;
|
|
float: left;
|
|
}
|
|
|
|
.gray {
|
|
/*filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");*/ /* Firefox 10+, Firefox on Android */
|
|
filter: gray; /* IE6-9 */
|
|
-webkit-filter: grayscale(100%) opacity(60%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
|
|
}
|
|
|
|
.DevSt {
|
|
padding-left: 5px;
|
|
border-bottom-style: solid;
|
|
border-bottom-width: 1px;
|
|
border-bottom-color: #DDDDDD;
|
|
}
|
|
|
|
.noselect {
|
|
-webkit-touch-callout: none;
|
|
-webkit-user-select: none;
|
|
-khtml-user-select: none;
|
|
-moz-user-select: none;
|
|
-ms-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
.fileIcon1 {
|
|
background: url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);
|
|
height: 16px;
|
|
width: 16px;
|
|
cursor: pointer;
|
|
border: none;
|
|
float: left;
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.fileIcon2 {
|
|
background: url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);
|
|
height: 16px;
|
|
width: 16px;
|
|
cursor: pointer;
|
|
border: none;
|
|
float: left;
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.fileIcon3 {
|
|
background: url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);
|
|
height: 16px;
|
|
width: 16px;
|
|
cursor: pointer;
|
|
border: none;
|
|
float: left;
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.fileIcon4 {
|
|
background: url(../images/meshicon16.png);
|
|
height: 16px;
|
|
width: 16px;
|
|
cursor: pointer;
|
|
border: none;
|
|
float: left;
|
|
margin-top: 1px;
|
|
}
|
|
|
|
.filelist {
|
|
-moz-user-select: none;
|
|
-khtml-user-select: none;
|
|
-webkit-user-select: none;
|
|
-o-user-select: none;
|
|
cursor: default;
|
|
-khtml-user-drag: element;
|
|
background-color: white;
|
|
clear: both;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
|
<div id="container">
|
|
<div id="mastheadx"></div>
|
|
<div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden">
|
|
<div style="width:calc(100% - 50px);overflow:hidden">
|
|
<div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px">
|
|
<strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong>
|
|
</div>
|
|
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:10px">
|
|
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
|
</div>
|
|
</div>
|
|
<img id="topMenuIcon" class="noselect" style="position:absolute;right:0;top:10px;bottom:50px;color:#c8c8c8;font-size:44px;margin-right:8px;cursor:pointer;display:none" onclick="topMenu()" src="/images/3bars-30.png" width="30" height="30">
|
|
</div>
|
|
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
|
<div id="column_l" style="width:100%;padding:0;position:absolute;bottom:0px;top:0px">
|
|
<div id="p0" style="display:none;width:100%;height:100%">
|
|
<div style="display:flex;align-items:center;width:100%;height:100%">
|
|
<div id="p0message" style="text-align:center;width:100%"><span id="p0span">Server odpojen</span>, <href onclick="reload()" style="cursor:pointer"><u>klikni pro opětovné připojení</u></href>.</div>
|
|
</div>
|
|
</div>
|
|
<div id="p1" style="display:none;width:100%;height:100%">
|
|
<div style="display:flex;align-items:center;width:100%;height:100%">
|
|
<div id="p1message" style="text-align:center;width:100%"></div>
|
|
</div>
|
|
</div>
|
|
<div id="p2" style="display:none">
|
|
<div id="xdevices"></div>
|
|
</div>
|
|
<div id="p3" style="display:none;position:absolute;bottom:0;top:0;width:100%">
|
|
<table cellspacing="0" style="margin:0;padding:0;border-spacing:0;border:0;">
|
|
<tbody><tr style="padding:0">
|
|
<td style="padding:0;color:#c8c8c8;text-align:center;cursor:pointer" width="60px" valign="top" onclick="goBack()">
|
|
<div style="padding:0;background-color:#036;width:10px;height:10px;float:right;border:0">
|
|
<div style="background-color:white;width:10px;height:10px;border-radius:10px 0 0 0;border-right:1px solid white;border-bottom:1px solid white"></div>
|
|
</div>
|
|
<div style="padding:0;font-size:25px;background-color:#036;width:50px;border-radius:0 0 10px 0;height:36px">◀</div>
|
|
</td>
|
|
<td>
|
|
<img src="/images/user-50.png" width="50" height="50">
|
|
</td>
|
|
<td>
|
|
<div style="margin-left:5px">
|
|
<strong style="font-size:large"><span id="p3userName"></span></strong><br>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p3info" style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
|
|
<div style="margin-left:8px">
|
|
<div id="p3AccountActions">
|
|
<p><strong>Nastavení bezpečnosti</strong></p>
|
|
<div style="margin-left:9px;margin-bottom:8px">
|
|
<div id="manageAuthApp" style="margin-top:5px;display:none"><a onclick="account_manageAuthApp()" style="cursor:pointer">Spravovat autentizační aplikace</a></div>
|
|
<div id="manageOtp" style="margin-top:5px;display:none"><a onclick="account_manageOtp(0)" style="cursor:pointer">Spravovat záložní kódy</a></div>
|
|
</div>
|
|
<p><strong>Akce účtu</strong></p>
|
|
<div style="margin-left:9px;margin-bottom:8px">
|
|
<div style="margin-top:5px"><span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Ověřit email</a></span></div>
|
|
<div style="margin-top:5px"><span id="changeEmailId" style="display:none"><a onclick="account_showChangeEmail()" style="cursor:pointer">Změnit emailovou adresu</a></span></div>
|
|
<div style="margin-top:5px"><a onclick="account_showChangePassword()" style="cursor:pointer">Změnit heslo</a><span id="p2nextPasswordUpdateTime"></span></div>
|
|
<div style="margin-top:5px"><a onclick="account_showDeleteAccount()" style="cursor:pointer">Smazat účet</a></div>
|
|
</div>
|
|
<br style="clear:both">
|
|
</div>
|
|
<strong>Skupiny zařízení</strong>
|
|
<span id="p3createMeshLink1">( <a onclick="account_createMesh()" style="cursor:pointer"><img src="images/icon-addnew.png" width="12" height="12" border="0"> Vytvořit</a> )</span>
|
|
<br><br>
|
|
<div id="p3meshes"></div>
|
|
<div id="p3noMeshFound" style="margin-left:9px;display:none">Žádná skupina zařízení.<span id="p3createMeshLink2"> <a onclick="account_createMesh()" style="cursor:pointer"><strong>Začněte zde!</strong></a></span></div>
|
|
<br style="clear:both">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="p5" style="display:none">
|
|
<table cellspacing="0" style="margin:0;padding:0;border-spacing:0;border:0;">
|
|
<tbody><tr style="padding:0">
|
|
<td style="padding:0;color:#c8c8c8;text-align:center;cursor:pointer" width="60px" valign="top" onclick="goBack()">
|
|
<div style="padding:0;background-color:#036;width:10px;height:10px;float:right;border:0">
|
|
<div style="background-color:white;width:10px;height:10px;border-radius:10px 0 0 0;border-right:1px solid white;border-bottom:1px solid white"></div>
|
|
</div>
|
|
<div style="padding:0;font-size:25px;background-color:#036;width:50px;border-radius:0 0 10px 0;height:36px">◀</div>
|
|
</td>
|
|
<td>
|
|
<img src="/images/user-50.png" width="50" height="50">
|
|
</td>
|
|
<td>
|
|
<div style="margin-left:5px">
|
|
<strong style="font-size:large">Moje soubory</strong><br>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p5myfiles" style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
|
|
<table id="p5toolbar" style="width:100%;height:78px" cellpadding="0" cellspacing="0">
|
|
<tbody><tr>
|
|
<td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom">
|
|
<div style="width:100%;text-align:center">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5FolderUp" disabled="disabled" onclick="p5folderup()" value="Nahoru">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5SelectAllButton" disabled="disabled" onclick="p5selectallfile()" value="Vybrat vše" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5RenameFileButton" disabled="disabled" value="Přejmenovat" onclick="p5renamefile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5DeleteFileButton" disabled="disabled" value="Smazat" onclick="p5deletefile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5NewFolderButton" disabled="disabled" value="Adresář" onclick="p5createfolder()" onkeypress="return false" onkeydown="return false">
|
|
</div>
|
|
<div style="width:100%;text-align:center">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5UploadButton" disabled="disabled" value="Nahrát" onclick="p5uploadFile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5CutButton" disabled="disabled" value="Vyjmout" onclick="p5copyFile(1)" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5CopyButton" disabled="disabled" value="Kopírovat" onclick="p5copyFile(0)" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5PasteButton" disabled="disabled" value="Vložit" onclick="p5pasteFile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p5RefreshButton" value="Obnovit" onclick="p5refreshFiles()" onkeypress="return false" onkeydown="return false">
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="background-color:#E4E9E7;height:28px">
|
|
<table style="width:100%">
|
|
<tbody><tr>
|
|
<td id="p5currentpath" style="overflow:hidden;padding-left:4px;padding-top:2px"></td>
|
|
<td style="text-align:right;padding-right:4px">
|
|
<select id="p5sortdropdown" onchange="updateFiles()">
|
|
<option value="1" selected="selected">Třídit podle jména</option>
|
|
<option value="2">Třídit podle velikosti</option>
|
|
<option value="3">STřídit podle datumu</option>
|
|
<option value="4">Sestupně podle jména</option>
|
|
<option value="5">Sestupně podle velikosti</option>
|
|
<option value="6">Sestupně podle datumu</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p5filetable" style="width:100%;height:calc(100% - 133px);overflow:auto;-webkit-user-select:none">
|
|
<!--
|
|
<div id="p5bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>✓</b></div>
|
|
<div id="p5bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>✗</b></div>
|
|
-->
|
|
<span id="p5files"></span>
|
|
</div>
|
|
<table id="p5toolbarBottom" style="width:100%;height:22px;position:absolute;bottom:0px;background-color:#D3D9D6" cellpadding="0" cellspacing="0">
|
|
<tbody><tr>
|
|
<td style="text-align:left;padding:3px"> <span id="p5bottomstatus"></span></td>
|
|
<td id="p5rightOfButtons" style="text-align:right;padding:3px"></td>
|
|
</tr>
|
|
</tbody></table>
|
|
</div>
|
|
</div>
|
|
<div id="p10" style="display:none;position:absolute;bottom:0;top:0;width:100%;overflow:hidden">
|
|
<table cellspacing="0" style="margin:0;padding:0;border-spacing:0;border:0;position:absolute;top:0">
|
|
<tbody><tr style="padding:0">
|
|
<td style="padding:0;color:#c8c8c8;text-align:center;cursor:pointer" width="60px" valign="top" onclick="goBack()">
|
|
<div style="padding:0;background-color:#036;width:10px;height:10px;float:right;border:0">
|
|
<div style="background-color:white;width:10px;height:10px;border-radius:10px 0 0 0;border-right:1px solid white;border-bottom:1px solid white"></div>
|
|
</div>
|
|
<div style="padding:0;font-size:25px;background-color:#036;width:50px;border-radius:0 0 10px 0;height:36px">◀</div>
|
|
</td>
|
|
<td>
|
|
<a id="MainComputerImage" style="cursor:pointer" onclick="p10showiconselector()"></a>
|
|
</td>
|
|
<td>
|
|
<div style="margin-left:5px">
|
|
<strong><span id="p10deviceName"></span></strong><br>
|
|
<span id="MainComputerState"></span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p10general" style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%">
|
|
<div id="p10html" style="margin-left:8px;margin-right:8px"></div>
|
|
<div id="p10html2"></div>
|
|
<div id="p10html3"></div>
|
|
</div>
|
|
<div id="p10desktop" style="overflow:hidden;position:absolute;top:55px;bottom:0px;width:100%;display:none">
|
|
<div id="deskarea1" style="position:absolute;top:0px;width:100%;height:25px">
|
|
<div style="padding-top:2px;padding-bottom:2px;background:#C0C0C0">
|
|
<div style="float:right;text-align:right">
|
|
<span id="p14power"></span>
|
|
<input id="DeskSoftInput" type="text" style="width:25px;display:none;opacity:.2" onblur="toggleSoftKeys(0)" onkeypress="return ondeskkeypress(event)" onkeydown="return ondeskkeydown(event)" onkeyup="return ondeskkeyup(event)">
|
|
</div>
|
|
<div style="margin-left:3px">
|
|
<input type="button" id="connectbutton1" value="Připojit" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled">
|
|
<input type="button" id="connectbutton1h" value="HW připojení" onclick="connectDesktop(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled">
|
|
<input type="button" id="disconnectbutton1" value="Odpojit" onclick="connectDesktop(event,0)" onkeypress="return false" onkeydown="return false">
|
|
<span id="deskstatus">Odpojeno</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="deskarea3" style="position:absolute;top:25px;width:100%;height:calc(100% - 50px)">
|
|
<div id="deskarea3x" style="background:black;text-align:center;height:100%;position:relative">
|
|
<div id="DeskParent" style="height:100%">
|
|
<canvas id="Desk" width="640" height="200" style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)" onmousewheel="dmousewheel(event)"></canvas>
|
|
</div>
|
|
<div id="DeskTools" style="position:absolute;width:400px;height:100%;background-color:gray;top:0;right:0;border-left:2px solid lightgray;display:none">
|
|
<a id="DeskToolsRefreshButton" style="float:right;padding:3px;cursor:pointer" onclick="refreshDeskTools()">Obnovit</a>
|
|
<div id="DeskToolsBar" style="position:absolute;padding:3px;border-radius: 3px 3px 0px 0px;top:5px;left:4px;bottom:26px;background-color:lightgray;cursor:pointer">Procesy</div>
|
|
<div style="position:absolute;top:26px;left:4px;right:4px;bottom:4px;background-color:lightgray;text-align:left">
|
|
<div style="border-bottom:1px solid darkgray;padding:3px"><a style="width:50px;padding-right:5px;float:left;cursor:pointer" onclick="sortProcess(0)">PID</a><a style="cursor:pointer" onclick="sortProcess(1)">Jméno</a></div>
|
|
<div id="DeskToolsProcesses" style="overflow-y:scroll;position:absolute;top:24px;bottom:0px;width:100%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="deskarea4" style="position:absolute;bottom:0px;width:100%;height:25px">
|
|
<div style="padding-top:2px;padding-bottom:2px;background:#C0C0C0">
|
|
<div style="float:right;text-align:right">
|
|
<select id="termdisplays" style="display:none" onchange="deskSetDisplay(event)" onclick="deskGetDisplayNumbers(event)"></select>
|
|
<span id="DeskToastButton"><img src="images/icon-notify.png" onclick="deviceToastFunction()" height="16" width="16" style="padding-top:2px"></span>
|
|
<!--<input id=DeskToolsButton type=button value=Tools onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()"> -->
|
|
</div>
|
|
<div>
|
|
<input id="deskActionsBtn" type="button" style="margin-left:3px" onkeypress="return false" onkeydown="return false" value="Akce" onclick="deviceActionFunction()">
|
|
<input type="button" value="Nastavení" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()">
|
|
<input type="button" onkeypress="return false" onkeydown="return false" value="Akce napájení" onclick="showPowerActionDlg()" style="display:none">
|
|
<input id="DeskSpecialKeys" type="button" value="Speciální klíče" onkeypress="return false" onkeydown="return false" onclick="sendSpecialKeys()">
|
|
<input id="DeskSoftKeys" type="button" value="Klávesnice" onkeypress="return false" onkeydown="return false" onclick="toggleSoftKeys(1)">
|
|
<label><span id="DeskControlSpan" style="display:none"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false">Vstup</span></label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="p10files" style="overflow-y:scroll;position:absolute;top:55px;bottom:0px;width:100%;display:none">
|
|
<table id="p13toolbar" style="width:100%;height:111px" cellpadding="0" cellspacing="0">
|
|
<tbody><tr>
|
|
<td style="background-color:#C0C0C0;border-bottom:2px solid black;padding:2px">
|
|
<div style="float:right;text-align:right">
|
|
<input id="filesActionsBtn" type="button" onkeypress="return false" onkeydown="return false" value="Akce" onclick="deviceActionFunction()" style="margin-right:2px">
|
|
</div>
|
|
<div style="margin-left:2px">
|
|
<input id="p13AutoConnect" value="Automatické připojení" onclick="autoConnectFiles(event)" onkeypress="return false" onkeydown="return false" type="button" style="display:none">
|
|
<input id="p13Connect" value="Připojit" onclick="connectFiles(event)" onkeypress="return false" onkeydown="return false" type="button">
|
|
<span id="p13Status">Odpojeno</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom">
|
|
<div style="width:100%;text-align:center">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Nahoru">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Vybrat vše" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13RenameFileButton" disabled="disabled" value="Přejmenovat" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13DeleteFileButton" disabled="disabled" value="Smazat" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13NewFolderButton" disabled="disabled" value="Adresář" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false">
|
|
</div>
|
|
<div style="width:100%;text-align:center">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13UploadButton" disabled="disabled" value="Nahrát" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13CutButton" disabled="disabled" value="Vyjmout" onclick="p13copyFile(1)" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13CopyButton" disabled="disabled" value="Kopírovat" onclick="p13copyFile(0)" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13PasteButton" disabled="disabled" value="Vložit" onclick="p13pasteFile()" onkeypress="return false" onkeydown="return false">
|
|
<input type="button" style="width:calc(100%/5 - 5px)" id="p13RefreshButton" disabled="disabled" value="Obnovit" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false">
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="background-color:#E4E9E7;height:28px">
|
|
<table style="width:100%">
|
|
<tbody><tr>
|
|
<td id="p13currentpath" style="overflow:hidden;padding-left:4px;padding-top:2px"></td>
|
|
<td style="text-align:right;padding-right:4px">
|
|
<select id="p13sortdropdown" onchange="p13updateFiles()">
|
|
<option value="1" selected="selected">Třídit podle jména</option>
|
|
<option value="2">Třídit podle velikosti</option>
|
|
<option value="3">STřídit podle datumu</option>
|
|
<option value="4">Sestupně podle jména</option>
|
|
<option value="5">Sestupně podle velikosti</option>
|
|
<option value="6">Sestupně podle datumu</option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p13filetable" style="width:100%;height:calc(100% - 133px);overflow:auto;-webkit-user-select:none">
|
|
<!--
|
|
<div id="p13bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>✓</b></div>
|
|
<div id="p13bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>✗</b></div>
|
|
-->
|
|
<span id="p13files"></span>
|
|
</div>
|
|
<table id="p13toolbarBottom" style="width:100%;height:22px;position:absolute;bottom:0px" cellpadding="0" cellspacing="0">
|
|
<tbody><tr><td style="text-align:left;padding:3px;text-align:center;background-color:#D3D9D6"> <span id="p13bottomstatus"></span></td></tr>
|
|
</tbody></table>
|
|
</div>
|
|
</div>
|
|
<div id="p20" style="display:none;position:absolute;bottom:0;top:0;width:100%">
|
|
<table cellspacing="0" style="margin:0;padding:0;border-spacing:0;border:0;">
|
|
<tbody><tr style="padding:0">
|
|
<td style="padding:0;color:#c8c8c8;text-align:center;cursor:pointer" width="60px" valign="top" onclick="goBack()">
|
|
<div style="padding:0;background-color:#036;width:10px;height:10px;float:right;border:0">
|
|
<div style="background-color:white;width:10px;height:10px;border-radius:10px 0 0 0;border-right:1px solid white;border-bottom:1px solid white"></div>
|
|
</div>
|
|
<div style="padding:0;font-size:25px;background-color:#036;width:50px;border-radius:0 0 10px 0;height:36px">◀</div>
|
|
</td>
|
|
<td onclick="p20editmesh(1)">
|
|
<img src="/images/meshicon50.png" width="50" height="50">
|
|
</td>
|
|
<td onclick="p20editmesh(1)">
|
|
<div style="margin-left:5px">
|
|
<strong style="font-size:large"><span id="p20meshName"></span></strong><br>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody></table>
|
|
<div id="p20info" style="margin-left:8px;margin-right:8px"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
|
<table id="footerMenu" cellpadding="0" cellspacing="0" style="height:32px;width:100%;color:white;cursor:pointer;table-layout:fixed"></table>
|
|
</div>
|
|
</div>
|
|
<div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:90px;width:300px;display:none">
|
|
<div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0">
|
|
<div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>X</b></div>
|
|
<div id="id_dialogtitle" style="padding:5px"></div>
|
|
<div style="width:100%;margin:6px"></div>
|
|
</div>
|
|
<div style="margin-right:16px;margin-left:8px">
|
|
<div id="dialog1" style="margin:auto;text-align:center;margin:3px">
|
|
<div id="id_dialogMessage" style="padding:10px"></div>
|
|
</div>
|
|
<div id="dialog2" style="margin:auto;margin:3px">
|
|
<div id="id_dialogOptions"></div>
|
|
</div>
|
|
<div id="dialog3" style="margin:auto;margin:3px">
|
|
<select id="deskkeys" style="width:100%">
|
|
<option value="10">Ctrl+Alt+Del</option>
|
|
<option value="11">Tab</option>
|
|
<option value="5">Win</option>
|
|
<option value="0">Win+Down</option>
|
|
<option value="1">Win+Up</option>
|
|
<option value="2">Win+L</option>
|
|
<option value="3">Win+M</option>
|
|
<option value="4">Shift+Win+M</option>
|
|
<option value="6">Win+R</option>
|
|
<option value="7">Alt-F4</option>
|
|
<option value="8">Ctrl-W</option>
|
|
<option value="9">Alt-Tab</option>
|
|
</select>
|
|
</div>
|
|
<div id="dialog7" style="margin:auto;margin:3px">
|
|
<div id="d7meshkvm">
|
|
<h4 style="width:100%;border-bottom:1px solid gray">Agent vzdálené plochy</h4>
|
|
<div style="margin:3px 0 3px 0">
|
|
<select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select>
|
|
<div style="height:20px">Kvalita</div>
|
|
</div>
|
|
<div style="margin:3px 0 3px 0">
|
|
<select id="d7bitmapscaling" style="float:right;width:200px;height:20px" dir="rtl">
|
|
<option selected="selected" value="1024">100%</option>
|
|
<option value="896">87.5%</option>
|
|
<option value="768">75%</option>
|
|
<option value="640">62.5%</option>
|
|
<option value="512">50%</option>
|
|
<option value="384">37.5%</option>
|
|
<option value="256">25%</option>
|
|
<option value="128">12.5%</option>
|
|
</select>
|
|
<div style="height:20px">Škálování</div>
|
|
</div>
|
|
<div style="margin:3px 0 3px 0">
|
|
<select id="d7framelimiter" style="float:right;width:200px;height:20px" dir="rtl">
|
|
<option selected="selected" value="50">Rychle</option>
|
|
<option value="100">Středně</option>
|
|
<option value="400">Pomalu</option>
|
|
<option value="1000">Velmi pomalu</option>
|
|
</select>
|
|
<div style="height:20px">Hodnocení</div>
|
|
</div>
|
|
</div>
|
|
<div id="d7amtkvm">
|
|
<h4 style="width:100%;border-bottom:1px solid gray">Intel® AMT Hardware KVM</h4>
|
|
<div style="height:26px">
|
|
<select id="d7desktopmode" style="float:right;width:200px">
|
|
<option value="1">RLE8, Rychlejší</option>
|
|
<option value="2">RLE16, doporučeno</option>
|
|
<option value="3">RAW8, pomalé</option>
|
|
<option value="4">RAW16, hodně pomalé</option>
|
|
</select>
|
|
<div>Kódování</div>
|
|
</div>
|
|
<div style="height:60px">
|
|
<div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white">
|
|
<label><input type="checkbox" id="d7showfocus">Zobrazit nástroj pro zaměření</label><br>
|
|
<label><input type="checkbox" id="d7showcursor">Zobrazit lokální kurzor myši</label><br>
|
|
</div>
|
|
<div>Ostatní</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
|
|
<input id="idx_dlgCancelButton" type="button" value="Zrušit" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">
|
|
<input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)">
|
|
</div>
|
|
</div>
|
|
<div id="topMenu" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:0px 0px 5px 5px;position:fixed;top:50px;right:5px;width:170px;display:none">
|
|
<div style="padding:12px;border-top:1px solid gray;color:black;cursor:pointer" onclick="topMenu(2)">Moje soubory</div>
|
|
<div style="padding:12px;border-top:1px solid gray;color:black;cursor:pointer" onclick="topMenu(1)">Můj účet</div>
|
|
<div id="logoutMenuOption"><a href="/logout"><div style="padding:12px;border-top:1px solid gray;color:black;cursor:pointer">Odhlásit</div></a></div>
|
|
</div>
|
|
<iframe name="fileUploadFrame" style="display:none"></iframe>
|
|
<script>
|
|
'use strict';
|
|
|
|
// Process server-side web state
|
|
var webState = '{{{webstate}}}';
|
|
if (webState != '') { webState = JSON.parse(decodeURIComponent(webState)); }
|
|
for (var i in webState) { localStorage.setItem(i, webState[i]); }
|
|
if (!webState.loctag) { delete localStorage.removeItem('loctag'); }
|
|
|
|
var args = parseUriArgs();
|
|
var debugLevel = parseInt('{{{debuglevel}}}');
|
|
var features = parseInt('{{{features}}}');
|
|
var sessionTime = parseInt('{{{sessiontime}}}');
|
|
var domain = '{{{domain}}}';
|
|
var domainUrl = '{{{domainurl}}}';
|
|
var authCookie = '{{{authCookie}}}';
|
|
var authRelayCookie = '{{{authRelayCookie}}}';
|
|
var authCookieRenewTimer = null;
|
|
var meshserver = null;
|
|
var xdr = null;
|
|
var serverinfo = null;
|
|
var nodes = [];
|
|
var meshes = {};
|
|
var filetree = {};
|
|
var userinfo = null;
|
|
var serverinfo = null;
|
|
var users = null;
|
|
var nodeShortIdent = 0;
|
|
var serverPublicNamePort = '{{{serverDnsName}}}:{{{serverPublicPort}}}';
|
|
var debugmode = false;
|
|
var attemptWebRTC = ((features & 128) != 0);
|
|
var StatusStrs = ["Odpojeno", "Připojování...", "Nastavení...", "Připojeno", "Intel® AMT připojeno"];
|
|
var files;
|
|
var passRequirements = '{{{passRequirements}}}';
|
|
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); }
|
|
var sessionActivity = Date.now();
|
|
|
|
function startup() {
|
|
if ((features & 32) == 0) {
|
|
// Guard against other site's top frames (web bugs).
|
|
var loc = null;
|
|
try { loc = top.location.toString().toLowerCase(); } catch (e) { }
|
|
if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
|
|
}
|
|
|
|
if (!args.locale) { var x = getstore('loctag', 0); if ((x != null) && (x != '*')) { args.locale = x; } }
|
|
|
|
window.onresize = center;
|
|
center();
|
|
QV('changeEmailId', (features & 0x200000) == 0);
|
|
QH('p1message', "Připojování...");
|
|
go(1);
|
|
|
|
// Connect to the mesh server
|
|
meshserver = MeshServerCreateControl(domainUrl, authCookie);
|
|
meshserver.onStateChanged = onStateChanged;
|
|
meshserver.onMessage = onMessage;
|
|
meshserver.Start();
|
|
|
|
// Load desktop settings
|
|
var t = localStorage.getItem('desktopsettings');
|
|
if (t != null) { desktopsettings = JSON.parse(t); }
|
|
applyDesktopSettings();
|
|
}
|
|
|
|
function onStateChanged(server, state, prevState, errorCode) {
|
|
if (state == 0) {
|
|
// Control web socket disconnected
|
|
setDialogMode(0); // Close any dialog boxes if present
|
|
go(0); // Go to disconnection panel
|
|
if (errorCode == 'noauth') { QH('p0span', "Unable to perform authentication"); return; }
|
|
if (prevState == 2) { setTimeout(serverPoll, 5000); } else { QH('p0span', "Nelze se připojit k web socketu"); }
|
|
// Clean up here
|
|
if (authCookieRenewTimer != null) { clearInterval(authCookieRenewTimer); authCookieRenewTimer = null; }
|
|
} else if (state == 2) {
|
|
// Fetch list of meshes, nodes, files
|
|
meshserver.send({ action: 'meshes' });
|
|
meshserver.send({ action: 'nodes' });
|
|
meshserver.send({ action: 'files' });
|
|
if (xxcurrentView < 2) { go(2); }
|
|
authCookieRenewTimer = setInterval(function () { meshserver.send({ action: 'authcookie' }); }, 1800000); // Request a cookie refresh every 30 minutes.
|
|
}
|
|
QV('topMenuIcon', state == 2);
|
|
}
|
|
|
|
// Poll the server, if it responds, refresh the page.
|
|
function serverPoll() {
|
|
xdr = null;
|
|
try { xdr = new XDomainRequest(); } catch (e) { }
|
|
if (!xdr) xdr = new XMLHttpRequest();
|
|
xdr.open('HEAD', window.location.href);
|
|
xdr.timeout = 15000;
|
|
xdr.onload = function () { reload(); };
|
|
xdr.onerror = xdr.ontimeout = function () { setTimeout(serverPoll, 10000); };
|
|
xdr.send();
|
|
}
|
|
|
|
function updateSelf() {
|
|
QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
|
|
QV('manageAuthApp', features & 4096);
|
|
QV('manageOtp', ((features & 4096) != 0) && ((userinfo.otpsecret == 1) || (userinfo.otphkeys > 0)));
|
|
|
|
// On the mobile app, don't allow group creation (for now).
|
|
QV('p3createMeshLink1', false);
|
|
QV('p3createMeshLink2', false);
|
|
|
|
if (typeof userinfo.passchange == 'number') {
|
|
if (userinfo.passchange == -1) { QH('p2nextPasswordUpdateTime', " - Reset při příštím přihlášení."); }
|
|
else if ((passRequirements != null) && (typeof passRequirements.reset == 'number')) {
|
|
var seconds = (userinfo.passchange) + (passRequirements.reset * 86400) - Math.floor(Date.now() / 1000);
|
|
if (seconds < 0) { QH('p2nextPasswordUpdateTime', " - Reset při příštím přihlášení."); }
|
|
else if (seconds < 3600) { QH('p2nextPasswordUpdateTime', format(" - Reset v {0} minut{1}.", Math.floor(seconds / 60), addLetterS(Math.floor(seconds / 60)))); }
|
|
else if (seconds < 86400) { QH('p2nextPasswordUpdateTime', format(" - Reset v {0} hodin{1}.", Math.floor(seconds / 3600), addLetterS(Math.floor(seconds / 3600)))); }
|
|
else { QH('p2nextPasswordUpdateTime', format(" - Reset v {0} den{1}."), Math.floor(seconds / 86400), addLetterS(Math.floor(seconds / 86400))); }
|
|
}
|
|
}
|
|
}
|
|
|
|
function addLetterS(x) { return (x > 1) ? 's' : ''; }
|
|
function setSessionActivity() { sessionActivity = Date.now(); }
|
|
function checkIdleSessionTimeout() { var delta = (Date.now() - sessionActivity); if (delta > serverinfo.timeout) { window.location.href = 'logout'; } }
|
|
|
|
function onMessage(server, message) {
|
|
switch (message.action) {
|
|
case 'serverinfo': {
|
|
serverinfo = message.serverinfo;
|
|
if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); }
|
|
QV('p3AccountActions', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide Account Actions if in single user mode or domain authentication
|
|
QV('logoutMenuOption', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide logout if in single user mode or domain authentication
|
|
break;
|
|
}
|
|
case 'authcookie': {
|
|
// Got an authentication cookie refresh
|
|
authCookie = message.cookie;
|
|
authRelayCookie = message.rcookie;
|
|
break;
|
|
}
|
|
case 'userinfo': {
|
|
userinfo = message.userinfo;
|
|
QH('p3userName', userinfo.name);
|
|
//updateSiteAdmin();
|
|
updateSelf();
|
|
break;
|
|
}
|
|
case 'users': {
|
|
users = {};
|
|
for (var m in message.users) { users[message.users[m]._id] = message.users[m]; }
|
|
updateUsers();
|
|
break;
|
|
}
|
|
case 'wssessioncount': {
|
|
wssessions = message.wssessions;
|
|
updateUsers();
|
|
break;
|
|
}
|
|
case 'meshes': {
|
|
meshes = {};
|
|
for (var m in message.meshes) { meshes[message.meshes[m]._id] = message.meshes[m]; }
|
|
updateMeshes();
|
|
updateDevices();
|
|
break;
|
|
}
|
|
case 'files': {
|
|
filetree = setupBackPointers(message.filetree);
|
|
updateFiles();
|
|
//d3updatefiles();
|
|
break;
|
|
}
|
|
case 'nodes': {
|
|
nodes = [];
|
|
for (var m in message.nodes) {
|
|
for (var n in message.nodes[m]) {
|
|
if (!meshes[m]) { console.log('Invalid mesh (1): ' + m); continue; }
|
|
message.nodes[m][n].namel = message.nodes[m][n].name.toLowerCase();
|
|
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; }
|
|
message.nodes[m][n].meshnamel = meshes[m].name.toLowerCase();
|
|
message.nodes[m][n].meshid = m;
|
|
message.nodes[m][n].state = (message.nodes[m][n].state) ? (message.nodes[m][n].state) : 0;
|
|
message.nodes[m][n].desc = message.nodes[m][n].desc;
|
|
if (!message.nodes[m][n].icon) message.nodes[m][n].icon = 1;
|
|
message.nodes[m][n].ident = ++nodeShortIdent;
|
|
nodes.push(message.nodes[m][n]);
|
|
}
|
|
}
|
|
//onSortSelectChange();
|
|
//onSearchInputChanged();
|
|
updateDevices();
|
|
//refreshMap(false, true);
|
|
if (xxcurrentView == 0) { if ('{{viewmode}}' != '') { go(parseInt('{{viewmode}}')); } else { setDialogMode(0); go(2); } }
|
|
if ('{{currentNode}}' != '') { gotoDevice('{{currentNode}}', parseInt('{{viewmode}}')); }
|
|
break;
|
|
}
|
|
case 'powertimeline': {
|
|
if (message.nodeid != powerTimelineReq) break;
|
|
powerTimelineNode = message.nodeid;
|
|
powerTimeline = message.timeline;
|
|
powerTimelineUpdate = Date.now() + 300000; // Update every 5 minutes
|
|
if (currentNode._id == message.nodeid) { drawDeviceTimeline(); }
|
|
break;
|
|
}
|
|
case 'otpauth-request': {
|
|
if ((xxdialogMode == 2) && (xxdialogTag == 'otpauth-request')) {
|
|
var secret = message.secret;
|
|
if (secret.length == 52) { secret = secret.split(/(.............)/).filter(Boolean).join(' '); }
|
|
else if (secret.length == 32) { secret = secret.split(/(....)/).filter(Boolean).join(' '); secret = secret.substring(0, 20) + '<br/>' + secret.substring(20) }
|
|
QH('d2optinfo', "Nainstalujte si <a href=\"https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2\" rel=\"noreferrer noopener\" target=_blank>Google Authenticator</a> nebo kompatibilní aplikaci, použijte <a href=\"' + message.url + '\" rel=\"noreferrer noopener\" target=_blank> tento odkaz</a> nebo vložte secret. Pak vložte aktuální 6 číselný token pro aktivaci 2-faktorového přihlašování." + '<br /><br /><div style=width:100%;text-align:center><tt id=d2optsecret secret=\"' + message.secret + '\" style=font-size:15px>' + secret + '</tt><br /><br />Token: <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></div>');
|
|
QV('idx_dlgOkButton', true);
|
|
QE('idx_dlgOkButton', false);
|
|
Q('d2otpauthinput').focus();
|
|
}
|
|
break;
|
|
}
|
|
case 'otpauth-setup': {
|
|
if (xxdialogMode) return;
|
|
setDialogMode(2, "Aplikace pro autentizaci", 1, null, message.success ? "<b style=color:green>2-faktorová autentizace zapnuta</b>. Je třeba platný token k přihlášení." : "<b style=color:red>2-faktorové přihlášení selhalo</b>. Je třeba smazat tajemství z aplikace a zkusit znovu. Na toto máte již jen pár minut.");
|
|
break;
|
|
}
|
|
case 'otpauth-clear': {
|
|
if (xxdialogMode) return;
|
|
setDialogMode(2, "Aplikace pro autentizaci", 1, null, message.success ? "<b style=color:green>2-faktorové přihlášení odstraněno</b>. Lze znovu kdykoliv zapnout." : "<b style=color:red>Odstranění 2-faktorového přihlášení selhalo</b>. Zkuste znovu.");
|
|
break;
|
|
}
|
|
case 'otpauth-getpasswords': {
|
|
if (xxdialogMode) return;
|
|
var x = "Jednorázové tokeny lze použít jako sekundární autentizaci. Vytvořte sadu, vytiskněte je a uložte na bezpečném místě.";
|
|
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 style=width:100%;text-align:center>';
|
|
if (message.passwords) {
|
|
var j = 0;
|
|
for (var i in message.passwords) {
|
|
if (++j % 2) { x += '<tr>'; }
|
|
var p = '' + message.passwords[i].p;
|
|
while (p.length < 8) { p = '0' + p; }
|
|
if (message.passwords[i].u === true) { x += '<td>' + p.substring(0, 4) + ' ' + p.substring(4); } else { x += '<td><strike style=color:#BBB>' + p.substring(0, 4) + ' ' + p.substring(4); + '</strike>'; }
|
|
}
|
|
} else {
|
|
x += '<tr><td>' + "Žádné aktivní tokeny";
|
|
}
|
|
x += '</table></div></div><br />';
|
|
x += '<div><input type=button value=\'' + "Zavřít" + '\' onclick=setDialogMode(0) style=float:right></input>';
|
|
x += '<input type=button value=\'' + "Nové tokeny" + '\' onclick=\'account_manageOtp(1);\'></input>';
|
|
if (message.passwords != null) { x += '<input type=button value=\'' + "Vymazat" + '\' onclick=\'account_manageOtp(2);\'></input>'; }
|
|
x += '</div><br />';
|
|
setDialogMode(2, "Spravovat záložní kódy", 8, null, x, 'otpauth-manage');
|
|
break;
|
|
}
|
|
case 'event': {
|
|
/*
|
|
if (!message.event.nolog) {
|
|
events.unshift(message.event);
|
|
var eventLimit = parseInt(p3limitdropdown.value);
|
|
while (events.length > eventLimit) { events.pop(); } // Remove element(s) at the end
|
|
events_update();
|
|
}
|
|
*/
|
|
if (message.event.noact) break; // Take no action on this event
|
|
switch (message.event.action) {
|
|
case 'userWebState': {
|
|
// New user web state, update the web page as needed
|
|
if (localStorage != null) {
|
|
var webstate = JSON.parse(message.event.state);
|
|
for (var i in webstate) { localStorage.setItem(i, webstate[i]); }
|
|
|
|
// Update the web page
|
|
if ((webstate.loctag != null) && (webstate.loctag != oldLoctag)) {
|
|
if (webstate.loctag != null) { args.locale = webstate.loctag; } else { delete args.locale; }
|
|
updateDevices();
|
|
updateMeshes();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 'accountchange': {
|
|
// An account was created or changed
|
|
if (userinfo.name == message.event.account.name) {
|
|
var newsiteadmin = message.event.account.siteadmin ? message.event.account.siteadmin : 0;
|
|
var oldsiteadmin = userinfo.siteadmin ? userinfo.siteadmin : 0;
|
|
if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
|
|
userinfo = message.event.account;
|
|
if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
|
|
updateSelf();
|
|
}
|
|
break;
|
|
}
|
|
case 'createmesh': {
|
|
// A new mesh was created
|
|
if (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.
|
|
meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
|
|
updateMeshes();
|
|
updateDevices();
|
|
meshserver.send({ action: 'files' });
|
|
}
|
|
break;
|
|
}
|
|
case 'meshchange': {
|
|
// Update mesh information
|
|
if (meshes[message.event.meshid] == null) {
|
|
// This is a new mesh for us
|
|
meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
|
|
meshserver.send({ action: 'nodes' }); // Request a refresh of all nodes (TODO: We could optimize this to only request nodes for the new mesh).
|
|
} else {
|
|
// This is an existing mesh
|
|
if (meshes[message.event.meshid].name != message.event.name) {
|
|
meshes[message.event.meshid].name = message.event.name;
|
|
for (var i in nodes) { if (nodes[i].meshid == message.event.meshid) { nodes[i].meshnamel = message.event.name.toLowerCase(); } }
|
|
}
|
|
meshes[message.event.meshid].desc = message.event.desc;
|
|
meshes[message.event.meshid].links = message.event.links;
|
|
|
|
// Check if we lost rights to this mesh in this change.
|
|
if (meshes[message.event.meshid].links[userinfo._id] == null) {
|
|
if ((xxcurrentView == 20) && (currentMesh == meshes[message.event.meshid])) go(2);
|
|
delete meshes[message.event.meshid];
|
|
|
|
// Delete all nodes in that mesh
|
|
var newnodes = [];
|
|
for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } }
|
|
nodes = newnodes;
|
|
|
|
// If we are looking at a node in the deleted mesh, move back to "My Devices"
|
|
if (xxcurrentView >= 10 && xxcurrentView < 20 && currentNode && currentNode.meshid == message.event.meshid) { setDialogMode(0); go(2); }
|
|
}
|
|
}
|
|
updateMeshes();
|
|
updateDevices();
|
|
meshserver.send({ action: 'files' });
|
|
|
|
// If we are looking at a mesh that is now deleted, move back to "My Account"
|
|
if (xxcurrentView == 20 && currentMesh._id == message.event.meshid) { p20updateMesh(); }
|
|
break;
|
|
}
|
|
case 'deletemesh': {
|
|
// Delete the mesh
|
|
if (meshes[message.event.meshid]) {
|
|
delete meshes[message.event.meshid];
|
|
updateMeshes();
|
|
meshserver.send({ action: 'files' });
|
|
}
|
|
|
|
// Delete all nodes in that mesh
|
|
var newnodes = [];
|
|
for (var i in nodes) { if (nodes[i].meshid != message.event.meshid) { newnodes.push(nodes[i]); } }
|
|
nodes = newnodes;
|
|
updateDevices();
|
|
|
|
// If we are looking at a mesh that is now deleted, move back to "My Account"
|
|
if (xxcurrentView >= 20 && xxcurrentView < 30 && currentMesh._id == message.event.meshid) { setDialogMode(0); go(2); }
|
|
// If we are looking at a node in the deleted mesh, move back to "My Devices"
|
|
if (xxcurrentView >= 10 && xxcurrentView < 20 && currentNode && currentNode.meshid == message.event.meshid) { setDialogMode(0); go(2); }
|
|
|
|
break;
|
|
}
|
|
case 'addnode': {
|
|
var node = message.event.node;
|
|
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.
|
|
if (getNodeFromId(node._id) != null) break; // This node is already known.
|
|
node.namel = node.name.toLowerCase();
|
|
if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
|
|
node.meshnamel = meshes[node.meshid].name.toLowerCase();
|
|
node.state = 0;
|
|
if (!node.icon) node.icon = 1;
|
|
node.ident = ++nodeShortIdent;
|
|
nodes.push(node);
|
|
//onSortSelectChange();
|
|
//onSearchInputChanged();
|
|
updateDevices();
|
|
//updateMapMarkers();
|
|
break;
|
|
}
|
|
case 'removenode': {
|
|
var index = -1;
|
|
for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
|
|
if (index != -1) {
|
|
var node = nodes[index];
|
|
if (currentNode == node) {
|
|
if (xxcurrentView >= 10 && xxcurrentView < 20) { setDialogMode(0); go(2); }
|
|
currentNode = null;
|
|
// TODO: Correctly disconnect from this node (Desktop/Terminal/Files...)
|
|
}
|
|
nodes.splice(index, 1);
|
|
updateDevices();
|
|
//updateMapMarkers();
|
|
}
|
|
break;
|
|
}
|
|
case 'changenode': {
|
|
var index = -1;
|
|
for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
|
|
if (index != -1) {
|
|
var node = nodes[index];
|
|
|
|
// Change the node
|
|
node.name = message.event.node.name;
|
|
node.rname = message.event.node.rname;
|
|
node.host = message.event.node.host;
|
|
node.desc = message.event.node.desc;
|
|
node.publicip = message.event.node.publicip;
|
|
node.iploc = message.event.node.iploc;
|
|
node.wifiloc = message.event.node.wifiloc;
|
|
node.gpsloc = message.event.node.gpsloc;
|
|
node.tags = message.event.node.tags;
|
|
node.userloc = message.event.node.userloc;
|
|
if (message.event.node.agent != null) {
|
|
if (node.agent == null) node.agent = {};
|
|
if (message.event.node.agent.ver != null) { node.agent.ver = message.event.node.agent.ver; }
|
|
if (message.event.node.agent.id != null) { node.agent.id = message.event.node.agent.id; }
|
|
if (message.event.node.agent.caps != null) { node.agent.caps = message.event.node.agent.caps; }
|
|
if (message.event.node.agent.core != null) { node.agent.core = message.event.node.agent.core; } else { if (node.agent.core) { delete node.agent.core; } }
|
|
node.agent.tag = message.event.node.agent.tag;
|
|
}
|
|
if (message.event.node.intelamt != null) {
|
|
if (node.intelamt == null) node.intelamt = {};
|
|
if (message.event.node.intelamt.state != null) { node.intelamt.state = message.event.node.intelamt.state; }
|
|
if (message.event.node.intelamt.host != null) { node.intelamt.user = message.event.node.intelamt.host; }
|
|
if (message.event.node.intelamt.user != null) { node.intelamt.user = message.event.node.intelamt.user; }
|
|
if (message.event.node.intelamt.tls != null) { node.intelamt.tls = message.event.node.intelamt.tls; }
|
|
if (message.event.node.intelamt.ver != null) { node.intelamt.ver = message.event.node.intelamt.ver; }
|
|
if (message.event.node.intelamt.tag != null) { node.intelamt.tag = message.event.node.intelamt.tag; }
|
|
if (message.event.node.intelamt.uuid != null) { node.intelamt.uuid = message.event.node.intelamt.uuid; }
|
|
if (message.event.node.intelamt.realm != null) { node.intelamt.realm = message.event.node.intelamt.realm; }
|
|
}
|
|
node.namel = node.name.toLowerCase();
|
|
if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
|
|
if (message.event.node.icon) { node.icon = message.event.node.icon; }
|
|
|
|
//onSortSelectChange(true);
|
|
//drawNotifications();
|
|
refreshDevice(node._id);
|
|
//updateMapMarkers();
|
|
updateDevices();
|
|
|
|
//if ((currentNode == node) && (xxdialogMode != null) && (xxdialogTag == '@xxmap')) { p10showNodeLocationDialog(); }
|
|
}
|
|
break;
|
|
}
|
|
case 'nodemeshchange': {
|
|
var index = -1;
|
|
for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
|
|
if (index != -1) {
|
|
var node = nodes[index];
|
|
if (meshes[message.event.newMeshId] == null) {
|
|
// We don't see the new mesh, remove this device
|
|
|
|
// TODO: Correctly disconnect from this node (Desktop/Terminal/Files...)
|
|
if (currentNode == node) { if (xxcurrentView >= 10 && xxcurrentView < 20) { setDialogMode(0); go(2); } currentNode = null; }
|
|
nodes.splice(index, 1);
|
|
} else {
|
|
// We see the new mesh, move this device
|
|
node.meshid = message.event.newMeshId;
|
|
node.meshnamel = meshes[message.event.newMeshId].name.toLowerCase();
|
|
}
|
|
updateDevices();
|
|
refreshDevice(message.event.nodeid);
|
|
} else {
|
|
// This is a new device, add it.
|
|
var node = message.event.node;
|
|
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.
|
|
node.namel = node.name.toLowerCase();
|
|
if (node.rname) { node.rnamel = node.rname.toLowerCase(); } else { node.rnamel = node.namel; }
|
|
node.meshnamel = meshes[node.meshid].name.toLowerCase();
|
|
node.state = 0;
|
|
if (!node.icon) node.icon = 1;
|
|
node.ident = ++nodeShortIdent;
|
|
if (nodes == null) { }
|
|
nodes.push(node);
|
|
|
|
// Web page update
|
|
//masterUpdate(1 | 2 | 4 | 16);
|
|
updateDevices();
|
|
}
|
|
break;
|
|
}
|
|
case 'nodeconnect': {
|
|
// Indicated a node has changed connectivity state
|
|
var index = -1;
|
|
for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
|
|
if (index != -1) {
|
|
var node = nodes[index];
|
|
|
|
// Change the node connection state
|
|
node.conn = message.event.conn;
|
|
node.pwr = message.event.pwr;
|
|
updateDevices();
|
|
//updateMapMarkers();
|
|
//refreshDevice(node._id);
|
|
}
|
|
break;
|
|
}
|
|
case 'login': {
|
|
// Update the last login time
|
|
if (users != null && users['user/' + domain + '/' + message.event.username.toLowerCase()]) { users['user/' + domain + '/' + message.event.username.toLowerCase()].login = message.event.time; }
|
|
break;
|
|
}
|
|
case 'notify': {
|
|
//var n = { text: message.event.value };
|
|
//if (message.event.tag != null) { n.tag = message.event.tag; }
|
|
//addNotification(n);
|
|
break;
|
|
}
|
|
case 'stopped': { // Server is stopping.
|
|
// TODO: Disconnect
|
|
break;
|
|
}
|
|
default:
|
|
//console.log('Unknown message.event.action', message.event.action);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
//console.log('Unknown message.action', message.action);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Menu System
|
|
//
|
|
|
|
function topMenu(select) {
|
|
if ((xxdialogMode != null) && (xxdialogMode != 0) && (xxdialogMode != 999)) return;
|
|
if (select === undefined) {
|
|
var x = (QS('topMenu').display == 'none');
|
|
if (x == true) { if ((xxdialogMode == 0) || (xxdialogMode == null)) { QV('topMenu', true); xxdialogMode = 999; } } else { QV('topMenu', false); xxdialogMode = 0; }
|
|
} else {
|
|
QV('topMenu', false);
|
|
xxdialogMode = 0;
|
|
if ((select == 1) && (xxcurrentView != 3)) { goForward('account'); } // My Account
|
|
if ((select == 2) && (xxcurrentView != 5)) { goForward('files'); } // My Files
|
|
}
|
|
}
|
|
|
|
var backStack = [];
|
|
function goBack() { if (xxdialogMode) return; if (backStack.length > 0) { backStack.pop(); } goStack(); }
|
|
function goForward(id) { if (xxdialogMode) return; backStack.push(id); goStack(); }
|
|
function goStack() {
|
|
if (backStack.length == 0) { go(2); return; }
|
|
var id = backStack[backStack.length - 1], idtype = id.split('/')[0];
|
|
if (idtype == 'node') { setupDeviceMenu(0); gotoDevice(id); }
|
|
if (idtype == 'mesh') { gotoMesh(id); }
|
|
if (idtype == 'account') { go(3); }
|
|
if (idtype == 'devices') { go(2); }
|
|
if (idtype == 'files') { go(5); }
|
|
}
|
|
|
|
function updateFooterMenu(options) {
|
|
while (options != null && options.length < 3) { options.push({ n: '' }); }
|
|
var x = '', prev = '';
|
|
if (options != null) { for (var i in options) { x += '<td style="cursor:pointer' + ((prev == '') ? '' : ';border-left:solid 1px white') + '" onclick="' + options[i].f + '">' + options[i].n; prev = options[i].n; } }
|
|
QH('footerMenu', '<tr>' + x);
|
|
}
|
|
|
|
//
|
|
// MY ACCOUNT
|
|
//
|
|
|
|
function account_manageAuthApp() {
|
|
if (xxdialogMode || ((features & 4096) == 0)) return;
|
|
if (userinfo.otpsecret == 1) { account_removeOtp(); } else { account_addOtp(); }
|
|
}
|
|
|
|
function account_addOtp() {
|
|
if (xxdialogMode || (userinfo.otpsecret == 1) || ((features & 4096) == 0)) return;
|
|
setDialogMode(2, "Aplikace pro autentizaci", 2, function () { meshserver.send({ action: 'otpauth-setup', secret: Q('d2optsecret').attributes.secret.value, token: Q('d2otpauthinput').value }); }, '<div id=d2optinfo>' + "Nahrávání..." + '</div>', 'otpauth-request');
|
|
meshserver.send({ action: 'otpauth-request' });
|
|
}
|
|
|
|
function account_addOtpCheck(e) {
|
|
var tokenIsValid = (Q('d2otpauthinput').value.length == 6);
|
|
QE('idx_dlgOkButton', tokenIsValid);
|
|
if (e && (e.keyCode == 13) && tokenIsValid) { dialogclose(1); }
|
|
}
|
|
|
|
function account_removeOtp() {
|
|
if (xxdialogMode || (userinfo.otpsecret != 1) || ((features & 4096) == 0)) return;
|
|
setDialogMode(2, "Aplikace pro autentizaci", 3, function () { meshserver.send({ action: 'otpauth-clear' }); }, "Potvrdit odstranění autentizační aplikace pro 2-faktorové přihlašování?");
|
|
}
|
|
|
|
function account_manageOtp(action) {
|
|
if ((xxdialogMode == 2) && (xxdialogTag == 'otpauth-manage')) { dialogclose(0); }
|
|
if (xxdialogMode || (userinfo.otpsecret != 1) || ((features & 4096) == 0)) return;
|
|
meshserver.send({ action: 'otpauth-getpasswords', subaction: action });
|
|
}
|
|
|
|
function account_showVerifyEmail() {
|
|
if (xxdialogMode || (userinfo.emailVerified == true) || (serverinfo.emailcheck != true)) return;
|
|
var x = "Klikni na OK pro zaslání verifikačního emailu na:" + '<br /><div style=padding:8px><b>' + EscapeHtml(userinfo.email) + '</b></div>' + "Prosím počkejte pár minut než dojde k verifikaci.";
|
|
setDialogMode(2, "Ověření emailu", 3, account_showVerifyEmailEx, x);
|
|
}
|
|
|
|
function account_showVerifyEmailEx() {
|
|
meshserver.send({ action: 'verifyemail', email: userinfo.email });
|
|
}
|
|
|
|
function account_showChangeEmail() {
|
|
if (xxdialogMode) return;
|
|
var x = addHtmlValue("Email", '<input id=dp3email style=width:170px maxlength=256 onchange=account_validateEmail() onkeyup=account_validateEmail(event) />');
|
|
setDialogMode(2, "Změna emailové adresy", 3, account_changeEmail, x);
|
|
if (userinfo.email != null) { Q('dp3email').value = userinfo.email; }
|
|
account_validateEmail();
|
|
Q('dp3email').focus();
|
|
}
|
|
|
|
function account_validateEmail(e, email) {
|
|
QE('idx_dlgOkButton', validateEmail(Q('dp3email').value) && (Q('dp3email').value != userinfo.email));
|
|
if ((e != null) && (e.keyCode == 13)) { dialogclose(1); }
|
|
}
|
|
|
|
function account_changeEmail() {
|
|
meshserver.send({ action: 'changeemail', email: Q('dp3email').value });
|
|
}
|
|
|
|
function account_showDeleteAccount() {
|
|
if (xxdialogMode) return;
|
|
var x = '<form method=post><table style=margin-left:10px><input type=hidden name=action value=deleteaccount /><input type=hidden name=authcookie value=' + authCookie + ' /><tr>';
|
|
x += '<td align=right>' + "Heslo:" + '</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>';
|
|
x += '</tr><tr><td align=right>' + "Heslo:" + '</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateDeleteAccount() onkeyup=account_validateDeleteAccount() /></td>';
|
|
x += '</tr></table><div style=padding:10px;margin-bottom:4px>';
|
|
x += '<input id=account_dlgCancelButton type=button value=\"' + "Zrušit" + '\" style=float:right;width:80px;margin-left:5px onclick=dialogclose(0)>';
|
|
x += '<input id=account_dlgOkButton type=submit value=\"' + "OK" + '\" style="float:right;width:80px" onclick=dialogclose(1)>';
|
|
x += '</div><br /></form>';
|
|
setDialogMode(2, "Smazat účet", 0, null, x);
|
|
account_validateDeleteAccount();
|
|
Q('apassword1').focus();
|
|
}
|
|
|
|
|
|
function account_showChangePassword() {
|
|
if (xxdialogMode) return false;
|
|
var x = '<table style=margin-left:10px>';
|
|
x += '<tr><td align=right>' + nobreak("Staré heslo:") + '</td><td><input id=apassword0 type=password name=apassword0 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b></b></td></tr>';
|
|
x += '<tr><td align=right>' + nobreak("Nové heslo:") + '</td><td><input id=apassword1 type=password name=apassword1 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /> <b><span id=dxPassWarn></span></b></td></tr>';
|
|
x += '<tr><td align=right>' + nobreak("Nové heslo:") + '</td><td><input id=apassword2 type=password name=apassword2 autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>';
|
|
if (features & 0x00010000) { x += '<tr><td align=right>' + "Nápověda k heslu:" + '</td><td><input id=apasswordhint name=apasswordhint maxlength=250 type=text autocomplete=off onchange=account_validateNewPassword() onkeyup=account_validateNewPassword() onkeydown=account_validateNewPassword() /></td></tr>'; }
|
|
x += '</table>'
|
|
if (passRequirements) {
|
|
var r = [], rc = 0;
|
|
for (var i in passRequirements) { if ((i != 'reset') && (i != 'hint')) { r.push(i + ':' + passRequirements[i]); rc++; } }
|
|
if (rc > 0) { x += '<br /><span style=font-size:x-small>' + format("Požadavky: {0}.", r.join(', ')) + '</span>'; }
|
|
}
|
|
x += '<br />';
|
|
setDialogMode(2, "Změnit heslo", 3, account_showChangePasswordEx, x);
|
|
Q('apassword0').focus();
|
|
account_validateNewPassword();
|
|
return false;
|
|
}
|
|
|
|
function account_showChangePasswordEx() {
|
|
if (Q('apassword1').value == Q('apassword2').value) {
|
|
var r = { action: 'changepassword', oldpass: Q('apassword0').value, newpass: Q('apassword1').value };
|
|
if (features & 0x00010000) { r.hint = Q('apasswordhint').value; }
|
|
meshserver.send(r);
|
|
}
|
|
}
|
|
|
|
function account_createMesh() {
|
|
if (xxdialogMode) return;
|
|
|
|
// Check if we are disallowed from creating a device group
|
|
if ((userinfo.siteadmin != 0xFFFFFFFF) && ((userinfo.siteadmin & 64) != 0)) { setDialogMode(2, "Nová skupina zařízení", 1, null, "Tento účet nemá práva k vytvoření nové skupiny zařízení."); return; }
|
|
|
|
// Remind the user to verify the email address
|
|
if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "Nastavení bezpečnosti", 1, null, "Nelze získat přístup k zařízení, dokud nebude ověřena e-mailová adresa. To je vyžadováno pro obnovení hesla. Jdi do \"Můj účet\" pro změnu a ověření emailu.."); return; }
|
|
|
|
// Remind the user to add two factor authentication
|
|
if ((features & 0x00040000) && !((userinfo.otpsecret == 1) || (userinfo.otphkeys > 0) || (userinfo.otpkeys > 0))) { setDialogMode(2, "Nastavení bezpečnosti", 1, null, "Nelze získat přístup k zařízení, dokud je 2-faktorová autentizace zapnuta. Toto je pro extra bezpečnost. Jdi do \"Můj účet\" a podívej se do sekce\"Nastavení bezpečnosti\"."); return; }
|
|
|
|
// We are allowed, let's prompt to information
|
|
var x = addHtmlValue("Jméno", '<input id=dp3meshname style=width:170px maxlength=64 onchange=account_validateMeshCreate() onkeyup=account_validateMeshCreate() />');
|
|
x += addHtmlValue("Typ", '<div style=width:170px;margin:0;padding:0><select id=dp3meshtype style=width:100% onchange=account_validateMeshCreate() ><option value=2>' + "Skupina Software Agent" + '</option><option value=1>' + "Intel® AMT pouze" + '</option></select></div>');
|
|
x += addHtmlValue("Popis", '<div style=width:170px;margin:0;padding:0><textarea id=dp3meshdesc maxlength=1024 style=width:100%;resize:none></textarea></div>');
|
|
setDialogMode(2, "Vytvořit skupinu zařízení", 3, account_createMeshEx, x);
|
|
account_validateMeshCreate();
|
|
Q('dp3meshname').focus();
|
|
}
|
|
|
|
function account_validateMeshCreate() {
|
|
QE('idx_dlgOkButton', Q('dp3meshname').value.length > 0);
|
|
}
|
|
|
|
function account_createMeshEx(button, tag) {
|
|
meshserver.send({ action: 'createmesh', meshname: Q('dp3meshname').value, meshtype: Q('dp3meshtype').value, desc: Q('dp3meshdesc').value });
|
|
}
|
|
|
|
function account_validateDeleteAccount() {
|
|
QE('account_dlgOkButton', (Q('apassword1').value.length > 0) && (Q('apassword1').value == Q('apassword2').value));
|
|
}
|
|
|
|
function account_validateNewPassword() {
|
|
var r = '', ok = (Q('apassword0').value.length > 0) && (Q('apassword1').value.length > 0) && (Q('apassword1').value == Q('apassword2').value) && (Q('apassword0').value != Q('apassword1').value);
|
|
if ((features & 0x00010000) && (Q('apasswordhint').value == Q('apassword1').value)) { ok = false; }
|
|
if (Q('apassword1').value != '') {
|
|
if (passRequirements == null || passRequirements == '') {
|
|
// No password requirements, display password strength
|
|
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
|
if (passStrength >= 80) { r = '<span style=color:green>Strong<span>'; } else if (passStrength >= 60) { r = '<span style=color:blue>●<span>'; } else { r = '<span style=color:red>●<span>'; }
|
|
} else {
|
|
// Password requirements provided, use that
|
|
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
|
if (passReq == false) { ok = false; r = '<span style=color:red>' + "Politika" + '<span>' }
|
|
}
|
|
}
|
|
QH('dxPassWarn', r);
|
|
//QE('account_dlgOkButton', ok);
|
|
QE('idx_dlgOkButton', ok);
|
|
}
|
|
|
|
// Return a password strength score
|
|
function checkPasswordStrength(password) {
|
|
var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
|
|
if (!password) return 0;
|
|
for (var i = 0; i < password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
|
|
for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
|
|
return parseInt(r + (varCount - 1) * 10);
|
|
}
|
|
|
|
// Check password requirements
|
|
function checkPasswordRequirements(password, requirements) {
|
|
if ((requirements == null) || (requirements == '') || (typeof requirements != 'object')) return true;
|
|
if (requirements.min) { if (password.length < requirements.min) return false; }
|
|
if (requirements.max) { if (password.length > requirements.max) return false; }
|
|
var num = 0, lower = 0, upper = 0, nonalpha = 0;
|
|
for (var i = 0; i < password.length; i++) {
|
|
if (/\d/.test(password[i])) { num++; }
|
|
if (/[a-z]/.test(password[i])) { lower++; }
|
|
if (/[A-Z]/.test(password[i])) { upper++; }
|
|
if (/\W/.test(password[i])) { nonalpha++; }
|
|
}
|
|
if (requirements.num && (num < requirements.num)) return false;
|
|
if (requirements.lower && (lower < requirements.lower)) return false;
|
|
if (requirements.upper && (upper < requirements.upper)) return false;
|
|
if (requirements.nonalpha && (nonalpha < requirements.nonalpha)) return false;
|
|
return true;
|
|
}
|
|
|
|
function updateMeshes() {
|
|
var r = '', count = 0;
|
|
for (i in meshes) {
|
|
count++;
|
|
|
|
// Mesh rights
|
|
var meshrights = meshes[i].links[userinfo._id].rights;
|
|
var rights = "Částečné práva";
|
|
if (meshrights == 0xFFFFFFFF) rights = "Hlavní administrátor"; else if (meshrights == 0) rights = "Žádná práva";
|
|
|
|
// Print the mesh information
|
|
r += '<div style=cursor:pointer onclick=goForward(\'' + i + '\')>';
|
|
r += '<div style="float:left;margin-left:4px"><img src="/images/meshicon50.png" width=50 height=50 /></div>';
|
|
r += '<div style="width:auto;height:40px;background-color:lightgray;margin-top:5px;margin-bottom:5px;margin-left:60px;padding-top:5px;padding-bottom:5px;border-radius:8px 0px 0px 8px">';
|
|
r += '<div><div style=padding-left:12px;padding-top:2px><b>' + EscapeHtml(meshes[i].name) + '</b></div><div style=padding-left:12px;padding-top:3px;color:gray>' + rights + '</div></div>';
|
|
r += '</div></div>';
|
|
}
|
|
|
|
QH('p3meshes', r);
|
|
QV('p3noMeshFound', count == 0);
|
|
}
|
|
|
|
function gotoMesh(meshid) {
|
|
currentMesh = meshes[meshid];
|
|
if (currentMesh == null) { goBack(); }
|
|
p20updateMesh();
|
|
go(20);
|
|
}
|
|
|
|
//
|
|
// MY FILES
|
|
//
|
|
|
|
var filetreelinkpath;
|
|
var filetreelocation = [];
|
|
|
|
function p5refreshFiles() { meshserver.send({ action: 'files' }); }
|
|
|
|
function updateFiles() {
|
|
QV('MainMenuMyFiles', ((features & 8) == 0));
|
|
if ((features & 8) != 0) return; // If running on a server without files, exit now.
|
|
var html1 = '', html2 = '', displayPath = '<a style=cursor:pointer onclick=p5folderup(0)>' + "Root" + '</a>', fullPath = 'Root', publicPath, filetreex = filetree, folderdepth = 1;
|
|
|
|
// Navigate to path location, build the paths at the same time
|
|
var filetreelocation2 = [], oldlinkpath = filetreelinkpath, checkedBoxes = [], checkboxes = document.getElementsByName('fc');
|
|
for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { checkedBoxes.push(checkboxes[i].value) }; } // Save all existing checked boxes
|
|
|
|
filetreelinkpath = '';
|
|
for (var i in filetreelocation) {
|
|
if ((filetreex.f != null) && (filetreex.f[filetreelocation[i]] != null)) {
|
|
filetreelocation2.push(filetreelocation[i]);
|
|
fullPath += ' / ' + filetreelocation[i];
|
|
if ((folderdepth == 1)) {
|
|
var sp = filetreelocation[i].split('/');
|
|
publicPath = window.location + sp[0] + 'files/' + sp[2];
|
|
//if (filetreelocation[i] === userinfo._id) { filetreelinkpath += 'self'; } else { filetreelinkpath += (sp[0] + '/' + sp[2]); }
|
|
filetreelinkpath += filetreelocation[i];
|
|
} else {
|
|
if (filetreelinkpath != '') { filetreelinkpath += '/' + filetreelocation[i]; if (folderdepth > 2) { publicPath += '/' + filetreelocation[i]; } }
|
|
}
|
|
filetreex = filetreex.f[filetreelocation[i]];
|
|
displayPath += ' / <a style=cursor:pointer onclick=p5folderup(' + folderdepth + ')>' + (filetreex.n != null ? filetreex.n : filetreelocation[i]) + '</a>';
|
|
folderdepth++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
filetreelocation = filetreelocation2; // In case we could not go down the full path, we set the new path location here.
|
|
var publicfolder = fullPath.toLowerCase().startsWith('root / ' + userinfo._id + ' / public');
|
|
|
|
// Sort the files
|
|
var filetreexx = p5sort_files(filetreex.f);
|
|
|
|
// Display all files and folders at this location
|
|
for (var i in filetreexx) {
|
|
// Figure out the name and shortname
|
|
var f = filetreexx[i], name = f.n, shortname;
|
|
shortname = name;
|
|
if (name.length > 40) { shortname = EscapeHtml(name.substring(0, 40)) + "..."; } else { shortname = EscapeHtml(name); }
|
|
name = EscapeHtml(name);
|
|
|
|
// Figure out the date
|
|
//var fdatestr = '';
|
|
//if (f.d != null) { var fdate = new Date(f.d), fdatestr = (fdate.getMonth() + 1) + '/' + (fdate.getDate()) + '/' + fdate.getFullYear() + ' ' + printTime(fdate) + ' '; }
|
|
|
|
// Figure out the size
|
|
var fsize = '';
|
|
if (f.s != null) { fsize = getFileSizeStr(f.s); }
|
|
|
|
var h = '';
|
|
if (f.t < 3 || f.t == 4) {
|
|
var right = (f.t == 1 || f.t == 4) ? p5getQuotabar(f) : '';
|
|
h = '<div class=filelist file=999><input file=999 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value=\'' + name + '\'> <span style=float:right;padding-right:4px>' + right + '</span><span><div class=fileIcon' + f.t + '></div><a style=cursor:pointer onclick=p5folderset(\"' + encodeURIComponent(f.nx) + '\")>' + shortname + '</a></span></div>';
|
|
} else {
|
|
var link = shortname;
|
|
var publiclink = '';
|
|
if (publicfolder) { publiclink = ' (<a style=cursor:pointer onclick=\'p5showPublicLink(\"' + publicPath + '/' + f.nx + '\")\'>' + "Odkaz" + '</a>)'; }
|
|
if (f.s > 0) { link = '<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"downloadfile.ashx?link=' + encodeURIComponent(filetreelinkpath + '/' + f.nx) + '\">' + shortname + '</a>' + publiclink; }
|
|
h = '<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value=\'' + f.nx + '\'> <span style=float:right;padding-right:4px>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
|
|
}
|
|
|
|
if (f.t < 3) { html1 += h; } else { html2 += h; }
|
|
}
|
|
|
|
//if (f.parent == null) { }
|
|
QH('p5rightOfButtons', p5getQuotabar(filetreex));
|
|
|
|
QH('p5files', html1 + html2);
|
|
QH('p5currentpath', displayPath);
|
|
QE('p5FolderUp', filetreelocation.length != 0);
|
|
QV('p5PublicShare', publicfolder);
|
|
|
|
// Re-check all boxes if needed
|
|
if (oldlinkpath == filetreelinkpath) {
|
|
checkboxes = document.getElementsByName('fc');
|
|
for (var i = 0; i < checkboxes.length; i++) {
|
|
checkboxes[i].checked = (checkedBoxes.indexOf(checkboxes[i].value) >= 0);
|
|
}
|
|
}
|
|
|
|
p5setActions();
|
|
}
|
|
|
|
function getNiceSize(bytes) {
|
|
if (bytes <= 0) return "Uložiště plné";
|
|
if (bytes < 2048) return format("{0}b zbývá", bytes);
|
|
if (bytes < 2097152) return format("{0}k zbývá", Math.round(bytes / 1024));
|
|
if (bytes < 2147483648) return format("{0}m zbývá", Math.round(bytes / 1024 / 1024));
|
|
return format("{0}g zbývá", Math.round(bytes / 1024 / 1024 / 1024));
|
|
}
|
|
|
|
function p5getQuotabar(f) {
|
|
while (f.t > 1 && f.t != 4) { f = f.parent; }
|
|
if ((f.t != 1 && f.t != 4) || (f.maxbytes == null)) return '';
|
|
return getNiceSize(f.maxbytes - f.s) + ' <progress style=height:10px;width:100px value=' + f.s + ' max=' + f.maxbytes + ' />';
|
|
}
|
|
|
|
function p5showPublicLink(u) { setDialogMode(2, "Veřejný odkaz", 1, null, '<input type=text style=width:100% value="' + u + '" readonly />'); }
|
|
|
|
var sortorder;
|
|
function p5sort_filename(a, b) { if (a.ln > b.ln) return (1 * sortorder); if (a.ln < b.ln) return (-1 * sortorder); return 0; }
|
|
function p5sort_timestamp(a, b) { if (a.d > b.d) return (1 * sortorder); if (a.d < b.d) return (-1 * sortorder); return 0; }
|
|
function p5sort_bysize(a, b) { if (a.s == b.s) return p5sort_filename(a, b); return (((a.s - b.s)) * sortorder); }
|
|
|
|
function p5sort_files(files) {
|
|
var r = [], sortselection = Q('p5sortdropdown').value;
|
|
for (var i in files) { files[i].nx = i; if (files[i].n == null) { files[i].n = i; } files[i].ln = files[i].n.toLowerCase(); r.push(files[i]); }
|
|
sortorder = 1;
|
|
if (sortselection > 3) { sortorder = -1; sortselection -= 3; }
|
|
if (sortselection == 1) { r.sort(p5sort_filename); }
|
|
else if (sortselection == 2) { r.sort(p5sort_bysize); }
|
|
else if (sortselection == 3) { r.sort(p5sort_timestamp); }
|
|
return r;
|
|
}
|
|
|
|
function p5setActions() {
|
|
var cc = getFileSelCount(), tc = getFileCount(), sfc = getFileSelCount(false); // In order: number of entires selected, number of total entries, number of selected entires that are files (not folders)
|
|
QE('p5DeleteFileButton', (cc > 0) && (filetreelocation.length > 0));
|
|
QE('p5NewFolderButton', filetreelocation.length > 0);
|
|
QE('p5UploadButton', filetreelocation.length > 0);
|
|
QE('p5RenameFileButton', (cc == 1) && (filetreelocation.length > 0));
|
|
QE('p5SelectAllButton', tc > 0);
|
|
Q('p5SelectAllButton').value = (cc > 0 ? "Nic" : "Vše");
|
|
QE('p5CutButton', (sfc > 0) && (cc == sfc));
|
|
QE('p5CopyButton', (sfc > 0) && (cc == sfc));
|
|
QE('p5PasteButton', (p5clipboard != null) && (p5clipboard.length > 0) && (filetreelocation.length > 0));
|
|
}
|
|
|
|
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; }
|
|
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; }
|
|
function getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fc'); return checkboxes.length; }
|
|
function p5selectallfile() { var nv = (getFileSelCount() == 0), checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p5setActions(); }
|
|
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; }
|
|
function getFileSizeStr(size) { if (size == 1) return "1 byte"; return format("{0} bytů", size); }
|
|
function p5folderup(x) { if (x == null) { filetreelocation.pop(); } else { while (filetreelocation.length > x) { filetreelocation.pop(); } } updateFiles(); return false; }
|
|
function p5folderset(x) { filetreelocation.push(decodeURIComponent(x)); updateFiles(); return false; }
|
|
function p5createfolder() { setDialogMode(2, "Nový adresář", 3, p5createfolderEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />'); focusTextBox('p5renameinput'); p5fileNameCheck(); }
|
|
function p5createfolderEx() { meshserver.send({ action: 'fileoperation', fileop: 'createfolder', path: filetreelocation, newfolder: Q('p5renameinput').value }); }
|
|
function p5deletefile() { var cc = getFileSelCount(), rec = (getFileSelDirCount() > 0) ? '<br /><br /><label><input type=checkbox id=p5recdeleteinput>' + "Rekurzivní mazání" + '</label><br>' : '<input type=checkbox id=p5recdeleteinput style=\'display:none\'>'; setDialogMode(2, "Smazat", 3, p5deletefileEx, (cc > 1) ? (format("Smazat {0} vybrané prvky?", cc) + rec) : ("Smazat vybraný prvek?" + rec)); }
|
|
function p5deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(checkboxes[i].value); } } meshserver.send({ action: 'fileoperation', fileop: 'delete', path: filetreelocation, delfiles: delfiles, rec: Q('p5recdeleteinput').checked }); }
|
|
function p5renamefile() { var renamefile, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = checkboxes[i].value; } } setDialogMode(2, "Přejmenovat", 3, p5renamefileEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'fileoperation', fileop: 'rename', path: filetreelocation, oldname: renamefile }); focusTextBox('p5renameinput'); p5fileNameCheck(); }
|
|
function p5renamefileEx(b, t) { t.newname = Q('p5renameinput').value; meshserver.send(t); }
|
|
function p5fileNameCheck(e) { var x = isFilenameValid(Q('p5renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e && e.keyCode == 13)) { dialogclose(1); } }
|
|
var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
|
|
function p5uploadFile() { setDialogMode(2, "Nahrát soubor", 3, p5uploadFileEx, '<form method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame><input type=text name=link style=display:none id=p5uploadpath value=\"' + encodeURIComponent(filetreelinkpath) + '\" /><input type=file name=files id=p5uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p5uploadinput\')" /><input type=hidden name=authCookie value=' + authCookie + ' /><input type=submit id=p5loginSubmit style=display:none /></form>'); updateUploadDialogOk('p5uploadinput'); }
|
|
function p5uploadFileEx() { Q('p5loginSubmit').click(); }
|
|
function updateUploadDialogOk(x) { QE('idx_dlgOkButton', Q(x).value != ''); }
|
|
|
|
var p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0;
|
|
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(); }
|
|
function p5pasteFile() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = format("Potvrdit {0} z {1} záznam{2} do tohoto umístění?", (p5clipboardCut == 0 ? 'copy' : 'move'), p5clipboard.length, ((p5clipboard.length > 1) ? 's' : '')) } setDialogMode(2, "Vložit", 3, p5pasteFileEx, x); }
|
|
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(); } }
|
|
function p5updateClipview() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = format("Držím {0} zaznamů{1} pro {2}", p5clipboard.length, ((p5clipboard.length > 1) ? 's' : ''), (p5clipboardCut == 0 ? "kopírovat" : "přesun")) + ', <a href=# onclick="return p5clearClip()" style=cursor:pointer>' + "Vymazat" + '</a>.' } QH('p5bottomstatus', x); p5setActions(); }
|
|
function p5clearClip() { p5clipboard = null; p5clipboardFolder = null; p5clipboardCut = 0; p5updateClipview(); return false; }
|
|
|
|
function p5fileDragDrop(e) {
|
|
haltEvent(e);
|
|
QV('bigfail', false);
|
|
QV('bigok', false);
|
|
//QV('p5fileCatchAllInput', false);
|
|
if (e.dataTransfer == null || e.dataTransfer.files.length == 0 || filetreelocation.length == 0) return;
|
|
var names = [], sizes = [], types = [], datas = [], readercount = e.dataTransfer.files.length;
|
|
for (var i = 0; i < e.dataTransfer.files.length; i++) {
|
|
var reader = new FileReader(), file = e.dataTransfer.files[i];
|
|
names.push(file.name);
|
|
sizes.push(file.size);
|
|
types.push(file.type);
|
|
reader.onload = function (event) {
|
|
datas.push(event.target.result);
|
|
if (--readercount == 0) {
|
|
Q('p5fileDragName').value = names.join('*');
|
|
Q('p5fileDragSize').value = sizes.join('*');
|
|
Q('p5fileDragType').value = types.join('*');
|
|
Q('p5fileDragData').value = datas.join('*');
|
|
Q('p5fileDragLink').value = encodeURIComponent(filetreelinkpath);
|
|
Q('p5loginSubmit2').click();
|
|
}
|
|
}
|
|
reader.readAsDataURL(file);
|
|
}
|
|
}
|
|
|
|
var p5dragtimer = null;
|
|
function p5fileDragOver(e) {
|
|
haltEvent(e);
|
|
if (p5dragtimer != null) { clearTimeout(p5dragtimer); p5dragtimer = null; }
|
|
var ac = true; // TODO: Set to true if we can accept the file
|
|
if (filetreelocation.length == 0) { ac = false; }
|
|
QV('bigok', ac);
|
|
QV('bigfail', !ac);
|
|
//QV('p5fileCatchAllInput', ac);
|
|
}
|
|
|
|
function p5fileDragLeave(e) {
|
|
haltEvent(e);
|
|
if (e.target.id != 'p5filetable') {
|
|
QV('bigfail', false);
|
|
QV('bigok', false);
|
|
//QV('p5fileCatchAllInput', false);
|
|
} else {
|
|
p5dragtimer = setTimeout('QV(\'bigfail\',false);QV(\'bigok\',false);p5dragtimer=null;', 200);
|
|
}
|
|
}
|
|
|
|
//
|
|
// MY DEVICES
|
|
//
|
|
|
|
function ondeskkeypress(e) {
|
|
toggleSoftKeys(0);
|
|
Q('DeskSoftInput').value = '';
|
|
setSessionActivity();
|
|
if (desktop && !xxdialogMode && xxcurrentView == 10) {
|
|
// Check what keys we are allows to send
|
|
if (currentNode != null) {
|
|
var mesh = meshes[currentNode.meshid];
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
|
if (inputAllowed == false) return false;
|
|
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
|
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
|
|
}
|
|
return desktop.m.handleKeys(e);
|
|
}
|
|
}
|
|
|
|
function ondeskkeydown(e) {
|
|
toggleSoftKeys(0);
|
|
Q('DeskSoftInput').value = '';
|
|
setSessionActivity();
|
|
if (desktop && !xxdialogMode && xxcurrentView == 10) {
|
|
// Check what keys we are allows to send
|
|
if (currentNode != null) {
|
|
var mesh = meshes[currentNode.meshid];
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
|
if (inputAllowed == false) return false;
|
|
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
|
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
|
|
}
|
|
return desktop.m.handleKeyDown(e);
|
|
}
|
|
}
|
|
|
|
function ondeskkeyup(e) {
|
|
toggleSoftKeys(0);
|
|
Q('DeskSoftInput').value = '';
|
|
setSessionActivity();
|
|
if (desktop && !xxdialogMode && xxcurrentView == 10) {
|
|
// Check what keys we are allows to send
|
|
if (currentNode != null) {
|
|
var mesh = meshes[currentNode.meshid];
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
|
if (inputAllowed == false) return false;
|
|
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
|
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || ((e.keyCode < 32) && (e.keyCode != 8) && (e.keyCode != 13)) || (e.keyCode > 90)) return false; }
|
|
}
|
|
return desktop.m.handleKeyUp(e);
|
|
}
|
|
}
|
|
|
|
// Since the update device call can be quite frequent, we can moderate it and only call it at most 5 times a second.
|
|
var updateDevicesTimer = null;
|
|
function updateDevices() { if (updateDevicesTimer != null) return; updateDevicesTimer = setTimeout(updateDevicesEx, 200); }
|
|
|
|
var sort = 0;
|
|
var deviceHeaderId = 0;
|
|
var deviceHeaderCount;
|
|
var deviceHeaders = {};
|
|
var showRealNames = false;
|
|
var deviceHeaderTotal = 0;
|
|
var deviceHeaders = {};
|
|
var deviceHeadersTitles = {};
|
|
function updateDevicesEx() {
|
|
if (updateDevicesTimer != null) { clearTimeout(updateDevicesTimer); updateDevicesTimer = null; }
|
|
var r = '', c = 0, current = null, count = 0, displayedMeshes = {}, groups = {}, groupCount = {};
|
|
|
|
// 3 wide, list view or desktop view
|
|
deviceHeaderId = 0;
|
|
deviceHeaderCount = {};
|
|
deviceHeaderTotal = 0;
|
|
deviceHeaders = {};
|
|
deviceHeadersTitles = {};
|
|
var current;
|
|
|
|
// Perform node sort
|
|
if (sort == 0) { nodes.sort(meshSort); }
|
|
else if (sort == 1) { nodes.sort(powerSort); }
|
|
else if (sort == 2) { if (showRealNames == true) { nodes.sort(deviceHostSort); } else { nodes.sort(deviceSort); } }
|
|
|
|
// Go thru the list of nodes and display them
|
|
for (var i in nodes) {
|
|
if (nodes[i].v == false) continue;
|
|
var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links[userinfo._id];
|
|
if (meshlinks == null) continue;
|
|
var meshrights = meshlinks.rights;
|
|
|
|
if (sort == 0) {
|
|
// Mesh header
|
|
nodes.sort(meshSort);
|
|
if (nodes[i].meshid != current) {
|
|
deviceHeaderSet();
|
|
var extra = '';
|
|
if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span style=color:lightgray>' + ", Intel® AMT pouze" + '</span>'; }
|
|
if (current != null) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
|
|
r += '<div class=DevSt style=padding-top:4px><span style=float:right>';
|
|
//r += getMeshActions(mesh2, meshrights);
|
|
r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' style=color:lightgray></span></div>';
|
|
current = nodes[i].meshid;
|
|
displayedMeshes[current] = 1;
|
|
c = 0;
|
|
}
|
|
} else if (sort == 1) {
|
|
// Power header
|
|
if (nodes[i].pwr !== current) {
|
|
deviceHeaderSet();
|
|
if (current !== null) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
|
|
r += '<div class=DevSt style=width:100%;padding-top:4px><span>' + PowerStateStr2(nodes[i].pwr) + '</span><span id=DevxHeader' + deviceHeaderId + ' style=color:lightgray></span></div>';
|
|
current = nodes[i].pwr;
|
|
c = 0;
|
|
}
|
|
} else if (sort == 2) {
|
|
// Device header
|
|
if (current == null) { current = '1'; }
|
|
}
|
|
|
|
count++;
|
|
var title = EscapeHtml(nodes[i].name);
|
|
if (title.length == 0) { title = '<i>' + "Nic" + '</i>'; }
|
|
if ((nodes[i].rname != null) && (nodes[i].rname.length > 0)) { title += " / " + EscapeHtml(nodes[i].rname); }
|
|
var name = EscapeHtml(nodes[i].name);
|
|
if (showRealNames == true && nodes[i].rname != null) name = EscapeHtml(nodes[i].rname);
|
|
if (name.length == 0) { name = '<i>' + "Nic" + '</i>'; }
|
|
|
|
// Node
|
|
var icon = nodes[i].icon, nodestate = NodeStateStr(nodes[i]);
|
|
if ((!nodes[i].conn) || (nodes[i].conn == 0)) { icon += ' gray'; }
|
|
r += '<div style=cursor:pointer onclick=goForward(\'' + nodes[i]._id + '\')>';
|
|
r += '<div class="i' + icon + '" style="float:left;margin-left:4px"></div>';
|
|
r += '<div style="width:auto;height:40px;background-color:lightgray;margin-top:5px;margin-bottom:5px;margin-left:60px;padding-top:5px;padding-bottom:5px;border-radius:8px 0px 0px 8px">';
|
|
r += '<div><div style=padding-left:12px;padding-top:2px><b>' + name + '</b></div><div style=padding-left:12px;padding-top:3px;color:gray>' + nodestate + '</div></div>';
|
|
r += '</div></div>';
|
|
|
|
// If we are displaying devices by group, put the device in the right group.
|
|
/*
|
|
if ((sort == 3) && (r != '')) {
|
|
if (nodes[i].tags) {
|
|
for (var j in nodes[i].tags) {
|
|
var tag = nodes[i].tags[j];
|
|
if (groups[tag] == null) { groups[tag] = r; groupCount[tag] = 1; } else { groups[tag] += r; groupCount[tag] += 1; }
|
|
if (view == 3) break;
|
|
}
|
|
}
|
|
r = '';
|
|
}
|
|
*/
|
|
|
|
deviceHeaderTotal++;
|
|
if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; }
|
|
}
|
|
|
|
// Display all empty meshes, we need to do this because users can add devices to these at any time.
|
|
if (sort == 0) {
|
|
for (var i in meshes) {
|
|
var mesh = meshes[i], meshlink = mesh.links[userinfo._id];
|
|
if (meshlink != null) {
|
|
var meshrights = meshlink.rights;
|
|
if (displayedMeshes[mesh._id] == null) {
|
|
if ((current != '') && (r != '')) { r += '</tr></table>'; }
|
|
r += '<div><div colspan=3 class=DevSt><span style=float:right>';
|
|
//r += getMeshActions(mesh, meshrights);
|
|
r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span></div>';
|
|
if (mesh.mtype == 1) { r += '<div style=padding:10px><i>' + "Žádné Intel® AMT zařízení v této skupině"; }
|
|
if (mesh.mtype == 2) { r += '<div style=padding:10px><i>' + "Žádné zařízení v této skupině"; }
|
|
r += '.</i></div></div>';
|
|
current = mesh._id;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count == 0) {
|
|
QH('xdevices', '<div style="margin-top:50px;text-align:center"><span style="font-size:30px">' + "Žádné zařízení" + '</span><br /><br />' + "Pro přidání zařízení použijte desktop verzi těchto stránek." + '</div>');
|
|
} else {
|
|
QH('xdevices', r);
|
|
}
|
|
deviceHeaderSet();
|
|
for (var i in deviceHeaders) { QH(i, deviceHeaders[i]); }
|
|
for (var i in deviceHeadersTitles) { Q(i).title = deviceHeadersTitles[i]; }
|
|
}
|
|
|
|
var powerStatetable = ['', "Zapnuto", "Spánek", "Spánek", "Spánek", "Hibernuji", "Vypnout", "Současnost"];
|
|
var powerStateStrings = ['', "Zapnuto", "Spí", "Spí", "Hluboký spánek", "Hibernuji", "Soft-Off", "Současnost"];
|
|
var powerStateStrings2 = ['', "Zařízení je zapnuto", "Zařízení je ve stavu spánku (S1)", "Zařízení je ve stavu spánku (S2)", "Zařízení je v hlubokém spánku (S3)", "Zařízení je hibernováno (S4)", "Zařízení je ve stavu soft-off (S5)", "Zařízení je přítomno, ale nelze získat stav napájení"];
|
|
var powerColorTable = ['#00000000', 'black', 'blue', 'blue', 'lightblue', 'blueviolet', 'darkgreen', 'lightseagreen', 'lightseagreen'];
|
|
function NodeStateStr(node) {
|
|
var states = [];
|
|
if (node.state > 0 && node.state < powerStatetable.length) state.push(powerStatetable[node.state]);
|
|
if (node.conn) {
|
|
if ((node.conn & 1) != 0) { states.push('<span>' + "Agent" + '</span>'); }
|
|
if ((node.conn & 2) != 0) { states.push('<span>' + "CIRA" + '</span>'); }
|
|
else if ((node.conn & 4) != 0) { states.push('<span>' + "Intel® AMT" + '</span>'); }
|
|
if ((node.conn & 8) != 0) { states.push('<span>' + "Přesměrování" + '</span>'); }
|
|
if ((node.conn & 16) != 0) { states.push('<span>' + "MQTT" + '</span>'); }
|
|
}
|
|
if ((node.pwr != null) && (node.pwr != 0)) { states.push(powerStateStrings[node.pwr]); }
|
|
return states.join(', ');
|
|
}
|
|
|
|
function PowerStateStr(x) {
|
|
if (x < powerStatetable.length) return powerStatetable[x];
|
|
return '';
|
|
}
|
|
|
|
function PowerStateStr2(x) {
|
|
if ((x != 0) && (x < powerStatetable.length)) return powerStatetable[x];
|
|
return "Neznámý";
|
|
}
|
|
|
|
function onSortSelectChange(skipsave) {
|
|
sort = document.getElementById('sortselect').selectedIndex;
|
|
if (!skipsave) { putstore('sort', sort); }
|
|
updateDevicesEx();
|
|
}
|
|
|
|
function deviceHeaderSet() {
|
|
if (deviceHeaderId == 0) { deviceHeaderId = 1; return; }
|
|
deviceHeaders['DevxHeader' + deviceHeaderId] = ', ' + deviceHeaderTotal + ((deviceHeaderTotal == 1) ? " nód" : " nódy");
|
|
var title = '';
|
|
for (var x in deviceHeaderCount) { if (title.length > 0) title += ', '; title += deviceHeaderCount[x] + ' ' + PowerStateStr2(x); }
|
|
deviceHeadersTitles['DevxHeader' + deviceHeaderId] = title;
|
|
deviceHeaderId++;
|
|
deviceHeaderCount = {};
|
|
deviceHeaderTotal = 0;
|
|
}
|
|
|
|
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; }
|
|
function powerSort(a, b) { var ap = a.pwr ? a.pwr : 0; var bp = b.pwr ? b.pwr : 0; 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; } } if (ap > bp) return 1; if (ap < bp) return -1; return 0; }
|
|
function deviceSort(a, b) { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; }
|
|
function deviceHostSort(a, b) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; }
|
|
|
|
//
|
|
// MY DEVICE
|
|
//
|
|
|
|
function refreshDevice(nodeid) {
|
|
if (!currentNode || currentNode._id != nodeid) return;
|
|
gotoDevice(nodeid, xxcurrentView, true);
|
|
}
|
|
|
|
function getNodeRights(nodeid) {
|
|
var node = getNodeFromId(nodeid), mesh = meshes[node.meshid];
|
|
return mesh.links[userinfo._id].rights;
|
|
}
|
|
|
|
var currentDevicePanel = 0;
|
|
var currentNode;
|
|
var powerTimelineNode = null;
|
|
var powerTimelineReq = null;
|
|
var powerTimelineUpdate = null;
|
|
var powerTimeline = null;
|
|
function getCurrentNode() { return currentNode; };
|
|
function gotoDevice(nodeid, panel, refresh) {
|
|
|
|
// Remind the user to verify the email address
|
|
if ((userinfo.emailVerified !== true) && (serverinfo.emailcheck == true) && (userinfo.siteadmin != 0xFFFFFFFF)) { setDialogMode(2, "Nastavení bezpečnosti", 1, null, "Nelze získat přístup k zařízení, dokud nebude ověřena e-mailová adresa. To je vyžadováno pro obnovení hesla. Jdi do \"Můj účet\" pro změnu a ověření emailu.."); return; }
|
|
|
|
// Remind the user to add two factor authentication
|
|
if ((features & 0x00040000) && !((userinfo.otpsecret == 1) || (userinfo.otphkeys > 0) || (userinfo.otpkeys > 0))) { setDialogMode(2, "Nastavení bezpečnosti", 1, null, "Nelze získat přístup k zařízení, dokud je 2-faktorová autentizace zapnuta. Toto je pro extra bezpečnost. Jdi do \"Můj účet\" a podívej se do sekce\"Nastavení bezpečnosti\"."); return; }
|
|
|
|
var node = getNodeFromId(nodeid);
|
|
if (node == null) { goBack(); return; }
|
|
var mesh = meshes[node.meshid];
|
|
if (mesh == null) { goBack(); return; }
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
if (!currentNode || currentNode._id != node._id || refresh == true) {
|
|
currentNode = node;
|
|
|
|
// Add node name
|
|
var nname = EscapeHtml(node.name);
|
|
if (nname.length == 0) { nname = '<i>' + "Nic" + '</i>'; }
|
|
if ((meshrights & 4) != 0) { nname = '<span onclick=showEditNodeValueDialog(0) style=cursor:pointer>' + nname + '</span>'; }
|
|
QH('p10deviceName', nname);
|
|
|
|
// Node attributes
|
|
var x = '<table style=width:100%>';
|
|
|
|
// Attribute: Mesh
|
|
x += addDeviceAttribute('<span>' + "Skupina" + '</span>', '<a onclick=goForward("' + node.meshid + '") style=cursor:pointer>' + EscapeHtml(meshes[node.meshid].name) + '</a>');
|
|
|
|
// Attribute: Name
|
|
if (node.rname != null) { x += addDeviceAttribute('<span>' + "Jméno" + '</span>', '<span>' + EscapeHtml(node.rname) + '</span>'); }
|
|
|
|
// Attribute: Host
|
|
if ((mesh.mtype == 1) || (node.name != node.host)) {
|
|
if ((meshrights & 4) != 0) {
|
|
if (node.host) {
|
|
x += addDeviceAttribute("Hostname", '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer>' + EscapeHtml(node.host) + '</span>');
|
|
} else {
|
|
x += addDeviceAttribute("Hostname", '<span onclick=showEditNodeValueDialog(1) style=cursor:pointer><i>' + "Nic" + '</i></span>');
|
|
}
|
|
} else {
|
|
x += addDeviceAttribute("Hostname", EscapeHtml(node.host));
|
|
}
|
|
}
|
|
|
|
// Attribute: Description
|
|
var description = node.desc ? EscapeHtml(node.desc) : '<i>' + "Nic" + '</i>';
|
|
if ((meshrights & 4) != 0) {
|
|
x += addDeviceAttribute("Popis", '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + '</span>');
|
|
} else {
|
|
x += addDeviceAttribute("Popis", description);
|
|
}
|
|
|
|
// Attribute: Mesh Agent
|
|
var agentsStr = ["Neznámý", "Windows 32bit konzole", "Windows 64bit konzole", "Windows 32bit služba", "Windows 64bit služba", "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 konzole", "Windows MinCore služba", "NodeJS", "ARM-Linaro", "ARMv6l / ARMv7l", "ARMv8 64bit", "ARMv6l / ARMv7l / NoKVM", "Neznámý", "Neznámý", "FreeBSD x86-64"];
|
|
if ((node.agent != null) && (node.agent.id != null) && (node.agent.ver != null)) {
|
|
var str = '';
|
|
if (node.agent.id <= agentsStr.length) { str = agentsStr[node.agent.id]; } else { str = agentsStr[0]; }
|
|
if (node.agent.ver != 0) { str += ' v' + node.agent.ver; }
|
|
x += addDeviceAttribute("Agent", str);
|
|
}
|
|
|
|
// Attribute: Intel AMT
|
|
if (node.intelamt != null) {
|
|
var str = '';
|
|
var provisioningStates = { 0: nobreak("Neaktivováno (před)"), 1: nobreak("Neaktivováno"), 2: nobreak("Aktivováno") };
|
|
if (node.intelamt.ver != null && node.intelamt.state == null) { str += '<i>' + nobreak("Neznámý stav") + '</i>, v' + node.intelamt.ver; } else
|
|
|
|
if ((node.intelamt.ver == null) && (node.intelamt.state == 2)) { str += '<i>' + "Aktivováno" + '</i>'; }
|
|
else if ((node.intelamt.ver == null) || (node.intelamt.state == null)) { str += '<i>' + "Neznámý stav & verze" + '</i>'; }
|
|
else {
|
|
str += provisioningStates[node.intelamt.state];
|
|
if (node.intelamt.flags) { if (node.intelamt.flags & 2) { str = ' <span>' + "CCM" + '</span>'; } else if (node.intelamt.flags & 4) { str = ' <span>' + "ACM" + '</span>'; } }
|
|
str += (', v' + node.intelamt.ver);
|
|
}
|
|
|
|
if (node.intelamt.tls == 1) { str += ', <span>' + "TLS" + '</span>'; }
|
|
if (node.intelamt.state == 2) {
|
|
if (node.intelamt.user == null || node.intelamt.user == '') {
|
|
if ((meshrights & 4) != 0) {
|
|
str += ', <i style=color:#FF0000;cursor:pointer onclick=editDeviceAmtSettings("' + node._id + '")>' + nobreak("Žádné přihlašovací údaje") + '</i>';
|
|
} else {
|
|
str += ', <i style=color:#FF0000>' + "Žádné přihlašovací údaje" + '</i>';
|
|
}
|
|
}
|
|
str += ' ';
|
|
if ((meshrights & 4) != 0) {
|
|
str += '<img src=images/link4.png height=10 width=10 style=cursor:pointer onclick=editDeviceAmtSettings("' + node._id + '")>';
|
|
}
|
|
}
|
|
|
|
var meName = "Intel® ME";
|
|
if (typeof node.intelamt.sku == 'number') {
|
|
if ((node.intelamt.sku & 8) != 0) { meName = "Intel® AMT"; }
|
|
else if ((node.intelamt.sku & 16) != 0) { meName = "Intel® SM"; }
|
|
}
|
|
x += addDeviceAttribute(meName, str);
|
|
}
|
|
|
|
// Attribute: Mesh Agent Tag
|
|
if ((node.agent != null) && (node.agent.tag != null) && (node.agent.tag != 'mailto:')) {
|
|
var tag = EscapeHtml(node.agent.tag);
|
|
if (tag.startsWith('mailto:')) { tag = '<a href="' + tag + '">' + tag.substring(7) + '</a>'; }
|
|
x += addDeviceAttribute("Značka agenta", tag);
|
|
}
|
|
|
|
// Attribute: Intel AMT
|
|
//if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
|
|
|
|
// Attribute: Connectivity (Only show this if more than just the agent is connected).
|
|
var connectivity = node.conn;
|
|
if (connectivity && connectivity > 1) {
|
|
var cstate = [];
|
|
if ((node.conn & 1) != 0) cstate.push('<span>' + "Agent" + '</span>');
|
|
if ((node.conn & 2) != 0) cstate.push('<span>' + "Intel® AMT CIRA" + '</span>');
|
|
else if ((node.conn & 4) != 0) cstate.push('<span>' + "Intel® AMT" + '</span>');
|
|
if ((node.conn & 8) != 0) cstate.push('<span>' + "Agent Relay (přesměrování)" + '</span>');
|
|
if ((node.conn & 16) != 0) cstate.push('<span>' + "MQTT" + '</span>');
|
|
x += addDeviceAttribute("Konektivita", cstate.join(', '));
|
|
}
|
|
|
|
// Node tags
|
|
var groupingTags = '<i>' + "Nic" + '</i>';
|
|
if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '<span style="background-color:lightgray;padding:3px;margin-right:4px;border-radius:5px">' + node.tags[i] + '</span>'; } }
|
|
if ((meshrights & 4) != 0) {
|
|
x += addDeviceAttribute("Tagy", '<span onclick=showEditNodeValueDialog(3) style=cursor:pointer>' + groupingTags + '</span>');
|
|
} else {
|
|
x += addDeviceAttribute("Tagy", groupingTags);
|
|
}
|
|
|
|
x += '</table><br />';
|
|
// Show action button, only show if we have permissions 4, 8, 64
|
|
if ((meshrights & 76) != 0) { x += '<input type=button value=Actions onclick=deviceActionFunction() />'; }
|
|
//x += '<input type=button value=Notes onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponent(node._id) + '") />';
|
|
//if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast onclick=deviceToastFunction() />'; }
|
|
QH('p10html', x);
|
|
|
|
// Show node last 7 days timeline
|
|
//drawDeviceTimeline();
|
|
setupFiles();
|
|
|
|
// Show bottom buttons
|
|
x = '<div style=float:right;font-size:x-small;margin-right:10px>';
|
|
if ((meshrights & 4) != 0) x += '<a style=cursor:pointer onclick=p10showDeleteNodeDialog("' + node._id + '")>' + "Smazat zařízení" + '</a>';
|
|
x += '</div><div style=font-size:x-small>';
|
|
//if (mesh.mtype == 2) x += '<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("' + node._id + '")>Interfaces</a> ';
|
|
//if (xxmap != null) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '")>Location</a> ';
|
|
x += '</div><br>'
|
|
|
|
QH('p10html3', x);
|
|
|
|
// Set the node power state
|
|
var powerstate = PowerStateStr(node.state);
|
|
//if (node.state == 0) { powerstate = 'Unknown State'; }
|
|
if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px>' + "Mesh Agent" + '</span>'; }
|
|
if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px>' + "Intel® AMT připojeno" + '</span>'; }
|
|
else if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px>' + "Intel® AMT detekováno" + '</span>'; }
|
|
if ((connectivity & 16) != 0) { if (powerstate.length > 0) { powerstate += '<br/>'; } powerstate += '<span style=font-size:12px>' + "MQTT kanál připojen" + '</span>'; }
|
|
QH('MainComputerState', powerstate);
|
|
|
|
// Set the node icon
|
|
QH('MainComputerImage', '<div class="i' + node.icon + '"></div>');
|
|
|
|
// Request the power timeline
|
|
if ((powerTimelineNode != currentNode._id) && (powerTimelineReq != currentNode._id)) { QH('p10html2', ''); powerTimelineReq = currentNode._id; meshserver.send({ action: 'powertimeline', nodeid: currentNode._id }); }
|
|
}
|
|
setupDesktop(); // Always refresh the desktop, even if we are on the same device, we need to do some canvas switching.
|
|
if (!panel) panel = 10;
|
|
go(panel);
|
|
|
|
// Update the footer menu
|
|
setupDeviceMenu();
|
|
}
|
|
|
|
function deviceToastFunction() {
|
|
if (xxdialogMode) return;
|
|
setDialogMode(2, "Device Toast", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
|
|
}
|
|
|
|
function deviceToastFunctionEx() {
|
|
meshserver.send({ action: 'toast', nodeids: [currentNode._id], title: 'MeshCentral', msg: Q('d2devToast').value });
|
|
}
|
|
|
|
function setupDeviceMenu(op, obj) {
|
|
var meshrights = 0;
|
|
if (currentNode) { meshrights = meshes[currentNode.meshid].links[userinfo._id].rights; }
|
|
if (op != null) { currentDevicePanel = op; }
|
|
QV('p10general', currentDevicePanel == 0);
|
|
QV('p10desktop', currentDevicePanel == 1); // Show if we have remote control rights or desktop view only rights
|
|
QV('p10files', currentDevicePanel == 2);
|
|
var menus = [];
|
|
if (currentDevicePanel != 0) { menus.push({ n: 'General', f: 'setupDeviceMenu(0)' }); }
|
|
if ((currentDevicePanel != 1) &&
|
|
(currentNode != null) &&
|
|
((meshrights & 8) || (meshrights & 256)) &&
|
|
(((meshes[currentNode.meshid].mtype == 1) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 1)))
|
|
) { menus.push({ n: 'Desktop', f: 'setupDeviceMenu(1)' }); }
|
|
if ((currentDevicePanel != 2) && (currentNode != null) && (meshrights & 8) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0)) && ((currentNode.mtype == 2) && (currentNode.agent.caps & 4))) { menus.push({ n: 'Files', f: 'setupDeviceMenu(2)' }); }
|
|
updateFooterMenu(menus);
|
|
}
|
|
|
|
function deviceActionFunction() {
|
|
if (xxdialogMode) return;
|
|
var meshrights = meshes[currentNode.meshid].links[userinfo._id].rights;
|
|
var x = "Vyber operaci na tomto zařízení." + '<br /><br />';
|
|
var y = '<select id=d2deviceop style=float:right;width:170px>';
|
|
if ((meshrights & 64) != 0) { y += '<option value=100>' + "Probudit" + '</option>'; } // Wake-up permission
|
|
if ((meshrights & 8) != 0) { y += '<option value=4>' + "Spánek" + '</option><option value=3>' + "Reset" + '</option><option value=2>' + "Vypnout" + '</option>'; } // Remote control permission
|
|
y += '</select>';
|
|
x += addHtmlValue("Operace", y);
|
|
setDialogMode(2, "Akce zařízení", 3, deviceActionFunctionEx, x);
|
|
}
|
|
|
|
function deviceActionFunctionEx() {
|
|
var op = Q('d2deviceop').value;
|
|
if (op == 100) {
|
|
// Device wake
|
|
meshserver.send({ action: 'wakedevices', nodeids: [currentNode._id] });
|
|
} else {
|
|
// Power operation
|
|
meshserver.send({ action: 'poweraction', nodeids: [currentNode._id], actiontype: op });
|
|
}
|
|
}
|
|
|
|
// Look to see if we need to update the device timeline
|
|
function updateDeviceTimeline() {
|
|
if ((meshserver.State != 2) || (powerTimelineNode == null) || (powerTimelineUpdate == null) || (currentNode == null)) return;
|
|
if ((powerTimelineNode == powerTimelineReq) && (currentNode._id == powerTimelineNode) && (powerTimelineUpdate < Date.now())) { powerTimelineUpdate = null; meshserver.send({ action: 'powertimeline', nodeid: currentNode._id }); }
|
|
}
|
|
|
|
// Draw device power bars. The bars are 766px wide.
|
|
function drawDeviceTimeline() {
|
|
var timeline = null, now = Date.now();
|
|
if (currentNode._id == powerTimelineNode) { timeline = powerTimeline; }
|
|
|
|
// Calculate when the timeline starts
|
|
var d = new Date();
|
|
d.setHours(0, 0, 0, 0);
|
|
d = new Date(d.getTime() - (1000 * 60 * 60 * 24 * 6));
|
|
var timelineStart = d.getTime();
|
|
|
|
// De-compact the timeline
|
|
var timeline2 = [];
|
|
if (timeline != null && timeline.length > 1) {
|
|
timeline2.push([0, timeline[1], timeline[0]]); // Start, End, Power
|
|
var ct = timeline[1];
|
|
for (var i = 2; i < timeline.length; i += 2) {
|
|
var power = timeline[i], dt = now;
|
|
if (timeline.length > (i + 1)) { dt = timeline[i + 1]; }
|
|
timeline2.push([ct, ct + dt, power]); // Start, End, Power
|
|
ct = ct + dt;
|
|
}
|
|
}
|
|
|
|
// Draw the timeline
|
|
var x = '', count = 1, date = new Date();
|
|
var totalWidth = Q('masthead').offsetWidth - (90 + 9 + 9 + 14); // Compute the total width of the power bar
|
|
date.setHours(0, 0, 0, 0);
|
|
for (var i = 0; i < 7; i++) {
|
|
var datavalue = '', start = date.getTime(), end = start + (1000 * 60 * 60 * 24);
|
|
for (var j in timeline2) {
|
|
var block = timeline2[j];
|
|
if (isTimeBlockInside(start, end, block[0], block[1]) == true) {
|
|
var ts = Math.max(start, block[0]);
|
|
var te = Math.min(Math.min(end, block[1]), now);
|
|
var width = Math.round(((te - ts) * totalWidth) / 86400000);
|
|
if (width > 0) { datavalue += '<div style=display:table-cell;width:' + width + 'px;background-color:' + powerColor(block[2]) + ';height:16px></div>'; }
|
|
}
|
|
}
|
|
x += '<tr style=' + (((count % 2) == 0) ? 'background-color:#DDD' : '') + '><td><div> ' + printDate(date) + '<div></div></div></td><td><div>' + datavalue + '</div></td></tr>';
|
|
++count;
|
|
date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day
|
|
}
|
|
QH('p10html2', '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse;width:calc(100% - 18px);margin:9px" border=0 cellpadding=2 cellspacing=0><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:center;width:90px>Day</th><th scope=col style=text-align:center>Power State</th></tr>' + x + '</tbody></table>');
|
|
}
|
|
|
|
// Return a color for the given power state
|
|
function powerColor(x) { if (x < powerColorTable.length) { return powerColorTable[x]; } return 'yellow'; }
|
|
|
|
// Return true if the time block is visible within the start/end period
|
|
function isTimeBlockInside(start, end, blockStart, blockEnd) {
|
|
if ((blockStart < start) && (blockEnd > end)) return true; // Block is wider than timespan
|
|
if ((blockStart > start) && (blockStart < end)) return true;
|
|
if ((blockEnd > start) && (blockEnd < end)) return true;
|
|
return false;
|
|
}
|
|
|
|
function addDeviceAttribute(name, value) {
|
|
return '<tr><td style=width:100px;color:gray>' + name + '</td><td style=overflow:hidden>' + value + '</td></tr>';
|
|
}
|
|
|
|
function editDeviceAmtSettings(nodeid, func) {
|
|
if (xxdialogMode) return;
|
|
var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = getNodeRights(nodeid);
|
|
if ((meshrights & 4) == 0) return;
|
|
x += addHtmlValue("Uživatel", '<input id=dp10username style=width:170px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
|
|
x += addHtmlValue("Heslo", '<input id=dp10password type=password style=width:170px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
|
|
x += addHtmlValue("Bezpečnost", '<select id=dp10tls style=width:176px><option value=0>' + "Žádné TLS" + '</option><option value=1>' + "TLS vyžadováno" + '</option></select>');
|
|
if ((node.intelamt.user != null) && (node.intelamt.user != '')) { buttons = 7; }
|
|
setDialogMode(2, "Upravit Intel® AMT pověření", buttons, editDeviceAmtSettingsEx, x, { node: node, func: func });
|
|
if ((node.intelamt.user != null) && (node.intelamt.user != '')) { Q('dp10username').value = node.intelamt.user; } else { Q('dp10username').value = 'admin'; }
|
|
Q('dp10tls').value = node.intelamt.tls;
|
|
validateDeviceAmtSettings();
|
|
}
|
|
|
|
function validateDeviceAmtSettings() {
|
|
QE('idx_dlgOkButton', passwordcheck(Q('dp10password').value));
|
|
}
|
|
|
|
function editDeviceAmtSettingsEx(button, tag) {
|
|
if (button == 2) {
|
|
// Delete button pressed, remove credentials
|
|
meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: '', pass: '' } });
|
|
} else {
|
|
// Change Intel AMT credentials
|
|
var amtuser = Q('dp10username').value;
|
|
if (amtuser == '') amtuser = 'admin';
|
|
var amtpass = Q('dp10password').value;
|
|
if (amtpass == '') amtuser = '';
|
|
meshserver.send({ action: 'changedevice', nodeid: tag.node._id, intelamt: { user: amtuser, pass: amtpass, tls: Q('dp10tls').value } });
|
|
tag.node.intelamt.user = amtuser;
|
|
tag.node.intelamt.tls = Q('dp10tls').value;
|
|
if (tag.func) { setTimeout(tag.func, 300); }
|
|
}
|
|
}
|
|
|
|
function p10showDeleteNodeDialog(nodeid) {
|
|
if (xxdialogMode) return;
|
|
setDialogMode(2, "Smazat nod", 3, p10showDeleteNodeDialogEx, format("Smazat {0}?", EscapeHtml(currentNode.name)) + '<br /><br /><input id=p10check type=checkbox onchange=p10validateDeleteNodeDialog() />' + "Potvrdit", nodeid);
|
|
p10validateDeleteNodeDialog();
|
|
}
|
|
|
|
function p10validateDeleteNodeDialog() {
|
|
QE('idx_dlgOkButton', Q('p10check').checked);
|
|
}
|
|
|
|
function p10showDeleteNodeDialogEx(buttons, nodeid) {
|
|
meshserver.send({ action: 'removedevices', nodeids: [nodeid] });
|
|
}
|
|
|
|
function p10showiconselector() {
|
|
if (xxdialogMode) return;
|
|
var mesh = meshes[currentNode.meshid];
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
if ((meshrights & 4) == 0) return;
|
|
|
|
var x = '<table align=center><td>';
|
|
x += '<div style=display:inline-block class=i1 onclick=p10setIcon(1)></div>';
|
|
x += '<div style=display:inline-block class=i2 onclick=p10setIcon(2)></div>';
|
|
x += '<div style=display:inline-block class=i3 onclick=p10setIcon(3)></div><br>';
|
|
x += '<div style=display:inline-block class=i4 onclick=p10setIcon(4)></div>';
|
|
x += '<div style=display:inline-block class=i5 onclick=p10setIcon(5)></div>';
|
|
x += '<div style=display:inline-block class=i6 onclick=p10setIcon(6)></div></table>';
|
|
setDialogMode(2, "Výběr ikony", 0, null, x);
|
|
QV('id_dialogclose', true);
|
|
}
|
|
|
|
function p10setIcon(icon) {
|
|
setDialogMode(0);
|
|
meshserver.send({ action: 'changedevice', nodeid: currentNode._id, icon: icon });
|
|
}
|
|
|
|
var showEditNodeValueDialog_modes = ["Název zařízení", "Hostname", "Popis", "Tagy"];
|
|
var showEditNodeValueDialog_modes2 = ['name', 'host', 'desc', 'tags'];
|
|
var showEditNodeValueDialog_modes3 = ['', '', '', "Skupina1, Skupina2, Skupina3"];
|
|
function showEditNodeValueDialog(mode) {
|
|
if (xxdialogMode) return;
|
|
var x = addHtmlValue(showEditNodeValueDialog_modes[mode], '<input id=dp10devicevalue style=width:170px maxlength=64 placeholder="' + showEditNodeValueDialog_modes3[mode] + '" onchange=p10editdevicevalueValidate(' + mode + ',event) onkeyup=p10editdevicevalueValidate(' + mode + ',event) />');
|
|
setDialogMode(2, "Upravit zařízení", 3, showEditNodeValueDialogEx, x, mode);
|
|
var v = currentNode[showEditNodeValueDialog_modes2[mode]];
|
|
if (v == null) v = '';
|
|
if (Array.isArray(v)) { v = v.join(', '); }
|
|
Q('dp10devicevalue').value = v;
|
|
p10editdevicevalueValidate();
|
|
Q('dp10devicevalue').focus();
|
|
}
|
|
|
|
function showEditNodeValueDialogEx(button, mode) {
|
|
var x = { action: 'changedevice', nodeid: currentNode._id };
|
|
x[showEditNodeValueDialog_modes2[mode]] = Q('dp10devicevalue').value;
|
|
meshserver.send(x);
|
|
}
|
|
|
|
function p10editdevicevalueValidate(mode, e) {
|
|
var x = ((mode > 1) || (Q('dp10devicevalue').value.length > 0));
|
|
QE('idx_dlgOkButton', x);
|
|
if ((e != null) && (x == true) && (e.keyCode == 13)) { dialogclose(1); }
|
|
}
|
|
|
|
//
|
|
// DESKTOP
|
|
//
|
|
|
|
var desktop;
|
|
var desktopNode;
|
|
var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50 };
|
|
function setupDesktop() {
|
|
// Setup the remote desktop
|
|
if ((desktopNode != currentNode) && (desktop != null)) { desktop.Stop(); desktopNode = null; desktop = null; }
|
|
|
|
// If the device desktop is already connected in multi-desktop, use that.
|
|
if ((desktopNode != currentNode) || (desktop == null)) {
|
|
// Device is not already connected, just setup a blank canvas
|
|
QH('DeskParent', '<canvas id=Desk width=640 height=200 style="width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown=dmousedown(event) onmouseup=dmouseup(event) onmousemove=dmousemove(event)></canvas>');
|
|
desktopNode = currentNode;
|
|
// Setup the mouse wheel
|
|
Q('Desk').addEventListener('DOMMouseScroll', function (e) { return dmousewheel(e); });
|
|
Q('Desk').addEventListener('mousewheel', function (e) { return dmousewheel(e); });
|
|
}
|
|
desktopNode = currentNode;
|
|
updateDesktopButtons();
|
|
|
|
// On some browsers like IE, we can't save screen shots. Hide the scheenshot/capture buttons.
|
|
if (!Q('Desk')['toBlob']) { QV('deskSaveBtn', false); }
|
|
}
|
|
|
|
// Show and enable the right buttons
|
|
function updateDesktopButtons() {
|
|
var mesh = meshes[currentNode.meshid];
|
|
var deskState = 0;
|
|
if (desktop != null) { deskState = desktop.State; }
|
|
var meshrights = mesh.links[userinfo._id].rights;
|
|
|
|
// Show the right buttons
|
|
QV('disconnectbutton1', (deskState != 0));
|
|
QV('connectbutton1', (deskState == 0) && (mesh.mtype == 2) && ((meshrights & 8) || (meshrights & 256)));
|
|
QV('connectbutton1h',
|
|
(deskState == 0) &&
|
|
(meshrights & 8) &&
|
|
((mesh.mtype == 1) ||
|
|
(currentNode.intelamt != null) &&
|
|
((currentNode.intelamt.state == 2) &&
|
|
(currentNode.intelamt.ver != null) &&
|
|
(typeof currentNode.intelamt.sku == 'number') &&
|
|
((currentNode.intelamt.sku & 8) != 0))
|
|
)
|
|
);
|
|
|
|
// Show the right settings
|
|
QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
|
|
QV('d7meshkvm', (mesh.mtype == 2) && ((deskState == false) || (desktop.contype == 1)));
|
|
|
|
// Enable buttons
|
|
var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
|
|
QE('connectbutton1', online);
|
|
var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
|
|
QE('connectbutton1h', hwonline);
|
|
//QE('deskSaveBtn', deskState == 3);
|
|
//QV('DeskCAD', meshrights & 8);
|
|
//QE('DeskCAD', deskState == 3);
|
|
//QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5));
|
|
//QE('DeskWD', deskState == 3);
|
|
//QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5));
|
|
//QE('deskkeys', deskState == 3);
|
|
//QE('DeskToolsButton', online);
|
|
QV('DeskToastButton', ((meshrights & 16384) != 0) && (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
|
|
//QE('DeskToastButton', online);
|
|
QV('deskActionsBtn', meshrights & 8);
|
|
Q('DeskControl').checked = ((meshrights & 8) != 0);
|
|
if (online == false) QV('DeskTools', false);
|
|
}
|
|
|
|
function connectDesktop(e, contype) {
|
|
setSessionActivity();
|
|
if (desktop == null) {
|
|
desktopNode = currentNode;
|
|
if (contype == 2) {
|
|
// Setup the Intel AMT remote desktop
|
|
if ((desktopNode.intelamt.user == null) || (desktopNode.intelamt.user == '')) { editDeviceAmtSettings(desktopNode._id, connectDesktop); return; }
|
|
desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'), authCookie);
|
|
desktop.debugmode = debugmode;
|
|
desktop.onStateChanged = onDesktopStateChange;
|
|
desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
|
|
desktop.m.useZRLE = (desktopsettings.encoding < 3);
|
|
desktop.m.showmouse = desktopsettings.showmouse;
|
|
desktop.m.onScreenSizeChange = deskAdjust;
|
|
desktop.Start(desktopNode._id, 16994, '*', '*', 0);
|
|
desktop.contype = 2;
|
|
} else {
|
|
// Setup the Mesh Agent remote desktop
|
|
desktop = CreateAgentRedirect(meshserver, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, authRelayCookie, domainUrl);
|
|
desktop.debugmode = debugmode;
|
|
desktop.m.debugmode = debugmode;
|
|
desktop.attemptWebRTC = attemptWebRTC;
|
|
desktop.onStateChanged = onDesktopStateChange;
|
|
desktop.m.CompressionLevel = desktopsettings.quality; // Number from 1 to 100. 50 or less is best.
|
|
desktop.m.ScalingLevel = desktopsettings.scaling;
|
|
desktop.m.FrameRateTimer = desktopsettings.framerate;
|
|
desktop.m.onDisplayinfo = deskDisplayInfo;
|
|
desktop.m.onScreenSizeChange = deskAdjust;
|
|
desktop.Start(desktopNode._id);
|
|
desktop.contype = 1;
|
|
}
|
|
} else {
|
|
// Disconnect and clean up the remote desktop
|
|
desktop.Stop();
|
|
desktopNode = desktop = null;
|
|
}
|
|
}
|
|
|
|
function onDesktopStateChange(xdesktop, state) {
|
|
var xstate = state;
|
|
if ((xstate == 3) && (xdesktop.contype == 2)) { xstate++; }
|
|
var str = StatusStrs[xstate];
|
|
if ((desktop != null) && (desktop.webRtcActive == true)) { str += ", WebRTC"; }
|
|
//if (desktop.m.stopInput == true) { str += ', Loopback'; }
|
|
QH('deskstatus', str);
|
|
switch (state) {
|
|
case 0:
|
|
// Disconnect and clean up the remote desktop
|
|
desktop.Stop();
|
|
desktopNode = desktop = null;
|
|
QV('termdisplays', false);
|
|
if (fullscreen == true) { deskToggleFull(); }
|
|
break;
|
|
case 2:
|
|
break;
|
|
default:
|
|
//console.log('Unknown onDesktopStateChange state', state);
|
|
break;
|
|
}
|
|
updateDesktopButtons();
|
|
deskAdjust();
|
|
setTimeout(deskAdjust, 50);
|
|
}
|
|
|
|
function showDesktopSettings() {
|
|
if (xxdialogMode) return;
|
|
applyDesktopSettings();
|
|
updateDesktopButtons();
|
|
setDialogMode(7, "Nastavení vzdálené plochy", 3, showDesktopSettingsChanged);
|
|
}
|
|
|
|
function showDesktopSettingsChanged() {
|
|
desktopsettings.encoding = d7desktopmode.value;
|
|
desktopsettings.showfocus = d7showfocus.checked;
|
|
desktopsettings.showmouse = d7showcursor.checked;
|
|
desktopsettings.quality = d7bitmapquality.value;
|
|
desktopsettings.scaling = d7bitmapscaling.value;
|
|
desktopsettings.framerate = d7framelimiter.value;
|
|
localStorage.setItem('desktopsettings', JSON.stringify(desktopsettings));
|
|
applyDesktopSettings();
|
|
if (desktop) {
|
|
if (desktop.contype == 1) {
|
|
if (desktop.State != 0) { desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); }
|
|
}
|
|
if (desktop.contype == 2) {
|
|
if (desktop.State != 0) { desktop.Stop(); setTimeout(function () { connectDesktop(null, 2); }, 50); }
|
|
}
|
|
}
|
|
}
|
|
|
|
function applyDesktopSettings() {
|
|
var r = '', ops = (features & 512) ? [90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1];
|
|
for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
|
|
QH('d7bitmapquality', r);
|
|
d7desktopmode.value = desktopsettings.encoding;
|
|
d7showfocus.checked = desktopsettings.showfocus;
|
|
d7showcursor.checked = desktopsettings.showmouse;
|
|
d7bitmapquality.value = 40; // Default value
|
|
if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
|
|
d7bitmapscaling.value = desktopsettings.scaling;
|
|
if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; }
|
|
}
|
|
|
|
var fullscreen = false;
|
|
/*
|
|
function deskToggleFull() {
|
|
fullscreen = !fullscreen;
|
|
QV('mastheadx', !fullscreen);
|
|
QV('masthead', !fullscreen);
|
|
QV('topbar', !fullscreen);
|
|
QV('p11deviceNameHeader', !fullscreen);
|
|
QV('footer', !fullscreen);
|
|
QV('column_l_bottomgap', !fullscreen);
|
|
QV('idx_deskFullBtn2', fullscreen);
|
|
QV('deskFullBtn', !fullscreen);
|
|
if (fullscreen) {
|
|
QS('container').width = '100%';
|
|
QS('container')['border-right'] = '0';
|
|
QS('container')['border-left'] = '0';
|
|
QS('column_l').padding = '0';
|
|
QS('column_l').width = '100%';
|
|
} else {
|
|
QS('container').width = '960px';
|
|
QS('container')['border-right'] = '1px solid #b7b7b7';
|
|
QS('container')['border-left'] = '1px solid #b7b7b7';
|
|
QS('column_l').padding = '0 15px';
|
|
QS('column_l').width = '930px';
|
|
toggleFullScreen();
|
|
}
|
|
deskAdjust();
|
|
}
|
|
*/
|
|
|
|
function deskAdjust() {
|
|
var x = (Q('DeskParent').clientHeight - Q('Desk').clientHeight) / 2;
|
|
if (x < 0) {
|
|
var mh = Q('DeskParent').clientHeight, mw = 9999;
|
|
if (desktop) { mw = (desktop.m.width / desktop.m.height) * mh; }
|
|
QS('Desk')['max-height'] = mh + 'px';
|
|
QS('Desk')['max-width'] = mw + 'px';
|
|
x = 0;
|
|
} else {
|
|
QS('Desk')['max-height'] = null;
|
|
QS('Desk')['max-width'] = null;
|
|
}
|
|
QS('Desk')['margin-top'] = x + 'px';
|
|
QS('Desk')['margin-bottom'] = x + 'px';
|
|
}
|
|
|
|
// Remote desktop special key combos for Windows
|
|
function deskSendKeys() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
var ks = Q('deskkeys').value;
|
|
if (ks == 0) { // WIN+Down arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff54, 1], [0xff54, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Down arrow press, Down arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 40], [desktop.m.KeyAction.UP, 40], [desktop.m.KeyAction.EXUP, 0x5B]]); // Agent: L-Winkey press, Down arrow press, Down arrow release, L-Winkey release
|
|
}
|
|
} else if (ks == 1) { // WIN+Up arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xff52, 1], [0xff52, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, Up arrow press, Up arrow release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 38], [desktop.m.KeyAction.UP, 38], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, Up arrow press, Up arrow release, L-Winkey release
|
|
}
|
|
} else if (ks == 2) { // WIN+L arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x6c, 1], [0x6c, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'l' press, 'l' release, Meta-left release
|
|
} else {
|
|
desktop.sendCtrlMsg('{"action":"lock"}');
|
|
//desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN,0x5B],[desktop.m.KeyAction.DOWN,76],[desktop.m.KeyAction.UP,76],[desktop.m.KeyAction.EXUP,0x5B]]); // MeshAgent: L-Winkey press, 'L' press, 'L' release, L-Winkey release
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXDOWN, 0x5B);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.DOWN, 76);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.UP, 76);
|
|
//desktop.m.SendKeyMsgKC(desktop.m.KeyAction.EXUP, 0x5B);
|
|
}
|
|
} else if (ks == 3) { // WIN+M arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'm' press, 'm' release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'M' press, 'M' release, L-Winkey release
|
|
}
|
|
} else if (ks == 4) { // Shift+WIN+M arrow
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe1, 1], [0xffe7, 1], [0x6d, 1], [0x6d, 0], [0xffe7, 0], [0xffe1, 0]]); // Intel AMT: Shift-left down, Meta-left down, 'm' press, 'm' release, Meta-left release, Shift-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN, 16], [desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 77], [desktop.m.KeyAction.UP, 77], [desktop.m.KeyAction.EXUP, 0x5B], [desktop.m.KeyAction.UP, 16]]); // MeshAgent: L-shift press, L-Winkey press, 'M' press, 'M' release, L-Winkey release, L-shift release
|
|
}
|
|
} else if (ks == 5) { // WIN
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0xffe7, 0]]); // Intel AMT: Meta-left down, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, L-Winkey release
|
|
}
|
|
} else if (ks == 6) { // WIN+R
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe7, 1], [0x72, 1], [0x72, 0], [0xffe7, 0]]); // Intel AMT: Meta-left down, 'r' press, 'r' release, Meta-left release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 0x5B], [desktop.m.KeyAction.DOWN, 82], [desktop.m.KeyAction.UP, 82], [desktop.m.KeyAction.EXUP, 0x5B]]); // MeshAgent: L-Winkey press, 'R' press, 'R' release, L-Winkey release
|
|
}
|
|
} else if (ks == 7) { // ALT-F4
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe9, 1], [0xffc1, 1], [0xffc1, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'F4' press, 'F4' release, Alt release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 115], [desktop.m.KeyAction.UP, 115], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'F4' press, 'F4' release, Alt release
|
|
}
|
|
} else if (ks == 8) { // CTRL-W
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe3, 1], [0x77, 1], [0x77, 0], [0xffe3, 0]]); // Intel AMT: Ctrl down, 'w' press, 'w' release, Ctrl release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 17], [desktop.m.KeyAction.DOWN, 87], [desktop.m.KeyAction.UP, 87], [desktop.m.KeyAction.EXUP, 17]]); // MeshAgent: Ctrl press, 'W' press, 'W' release, Ctrl release
|
|
}
|
|
} else if (ks == 9) { // ALT-TAB
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xffe9, 1], [0xff09, 1], [0xff09, 0], [0xffe9, 0]]); // Intel AMT: Alt down, 'TAB' press, 'TAB' release, Alt release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.EXDOWN, 18], [desktop.m.KeyAction.DOWN, 9], [desktop.m.KeyAction.UP, 9], [desktop.m.KeyAction.EXUP, 18]]); // MeshAgent: Alt press, 'TAB' press, 'TAB' release, Alt release
|
|
}
|
|
} else if (ks == 10) { // CTRL-ALT-DEL
|
|
desktop.m.sendcad();
|
|
} else if (ks == 11) { // TAB
|
|
if (desktop.contype == 2) {
|
|
desktop.m.sendkey([[0xff09, 1], [0xff09, 0]]); // Intel AMT: 'TAB' press, 'TAB' release
|
|
} else {
|
|
desktop.m.SendKeyMsgKC([[desktop.m.KeyAction.DOWN, 9], [desktop.m.KeyAction.UP, 9]]); // MeshAgent: 'TAB' press, 'TAB' release
|
|
}
|
|
}
|
|
}
|
|
|
|
function sendSpecialKeys() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
setDialogMode(3, "Speciální klíče", 3, deskSendKeys);
|
|
}
|
|
|
|
// Send CTRL-ALT-DEL
|
|
/*
|
|
function sendCAD() {
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
desktop.m.sendcad();
|
|
}
|
|
*/
|
|
|
|
// Toggle soft keyboard
|
|
function toggleSoftKeys(x) {
|
|
QV('DeskSoftInput', x == 1);
|
|
if (x == 1) { Q('DeskSoftInput').focus(); }
|
|
}
|
|
|
|
// Show process dialogs
|
|
function toggleDeskTools() {
|
|
setSessionActivity();
|
|
if (xxdialogMode) return;
|
|
if (QS('DeskTools').display == 'none') {
|
|
QV('DeskTools', true);
|
|
Q('DeskTools').nodeid = currentNode._id;
|
|
refreshDeskTools();
|
|
} else {
|
|
QV('DeskTools', false);
|
|
}
|
|
}
|
|
|
|
// Refresh all of the desktop tool panels
|
|
function refreshDeskTools() {
|
|
setSessionActivity();
|
|
QV('DeskToolsRefreshButton', false);
|
|
setTimeout(refreshDeskToolsEx, 500);
|
|
meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
|
|
}
|
|
function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
|
|
var deskTools = { sort: 1, msg: null };
|
|
function sortProcess(sort) { deskTools.sort = sort; showDeskToolsProcesses(deskTools.msg); }
|
|
function sortProcessPid(a, b) { if (a.p > b.p) return 1; if (a.p < b.p) return (-1); return 0; }
|
|
function sortProcessName(a, b) { if (a.d > b.d) return 1; if (a.d < b.d) return (-1); return 0; }
|
|
function showDeskToolsProcesses(message) {
|
|
deskTools.msg = message;
|
|
if (message == null) { QH('DeskToolsProcesses', ''); return; }
|
|
if (Q('DeskTools').nodeid != message.nodeid) return;
|
|
var p = [], processes = null;
|
|
try { processes = JSON.parse(message.value); } catch (e) { }
|
|
console.log(processes);
|
|
if (processes != null) {
|
|
for (var pid in processes) { p.push({ p: parseInt(pid), c: processes[pid].cmd, d: processes[pid].cmd.toLowerCase(), u: processes[pid].user }); }
|
|
if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
|
|
var x = '';
|
|
for (var i in p) { if (p[i].p != 0) { x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + p[i].p + '</div><a style=float:right;padding-right:5px;cursor:pointer onclick=stopProcess(' + p[i].p + ',"' + p[i].c + '")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? p[i].u : '') + '</div><div>' + p[i].c + '</div></div>'; } }
|
|
QH('DeskToolsProcesses', x);
|
|
}
|
|
}
|
|
|
|
// Save the desktop image to file
|
|
function deskSaveImage() {
|
|
setSessionActivity();
|
|
if (xxdialogMode || desktop == null || desktop.State != 3) return;
|
|
var d = new Date(), n = 'Desktop-' + currentNode.name + '-' + d.getFullYear() + '-' + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + "-" + ("0" + d.getHours()).slice(-2) + '-' + ('0' + d.getMinutes()).slice(-2);
|
|
Q('Desk')['toBlob'](function (blob) { saveAs(blob, n + '.jpg'); });
|
|
}
|
|
|
|
function deskDisplayInfo(sender, info, selDisplay, selItem) {
|
|
var txt = Q('termdisplays').value;
|
|
if (info.length > 0) { var options = ''; for (var x in info) { options += '<option' + ((txt == info[x]) ? ' selected' : '') + '>' + info[x] + '</option>'; } QH('termdisplays', options); }
|
|
QV('termdisplays', info.length > 0);
|
|
}
|
|
|
|
function deskGetDisplayNumbers(e) { desktop.m.GetDisplayNumbers(); }
|
|
|
|
function deskSetDisplay(e) {
|
|
setSessionActivity();
|
|
var display = 0, txt = Q('termdisplays').value;
|
|
if (txt == "Všechny displeje") display = 65535; else display = parseInt(txt.substring(8));
|
|
desktop.m.SetDisplay(display);
|
|
}
|
|
|
|
function dmousedown(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) desktop.m.mousedown(e) }
|
|
function dmouseup(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) desktop.m.mouseup(e) }
|
|
function dmousemove(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null)) desktop.m.mousemove(e) }
|
|
function dmousewheel(e) { setSessionActivity(); if ((!xxdialogMode && desktop != null) && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
|
|
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
|
|
function stopProcess(id, name) { setDialogMode(2, "Správa procesů", 3, stopProcessEx, format("Ukončit proces #{0} \"{1}\"?", id, name), id); return false; }
|
|
function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type: 'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
|
|
|
|
//
|
|
// FILES
|
|
//
|
|
|
|
var filesNode;
|
|
function setupFiles() {
|
|
// Setup the files tab
|
|
var samenode = (filesNode == currentNode);
|
|
filesNode = currentNode;
|
|
var online = ((filesNode.conn & 1) != 0) ? true : false; // If Agent (1) connected, enable Terminal
|
|
QE('p13Connect', online);
|
|
if (((samenode == false) || (online == false)) && files) { files.Stop(); files = null; }
|
|
}
|
|
|
|
function onFilesStateChange(xfiles, state) {
|
|
setSessionActivity();
|
|
p13Connect.value = (state == 0) ? "Připojit" : "Odpojit";
|
|
var str = StatusStrs[state];
|
|
if (files.webRtcActive == true) { str += ", WebRTC"; }
|
|
Q('p13Status').textContent = str;
|
|
switch (state) {
|
|
case 0:
|
|
// Disconnected, clear the files
|
|
QH('p13files', '');
|
|
p13filetree = null;
|
|
p13filetreelocation = [];
|
|
QH('p13currentpath', '');
|
|
QE('p13FolderUp', false);
|
|
p13setActions();
|
|
if (files != null) { files.Stop(); files = null; }
|
|
break;
|
|
case 3:
|
|
p13targetpath = '';
|
|
files.sendText({ action: 'ls', reqid: 1, path: '' });
|
|
break;
|
|
default:
|
|
//console.log('Unknown onFilesStateChange state', state);
|
|
break;
|
|
}
|
|
}
|
|
|
|
function CreateRemoteFiles(onFileUpdate) {
|
|
var obj = { protocol: 5 };
|
|
obj.onFileUpdate = onFileUpdate;
|
|
obj.xxStateChange = function (state) { }
|
|
obj.ProcessData = function (data) { obj.onFileUpdate(data); }
|
|
return obj;
|
|
}
|
|
|
|
// Debug Only
|
|
var autoConnectFilesTimer = null;
|
|
function autoConnectFiles(e) { if (autoConnectFilesTimer == null) { autoConnectFilesTimer = setInterval(connectFiles, 100); } else { clearInterval(autoConnectFilesTimer); autoConnectFilesTimer = null; } }
|
|
|
|
function connectFiles(e) {
|
|
if (!files) {
|
|
// Setup a mesh agent files
|
|
files = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotFiles), serverPublicNamePort, authCookie, authRelayCookie, domainUrl);
|
|
files.attemptWebRTC = attemptWebRTC;
|
|
files.onStateChanged = onFilesStateChange;
|
|
files.Start(filesNode._id);
|
|
} else {
|
|
//QH('Term', '');
|
|
files.Stop();
|
|
files = null;
|
|
}
|
|
p13clipboard = p13clipboardFolder = null;
|
|
p13clipboardCut = 0;
|
|
p13updateClipview();
|
|
}
|
|
|
|
var p13filetree = null;
|
|
var p13targetpath = null;
|
|
var p13filetreelocation = [];
|
|
|
|
function p13gotFiles(data) {
|
|
setSessionActivity();
|
|
//console.log('p13gotFiles', data);
|
|
if ((data.length > 0) && (data.charCodeAt(0) != 123)) { p13gotDownloadBinaryData(data); return; }
|
|
//console.log('p13gotFiles', data);
|
|
data = JSON.parse(decode_utf8(data));
|
|
if (data.action == 'download') { p13gotDownloadCommand(data); return; }
|
|
data.path = data.path.replace(/\//g, "\\");
|
|
if ((p13filetree != null) && (data.path == p13filetree.path)) {
|
|
// This is an update to the same folder
|
|
var checkedNames = p13getCheckedNames();
|
|
p13filetree = data;
|
|
p13updateFiles(checkedNames);
|
|
} else {
|
|
// Make both paths use the same seperator not start with /
|
|
var x1 = data.path.replace(/\//g, "\\"), x2 = p13targetpath.replace(/\//g, "\\");
|
|
while ((x1.length > 0) && (x1[0] == '\\')) { x1 = x1.substring(1); }
|
|
while ((x2.length > 0) && (x2[0] == '\\')) { x2 = x2.substring(1); }
|
|
if ((x1 == x2) || ((data.path == '\\') && (p13targetpath == ''))) {
|
|
// This is a different folder
|
|
p13filetree = data;
|
|
p13updateFiles();
|
|
}
|
|
}
|
|
}
|
|
|
|
function p13getCheckedNames() {
|
|
// Save all existing checked boxes
|
|
var checkedNames = [], checkboxes = document.getElementsByName('fd');
|
|
for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { checkedNames.push(p13filetree.dir[checkboxes[i].value].n) }; }
|
|
return checkedNames;
|
|
}
|
|
|
|
function p13updateFiles(checkedNames) {
|
|
var html1 = '', html2 = '', displayPath = '<a style=cursor:pointer onclick=p13folderup(0)>' + "Root" + '</a>', fullPath = 'Root';
|
|
|
|
// Work on parsing the file path
|
|
var x = p13filetree.path.split('\\');
|
|
p13filetreelocation = [];
|
|
for (var i in x) { if (x[i] != '') { p13filetreelocation.push(x[i]); } } // Remove empty spaces
|
|
for (var i in p13filetreelocation) { displayPath += ' / <a style=cursor:pointer onclick=p13folderup(' + (parseInt(i) + 1) + ')>' + p13filetreelocation[i] + '</a>' } // Setup the path we display
|
|
var newlinkpath = p13filetreelocation.join('/');
|
|
|
|
// Sort the files
|
|
var filetreexx = p13sort_files(p13filetree.dir);
|
|
|
|
// Display all files and folders at this location
|
|
for (var i in filetreexx) {
|
|
// Figure out the name and shortname
|
|
var f = filetreexx[i], name = f.n, shortname;
|
|
shortname = name;
|
|
if (name.length > 70) { shortname = EscapeHtml(name.substring(0, 70)) + "..."; } else { shortname = EscapeHtml(name); }
|
|
name = EscapeHtml(name);
|
|
|
|
// Figure out the size
|
|
var fsize = '';
|
|
if (f.s != null) { fsize = getFileSizeStr(f.s); }
|
|
|
|
var h = '';
|
|
if (f.t < 3) {
|
|
var right = '';
|
|
h = '<div class=filelist file=999><input file=999 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'> <span style=float:right>' + right + '</span><span><div class=fileIcon' + f.t + '></div><a style=cursor:pointer onclick=p13folderset(\"' + encodeURIComponent(f.nx) + '\")>' + shortname + '</a></span></div>';
|
|
} else {
|
|
var link = shortname;
|
|
if (f.s > 0) { link = '<a rel=\"noreferrer noopener\" target=\"_blank\" style=cursor:pointer onclick=\"p13downloadfile(\'' + encodeURIComponent(newlinkpath + '/' + name) + '\',\'' + encodeURIComponent(name) + '\',' + f.s + ')\">' + shortname + '</a>'; }
|
|
h = '<div class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'> <span style=float:right;padding-right:4px>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
|
|
}
|
|
|
|
if (f.t < 3) { html1 += h; } else { html2 += h; }
|
|
}
|
|
|
|
// Display the files and path
|
|
QH('p13files', html1 + html2);
|
|
QH('p13currentpath', displayPath);
|
|
QE('p13FolderUp', p13filetreelocation.length != 0);
|
|
|
|
// Re-check all boxes if needed using names
|
|
if (checkedNames != null) { var checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkedNames.indexOf(p13filetree.dir[checkboxes[i].value].n) >= 0) { checkboxes[i].checked = true; } } }
|
|
|
|
// Update the actions buttons
|
|
p13setActions();
|
|
}
|
|
|
|
function p13folderset(x) {
|
|
p13targetpath = joinPaths(p13filetree.path, p13filetree.dir[x].n).split('\\').join('/');
|
|
files.sendText({ action: 'ls', reqid: 1, path: p13targetpath });
|
|
}
|
|
|
|
function p13folderup(x) {
|
|
if (x == null) { p13filetreelocation.pop(); } else { while (p13filetreelocation.length > x) { p13filetreelocation.pop(); } }
|
|
p13targetpath = p13filetreelocation.join('/');
|
|
files.sendText({ action: 'ls', reqid: 1, path: p13targetpath });
|
|
}
|
|
|
|
var p13sortorder;
|
|
function p13sort_filename(a, b) { if (a.ln > b.ln) return (1 * p13sortorder); if (a.ln < b.ln) return (-1 * p13sortorder); return 0; }
|
|
function p13sort_timestamp(a, b) { if (a.d > b.d) return (1 * p13sortorder); if (a.d < b.d) return (-1 * p13sortorder); return 0; }
|
|
function p13sort_bysize(a, b) { if (a.s == b.s) return p13sort_filename(a, b); return (((a.s - b.s)) * p13sortorder); }
|
|
|
|
function p13sort_files(files) {
|
|
var r = [], sortselection = Q('p13sortdropdown').value;
|
|
for (var i in files) { files[i].nx = i; if (files[i].s == null) { files[i].s = 0; } if (files[i].n == null) { files[i].n = i; } files[i].ln = files[i].n.toLowerCase(); r.push(files[i]); }
|
|
p13sortorder = 1;
|
|
if (sortselection > 3) { p13sortorder = -1; sortselection -= 3; }
|
|
if (sortselection == 1) { r.sort(p13sort_filename); }
|
|
else if (sortselection == 2) { r.sort(p13sort_bysize); }
|
|
else if (sortselection == 3) { r.sort(p13sort_timestamp); }
|
|
return r;
|
|
}
|
|
|
|
function p13setActions() {
|
|
if (p13filetree == null) {
|
|
QE('p13DeleteFileButton', false);
|
|
QE('p13NewFolderButton', false);
|
|
QE('p13UploadButton', false);
|
|
QE('p13RenameFileButton', false);
|
|
QE('p13SelectAllButton', false);
|
|
Q('p13SelectAllButton').value = "Vše";
|
|
QE('p13RefreshButton', false);
|
|
QE('p13CutButton', false);
|
|
QE('p13CopyButton', false);
|
|
QE('p13PasteButton', false);
|
|
} else {
|
|
var cc = p13getFileSelCount(), tc = p13getFileCount(), sfc = p13getFileSelCount(false); // In order: number of entires selected, number of total entries, number of selected entires that are files (not folders)
|
|
var winAgent = ((currentNode.agent.id > 0) && (currentNode.agent.id < 5));
|
|
QE('p13DeleteFileButton', (cc > 0) && ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13NewFolderButton', ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13UploadButton', ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13RenameFileButton', (cc == 1) && ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13SelectAllButton', tc > 0);
|
|
Q('p13SelectAllButton').value = (cc > 0 ? "Nic" : "Vše");
|
|
QE('p13RefreshButton', true);
|
|
QE('p13CutButton', (cc > 0) && (cc == sfc) && ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13CopyButton', (cc > 0) && (cc == sfc) && ((p13filetreelocation.length > 0) || (winAgent == false)));
|
|
QE('p13PasteButton', ((p13filetreelocation.length > 0) || (winAgent == false)) && ((p13clipboard != null) && (p13clipboard.length > 0)));
|
|
}
|
|
}
|
|
|
|
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; }
|
|
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; }
|
|
function p13getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fd'); return checkboxes.length; }
|
|
function p13selectallfile() { var nv = (p13getFileSelCount() == 0), checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p13setActions(); }
|
|
function p13createfolder() { setDialogMode(2, "Nový adresář", 3, p13createfolderEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />'); focusTextBox('p13renameinput'); p13fileNameCheck(); }
|
|
function p13createfolderEx() { files.sendText({ action: 'mkdir', reqid: 1, path: p13filetreelocation.join('/') + '/' + Q('p13renameinput').value }); p13folderup(999); }
|
|
function p13deletefile() { var cc = p13getFileSelCount(), rec = (p13getFileSelDirCount() > 0) ? '<br /><br /><label><input type=checkbox id=p13recdeleteinput>' + "Rekurzivní mazání" + '</label><br>' : '<input type=checkbox id=p13recdeleteinput style=\'display:none\'>'; setDialogMode(2, "Smazat", 3, p13deletefileEx, (cc > 1) ? (format("Smazat {0} vybrané prvky?", cc) + rec) : ("Smazat vybraný prvek?" + rec)); }
|
|
function p13deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(p13filetree.dir[checkboxes[i].value].n); } } files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: delfiles, rec: Q('p13recdeleteinput').checked }); p13folderup(999); }
|
|
function p13renamefile() { var renamefile, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = p13filetree.dir[checkboxes[i].value].n; } } setDialogMode(2, "Přejmenovat", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: renamefile }); focusTextBox('p13renameinput'); p13fileNameCheck(); }
|
|
function p13renamefileEx(b, t) { t.newname = Q('p13renameinput').value; files.sendText(t); p13folderup(999); }
|
|
function p13fileNameCheck(e) { var x = isFilenameValid(Q('p13renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e != null) && (e.keyCode == 13)) { dialogclose(1); } }
|
|
function p13uploadFile() { setDialogMode(2, "Nahrát soubor", 3, p13uploadFileEx, '<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p13uploadinput\')" />'); updateUploadDialogOk('p13uploadinput'); }
|
|
function p13uploadFileEx() { p13doUploadFiles(Q('p13uploadinput').files); }
|
|
function p13viewfile() {
|
|
var checkboxes = document.getElementsByName('fd');
|
|
for (var i = 0; i < checkboxes.length; i++) {
|
|
if (checkboxes[i].checked) {
|
|
if (p13filetree.dir[checkboxes[i].value].s <= 204800) {
|
|
p13downloadfile(encodeURIComponent(p13filetreelocation.join('/') + '/' + p13filetree.dir[checkboxes[i].value].n), encodeURIComponent(p13filetree.dir[checkboxes[i].value].n), p13filetree.dir[checkboxes[i].value].s, 'viewer');
|
|
} else { messagebox("Editor souborů", "Jen soubory menší než 200k mohou být editovány."); }
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
var p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0;
|
|
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(); }
|
|
function p13pasteFile() {
|
|
var x = '';
|
|
if ((p13clipboard != null) && (p13clipboard.length > 0)) {
|
|
if (p13clipboardCut == 0) {
|
|
if (p13clipboard.length > 1) { x = format("Potvrdit kopírování {0} zaznámů do tohoto umístění?", p13clipboard.length); } else { x = format("Potvrdit kopírování jednoho záznamu do tohoto umístění?"); }
|
|
} else {
|
|
if (p13clipboard.length > 1) { x = format("Potvrdit přesun {0} záznamů do tohoto umístění?", p13clipboard.length); } else { x = format("Potvrdit přesun jednoho záznamu do tohoto umístění?"); }
|
|
}
|
|
}
|
|
setDialogMode(2, "Vložit", 3, p13pasteFileEx, x);
|
|
}
|
|
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(); } }
|
|
function p13updateClipview() {
|
|
var x = '';
|
|
if ((p13clipboard != null) && (p13clipboard.length > 0)) {
|
|
if (p13clipboardCut == 0) {
|
|
if (p13clipboard.length > 1) {
|
|
x = format("Držím {0} záznamů pro kopii" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Vymazat" + '</a>.', p13clipboard.length);
|
|
} else {
|
|
x = format("Držím jeden záznam pro kopii" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Vymazat" + '</a>.');
|
|
}
|
|
} else {
|
|
if (p13clipboard.length > 1) {
|
|
x = format("Držím {0} zaznamů pro přesun" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Vymazat" + '</a>.', p13clipboard.length);
|
|
} else {
|
|
x = format("Držím jeden záznam pro přesun" + ', <a href=# onclick="return p13clearClip()" style=cursor:pointer>' + "Vymazat" + '</a>.');
|
|
}
|
|
}
|
|
}
|
|
QH('p13bottomstatus', x);
|
|
p13setActions();
|
|
}
|
|
function p13clearClip() { p13clipboard = null; p13clipboardFolder = null; p13clipboardCut = 0; p13updateClipview(); return false; } function updateUploadDialogOk(x) { QE('idx_dlgOkButton', Q(x).value != ''); }
|
|
function getFileSelCount(includeDirs) { var cc = 0; var 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; }
|
|
function getFileCount() { var cc = 0; var checkboxes = document.getElementsByName('fc'); return checkboxes.length; }
|
|
|
|
//
|
|
// FILES DOWNLOAD
|
|
//
|
|
|
|
var downloadFile; // Global state for file download
|
|
|
|
// Called by the html page to start a download, arguments are: path, file name and file size.
|
|
function p13downloadfile(x, y, z) {
|
|
if (xxdialogMode || downloadFile || !files) return;
|
|
downloadFile = { path: decodeURIComponent(x), file: decodeURIComponent(y), size: z, tsize: 0, data: '', state: 0, id: Math.random() }
|
|
//console.log('p13downloadFileCancel', downloadFile);
|
|
files.sendText({ action: 'download', sub: 'start', id: downloadFile.id, path: downloadFile.path });
|
|
setDialogMode(2, "Stáhnout soubor", 10, p13downloadFileCancel, '<div>' + downloadFile.file + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
|
|
}
|
|
|
|
// Called by the html page to cancel the download
|
|
function p13downloadFileCancel() { setDialogMode(0); files.sendText({ action: 'download', sub: 'cancel', id: downloadFile.id }); downloadFile = null; }
|
|
|
|
// Called by the transport when download control command is received
|
|
function p13gotDownloadCommand(cmd) {
|
|
//console.log('p13gotDownloadCommand', cmd);
|
|
if ((downloadFile == null) || (cmd.id != downloadFile.id)) return;
|
|
if (cmd.sub == 'start') { downloadFile.state = 1; files.sendText({ action: 'download', sub: 'startack', id: downloadFile.id }); }
|
|
else if (cmd.sub == 'cancel') { downloadFile = null; setDialogMode(0); }
|
|
}
|
|
|
|
// Called by the transport when binary data is received
|
|
function p13gotDownloadBinaryData(data) {
|
|
if (!downloadFile || downloadFile.state == 0) return;
|
|
if (data.length > 4) {
|
|
downloadFile.tsize += (data.length - 4); // Add to the total bytes received
|
|
downloadFile.data += data.substring(4); // Append the data
|
|
Q('d2progressBar').value = downloadFile.tsize; // Change the progress bar
|
|
}
|
|
if ((ReadInt(data, 0) & 1) != 0) { // Check end flag
|
|
saveAs(data2blob(downloadFile.data), downloadFile.file); downloadFile = null; setDialogMode(0); // Save the file
|
|
} else {
|
|
files.sendText({ action: 'download', sub: 'ack', id: downloadFile.id }); // Send the ACK
|
|
}
|
|
}
|
|
|
|
/*
|
|
var downloadFile; // Global state for file download
|
|
|
|
// Called by the html page to start a download, arguments are: path, file name and file size.
|
|
function p13downloadfile(x, y, z) {
|
|
if (xxdialogMode) return;
|
|
downloadFile = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotDownloadData), serverPublicNamePort, authCookie, authRelayCookie, domainUrl); // Create our websocket file transport
|
|
downloadFile.ctrlMsgAllowed = false;
|
|
downloadFile.onStateChanged = onFileDownloadStateChange;
|
|
downloadFile.xpath = decodeURIComponent(x);
|
|
downloadFile.xfile = decodeURIComponent(y);
|
|
downloadFile.xsize = z;
|
|
downloadFile.xtsize = 0;
|
|
downloadFile.xstate = 0;
|
|
downloadFile.Start(filesNode._id);
|
|
setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + downloadFile.xfile + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
|
|
}
|
|
|
|
// Called by the html page to cancel the download
|
|
function p13downloadFileCancel(button, tag) {
|
|
//console.log('p13downloadFileCancel');
|
|
downloadFile.Stop();
|
|
delete downloadFile;
|
|
downloadFile = null;
|
|
}
|
|
|
|
// Called by the file transport to indicate when the transport connection state has changed
|
|
function onFileDownloadStateChange(xdownloadFile, state) {
|
|
switch (state) {
|
|
case 0: // Transport as disconnected. If this is not part of an abort, we need to save the file
|
|
setDialogMode(0); // Close any dialog boxes if present
|
|
if ((downloadFile != null) && (downloadFile.xstate == 1)) { saveAs(data2blob(downloadFile.xdata), downloadFile.xfile); } // Save the file
|
|
break;
|
|
case 3: // Transport as connected, send a command to indicate we want to start a file download
|
|
downloadFile.send(JSON.stringify({ action: 'download', reqid: 1, path: downloadFile.xpath }));
|
|
break;
|
|
default:
|
|
console.log('Unknown onFileDownloadStateChange state', state);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Called by the transport when data is received
|
|
function p13gotDownloadData(data) {
|
|
if (downloadFile.xstate == 0) { // If state is 0, this is a command confirming if the file will be transfered.
|
|
var cmd = JSON.parse(data);
|
|
if (cmd.action == 'downloadstart') { // Yes, the file is about to start
|
|
downloadFile.xstate = 1; // Switch to state 1, we will start receiving the file data
|
|
downloadFile.xdata = ''; // Start with empty data
|
|
downloadFile.send('a'); // Send the first ACK
|
|
} else if (cmd.action == 'downloaderror') { // Problem opening this file, cancel
|
|
p13downloadFileCancel();
|
|
}
|
|
} else { // We are in the process of receiving the file
|
|
downloadFile.xtsize += (data.length); // Add to the total bytes received
|
|
downloadFile.xdata += data; // Append the data
|
|
Q('d2progressBar').value = downloadFile.xtsize; // Change the progress bar
|
|
downloadFile.send('a'); // Send the ACK
|
|
}
|
|
}
|
|
*/
|
|
|
|
//
|
|
// FILES UPLOAD
|
|
//
|
|
|
|
var uploadFile;
|
|
function p13doUploadFiles(files) {
|
|
if (xxdialogMode) return;
|
|
uploadFile = {};
|
|
uploadFile.xpath = p13filetreelocation.join('/');
|
|
uploadFile.xfiles = files;
|
|
uploadFile.xfilePtr = -1;
|
|
setDialogMode(2, "Nahrát soubor", 10, p13uploadFileCancel, '<div id=p13dfileName>' + "Připojování..." + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=0 />');
|
|
p13uploadReconnect();
|
|
}
|
|
|
|
function onFileUploadStateChange(xdownloadFile, state) {
|
|
switch (state) {
|
|
case 0:
|
|
p13folderup(9999);
|
|
break;
|
|
case 3:
|
|
p13uploadNextFile();
|
|
break;
|
|
default:
|
|
console.log('Unknown onFileUploadStateChange state', state);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Connect again
|
|
function p13uploadReconnect() {
|
|
uploadFile.ws = CreateAgentRedirect(meshserver, CreateRemoteFiles(p13gotUploadData), serverPublicNamePort, authCookie, authRelayCookie, domainUrl);
|
|
uploadFile.ws.attemptWebRTC = false;
|
|
uploadFile.ws.ctrlMsgAllowed = false;
|
|
uploadFile.ws.onStateChanged = onFileUploadStateChange;
|
|
uploadFile.ws.Start(filesNode._id);
|
|
}
|
|
|
|
// Push the next file
|
|
function p13uploadNextFile() {
|
|
uploadFile.xfilePtr++;
|
|
if (uploadFile.xfiles.length > uploadFile.xfilePtr) {
|
|
uploadFile.xptr = 0;
|
|
var file = uploadFile.xfiles[uploadFile.xfilePtr];
|
|
QH('p13dfileName', file.name);
|
|
Q('d2progressBar').max = file.size;
|
|
Q('d2progressBar').value = 0;
|
|
|
|
uploadFile.xreader = new FileReader();
|
|
uploadFile.xreader.onload = function () {
|
|
uploadFile.xdata = uploadFile.xreader.result;
|
|
uploadFile.ws.sendText({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength });
|
|
};
|
|
uploadFile.xreader.readAsArrayBuffer(file);
|
|
} else {
|
|
p13uploadFileCancel();
|
|
}
|
|
}
|
|
|
|
// Used to cancel the entire transfer.
|
|
function p13uploadFileCancel(button, tag) {
|
|
if (uploadFile != null) {
|
|
if (uploadFile.ws != null) {
|
|
uploadFile.ws.Stop();
|
|
uploadFile.ws = null;
|
|
}
|
|
uploadFile = null;
|
|
}
|
|
setDialogMode(0); // Close any dialog boxes if present
|
|
}
|
|
|
|
// Receive upload ack from the mesh agent, use this to keep sending more data
|
|
function p13gotUploadData(data) {
|
|
var cmd = JSON.parse(data);
|
|
if ((uploadFile == null) || (parseInt(uploadFile.xfilePtr) != parseInt(cmd.reqid))) { return; }
|
|
|
|
if (cmd.action == 'uploadstart') {
|
|
p13uploadNextPart(false);
|
|
for (var i = 0; i < 8; i++) { p13uploadNextPart(true); } // Send 8 more blocks of 4 k to full the websocket.
|
|
} else if (cmd.action == 'uploadack') {
|
|
p13uploadNextPart(false);
|
|
} else if (cmd.action == 'uploaderror') {
|
|
p13uploadFileCancel();
|
|
}
|
|
}
|
|
|
|
// Push the next part of the file into the websocket. If dataPriming is true, push more data only if it's not the last block of the file.
|
|
function p13uploadNextPart(dataPriming) {
|
|
var data = uploadFile.xdata;
|
|
var start = uploadFile.xptr;
|
|
var end = uploadFile.xptr + 4096;
|
|
if (end > data.byteLength) { if (dataPriming == true) { return; } end = data.byteLength; }
|
|
if (start == data.byteLength) {
|
|
if (uploadFile.ws != null) { uploadFile.ws.Stop(); uploadFile.ws = null; }
|
|
if (uploadFile.xfiles.length > uploadFile.xfilePtr + 1) { p13uploadReconnect(); } else { p13uploadFileCancel(); }
|
|
} else {
|
|
var datapart = data.slice(start, end);
|
|
uploadFile.ws.send(datapart);
|
|
uploadFile.xptr = end;
|
|
Q('d2progressBar').value = end;
|
|
}
|
|
}
|
|
|
|
//
|
|
// MY MESHS
|
|
//
|
|
|
|
var currentMesh;
|
|
function p20updateMesh() {
|
|
if (currentMesh == null) return;
|
|
QH('p20meshName', EscapeHtml(currentMesh.name));
|
|
var meshtype = format("Neznámý #{0}", currentMesh.mtype);
|
|
var meshrights = currentMesh.links[userinfo._id].rights;
|
|
if (currentMesh.mtype == 1) meshtype = "Intel® AMT pouze, bez agenta";
|
|
if (currentMesh.mtype == 2) meshtype = "Spravovat pomocí softwarového aenta";
|
|
|
|
var x = '';
|
|
x += addHtmlValue("Jméno", addLinkConditional(EscapeHtml(currentMesh.name), 'p20editmesh(1)', (meshrights & 1) != 0));
|
|
x += addHtmlValue("Popis", addLinkConditional(((currentMesh.desc && currentMesh.desc != '') ? EscapeHtml(currentMesh.desc) : ('<i>' + "Nic" + '</i>')), 'p20editmesh(2)', (meshrights & 1) != 0));
|
|
x += addHtmlValue("Typ", meshtype);
|
|
//x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]);
|
|
|
|
//x += '<br><input type=button value=Notes onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />';
|
|
|
|
x += '<br style=clear:both><br>';
|
|
var currentMeshLinks = currentMesh.links[userinfo._id];
|
|
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<div style=margin-bottom:6px><a onclick=p20showAddMeshUserDialog() style=cursor:pointer><img src=images/icon-addnew.png border=0 height=12 width=12>' + " Přidat uživatele" + '</a></div>'; }
|
|
|
|
/*
|
|
if ((meshrights & 4) != 0) {
|
|
if (currentMesh.mtype == 1) {
|
|
x += '<a onclick=addCiraDeviceToMesh(\"' + currentMesh._id + '\") style=cursor:pointer;margin-right:10px><img src=images/icon-installmesh.png border=0 height=12 width=12> Install CIRA</a>';
|
|
x += '<a onclick=addDeviceToMesh(\"' + currentMesh._id + '\") style=cursor:pointer;margin-right:10px><img src=images/icon-installmesh.png border=0 height=12 width=12> Install local</a>';
|
|
}
|
|
if (currentMesh.mtype == 2) {
|
|
x += '<a onclick=addAgentToMesh(\"' + currentMesh._id + '\") style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> Install</a>';
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
function getMeshActions(mesh, meshrights) {
|
|
if ((meshrights & 4) == 0) return '';
|
|
var r = '';
|
|
if (mesh.mtype == 1) {
|
|
r += ' <a style=cursor:pointer;font-size:10px onclick=addCiraDeviceToMesh(\"' + mesh._id + '\")>Add CIRA</a>';
|
|
r += ' <a style=cursor:pointer;font-size:10px onclick=addDeviceToMesh(\"' + mesh._id + '\")>Add Local</a>';
|
|
}
|
|
if (mesh.mtype == 2) {
|
|
r += ' <a style=cursor:pointer;font-size:10px onclick=addAgentToMesh(\"' + mesh._id + '\")>Add Agent</a>';
|
|
}
|
|
return r;
|
|
}
|
|
*/
|
|
|
|
x += '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>' + "Uživatelská oprávnění" + '</th></tr>';
|
|
|
|
// Sort the users for this mesh
|
|
var count = 1, sortedusers = [];
|
|
for (var i in currentMesh.links) { sortedusers.push({ id: i, name: i.split('/')[2], rights: currentMesh.links[i].rights }); }
|
|
sortedusers.sort(function (a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; });
|
|
|
|
// Display all users for this mesh
|
|
for (var i in sortedusers) {
|
|
var trash = '', rights = "Částečné práva", r = sortedusers[i].rights;
|
|
if (r == 0xFFFFFFFF) rights = "Hlavní administrátor"; else if (r == 0) rights = "Žádná práva";
|
|
if ((i != userinfo._id) && (meshrights == 0xFFFFFFFF || (((meshrights & 2) != 0)))) { trash = '<a onclick=p20deleteUser(event,"' + encodeURIComponent(sortedusers[i].id) + '") style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
|
|
x += '<tr onclick=p20viewuser("' + encodeURIComponent(sortedusers[i].id) + '") style=height:32px;cursor:pointer' + (((count % 2) == 0) ? ';background-color:#DDD' : '') + '><td>';
|
|
x += '<div style=float:right>' + trash + '</div><div style=float:right;padding-right:4px>' + rights + '</div><div class=m2></div><div> ' + EscapeHtml(decodeURIComponent(sortedusers[i].name)) + '<div></div></div>';
|
|
x += '</td></tr>';
|
|
++count;
|
|
}
|
|
|
|
x += '</tbody></table>';
|
|
|
|
// If we are full administrator on this mesh, allow deletion of the mesh
|
|
if (meshrights == 0xFFFFFFFF) { x += '<div style=font-size:small;text-align:right;margin-top:6px><span><a onclick=p20showDeleteMeshDialog() style=cursor:pointer>' + "Smazat skupinu" + '</a></span></div>'; }
|
|
|
|
QH('p20info', x);
|
|
}
|
|
|
|
function p20showDeleteMeshDialog() {
|
|
if (xxdialogMode) return false;
|
|
var x = format("Opravdu smazat skupinu {0}? Smazáním skupiny se smažou všechny informace o zařízeních v této skupině.", EscapeHtml(currentMesh.name)) + '<br /><br />';
|
|
x += '<label><input id=p20check type=checkbox onchange=p20validateDeleteMeshDialog() />' + "Potvrdit" + '</label>';
|
|
setDialogMode(2, "Smazat skupinu", 3, p20showDeleteMeshDialogEx, x);
|
|
p20validateDeleteMeshDialog();
|
|
return false;
|
|
}
|
|
|
|
function p20validateDeleteMeshDialog() {
|
|
QE('idx_dlgOkButton', Q('p20check').checked);
|
|
}
|
|
|
|
function p20showDeleteMeshDialogEx(buttons, tag) {
|
|
meshserver.send({ action: 'deletemesh', meshid: currentMesh._id, meshname: currentMesh.name });
|
|
}
|
|
|
|
function p20editmesh(focus) {
|
|
if (xxdialogMode) return;
|
|
var x = addHtmlValue("Jméno", '<input id=dp20meshname style=width:170px maxlength=32 onchange=p20editmeshValidate() onkeyup=p20editmeshValidate() />');
|
|
x += addHtmlValue("Popis", '<input id=dp20meshdesc style=width:170px maxlength=1024 onkeyup=p20editmeshValidate() />');
|
|
setDialogMode(2, "Upravit skupinu zařízení", 3, p20editmeshEx, x);
|
|
Q('dp20meshname').value = currentMesh.name;
|
|
if (currentMesh.desc) Q('dp20meshdesc').value = currentMesh.desc;
|
|
p20editmeshValidate();
|
|
if (focus == 2) { Q('dp20meshdesc').focus(); } else { Q('dp20meshname').focus(); }
|
|
}
|
|
|
|
function p20editmeshEx() {
|
|
meshserver.send({ action: 'editmesh', meshid: currentMesh._id, meshname: Q('dp20meshname').value, desc: Q('dp20meshdesc').value });
|
|
}
|
|
|
|
function p20editmeshValidate() {
|
|
QE('idx_dlgOkButton', Q('dp20meshname').value.length > 0);
|
|
}
|
|
|
|
function p20showAddMeshUserDialog() {
|
|
if (xxdialogMode) return;
|
|
var x = addHtmlValue('User', '<input id=dp20username style=width:170px maxlength=32 onchange=p20validateAddMeshUserDialog() onkeyup=p20validateAddMeshUserDialog() />');
|
|
x += '<div style="border:2px groove gray;background-color:white;max-height:120px;overflow-y:scroll">';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20fulladmin>' + "Hlavní administrátor" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editmesh>' + "Upravit skupinu zařízení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20manageusers>' + "Spravovat uživatele pro skupinu zařízení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>' + "Správa skupin zařízení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>' + "Vzdálené ovládání" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>' + "Pouze vzdálené prohlížení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>' + "Pouze omezené vstupy" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noterminal style=margin-left:12px>' + "Žádný přístup k terminálu" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20nofiles style=margin-left:12px>' + "Žádný přístup k souborům" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noamt style=margin-left:12px>' + "Žádné Intel® AMT" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshagentconsole>' + "Konzole agenta" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>' + "Soubory serveru" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>' + "Probudit zařízení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>' + "Upravit popis zařízení" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20limitevents>' + "Zobrazit pouze vlastní události" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20chatnotify>' + "Chat & Upozornění" + '</label><br>';
|
|
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20uninstall>' + "Odinstalovat agenta" + '</label><br>';
|
|
x += '</div>';
|
|
setDialogMode(2, "Přidat uživatele do skupiny", 3, p20showAddMeshUserDialogEx, x);
|
|
p20validateAddMeshUserDialog();
|
|
Q('dp20username').focus();
|
|
}
|
|
|
|
function p20validateAddMeshUserDialog() {
|
|
var meshrights = currentMesh.links[userinfo._id].rights;
|
|
var nc = !Q('p20fulladmin').checked;
|
|
QE('p20fulladmin', meshrights == 0xFFFFFFFF);
|
|
QE('p20editmesh', nc && (meshrights == 0xFFFFFFFF));
|
|
QE('p20manageusers', nc);
|
|
QE('p20managecomputers', nc);
|
|
QE('p20remotecontrol', nc);
|
|
QE('p20meshagentconsole', nc);
|
|
QE('p20meshserverfiles', nc);
|
|
QE('p20wakedevices', nc);
|
|
QE('p20editnotes', nc);
|
|
QE('p20limitevents', nc);
|
|
QE('p20remoteview', nc && Q('p20remotecontrol').checked);
|
|
QE('p20remotelimitedinput', nc && Q('p20remotecontrol').checked && !Q('p20remoteview').checked);
|
|
QE('p20noterminal', nc && Q('p20remotecontrol').checked);
|
|
QE('p20nofiles', nc && Q('p20remotecontrol').checked);
|
|
QE('p20noamt', nc && Q('p20remotecontrol').checked);
|
|
QE('p20chatnotify', nc);
|
|
QE('p20uninstall', nc);
|
|
}
|
|
|
|
function p20showAddMeshUserDialogEx() {
|
|
var meshadmin = 0;
|
|
if (Q('p20fulladmin').checked == true) { meshadmin = 0xFFFFFFFF; } else {
|
|
if (Q('p20editmesh').checked == true) meshadmin += 1;
|
|
if (Q('p20manageusers').checked == true) meshadmin += 2;
|
|
if (Q('p20managecomputers').checked == true) meshadmin += 4;
|
|
if (Q('p20remotecontrol').checked == true) meshadmin += 8;
|
|
if (Q('p20meshagentconsole').checked == true) meshadmin += 16;
|
|
if (Q('p20meshserverfiles').checked == true) meshadmin += 32;
|
|
if (Q('p20wakedevices').checked == true) meshadmin += 64;
|
|
if (Q('p20editnotes').checked == true) meshadmin += 128;
|
|
if (Q('p20remoteview').checked == true) meshadmin += 256;
|
|
if (Q('p20noterminal').checked == true) meshadmin += 512;
|
|
if (Q('p20nofiles').checked == true) meshadmin += 1024;
|
|
if (Q('p20noamt').checked == true) meshadmin += 2048;
|
|
if (Q('p20remotelimitedinput').checked == true) meshadmin += 4096;
|
|
if (Q('p20limitevents').checked == true) meshadmin += 8192;
|
|
if (Q('p20chatnotify').checked == true) meshadmin += 16384;
|
|
if (Q('p20uninstall').checked == true) meshadmin += 32768;
|
|
}
|
|
var users = Q('dp20username').value.split(','), users2 = [];
|
|
for (var i in users) { users2.push(users[i].trim()); }
|
|
meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, usernames: users2, meshadmin: meshadmin });
|
|
}
|
|
|
|
function p20viewuser(userid) {
|
|
if (xxdialogMode) return;
|
|
userid = decodeURIComponent(userid);
|
|
var r = [], cmeshrights = currentMesh.links[userinfo._id].rights, meshrights = currentMesh.links[userid].rights;
|
|
if (meshrights == 0xFFFFFFFF) r.push("Hlavní administrátor"); else {
|
|
if ((meshrights & 1) != 0) r.push("Upravit skupinu zařízení");
|
|
if ((meshrights & 2) != 0) r.push("Spravovat uživatele pro skupinu zařízení");
|
|
if ((meshrights & 4) != 0) r.push("Správa skupin zařízení");
|
|
if ((meshrights & 8) != 0) r.push("Vzdálené ovládání");
|
|
if ((meshrights & 16) != 0) r.push("Konzole agenta");
|
|
if ((meshrights & 32) != 0) r.push("Soubory serveru");
|
|
if ((meshrights & 64) != 0) r.push("Probudit zařízení");
|
|
if ((meshrights & 128) != 0) r.push("Upravit poznámky");
|
|
if ((meshrights & 256) != 0) r.push("Pouze vzdálené prohlížení");
|
|
if ((meshrights & 512) != 0) r.push("Žádný terminál");
|
|
if ((meshrights & 1024) != 0) r.push("Žádné soubory");
|
|
if ((meshrights & 2048) != 0) r.push("Žádné Intel® AMT");
|
|
if (((meshrights & 8) != 0) && ((meshrights & 4096) != 0) && ((meshrights & 256) == 0)) r.push("Omezené vstupy");
|
|
if ((meshrights & 8192) != 0) r.push("Pouze vlastní události");
|
|
if ((meshrights & 16384) != 0) r.push("Chat & Upozornění");
|
|
if ((meshrights & 32768) != 0) r.push("Odinstalace");
|
|
}
|
|
if (r.length == 0) { r.push("Žádná práva"); }
|
|
var buttons = 1, x = addHtmlValue("Uživatel", EscapeHtml(decodeURIComponent(userid.split('/')[2])));
|
|
x += addHtmlValue("Práva", r.join(", "));
|
|
if (((userinfo._id) != userid) && (cmeshrights == 0xFFFFFFFF || (((cmeshrights & 2) != 0) && (meshrights != 0xFFFFFFFF)))) buttons += 4;
|
|
setDialogMode(2, "Uživatelé této skupiny zařízení", buttons, p20viewuserEx, x, userid);
|
|
}
|
|
|
|
function p20viewuserEx(button, userid) { if (button != 2) return; setDialogMode(2, "Vzdálený uživatel", 3, p20viewuserEx2, format("Potvrdit odstranění uživatele {0}?", userid.split('/')[2]), userid); }
|
|
function p20deleteUser(e, userid) { haltEvent(e); p20viewuserEx(2, decodeURIComponent(userid)); }
|
|
function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid }); }
|
|
|
|
//
|
|
// PANELS
|
|
//
|
|
|
|
var xxcurrentView = -1;
|
|
function go(x) {
|
|
setSessionActivity();
|
|
if (xxdialogMode || xxcurrentView == x) return;
|
|
updateFooterMenu();
|
|
setDialogMode(0);
|
|
// Edit this line when adding a new screen
|
|
for (var i = 0; i < 32; i++) { QV('p' + i, i == x); }
|
|
xxcurrentView = x;
|
|
}
|
|
|
|
//
|
|
// POPUP DIALOG
|
|
//
|
|
|
|
// undefined = Hidden, 1 = Generic Message
|
|
var xxdialogMode;
|
|
var xxdialogFunc;
|
|
var xxdialogButtons;
|
|
var xxdialogTag;
|
|
|
|
// Display a dialog box
|
|
// Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
|
|
function setDialogMode(x, y, b, f, c, tag) {
|
|
setSessionActivity();
|
|
xxdialogMode = x;
|
|
xxdialogFunc = f;
|
|
xxdialogButtons = b;
|
|
xxdialogTag = tag;
|
|
QE('idx_dlgOkButton', true);
|
|
QV('idx_dlgOkButton', b & 1);
|
|
QV('idx_dlgCancelButton', b & 2);
|
|
QV('id_dialogclose', (b & 2) || (b & 8));
|
|
QV('idx_dlgButtonBar', b & 7);
|
|
if (y) QH('id_dialogtitle', y);
|
|
for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
|
|
QV('dialog', x);
|
|
if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
|
|
}
|
|
|
|
function dialogclose(x) {
|
|
setSessionActivity();
|
|
var f = xxdialogFunc;
|
|
var b = xxdialogButtons;
|
|
var t = xxdialogTag;
|
|
setDialogMode();
|
|
if (((b & 8) || x) && f) f(x, t);
|
|
}
|
|
|
|
function putstore(name, val) { try { if ((typeof (localStorage) === 'undefined') || (localStorage.getItem(name) == val)) return; if (val == null) { localStorage.removeItem(name); } else { localStorage.setItem(name, val); } } catch (e) { } if (name[0] != '_') { var s = {}; for (var i = 0, len = localStorage.length; i < len; ++i) { var k = localStorage.key(i); if (k[0] != '_') { s[k] = localStorage.getItem(k); } } meshserver.send({ action: 'userWebState', state: JSON.stringify(s) }); } }
|
|
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
|
|
function center() { QS('dialog').left = ((((getDocWidth() - 300) / 2)) + 'px'); deskAdjust(); deskAdjust(); /*drawDeviceTimeline();*/ }
|
|
function messagebox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
|
function statusbox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t); }
|
|
function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
|
|
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
|
function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
|
|
function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); }
|
|
function reload() { window.location.href = window.location.href; }
|
|
function getNodeFromId(id) { for (var i in nodes) { if (nodes[i]._id == id) return nodes[i]; } return null; }
|
|
function addHtmlValue(t, v) { return '<table><td style=width:120px>' + t + '<td><b>' + v + '</b></table>'; }
|
|
function addHtmlValue2(t, v) { return '<div><div style=display:inline-block;float:right>' + v + '</div><div style=display:inline-block>' + t + '</div></div>'; }
|
|
function addLink(x, f) { return '<a style=cursor:pointer;color:darkblue;text-decoration:none onclick=\'' + f + '\'>♦ ' + x + '</a>'; }
|
|
function addLinkConditional(x, f, c) { if (c) return addLink(x, f); return x; }
|
|
function passwordcheck(p) { var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()]).{8,}/; return re.test(p); }
|
|
function getFileSizeStr(size) { if (size == 1) return "1 byte"; return format('{0} bytes', size); }
|
|
function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
|
|
function focusTextBox(x) { setTimeout(function () { Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
|
|
var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
|
|
function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
|
|
function printDate(d) { return d.toLocaleDateString(args.locale); }
|
|
function printTime(d) { return d.toLocaleTimeString(args.locale); }
|
|
function printDateTime(d) { return d.toLocaleString(args.locale); }
|
|
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; }); };
|
|
function nobreak(x) { return x.split(' ').join(' '); }
|
|
|
|
</script>
|
|
|
|
</body></html> |