mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 06:05:53 -05:00
Removed auto-generated files.
This commit is contained in:
parent
e2f69f8bf6
commit
8547f0c101
2617
agents/meshcmd.min.js
vendored
2617
agents/meshcmd.min.js
vendored
File diff suppressed because one or more lines are too long
2987
agents/meshcore.min.js
vendored
2987
agents/meshcore.min.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,537 +0,0 @@
|
||||
<!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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-terminal-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>
|
||||
</head>
|
||||
<body style="overflow:hidden;background-color:black">
|
||||
<div id="p11" class="noselect" style="overflow:hidden">
|
||||
<div id="deskarea0">
|
||||
<div id="deskarea1" class="areaHead">
|
||||
<div class="toright2">
|
||||
<div class="deskareaicon" title="Přepnout režim zobrazení" onclick="toggleAspectRatio(1)">⇲</div>
|
||||
</div>
|
||||
<div>
|
||||
<input id="OpenFileButton" type="button" value="Otevřít soubor..." onclick="openfile()">
|
||||
<span id="deskstatus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="deskarea2" style="">
|
||||
<div class="areaProgress"><div id="progressbar" style=""></div></div>
|
||||
</div>
|
||||
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
|
||||
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b>✓</b></div>
|
||||
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b>✗</b></div>
|
||||
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
|
||||
<div id="DeskParent">
|
||||
<canvas id="Desk" width="640" height="480"></canvas>
|
||||
</div>
|
||||
<div id="TermParent" style="display:none">
|
||||
<pre id="Term"></pre>
|
||||
</div>
|
||||
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
|
||||
</div>
|
||||
<div id="deskarea4" class="areaFoot">
|
||||
<div class="toright2">
|
||||
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<input id="PlayButton" type="button" value="Spustit" disabled="disabled" onclick="play()">
|
||||
<input id="PauseButton" type="button" value="Pauza" disabled="disabled" onclick="pause()">
|
||||
<input id="RestartButton" type="button" value="Restart" disabled="disabled" onclick="restart()">
|
||||
<select id="PlaySpeed" onchange="this.blur();">
|
||||
<option value="4">1/4 rychlost</option>
|
||||
<option value="2">1/2 rychlost</option>
|
||||
<option value="1" selected="">Normalní rychlost</option>
|
||||
<option value="0.5">2x rychlost</option>
|
||||
<option value="0.25">4x rychlost</option>
|
||||
<option value="0.1">10x rychlost</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog" class="noselect" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
||||
<div id="id_dialogtitle"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Zrušit" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
<div><input id="idx_dlgDeleteButton" type="button" value="Smazat" style="display:none" onclick="dialogclose(2)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var recFile = null;
|
||||
var recFilePtr = 0;
|
||||
var recFileStartTime = 0;
|
||||
var recFileLastTime = 0;
|
||||
var recFileEndTime = 0;
|
||||
var recFileMetadata = null;
|
||||
var recFileProtocol = 0;
|
||||
var agentDesktop = null;
|
||||
var amtDesktop = null;
|
||||
var playing = false;
|
||||
var readState = 0;
|
||||
var waitTimer = null;
|
||||
var waitTimerArgs = null;
|
||||
var deskAspectRatio = 0;
|
||||
var currentDeltaTimeTotalSec = 0;
|
||||
|
||||
function start() {
|
||||
window.onresize = deskAdjust;
|
||||
document.ondrop = ondrop;
|
||||
document.ondragover = ondragover;
|
||||
document.ondragleave = ondragleave;
|
||||
document.onkeypress = onkeypress;
|
||||
Q('PlaySpeed').value = 1;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function readNextBlock(func) {
|
||||
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr2 = new FileReader();
|
||||
fr2.onload = function () {
|
||||
recFilePtr += (16 + size);
|
||||
if (recFileEndTime == 0) {
|
||||
// File pointer progress bar
|
||||
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
|
||||
} else {
|
||||
// Time progress bar
|
||||
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
|
||||
}
|
||||
func(type, flags, time, this.result);
|
||||
};
|
||||
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
|
||||
}
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
|
||||
}
|
||||
}
|
||||
|
||||
function readLastBlock(func) {
|
||||
if (recFile.size < 32) { func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
|
||||
}
|
||||
}
|
||||
|
||||
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
|
||||
|
||||
function addInfoNoEsc(name, value) {
|
||||
if (value == null) return '';
|
||||
return '<span style=color:gray>' + EscapeHtml(name) + '</span>: <span style=font-size:20px>' + value + '</span><br/>';
|
||||
}
|
||||
|
||||
function processFirstBlock(type, flags, time, data) {
|
||||
recFileProtocol = 0;
|
||||
if ((type != 1) || (flags != 0)) { cleanup(); return; }
|
||||
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
|
||||
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
|
||||
var x = '';
|
||||
x += addInfo("Čas", recFileMetadata.time);
|
||||
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("Trvání", format("{0} sekund{1}", secs, (secs > 1) ? 's' : '')); }
|
||||
x += addInfo("Uživatel", recFileMetadata.username);
|
||||
x += addInfo("Uživatelské ID", recFileMetadata.userid);
|
||||
x += addInfo("SessionID", recFileMetadata.sessionid);
|
||||
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("Adresy", format("{0} na {1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
|
||||
if (recFileMetadata.devicename) { x += addInfo("Název zařízení", recFileMetadata.devicename); }
|
||||
x += addInfo("NodeID", recFileMetadata.nodeid);
|
||||
if (recFileMetadata.protocol) {
|
||||
var p = recFileMetadata.protocol;
|
||||
if (p == 1) { p = "MeshCentral terminal"; }
|
||||
else if (p == 2) { p = "MeshCentral plocha"; }
|
||||
else if (p == 100) { p = "Intel® AMT WSMAN"; }
|
||||
else if (p == 101) { p = "Intel® AMT přesměrování"; }
|
||||
x += addInfoNoEsc("Protokol", p);
|
||||
}
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (recFileMetadata.protocol == 1) {
|
||||
// MeshCentral remote terminal
|
||||
recFileProtocol = 1;
|
||||
x += '<br /><br /><span style=color:gray>' + "Zmáčkni [mezerník] pro spuštění/pauzu." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
}
|
||||
else if (recFileMetadata.protocol == 2) {
|
||||
// MeshCentral remote desktop
|
||||
recFileProtocol = 2;
|
||||
x += '<br /><br /><span style=color:gray>' + "Zmáčkni [mezerník] pro spuštění/pauzu." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
agentDesktop = CreateAgentRemoteDesktop('Desk');
|
||||
agentDesktop.onScreenSizeChange = deskAdjust;
|
||||
agentDesktop.State = 3;
|
||||
deskAdjust();
|
||||
}
|
||||
else if (recFileMetadata.protocol == 101) {
|
||||
// Intel AMT Redirection
|
||||
recFileProtocol = 101;
|
||||
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
deskAdjust();
|
||||
}
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', x);
|
||||
QH('deskstatus', recFile.name);
|
||||
}
|
||||
|
||||
function processBlock(type, flags, time, data) {
|
||||
if (type < 0) { pause(); return; }
|
||||
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
|
||||
if (waitTime < 5) {
|
||||
processBlockEx(type, flags, time, data);
|
||||
} else {
|
||||
waitTimerArgs = [type, flags, time, data]
|
||||
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockEx(type, flags, time, data) {
|
||||
if (playing == false) return;
|
||||
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
|
||||
|
||||
// Update the clock
|
||||
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
|
||||
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
|
||||
currentDeltaTimeTotalSec = deltaTimeTotalSec;
|
||||
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 3600)
|
||||
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 60)
|
||||
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
|
||||
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
|
||||
}
|
||||
|
||||
if ((type == 2) && flagBinary && !flagUser) {
|
||||
// Device --> User data
|
||||
if (recFileProtocol == 1) {
|
||||
// MeshCentral Terminal
|
||||
agentTerminal.ProcessData(data);
|
||||
} else if (recFileProtocol == 2) {
|
||||
// MeshCentral Remote Desktop
|
||||
agentDesktop.ProcessData(data);
|
||||
} else if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
|
||||
// We are not authenticated, KVM data starts here.
|
||||
readState = 1;
|
||||
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
|
||||
} else if (readState == 1) {
|
||||
amtDesktop.ProcessData(data);
|
||||
}
|
||||
}
|
||||
} else if ((type == 2) && flagBinary && flagUser) {
|
||||
// User --> Device data
|
||||
if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
|
||||
}
|
||||
}
|
||||
|
||||
recFileLastTime = time;
|
||||
if (playing) { readNextBlock(processBlock); }
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
recFile = null;
|
||||
recFilePtr = 0;
|
||||
recFileMetadata = null;
|
||||
playing = false;
|
||||
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
|
||||
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
|
||||
readState = 0;
|
||||
waitTimerArgs = null;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
recFileEndTime = 0;
|
||||
agentTerminal = null;
|
||||
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
|
||||
QH('deskstatus', '');
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + "Drag & drop soubor .mcrec nebo klikni na \"Otevřít soubor...\"" + '</span>');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
}
|
||||
|
||||
function ondrop(e) {
|
||||
haltEvent(e);
|
||||
QV('bigfail', false);
|
||||
QV('bigok', false);
|
||||
|
||||
// Check if these are files we can upload, remove all folders.
|
||||
if (e.dataTransfer == null) return;
|
||||
var files = [];
|
||||
for (var i in e.dataTransfer.files) {
|
||||
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
|
||||
files.push(e.dataTransfer.files[i]);
|
||||
}
|
||||
}
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
}
|
||||
|
||||
var dragtimer = null;
|
||||
function ondragover(e) {
|
||||
haltEvent(e);
|
||||
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
|
||||
var ac = true;
|
||||
QV('bigok', ac);
|
||||
QV('bigfail', !ac);
|
||||
}
|
||||
|
||||
function ondragleave(e) {
|
||||
haltEvent(e);
|
||||
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
|
||||
}
|
||||
|
||||
function onkeypress(e) {
|
||||
if (xxdialogMode) return;
|
||||
if (e.key == ' ') { togglePause(); haltEvent(e); }
|
||||
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
|
||||
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
|
||||
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
|
||||
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
|
||||
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
|
||||
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
|
||||
if (e.key == '0') { pause(); restart(); haltEvent(e); }
|
||||
}
|
||||
|
||||
function openfile() {
|
||||
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
|
||||
setDialogMode(2, "Otevřít soubor...", 3, openfileEx, x);
|
||||
QE('idx_dlgOkButton', false);
|
||||
}
|
||||
|
||||
function openfileEx() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
Q('OpenFileButton').blur();
|
||||
}
|
||||
|
||||
function openfileChanged() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
QE('idx_dlgOkButton', files.length == 1);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
|
||||
}
|
||||
|
||||
function play() {
|
||||
Q('PlayButton').blur();
|
||||
if ((playing == true) || (recFileProtocol == 0)) return;
|
||||
playing = true;
|
||||
QV('metadatadiv', false);
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', true);
|
||||
QE('RestartButton', false);
|
||||
if ((recFileProtocol == 1) && (agentTerminal == null)) {
|
||||
QV('DeskParent', false);
|
||||
QV('TermParent', true);
|
||||
agentTerminal = CreateAmtRemoteTerminal('Term', {});
|
||||
agentTerminal.State = 3;
|
||||
}
|
||||
readNextBlock(processBlock);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
Q('PauseButton').blur();
|
||||
if (playing == false) return;
|
||||
playing = false;
|
||||
QE('PlayButton', recFilePtr != recFile.size);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', recFilePtr != 0);
|
||||
if (waitTimer != null) {
|
||||
clearTimeout(waitTimer);
|
||||
waitTimer = null;
|
||||
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
|
||||
waitTimerArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Q('RestartButton').blur();
|
||||
if (playing == true) return;
|
||||
recFilePtr = 0;
|
||||
readState = 0;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
QV('metadatadiv', true);
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (agentDesktop) {
|
||||
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
|
||||
} else if (amtDesktop) {
|
||||
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
} else if (agentTerminal) {
|
||||
agentTerminal = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleAspectRatio(toggle) {
|
||||
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
||||
deskAdjust();
|
||||
}
|
||||
|
||||
function deskAdjust() {
|
||||
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
||||
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
||||
|
||||
if (deskAspectRatio == 2) {
|
||||
// Scale mode
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('Desk').height = '100%';
|
||||
QS('Desk').width = '100%';
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
} else if (deskAspectRatio == 1) {
|
||||
// Zoomed mode
|
||||
QS('Desk')['margin-top'] = '0px';
|
||||
//QS('Desk')['margin-left'] = '0px';
|
||||
QS('Desk').height = deskH + 'px';
|
||||
QS('Desk').width = deskW + 'px';
|
||||
QS('DeskParent').overflow = 'scroll';
|
||||
} else {
|
||||
// Fixed aspect ratio
|
||||
if ((parentH / parentW) > (deskH / deskW)) {
|
||||
var hNew = ((deskH * parentW) / deskW) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('deskarea3x').height = null;
|
||||
//} else {
|
||||
// QS('deskarea3x').height = hNew;
|
||||
//QS('deskarea3x').height = null;
|
||||
//}
|
||||
QS('Desk').height = hNew;
|
||||
QS('Desk').width = '100%';
|
||||
} else {
|
||||
var wNew = ((deskW * parentH) / deskH) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('Desk').height = null;
|
||||
//} else {
|
||||
QS('Desk').height = '100%';
|
||||
//}
|
||||
QS('Desk').width = wNew;
|
||||
}
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// null = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = -1;
|
||||
|
||||
// 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) {
|
||||
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_dlgDeleteButton', b & 4);
|
||||
QV('idx_dlgButtonBar', b & 7);
|
||||
if (y) QH('id_dialogtitle', y);
|
||||
for (var i = 1; i < 3; 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) {
|
||||
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
||||
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
||||
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
||||
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
||||
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; }); };
|
||||
|
||||
start();
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,537 +0,0 @@
|
||||
<!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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-terminal-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>
|
||||
</head>
|
||||
<body style="overflow:hidden;background-color:black">
|
||||
<div id="p11" class="noselect" style="overflow:hidden">
|
||||
<div id="deskarea0">
|
||||
<div id="deskarea1" class="areaHead">
|
||||
<div class="toright2">
|
||||
<div class="deskareaicon" title="Toggle View Mode" onclick="toggleAspectRatio(1)">⇲</div>
|
||||
</div>
|
||||
<div>
|
||||
<input id="OpenFileButton" type="button" value="Open File..." onclick="openfile()">
|
||||
<span id="deskstatus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="deskarea2" style="">
|
||||
<div class="areaProgress"><div id="progressbar" style=""></div></div>
|
||||
</div>
|
||||
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
|
||||
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b>✓</b></div>
|
||||
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b>✗</b></div>
|
||||
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
|
||||
<div id="DeskParent">
|
||||
<canvas id="Desk" width="640" height="480"></canvas>
|
||||
</div>
|
||||
<div id="TermParent" style="display:none">
|
||||
<pre id="Term"></pre>
|
||||
</div>
|
||||
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
|
||||
</div>
|
||||
<div id="deskarea4" class="areaFoot">
|
||||
<div class="toright2">
|
||||
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<input id="PlayButton" type="button" value="Jouer" disabled="disabled" onclick="play()">
|
||||
<input id="PauseButton" type="button" value="Pause" disabled="disabled" onclick="pause()">
|
||||
<input id="RestartButton" type="button" value="Redémarrer" disabled="disabled" onclick="restart()">
|
||||
<select id="PlaySpeed" onchange="this.blur();">
|
||||
<option value="4">1/4 vitesse</option>
|
||||
<option value="2">1/2 vitesse</option>
|
||||
<option value="1" selected="">Vitesse normale</option>
|
||||
<option value="0.5">2x vitesse</option>
|
||||
<option value="0.25">4x vitesse</option>
|
||||
<option value="0.1">10x vitesse</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog" class="noselect" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
||||
<div id="id_dialogtitle"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Annuler" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
<div><input id="idx_dlgDeleteButton" type="button" value="Delete" style="display:none" onclick="dialogclose(2)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var recFile = null;
|
||||
var recFilePtr = 0;
|
||||
var recFileStartTime = 0;
|
||||
var recFileLastTime = 0;
|
||||
var recFileEndTime = 0;
|
||||
var recFileMetadata = null;
|
||||
var recFileProtocol = 0;
|
||||
var agentDesktop = null;
|
||||
var amtDesktop = null;
|
||||
var playing = false;
|
||||
var readState = 0;
|
||||
var waitTimer = null;
|
||||
var waitTimerArgs = null;
|
||||
var deskAspectRatio = 0;
|
||||
var currentDeltaTimeTotalSec = 0;
|
||||
|
||||
function start() {
|
||||
window.onresize = deskAdjust;
|
||||
document.ondrop = ondrop;
|
||||
document.ondragover = ondragover;
|
||||
document.ondragleave = ondragleave;
|
||||
document.onkeypress = onkeypress;
|
||||
Q('PlaySpeed').value = 1;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function readNextBlock(func) {
|
||||
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr2 = new FileReader();
|
||||
fr2.onload = function () {
|
||||
recFilePtr += (16 + size);
|
||||
if (recFileEndTime == 0) {
|
||||
// File pointer progress bar
|
||||
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
|
||||
} else {
|
||||
// Time progress bar
|
||||
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
|
||||
}
|
||||
func(type, flags, time, this.result);
|
||||
};
|
||||
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
|
||||
}
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
|
||||
}
|
||||
}
|
||||
|
||||
function readLastBlock(func) {
|
||||
if (recFile.size < 32) { func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
|
||||
}
|
||||
}
|
||||
|
||||
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
|
||||
|
||||
function addInfoNoEsc(name, value) {
|
||||
if (value == null) return '';
|
||||
return '<span style=color:gray>' + EscapeHtml(name) + '</span>: <span style=font-size:20px>' + value + '</span><br/>';
|
||||
}
|
||||
|
||||
function processFirstBlock(type, flags, time, data) {
|
||||
recFileProtocol = 0;
|
||||
if ((type != 1) || (flags != 0)) { cleanup(); return; }
|
||||
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
|
||||
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
|
||||
var x = '';
|
||||
x += addInfo("Temps", recFileMetadata.time);
|
||||
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("Duration", format("{0} second{1}", secs, (secs > 1) ? 's' : '')); }
|
||||
x += addInfo("Nom d'utilisateur", recFileMetadata.username);
|
||||
x += addInfo("Identifiant d'utilisateur", recFileMetadata.userid);
|
||||
x += addInfo("ID de session", recFileMetadata.sessionid);
|
||||
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("Addresses", format("{0} to {1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
|
||||
if (recFileMetadata.devicename) { x += addInfo("Device Name", recFileMetadata.devicename); }
|
||||
x += addInfo("NodeID", recFileMetadata.nodeid);
|
||||
if (recFileMetadata.protocol) {
|
||||
var p = recFileMetadata.protocol;
|
||||
if (p == 1) { p = "MeshCentral Terminal"; }
|
||||
else if (p == 2) { p = "MeshCentral Desktop"; }
|
||||
else if (p == 100) { p = "Intel® AMT WSMAN"; }
|
||||
else if (p == 101) { p = "Intel® AMT Redirection"; }
|
||||
x += addInfoNoEsc("Protocole", p);
|
||||
}
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (recFileMetadata.protocol == 1) {
|
||||
// MeshCentral remote terminal
|
||||
recFileProtocol = 1;
|
||||
x += '<br /><br /><span style=color:gray>' + "Appuyez sur [espace] pour jouer/mettre en pause." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
}
|
||||
else if (recFileMetadata.protocol == 2) {
|
||||
// MeshCentral remote desktop
|
||||
recFileProtocol = 2;
|
||||
x += '<br /><br /><span style=color:gray>' + "Appuyez sur [espace] pour jouer/mettre en pause." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
agentDesktop = CreateAgentRemoteDesktop('Desk');
|
||||
agentDesktop.onScreenSizeChange = deskAdjust;
|
||||
agentDesktop.State = 3;
|
||||
deskAdjust();
|
||||
}
|
||||
else if (recFileMetadata.protocol == 101) {
|
||||
// Intel AMT Redirection
|
||||
recFileProtocol = 101;
|
||||
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
deskAdjust();
|
||||
}
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', x);
|
||||
QH('deskstatus', recFile.name);
|
||||
}
|
||||
|
||||
function processBlock(type, flags, time, data) {
|
||||
if (type < 0) { pause(); return; }
|
||||
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
|
||||
if (waitTime < 5) {
|
||||
processBlockEx(type, flags, time, data);
|
||||
} else {
|
||||
waitTimerArgs = [type, flags, time, data]
|
||||
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockEx(type, flags, time, data) {
|
||||
if (playing == false) return;
|
||||
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
|
||||
|
||||
// Update the clock
|
||||
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
|
||||
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
|
||||
currentDeltaTimeTotalSec = deltaTimeTotalSec;
|
||||
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 3600)
|
||||
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 60)
|
||||
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
|
||||
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
|
||||
}
|
||||
|
||||
if ((type == 2) && flagBinary && !flagUser) {
|
||||
// Device --> User data
|
||||
if (recFileProtocol == 1) {
|
||||
// MeshCentral Terminal
|
||||
agentTerminal.ProcessData(data);
|
||||
} else if (recFileProtocol == 2) {
|
||||
// MeshCentral Remote Desktop
|
||||
agentDesktop.ProcessData(data);
|
||||
} else if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
|
||||
// We are not authenticated, KVM data starts here.
|
||||
readState = 1;
|
||||
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
|
||||
} else if (readState == 1) {
|
||||
amtDesktop.ProcessData(data);
|
||||
}
|
||||
}
|
||||
} else if ((type == 2) && flagBinary && flagUser) {
|
||||
// User --> Device data
|
||||
if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
|
||||
}
|
||||
}
|
||||
|
||||
recFileLastTime = time;
|
||||
if (playing) { readNextBlock(processBlock); }
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
recFile = null;
|
||||
recFilePtr = 0;
|
||||
recFileMetadata = null;
|
||||
playing = false;
|
||||
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
|
||||
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
|
||||
readState = 0;
|
||||
waitTimerArgs = null;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
recFileEndTime = 0;
|
||||
agentTerminal = null;
|
||||
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
|
||||
QH('deskstatus', '');
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + "Drag & drop a .mcrec file or click \"Open File...\"" + '</span>');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
}
|
||||
|
||||
function ondrop(e) {
|
||||
haltEvent(e);
|
||||
QV('bigfail', false);
|
||||
QV('bigok', false);
|
||||
|
||||
// Check if these are files we can upload, remove all folders.
|
||||
if (e.dataTransfer == null) return;
|
||||
var files = [];
|
||||
for (var i in e.dataTransfer.files) {
|
||||
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
|
||||
files.push(e.dataTransfer.files[i]);
|
||||
}
|
||||
}
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
}
|
||||
|
||||
var dragtimer = null;
|
||||
function ondragover(e) {
|
||||
haltEvent(e);
|
||||
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
|
||||
var ac = true;
|
||||
QV('bigok', ac);
|
||||
QV('bigfail', !ac);
|
||||
}
|
||||
|
||||
function ondragleave(e) {
|
||||
haltEvent(e);
|
||||
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
|
||||
}
|
||||
|
||||
function onkeypress(e) {
|
||||
if (xxdialogMode) return;
|
||||
if (e.key == ' ') { togglePause(); haltEvent(e); }
|
||||
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
|
||||
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
|
||||
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
|
||||
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
|
||||
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
|
||||
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
|
||||
if (e.key == '0') { pause(); restart(); haltEvent(e); }
|
||||
}
|
||||
|
||||
function openfile() {
|
||||
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
|
||||
setDialogMode(2, "Open File...", 3, openfileEx, x);
|
||||
QE('idx_dlgOkButton', false);
|
||||
}
|
||||
|
||||
function openfileEx() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
Q('OpenFileButton').blur();
|
||||
}
|
||||
|
||||
function openfileChanged() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
QE('idx_dlgOkButton', files.length == 1);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
|
||||
}
|
||||
|
||||
function play() {
|
||||
Q('PlayButton').blur();
|
||||
if ((playing == true) || (recFileProtocol == 0)) return;
|
||||
playing = true;
|
||||
QV('metadatadiv', false);
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', true);
|
||||
QE('RestartButton', false);
|
||||
if ((recFileProtocol == 1) && (agentTerminal == null)) {
|
||||
QV('DeskParent', false);
|
||||
QV('TermParent', true);
|
||||
agentTerminal = CreateAmtRemoteTerminal('Term', {});
|
||||
agentTerminal.State = 3;
|
||||
}
|
||||
readNextBlock(processBlock);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
Q('PauseButton').blur();
|
||||
if (playing == false) return;
|
||||
playing = false;
|
||||
QE('PlayButton', recFilePtr != recFile.size);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', recFilePtr != 0);
|
||||
if (waitTimer != null) {
|
||||
clearTimeout(waitTimer);
|
||||
waitTimer = null;
|
||||
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
|
||||
waitTimerArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Q('RestartButton').blur();
|
||||
if (playing == true) return;
|
||||
recFilePtr = 0;
|
||||
readState = 0;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
QV('metadatadiv', true);
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (agentDesktop) {
|
||||
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
|
||||
} else if (amtDesktop) {
|
||||
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
} else if (agentTerminal) {
|
||||
agentTerminal = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleAspectRatio(toggle) {
|
||||
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
||||
deskAdjust();
|
||||
}
|
||||
|
||||
function deskAdjust() {
|
||||
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
||||
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
||||
|
||||
if (deskAspectRatio == 2) {
|
||||
// Scale mode
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('Desk').height = '100%';
|
||||
QS('Desk').width = '100%';
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
} else if (deskAspectRatio == 1) {
|
||||
// Zoomed mode
|
||||
QS('Desk')['margin-top'] = '0px';
|
||||
//QS('Desk')['margin-left'] = '0px';
|
||||
QS('Desk').height = deskH + 'px';
|
||||
QS('Desk').width = deskW + 'px';
|
||||
QS('DeskParent').overflow = 'scroll';
|
||||
} else {
|
||||
// Fixed aspect ratio
|
||||
if ((parentH / parentW) > (deskH / deskW)) {
|
||||
var hNew = ((deskH * parentW) / deskW) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('deskarea3x').height = null;
|
||||
//} else {
|
||||
// QS('deskarea3x').height = hNew;
|
||||
//QS('deskarea3x').height = null;
|
||||
//}
|
||||
QS('Desk').height = hNew;
|
||||
QS('Desk').width = '100%';
|
||||
} else {
|
||||
var wNew = ((deskW * parentH) / deskH) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('Desk').height = null;
|
||||
//} else {
|
||||
QS('Desk').height = '100%';
|
||||
//}
|
||||
QS('Desk').width = wNew;
|
||||
}
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// null = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = -1;
|
||||
|
||||
// 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) {
|
||||
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_dlgDeleteButton', b & 4);
|
||||
QV('idx_dlgButtonBar', b & 7);
|
||||
if (y) QH('id_dialogtitle', y);
|
||||
for (var i = 1; i < 3; 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) {
|
||||
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
||||
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
||||
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
||||
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
||||
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; }); };
|
||||
|
||||
start();
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,537 +0,0 @@
|
||||
<!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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-terminal-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>
|
||||
</head>
|
||||
<body style="overflow:hidden;background-color:black">
|
||||
<div id="p11" class="noselect" style="overflow:hidden">
|
||||
<div id="deskarea0">
|
||||
<div id="deskarea1" class="areaHead">
|
||||
<div class="toright2">
|
||||
<div class="deskareaicon" title="表示モードの切り替え" onclick="toggleAspectRatio(1)">⇲</div>
|
||||
</div>
|
||||
<div>
|
||||
<input id="OpenFileButton" type="button" value="ファイルを開く..." onclick="openfile()">
|
||||
<span id="deskstatus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="deskarea2" style="">
|
||||
<div class="areaProgress"><div id="progressbar" style=""></div></div>
|
||||
</div>
|
||||
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
|
||||
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b>✓</b></div>
|
||||
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b>✗</b></div>
|
||||
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
|
||||
<div id="DeskParent">
|
||||
<canvas id="Desk" width="640" height="480"></canvas>
|
||||
</div>
|
||||
<div id="TermParent" style="display:none">
|
||||
<pre id="Term"></pre>
|
||||
</div>
|
||||
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
|
||||
</div>
|
||||
<div id="deskarea4" class="areaFoot">
|
||||
<div class="toright2">
|
||||
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<input id="PlayButton" type="button" value="遊びます" disabled="disabled" onclick="play()">
|
||||
<input id="PauseButton" type="button" value="一時停止" disabled="disabled" onclick="pause()">
|
||||
<input id="RestartButton" type="button" value="再起動" disabled="disabled" onclick="restart()">
|
||||
<select id="PlaySpeed" onchange="this.blur();">
|
||||
<option value="4">1/4スピード</option>
|
||||
<option value="2">1/2速度</option>
|
||||
<option value="1" selected="">通常速度</option>
|
||||
<option value="0.5">2倍速</option>
|
||||
<option value="0.25">4倍速</option>
|
||||
<option value="0.1">10倍速</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog" class="noselect" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
||||
<div id="id_dialogtitle"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar">
|
||||
<input id="idx_dlgCancelButton" type="button" value="キャンセル" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
<div><input id="idx_dlgDeleteButton" type="button" value="削除する" style="display:none" onclick="dialogclose(2)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var recFile = null;
|
||||
var recFilePtr = 0;
|
||||
var recFileStartTime = 0;
|
||||
var recFileLastTime = 0;
|
||||
var recFileEndTime = 0;
|
||||
var recFileMetadata = null;
|
||||
var recFileProtocol = 0;
|
||||
var agentDesktop = null;
|
||||
var amtDesktop = null;
|
||||
var playing = false;
|
||||
var readState = 0;
|
||||
var waitTimer = null;
|
||||
var waitTimerArgs = null;
|
||||
var deskAspectRatio = 0;
|
||||
var currentDeltaTimeTotalSec = 0;
|
||||
|
||||
function start() {
|
||||
window.onresize = deskAdjust;
|
||||
document.ondrop = ondrop;
|
||||
document.ondragover = ondragover;
|
||||
document.ondragleave = ondragleave;
|
||||
document.onkeypress = onkeypress;
|
||||
Q('PlaySpeed').value = 1;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function readNextBlock(func) {
|
||||
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr2 = new FileReader();
|
||||
fr2.onload = function () {
|
||||
recFilePtr += (16 + size);
|
||||
if (recFileEndTime == 0) {
|
||||
// File pointer progress bar
|
||||
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
|
||||
} else {
|
||||
// Time progress bar
|
||||
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
|
||||
}
|
||||
func(type, flags, time, this.result);
|
||||
};
|
||||
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
|
||||
}
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
|
||||
}
|
||||
}
|
||||
|
||||
function readLastBlock(func) {
|
||||
if (recFile.size < 32) { func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
|
||||
}
|
||||
}
|
||||
|
||||
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
|
||||
|
||||
function addInfoNoEsc(name, value) {
|
||||
if (value == null) return '';
|
||||
return '<span style=color:gray>' + EscapeHtml(name) + '</span>: <span style=font-size:20px>' + value + '</span><br/>';
|
||||
}
|
||||
|
||||
function processFirstBlock(type, flags, time, data) {
|
||||
recFileProtocol = 0;
|
||||
if ((type != 1) || (flags != 0)) { cleanup(); return; }
|
||||
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
|
||||
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
|
||||
var x = '';
|
||||
x += addInfo("時間", recFileMetadata.time);
|
||||
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("期間", format("{0}秒{1}", secs, (secs > 1) ? 's' : '')); }
|
||||
x += addInfo("ユーザー名", recFileMetadata.username);
|
||||
x += addInfo("ユーザーID", recFileMetadata.userid);
|
||||
x += addInfo("セッションID", recFileMetadata.sessionid);
|
||||
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("住所", format("{0}から{1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
|
||||
if (recFileMetadata.devicename) { x += addInfo("装置名", recFileMetadata.devicename); }
|
||||
x += addInfo("NodeID", recFileMetadata.nodeid);
|
||||
if (recFileMetadata.protocol) {
|
||||
var p = recFileMetadata.protocol;
|
||||
if (p == 1) { p = "MeshCentralターミナル"; }
|
||||
else if (p == 2) { p = "MeshCentralデスクトップ"; }
|
||||
else if (p == 100) { p = "Intel® AMT WSMAN"; }
|
||||
else if (p == 101) { p = "Intel® AMTリダイレクト"; }
|
||||
x += addInfoNoEsc("プロトコル", p);
|
||||
}
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (recFileMetadata.protocol == 1) {
|
||||
// MeshCentral remote terminal
|
||||
recFileProtocol = 1;
|
||||
x += '<br /><br /><span style=color:gray>' + "[スペース]を押して再生/一時停止します。" + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
}
|
||||
else if (recFileMetadata.protocol == 2) {
|
||||
// MeshCentral remote desktop
|
||||
recFileProtocol = 2;
|
||||
x += '<br /><br /><span style=color:gray>' + "[スペース]を押して再生/一時停止します。" + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
agentDesktop = CreateAgentRemoteDesktop('Desk');
|
||||
agentDesktop.onScreenSizeChange = deskAdjust;
|
||||
agentDesktop.State = 3;
|
||||
deskAdjust();
|
||||
}
|
||||
else if (recFileMetadata.protocol == 101) {
|
||||
// Intel AMT Redirection
|
||||
recFileProtocol = 101;
|
||||
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
deskAdjust();
|
||||
}
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', x);
|
||||
QH('deskstatus', recFile.name);
|
||||
}
|
||||
|
||||
function processBlock(type, flags, time, data) {
|
||||
if (type < 0) { pause(); return; }
|
||||
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
|
||||
if (waitTime < 5) {
|
||||
processBlockEx(type, flags, time, data);
|
||||
} else {
|
||||
waitTimerArgs = [type, flags, time, data]
|
||||
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockEx(type, flags, time, data) {
|
||||
if (playing == false) return;
|
||||
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
|
||||
|
||||
// Update the clock
|
||||
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
|
||||
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
|
||||
currentDeltaTimeTotalSec = deltaTimeTotalSec;
|
||||
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 3600)
|
||||
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 60)
|
||||
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
|
||||
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
|
||||
}
|
||||
|
||||
if ((type == 2) && flagBinary && !flagUser) {
|
||||
// Device --> User data
|
||||
if (recFileProtocol == 1) {
|
||||
// MeshCentral Terminal
|
||||
agentTerminal.ProcessData(data);
|
||||
} else if (recFileProtocol == 2) {
|
||||
// MeshCentral Remote Desktop
|
||||
agentDesktop.ProcessData(data);
|
||||
} else if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
|
||||
// We are not authenticated, KVM data starts here.
|
||||
readState = 1;
|
||||
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
|
||||
} else if (readState == 1) {
|
||||
amtDesktop.ProcessData(data);
|
||||
}
|
||||
}
|
||||
} else if ((type == 2) && flagBinary && flagUser) {
|
||||
// User --> Device data
|
||||
if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
|
||||
}
|
||||
}
|
||||
|
||||
recFileLastTime = time;
|
||||
if (playing) { readNextBlock(processBlock); }
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
recFile = null;
|
||||
recFilePtr = 0;
|
||||
recFileMetadata = null;
|
||||
playing = false;
|
||||
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
|
||||
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
|
||||
readState = 0;
|
||||
waitTimerArgs = null;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
recFileEndTime = 0;
|
||||
agentTerminal = null;
|
||||
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
|
||||
QH('deskstatus', '');
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + ".mcrecファイルをドラッグアンドドロップするか、[ファイルを開く...]をクリックします" + '</span>');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
}
|
||||
|
||||
function ondrop(e) {
|
||||
haltEvent(e);
|
||||
QV('bigfail', false);
|
||||
QV('bigok', false);
|
||||
|
||||
// Check if these are files we can upload, remove all folders.
|
||||
if (e.dataTransfer == null) return;
|
||||
var files = [];
|
||||
for (var i in e.dataTransfer.files) {
|
||||
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
|
||||
files.push(e.dataTransfer.files[i]);
|
||||
}
|
||||
}
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
}
|
||||
|
||||
var dragtimer = null;
|
||||
function ondragover(e) {
|
||||
haltEvent(e);
|
||||
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
|
||||
var ac = true;
|
||||
QV('bigok', ac);
|
||||
QV('bigfail', !ac);
|
||||
}
|
||||
|
||||
function ondragleave(e) {
|
||||
haltEvent(e);
|
||||
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
|
||||
}
|
||||
|
||||
function onkeypress(e) {
|
||||
if (xxdialogMode) return;
|
||||
if (e.key == ' ') { togglePause(); haltEvent(e); }
|
||||
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
|
||||
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
|
||||
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
|
||||
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
|
||||
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
|
||||
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
|
||||
if (e.key == '0') { pause(); restart(); haltEvent(e); }
|
||||
}
|
||||
|
||||
function openfile() {
|
||||
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
|
||||
setDialogMode(2, "ファイルを開く...", 3, openfileEx, x);
|
||||
QE('idx_dlgOkButton', false);
|
||||
}
|
||||
|
||||
function openfileEx() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
Q('OpenFileButton').blur();
|
||||
}
|
||||
|
||||
function openfileChanged() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
QE('idx_dlgOkButton', files.length == 1);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
|
||||
}
|
||||
|
||||
function play() {
|
||||
Q('PlayButton').blur();
|
||||
if ((playing == true) || (recFileProtocol == 0)) return;
|
||||
playing = true;
|
||||
QV('metadatadiv', false);
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', true);
|
||||
QE('RestartButton', false);
|
||||
if ((recFileProtocol == 1) && (agentTerminal == null)) {
|
||||
QV('DeskParent', false);
|
||||
QV('TermParent', true);
|
||||
agentTerminal = CreateAmtRemoteTerminal('Term', {});
|
||||
agentTerminal.State = 3;
|
||||
}
|
||||
readNextBlock(processBlock);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
Q('PauseButton').blur();
|
||||
if (playing == false) return;
|
||||
playing = false;
|
||||
QE('PlayButton', recFilePtr != recFile.size);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', recFilePtr != 0);
|
||||
if (waitTimer != null) {
|
||||
clearTimeout(waitTimer);
|
||||
waitTimer = null;
|
||||
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
|
||||
waitTimerArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Q('RestartButton').blur();
|
||||
if (playing == true) return;
|
||||
recFilePtr = 0;
|
||||
readState = 0;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
QV('metadatadiv', true);
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (agentDesktop) {
|
||||
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
|
||||
} else if (amtDesktop) {
|
||||
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
} else if (agentTerminal) {
|
||||
agentTerminal = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleAspectRatio(toggle) {
|
||||
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
||||
deskAdjust();
|
||||
}
|
||||
|
||||
function deskAdjust() {
|
||||
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
||||
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
||||
|
||||
if (deskAspectRatio == 2) {
|
||||
// Scale mode
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('Desk').height = '100%';
|
||||
QS('Desk').width = '100%';
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
} else if (deskAspectRatio == 1) {
|
||||
// Zoomed mode
|
||||
QS('Desk')['margin-top'] = '0px';
|
||||
//QS('Desk')['margin-left'] = '0px';
|
||||
QS('Desk').height = deskH + 'px';
|
||||
QS('Desk').width = deskW + 'px';
|
||||
QS('DeskParent').overflow = 'scroll';
|
||||
} else {
|
||||
// Fixed aspect ratio
|
||||
if ((parentH / parentW) > (deskH / deskW)) {
|
||||
var hNew = ((deskH * parentW) / deskW) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('deskarea3x').height = null;
|
||||
//} else {
|
||||
// QS('deskarea3x').height = hNew;
|
||||
//QS('deskarea3x').height = null;
|
||||
//}
|
||||
QS('Desk').height = hNew;
|
||||
QS('Desk').width = '100%';
|
||||
} else {
|
||||
var wNew = ((deskW * parentH) / deskH) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('Desk').height = null;
|
||||
//} else {
|
||||
QS('Desk').height = '100%';
|
||||
//}
|
||||
QS('Desk').width = wNew;
|
||||
}
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// null = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = -1;
|
||||
|
||||
// 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) {
|
||||
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_dlgDeleteButton', b & 4);
|
||||
QV('idx_dlgButtonBar', b & 7);
|
||||
if (y) QH('id_dialogtitle', y);
|
||||
for (var i = 1; i < 3; 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) {
|
||||
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
||||
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
||||
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
||||
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
||||
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; }); };
|
||||
|
||||
start();
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,537 +0,0 @@
|
||||
<!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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-terminal-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>
|
||||
</head>
|
||||
<body style="overflow:hidden;background-color:black">
|
||||
<div id="p11" class="noselect" style="overflow:hidden">
|
||||
<div id="deskarea0">
|
||||
<div id="deskarea1" class="areaHead">
|
||||
<div class="toright2">
|
||||
<div class="deskareaicon" title="Schakel weergavemodus" onclick="toggleAspectRatio(1)">⇲</div>
|
||||
</div>
|
||||
<div>
|
||||
<input id="OpenFileButton" type="button" value="Open bestand..." onclick="openfile()">
|
||||
<span id="deskstatus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="deskarea2" style="">
|
||||
<div class="areaProgress"><div id="progressbar" style=""></div></div>
|
||||
</div>
|
||||
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
|
||||
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b>✓</b></div>
|
||||
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b>✗</b></div>
|
||||
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
|
||||
<div id="DeskParent">
|
||||
<canvas id="Desk" width="640" height="480"></canvas>
|
||||
</div>
|
||||
<div id="TermParent" style="display:none">
|
||||
<pre id="Term"></pre>
|
||||
</div>
|
||||
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
|
||||
</div>
|
||||
<div id="deskarea4" class="areaFoot">
|
||||
<div class="toright2">
|
||||
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<input id="PlayButton" type="button" value="Afspelen" disabled="disabled" onclick="play()">
|
||||
<input id="PauseButton" type="button" value="Pause" disabled="disabled" onclick="pause()">
|
||||
<input id="RestartButton" type="button" value="Herstarten" disabled="disabled" onclick="restart()">
|
||||
<select id="PlaySpeed" onchange="this.blur();">
|
||||
<option value="4">1/4 snelheid</option>
|
||||
<option value="2">1/2 snelheid</option>
|
||||
<option value="1" selected="">Normale snelheid</option>
|
||||
<option value="0.5">2x Snelheid</option>
|
||||
<option value="0.25">4x snelheid</option>
|
||||
<option value="0.1">10x Snelheid</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog" class="noselect" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
||||
<div id="id_dialogtitle"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Afbreken" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="Oke" style="" onclick="dialogclose(1)">
|
||||
<div><input id="idx_dlgDeleteButton" type="button" value="Verwijderen" style="display:none" onclick="dialogclose(2)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var recFile = null;
|
||||
var recFilePtr = 0;
|
||||
var recFileStartTime = 0;
|
||||
var recFileLastTime = 0;
|
||||
var recFileEndTime = 0;
|
||||
var recFileMetadata = null;
|
||||
var recFileProtocol = 0;
|
||||
var agentDesktop = null;
|
||||
var amtDesktop = null;
|
||||
var playing = false;
|
||||
var readState = 0;
|
||||
var waitTimer = null;
|
||||
var waitTimerArgs = null;
|
||||
var deskAspectRatio = 0;
|
||||
var currentDeltaTimeTotalSec = 0;
|
||||
|
||||
function start() {
|
||||
window.onresize = deskAdjust;
|
||||
document.ondrop = ondrop;
|
||||
document.ondragover = ondragover;
|
||||
document.ondragleave = ondragleave;
|
||||
document.onkeypress = onkeypress;
|
||||
Q('PlaySpeed').value = 1;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function readNextBlock(func) {
|
||||
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr2 = new FileReader();
|
||||
fr2.onload = function () {
|
||||
recFilePtr += (16 + size);
|
||||
if (recFileEndTime == 0) {
|
||||
// File pointer progress bar
|
||||
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
|
||||
} else {
|
||||
// Time progress bar
|
||||
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
|
||||
}
|
||||
func(type, flags, time, this.result);
|
||||
};
|
||||
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
|
||||
}
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
|
||||
}
|
||||
}
|
||||
|
||||
function readLastBlock(func) {
|
||||
if (recFile.size < 32) { func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
|
||||
}
|
||||
}
|
||||
|
||||
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
|
||||
|
||||
function addInfoNoEsc(name, value) {
|
||||
if (value == null) return '';
|
||||
return '<span style=color:gray>' + EscapeHtml(name) + '</span>: <span style=font-size:20px>' + value + '</span><br/>';
|
||||
}
|
||||
|
||||
function processFirstBlock(type, flags, time, data) {
|
||||
recFileProtocol = 0;
|
||||
if ((type != 1) || (flags != 0)) { cleanup(); return; }
|
||||
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
|
||||
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
|
||||
var x = '';
|
||||
x += addInfo("Tijd", recFileMetadata.time);
|
||||
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("Looptijd", format("{0} seconde {1}", secs, (secs > 1) ? 's' : '')); }
|
||||
x += addInfo("Gebruikersnaam", recFileMetadata.username);
|
||||
x += addInfo("GebruikersID", recFileMetadata.userid);
|
||||
x += addInfo("SessieID", recFileMetadata.sessionid);
|
||||
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("Adressen", format("{0} tot {1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
|
||||
if (recFileMetadata.devicename) { x += addInfo("Apparaat naam", recFileMetadata.devicename); }
|
||||
x += addInfo("NodeID", recFileMetadata.nodeid);
|
||||
if (recFileMetadata.protocol) {
|
||||
var p = recFileMetadata.protocol;
|
||||
if (p == 1) { p = "MeshCentral Terminal"; }
|
||||
else if (p == 2) { p = "MeshCentral Desktop"; }
|
||||
else if (p == 100) { p = "Intel® AMT WSMAN"; }
|
||||
else if (p == 101) { p = "Intel® AMT omleiding"; }
|
||||
x += addInfoNoEsc("Protocol", p);
|
||||
}
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (recFileMetadata.protocol == 1) {
|
||||
// MeshCentral remote terminal
|
||||
recFileProtocol = 1;
|
||||
x += '<br /><br /><span style=color:gray>' + "Druk op [spatie] om te spelen / pauzeren." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
}
|
||||
else if (recFileMetadata.protocol == 2) {
|
||||
// MeshCentral remote desktop
|
||||
recFileProtocol = 2;
|
||||
x += '<br /><br /><span style=color:gray>' + "Druk op [spatie] om te spelen / pauzeren." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
agentDesktop = CreateAgentRemoteDesktop('Desk');
|
||||
agentDesktop.onScreenSizeChange = deskAdjust;
|
||||
agentDesktop.State = 3;
|
||||
deskAdjust();
|
||||
}
|
||||
else if (recFileMetadata.protocol == 101) {
|
||||
// Intel AMT Redirection
|
||||
recFileProtocol = 101;
|
||||
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
deskAdjust();
|
||||
}
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', x);
|
||||
QH('deskstatus', recFile.name);
|
||||
}
|
||||
|
||||
function processBlock(type, flags, time, data) {
|
||||
if (type < 0) { pause(); return; }
|
||||
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
|
||||
if (waitTime < 5) {
|
||||
processBlockEx(type, flags, time, data);
|
||||
} else {
|
||||
waitTimerArgs = [type, flags, time, data]
|
||||
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockEx(type, flags, time, data) {
|
||||
if (playing == false) return;
|
||||
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
|
||||
|
||||
// Update the clock
|
||||
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
|
||||
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
|
||||
currentDeltaTimeTotalSec = deltaTimeTotalSec;
|
||||
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 3600)
|
||||
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 60)
|
||||
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
|
||||
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
|
||||
}
|
||||
|
||||
if ((type == 2) && flagBinary && !flagUser) {
|
||||
// Device --> User data
|
||||
if (recFileProtocol == 1) {
|
||||
// MeshCentral Terminal
|
||||
agentTerminal.ProcessData(data);
|
||||
} else if (recFileProtocol == 2) {
|
||||
// MeshCentral Remote Desktop
|
||||
agentDesktop.ProcessData(data);
|
||||
} else if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
|
||||
// We are not authenticated, KVM data starts here.
|
||||
readState = 1;
|
||||
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
|
||||
} else if (readState == 1) {
|
||||
amtDesktop.ProcessData(data);
|
||||
}
|
||||
}
|
||||
} else if ((type == 2) && flagBinary && flagUser) {
|
||||
// User --> Device data
|
||||
if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
|
||||
}
|
||||
}
|
||||
|
||||
recFileLastTime = time;
|
||||
if (playing) { readNextBlock(processBlock); }
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
recFile = null;
|
||||
recFilePtr = 0;
|
||||
recFileMetadata = null;
|
||||
playing = false;
|
||||
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
|
||||
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
|
||||
readState = 0;
|
||||
waitTimerArgs = null;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
recFileEndTime = 0;
|
||||
agentTerminal = null;
|
||||
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
|
||||
QH('deskstatus', '');
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + "Sleep een .mcrec-bestand of klik op \"Bestand openen ...\"" + '</span>');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
}
|
||||
|
||||
function ondrop(e) {
|
||||
haltEvent(e);
|
||||
QV('bigfail', false);
|
||||
QV('bigok', false);
|
||||
|
||||
// Check if these are files we can upload, remove all folders.
|
||||
if (e.dataTransfer == null) return;
|
||||
var files = [];
|
||||
for (var i in e.dataTransfer.files) {
|
||||
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
|
||||
files.push(e.dataTransfer.files[i]);
|
||||
}
|
||||
}
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
}
|
||||
|
||||
var dragtimer = null;
|
||||
function ondragover(e) {
|
||||
haltEvent(e);
|
||||
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
|
||||
var ac = true;
|
||||
QV('bigok', ac);
|
||||
QV('bigfail', !ac);
|
||||
}
|
||||
|
||||
function ondragleave(e) {
|
||||
haltEvent(e);
|
||||
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
|
||||
}
|
||||
|
||||
function onkeypress(e) {
|
||||
if (xxdialogMode) return;
|
||||
if (e.key == ' ') { togglePause(); haltEvent(e); }
|
||||
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
|
||||
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
|
||||
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
|
||||
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
|
||||
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
|
||||
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
|
||||
if (e.key == '0') { pause(); restart(); haltEvent(e); }
|
||||
}
|
||||
|
||||
function openfile() {
|
||||
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
|
||||
setDialogMode(2, "Open bestand...", 3, openfileEx, x);
|
||||
QE('idx_dlgOkButton', false);
|
||||
}
|
||||
|
||||
function openfileEx() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
Q('OpenFileButton').blur();
|
||||
}
|
||||
|
||||
function openfileChanged() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
QE('idx_dlgOkButton', files.length == 1);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
|
||||
}
|
||||
|
||||
function play() {
|
||||
Q('PlayButton').blur();
|
||||
if ((playing == true) || (recFileProtocol == 0)) return;
|
||||
playing = true;
|
||||
QV('metadatadiv', false);
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', true);
|
||||
QE('RestartButton', false);
|
||||
if ((recFileProtocol == 1) && (agentTerminal == null)) {
|
||||
QV('DeskParent', false);
|
||||
QV('TermParent', true);
|
||||
agentTerminal = CreateAmtRemoteTerminal('Term', {});
|
||||
agentTerminal.State = 3;
|
||||
}
|
||||
readNextBlock(processBlock);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
Q('PauseButton').blur();
|
||||
if (playing == false) return;
|
||||
playing = false;
|
||||
QE('PlayButton', recFilePtr != recFile.size);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', recFilePtr != 0);
|
||||
if (waitTimer != null) {
|
||||
clearTimeout(waitTimer);
|
||||
waitTimer = null;
|
||||
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
|
||||
waitTimerArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Q('RestartButton').blur();
|
||||
if (playing == true) return;
|
||||
recFilePtr = 0;
|
||||
readState = 0;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
QV('metadatadiv', true);
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (agentDesktop) {
|
||||
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
|
||||
} else if (amtDesktop) {
|
||||
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
} else if (agentTerminal) {
|
||||
agentTerminal = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleAspectRatio(toggle) {
|
||||
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
||||
deskAdjust();
|
||||
}
|
||||
|
||||
function deskAdjust() {
|
||||
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
||||
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
||||
|
||||
if (deskAspectRatio == 2) {
|
||||
// Scale mode
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('Desk').height = '100%';
|
||||
QS('Desk').width = '100%';
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
} else if (deskAspectRatio == 1) {
|
||||
// Zoomed mode
|
||||
QS('Desk')['margin-top'] = '0px';
|
||||
//QS('Desk')['margin-left'] = '0px';
|
||||
QS('Desk').height = deskH + 'px';
|
||||
QS('Desk').width = deskW + 'px';
|
||||
QS('DeskParent').overflow = 'scroll';
|
||||
} else {
|
||||
// Fixed aspect ratio
|
||||
if ((parentH / parentW) > (deskH / deskW)) {
|
||||
var hNew = ((deskH * parentW) / deskW) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('deskarea3x').height = null;
|
||||
//} else {
|
||||
// QS('deskarea3x').height = hNew;
|
||||
//QS('deskarea3x').height = null;
|
||||
//}
|
||||
QS('Desk').height = hNew;
|
||||
QS('Desk').width = '100%';
|
||||
} else {
|
||||
var wNew = ((deskW * parentH) / deskH) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('Desk').height = null;
|
||||
//} else {
|
||||
QS('Desk').height = '100%';
|
||||
//}
|
||||
QS('Desk').width = wNew;
|
||||
}
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// null = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = -1;
|
||||
|
||||
// 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) {
|
||||
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_dlgDeleteButton', b & 4);
|
||||
QV('idx_dlgButtonBar', b & 7);
|
||||
if (y) QH('id_dialogtitle', y);
|
||||
for (var i = 1; i < 3; 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) {
|
||||
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
||||
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
||||
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
||||
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
||||
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; }); };
|
||||
|
||||
start();
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,537 +0,0 @@
|
||||
<!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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-desktop-0.0.2.js"></script>
|
||||
<script type="text/javascript" src="scripts/amt-terminal-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>
|
||||
</head>
|
||||
<body style="overflow:hidden;background-color:black">
|
||||
<div id="p11" class="noselect" style="overflow:hidden">
|
||||
<div id="deskarea0">
|
||||
<div id="deskarea1" class="areaHead">
|
||||
<div class="toright2">
|
||||
<div class="deskareaicon" title="Alternar modo de exibição" onclick="toggleAspectRatio(1)">⇲</div>
|
||||
</div>
|
||||
<div>
|
||||
<input id="OpenFileButton" type="button" value="Abrir arquivo..." onclick="openfile()">
|
||||
<span id="deskstatus"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="deskarea2" style="">
|
||||
<div class="areaProgress"><div id="progressbar" style=""></div></div>
|
||||
</div>
|
||||
<div id="deskarea3x" style="max-height:calc(100vh - 54px);height:calc(100vh - 54px);" onclick="togglePause()">
|
||||
<div id="bigok" style="display:none;left:calc((100vh / 2))"><b>✓</b></div>
|
||||
<div id="bigfail" style="display:none;left:calc((100vh / 2))"><b>✗</b></div>
|
||||
<div id="metadatadiv" style="padding:20px;color:lightgrey;text-align:left;display:none"></div>
|
||||
<div id="DeskParent">
|
||||
<canvas id="Desk" width="640" height="480"></canvas>
|
||||
</div>
|
||||
<div id="TermParent" style="display:none">
|
||||
<pre id="Term"></pre>
|
||||
</div>
|
||||
<div id="p11DeskConsoleMsg" style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick="clearConsoleMsg()"></div>
|
||||
</div>
|
||||
<div id="deskarea4" class="areaFoot">
|
||||
<div class="toright2">
|
||||
<div id="timespan" style="padding-top:4px;padding-right:4px">00:00:00</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<input id="PlayButton" type="button" value="Play" disabled="disabled" onclick="play()">
|
||||
<input id="PauseButton" type="button" value="Pausa" disabled="disabled" onclick="pause()">
|
||||
<input id="RestartButton" type="button" value="Reiniciar" disabled="disabled" onclick="restart()">
|
||||
<select id="PlaySpeed" onchange="this.blur();">
|
||||
<option value="4">1/4 de velocidade</option>
|
||||
<option value="2">1/2 velocidade</option>
|
||||
<option value="1" selected="">Velocidade normal</option>
|
||||
<option value="0.5">2x velocidade</option>
|
||||
<option value="0.25">4x velocidade</option>
|
||||
<option value="0.1">10x Velocidade</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dialog" class="noselect" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div tabindex="0" id="id_dialogclose" onclick="setDialogMode()" onkeypress="if (event.key == 'Enter') setDialogMode()">✖</div>
|
||||
<div id="id_dialogtitle"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Cancelar" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="Ok" style="" onclick="dialogclose(1)">
|
||||
<div><input id="idx_dlgDeleteButton" type="button" value="Deletar" style="display:none" onclick="dialogclose(2)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var recFile = null;
|
||||
var recFilePtr = 0;
|
||||
var recFileStartTime = 0;
|
||||
var recFileLastTime = 0;
|
||||
var recFileEndTime = 0;
|
||||
var recFileMetadata = null;
|
||||
var recFileProtocol = 0;
|
||||
var agentDesktop = null;
|
||||
var amtDesktop = null;
|
||||
var playing = false;
|
||||
var readState = 0;
|
||||
var waitTimer = null;
|
||||
var waitTimerArgs = null;
|
||||
var deskAspectRatio = 0;
|
||||
var currentDeltaTimeTotalSec = 0;
|
||||
|
||||
function start() {
|
||||
window.onresize = deskAdjust;
|
||||
document.ondrop = ondrop;
|
||||
document.ondragover = ondragover;
|
||||
document.ondragleave = ondragleave;
|
||||
document.onkeypress = onkeypress;
|
||||
Q('PlaySpeed').value = 1;
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function readNextBlock(func) {
|
||||
if ((recFilePtr + 16) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((recFilePtr + 16 + size) > recFile.size) { QS('progressbar').width = '100%'; func(-1); } else {
|
||||
var fr2 = new FileReader();
|
||||
fr2.onload = function () {
|
||||
recFilePtr += (16 + size);
|
||||
if (recFileEndTime == 0) {
|
||||
// File pointer progress bar
|
||||
QS('progressbar').width = Math.floor(100 * (recFilePtr / recFile.size)) + '%';
|
||||
} else {
|
||||
// Time progress bar
|
||||
QS('progressbar').width = Math.floor(((recFileLastTime - recFileStartTime) / (recFileEndTime - recFileStartTime)) * 100) + '%';
|
||||
}
|
||||
func(type, flags, time, this.result);
|
||||
};
|
||||
fr2.readAsBinaryString(recFile.slice(recFilePtr + 16, recFilePtr + 16 + size));
|
||||
}
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFilePtr, recFilePtr + 16));
|
||||
}
|
||||
}
|
||||
|
||||
function readLastBlock(func) {
|
||||
if (recFile.size < 32) { func(-1); } else {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function () {
|
||||
var type = ReadShort(this.result, 0);
|
||||
var flags = ReadShort(this.result, 2);
|
||||
var size = ReadInt(this.result, 4);
|
||||
var time = (ReadInt(this.result, 8) << 32) + ReadInt(this.result, 12);
|
||||
if ((type == 3) && (size == 16) && (this.result.substring(16, 32) == 'MeshCentralMCREC')) { func(type, flags, time); } else { func(-1); }
|
||||
};
|
||||
fr.readAsBinaryString(recFile.slice(recFile.size - 32, recFile.size));
|
||||
}
|
||||
}
|
||||
|
||||
function addInfo(name, value) { if (value == null) return ''; return addInfoNoEsc(name, EscapeHtml(value)); }
|
||||
|
||||
function addInfoNoEsc(name, value) {
|
||||
if (value == null) return '';
|
||||
return '<span style=color:gray>' + EscapeHtml(name) + '</span>: <span style=font-size:20px>' + value + '</span><br/>';
|
||||
}
|
||||
|
||||
function processFirstBlock(type, flags, time, data) {
|
||||
recFileProtocol = 0;
|
||||
if ((type != 1) || (flags != 0)) { cleanup(); return; }
|
||||
try { recFileMetadata = JSON.parse(data) } catch (ex) { cleanup(); return; }
|
||||
if ((recFileMetadata == null) || (recFileMetadata.magic != 'MeshCentralRelaySession') || (recFileMetadata.ver != 1)) { cleanup(); return; }
|
||||
var x = '';
|
||||
x += addInfo("Tempo", recFileMetadata.time);
|
||||
if (recFileEndTime != 0) { var secs = Math.floor((recFileEndTime - time) / 1000); x += addInfo("Duração", format("{0} segundo{1}", secs, (secs > 1) ? 's' : '')); }
|
||||
x += addInfo("Nome de usuário", recFileMetadata.username);
|
||||
x += addInfo("ID do usuário", recFileMetadata.userid);
|
||||
x += addInfo("ID da sessão", recFileMetadata.sessionid);
|
||||
if (recFileMetadata.ipaddr1 && recFileMetadata.ipaddr2) { x += addInfo("Endereços", format("{0} para {1}", recFileMetadata.ipaddr1, recFileMetadata.ipaddr2)); }
|
||||
if (recFileMetadata.devicename) { x += addInfo("Nome do Dispositivo", recFileMetadata.devicename); }
|
||||
x += addInfo("NodeID", recFileMetadata.nodeid);
|
||||
if (recFileMetadata.protocol) {
|
||||
var p = recFileMetadata.protocol;
|
||||
if (p == 1) { p = "MeshCentral Terminal"; }
|
||||
else if (p == 2) { p = "MeshCentral Desktop"; }
|
||||
else if (p == 100) { p = "Intel® AMT WSMAN"; }
|
||||
else if (p == 101) { p = "Intel® Redirecionamento AMT"; }
|
||||
x += addInfoNoEsc("Protocolo", p);
|
||||
}
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (recFileMetadata.protocol == 1) {
|
||||
// MeshCentral remote terminal
|
||||
recFileProtocol = 1;
|
||||
x += '<br /><br /><span style=color:gray>' + "Pressione [espaço] para reproduzir / pausar." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
}
|
||||
else if (recFileMetadata.protocol == 2) {
|
||||
// MeshCentral remote desktop
|
||||
recFileProtocol = 2;
|
||||
x += '<br /><br /><span style=color:gray>' + "Pressione [espaço] para reproduzir / pausar." + '</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
agentDesktop = CreateAgentRemoteDesktop('Desk');
|
||||
agentDesktop.onScreenSizeChange = deskAdjust;
|
||||
agentDesktop.State = 3;
|
||||
deskAdjust();
|
||||
}
|
||||
else if (recFileMetadata.protocol == 101) {
|
||||
// Intel AMT Redirection
|
||||
recFileProtocol = 101;
|
||||
x += '<br /><br /><span style=color:gray>Press [space] to play/pause.</span>';
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
recFileStartTime = recFileLastTime = time;
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
deskAdjust();
|
||||
}
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', x);
|
||||
QH('deskstatus', recFile.name);
|
||||
}
|
||||
|
||||
function processBlock(type, flags, time, data) {
|
||||
if (type < 0) { pause(); return; }
|
||||
var waitTime = Math.round((time - recFileLastTime) * parseFloat(Q('PlaySpeed').value));
|
||||
if (waitTime < 5) {
|
||||
processBlockEx(type, flags, time, data);
|
||||
} else {
|
||||
waitTimerArgs = [type, flags, time, data]
|
||||
waitTimer = setTimeout(function () { waitTimer = null; processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]); }, waitTime);
|
||||
}
|
||||
}
|
||||
|
||||
function processBlockEx(type, flags, time, data) {
|
||||
if (playing == false) return;
|
||||
var flagBinary = (flags & 1) != 0, flagUser = (flags & 2) != 0;
|
||||
|
||||
// Update the clock
|
||||
var deltaTimeTotalSec = Math.floor((time - recFileStartTime) / 1000);
|
||||
if (currentDeltaTimeTotalSec != deltaTimeTotalSec) {
|
||||
currentDeltaTimeTotalSec = deltaTimeTotalSec;
|
||||
var deltaTimeHours = Math.floor(deltaTimeTotalSec / 3600);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 3600)
|
||||
var deltaTimeMinutes = Math.floor(deltaTimeTotalSec / 60);
|
||||
deltaTimeTotalSec -= (deltaTimeHours * 60)
|
||||
var deltaTimeSeconds = Math.floor(deltaTimeTotalSec);
|
||||
QH('timespan', pad2(deltaTimeHours) + ':' + pad2(deltaTimeMinutes) + ':' + pad2(deltaTimeSeconds))
|
||||
}
|
||||
|
||||
if ((type == 2) && flagBinary && !flagUser) {
|
||||
// Device --> User data
|
||||
if (recFileProtocol == 1) {
|
||||
// MeshCentral Terminal
|
||||
agentTerminal.ProcessData(data);
|
||||
} else if (recFileProtocol == 2) {
|
||||
// MeshCentral Remote Desktop
|
||||
agentDesktop.ProcessData(data);
|
||||
} else if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if ((readState == 0) && (rstr2hex(data) == '4100000000000000')) {
|
||||
// We are not authenticated, KVM data starts here.
|
||||
readState = 1;
|
||||
if (data.length > 8) { amtDesktop.ProcessData(data.substring(8)); }
|
||||
} else if (readState == 1) {
|
||||
amtDesktop.ProcessData(data);
|
||||
}
|
||||
}
|
||||
} else if ((type == 2) && flagBinary && flagUser) {
|
||||
// User --> Device data
|
||||
if (recFileProtocol == 101) {
|
||||
// Intel AMT KVM
|
||||
if (rstr2hex(data) == '0000000008080001000700070003050200000000') { amtDesktop.bpp = 1; } // Switch to 1 byte per pixel.
|
||||
}
|
||||
}
|
||||
|
||||
recFileLastTime = time;
|
||||
if (playing) { readNextBlock(processBlock); }
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
recFile = null;
|
||||
recFilePtr = 0;
|
||||
recFileMetadata = null;
|
||||
playing = false;
|
||||
if (agentDesktop != null) { agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height); agentDesktop = null; }
|
||||
if (amtDesktop != null) { amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height); amtDesktop = null; }
|
||||
readState = 0;
|
||||
waitTimerArgs = null;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
recFileEndTime = 0;
|
||||
agentTerminal = null;
|
||||
if (waitTimer != null) { clearTimeout(waitTimer); waitTimer = null; }
|
||||
QH('deskstatus', '');
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('metadatadiv', true);
|
||||
QH('metadatadiv', '<span style=\"font-family:Arial,Helvetica Neue,Helvetica,sans-serif;font-size:28px\">MeshCentral Session Player</span><br /><br /><span style=color:gray>' + "Arraste e solte um arquivo .mcrec ou clique em \"Abrir arquivo...\"" + '</span>');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
}
|
||||
|
||||
function ondrop(e) {
|
||||
haltEvent(e);
|
||||
QV('bigfail', false);
|
||||
QV('bigok', false);
|
||||
|
||||
// Check if these are files we can upload, remove all folders.
|
||||
if (e.dataTransfer == null) return;
|
||||
var files = [];
|
||||
for (var i in e.dataTransfer.files) {
|
||||
if ((e.dataTransfer.files[i].type != null) && (e.dataTransfer.files[i].size != null) && (e.dataTransfer.files[i].size != 0) && (e.dataTransfer.files[i].name.endsWith('.mcrec'))) {
|
||||
files.push(e.dataTransfer.files[i]);
|
||||
}
|
||||
}
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
}
|
||||
|
||||
var dragtimer = null;
|
||||
function ondragover(e) {
|
||||
haltEvent(e);
|
||||
if (dragtimer != null) { clearTimeout(dragtimer); dragtimer = null; }
|
||||
var ac = true;
|
||||
QV('bigok', ac);
|
||||
QV('bigfail', !ac);
|
||||
}
|
||||
|
||||
function ondragleave(e) {
|
||||
haltEvent(e);
|
||||
dragtimer = setTimeout(function () { QV('bigfail', false); QV('bigok', false); dragtimer = null; }, 10);
|
||||
}
|
||||
|
||||
function onkeypress(e) {
|
||||
if (xxdialogMode) return;
|
||||
if (e.key == ' ') { togglePause(); haltEvent(e); }
|
||||
if (e.key == '1') { Q('PlaySpeed').value = 4; haltEvent(e); }
|
||||
if (e.key == '2') { Q('PlaySpeed').value = 2; haltEvent(e); }
|
||||
if (e.key == '3') { Q('PlaySpeed').value = 1; haltEvent(e); }
|
||||
if (e.key == '4') { Q('PlaySpeed').value = 0.5; haltEvent(e); }
|
||||
if (e.key == '5') { Q('PlaySpeed').value = 0.25; haltEvent(e); }
|
||||
if (e.key == '6') { Q('PlaySpeed').value = 0.1; haltEvent(e); }
|
||||
if (e.key == '0') { pause(); restart(); haltEvent(e); }
|
||||
}
|
||||
|
||||
function openfile() {
|
||||
var x = '<input type=file name=files id=p2fileinput style=width:100% accept=".mcrec" onchange="openfileChanged()" />';
|
||||
setDialogMode(2, "Abrir arquivo...", 3, openfileEx, x);
|
||||
QE('idx_dlgOkButton', false);
|
||||
}
|
||||
|
||||
function openfileEx() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
if (files.length == 0) return;
|
||||
cleanup();
|
||||
recFile = files[0];
|
||||
recFilePtr = 0;
|
||||
readNextBlock(processFirstBlock);
|
||||
readLastBlock(function (type, flags, time) { if (type == 3) { recFileEndTime = time; } else { recFileEndTime = 0; } });
|
||||
Q('OpenFileButton').blur();
|
||||
}
|
||||
|
||||
function openfileChanged() {
|
||||
var xfiles = Q('p2fileinput').files;
|
||||
if (xfiles != null) { var files = []; for (var i in xfiles) { if ((xfiles[i].type != null) && (xfiles[i].size != null) && (xfiles[i].size != 0) && (xfiles[i].name.endsWith('.mcrec'))) { files.push(xfiles[i]); } } }
|
||||
QE('idx_dlgOkButton', files.length == 1);
|
||||
}
|
||||
|
||||
function togglePause() {
|
||||
if (recFile != null) { if (playing == true) { pause(); } else { if (recFilePtr != recFile.size) { play(); } } } return false;
|
||||
}
|
||||
|
||||
function play() {
|
||||
Q('PlayButton').blur();
|
||||
if ((playing == true) || (recFileProtocol == 0)) return;
|
||||
playing = true;
|
||||
QV('metadatadiv', false);
|
||||
QE('PlayButton', false);
|
||||
QE('PauseButton', true);
|
||||
QE('RestartButton', false);
|
||||
if ((recFileProtocol == 1) && (agentTerminal == null)) {
|
||||
QV('DeskParent', false);
|
||||
QV('TermParent', true);
|
||||
agentTerminal = CreateAmtRemoteTerminal('Term', {});
|
||||
agentTerminal.State = 3;
|
||||
}
|
||||
readNextBlock(processBlock);
|
||||
}
|
||||
|
||||
function pause() {
|
||||
Q('PauseButton').blur();
|
||||
if (playing == false) return;
|
||||
playing = false;
|
||||
QE('PlayButton', recFilePtr != recFile.size);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', recFilePtr != 0);
|
||||
if (waitTimer != null) {
|
||||
clearTimeout(waitTimer);
|
||||
waitTimer = null;
|
||||
processBlockEx(waitTimerArgs[0], waitTimerArgs[1], waitTimerArgs[2], waitTimerArgs[3]);
|
||||
waitTimerArgs = null;
|
||||
}
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Q('RestartButton').blur();
|
||||
if (playing == true) return;
|
||||
recFilePtr = 0;
|
||||
readState = 0;
|
||||
currentDeltaTimeTotalSec = 0;
|
||||
QV('metadatadiv', true);
|
||||
QE('PlayButton', true);
|
||||
QE('PauseButton', false);
|
||||
QE('RestartButton', false);
|
||||
QS('progressbar').width = '0px';
|
||||
QH('timespan', '00:00:00');
|
||||
QV('DeskParent', true);
|
||||
QV('TermParent', false);
|
||||
if (agentDesktop) {
|
||||
agentDesktop.Canvas.clearRect(0, 0, agentDesktop.CanvasId.width, agentDesktop.CanvasId.height);
|
||||
} else if (amtDesktop) {
|
||||
amtDesktop.canvas.clearRect(0, 0, amtDesktop.CanvasId.width, amtDesktop.CanvasId.height);
|
||||
amtDesktop = CreateAmtRemoteDesktop('Desk');
|
||||
amtDesktop.onScreenSizeChange = deskAdjust;
|
||||
amtDesktop.State = 3;
|
||||
amtDesktop.Start();
|
||||
} else if (agentTerminal) {
|
||||
agentTerminal = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleAspectRatio(toggle) {
|
||||
if (toggle === 1) { deskAspectRatio = ((deskAspectRatio + 1) % 3); }
|
||||
deskAdjust();
|
||||
}
|
||||
|
||||
function deskAdjust() {
|
||||
var parentH = Q('DeskParent').clientHeight, parentW = Q('DeskParent').clientWidth;
|
||||
var deskH = Q('Desk').height, deskW = Q('Desk').width;
|
||||
|
||||
if (deskAspectRatio == 2) {
|
||||
// Scale mode
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('Desk').height = '100%';
|
||||
QS('Desk').width = '100%';
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
} else if (deskAspectRatio == 1) {
|
||||
// Zoomed mode
|
||||
QS('Desk')['margin-top'] = '0px';
|
||||
//QS('Desk')['margin-left'] = '0px';
|
||||
QS('Desk').height = deskH + 'px';
|
||||
QS('Desk').width = deskW + 'px';
|
||||
QS('DeskParent').overflow = 'scroll';
|
||||
} else {
|
||||
// Fixed aspect ratio
|
||||
if ((parentH / parentW) > (deskH / deskW)) {
|
||||
var hNew = ((deskH * parentW) / deskW) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('deskarea3x').height = null;
|
||||
//} else {
|
||||
// QS('deskarea3x').height = hNew;
|
||||
//QS('deskarea3x').height = null;
|
||||
//}
|
||||
QS('Desk').height = hNew;
|
||||
QS('Desk').width = '100%';
|
||||
} else {
|
||||
var wNew = ((deskW * parentH) / deskH) + 'px';
|
||||
//if (webPageFullScreen || fullscreen) {
|
||||
//QS('Desk').height = null;
|
||||
//} else {
|
||||
QS('Desk').height = '100%';
|
||||
//}
|
||||
QS('Desk').width = wNew;
|
||||
}
|
||||
QS('Desk')['margin-top'] = null;
|
||||
QS('DeskParent').overflow = 'hidden';
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// null = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = -1;
|
||||
|
||||
// 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) {
|
||||
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_dlgDeleteButton', b & 4);
|
||||
QV('idx_dlgButtonBar', b & 7);
|
||||
if (y) QH('id_dialogtitle', y);
|
||||
for (var i = 1; i < 3; 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) {
|
||||
var f = xxdialogFunc, b = xxdialogButtons, t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function messagebox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
|
||||
function statusbox(t, m) { setSessionActivity(); QH('id_dialogMessage', m); setDialogMode(1, t); }
|
||||
function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
|
||||
function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); }
|
||||
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; }); };
|
||||
|
||||
start();
|
||||
</script>
|
||||
|
||||
</body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,295 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}} - Agent Installation</title>
|
||||
<style>
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Výběr rozhraní uživatele" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Rozhraní levé lišty"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Rozhraní horní lišty"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Rozhraní s pevnou šířkou"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Přepnout na noční mód"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<h1>Instalace agenta pro vzdálený přístup<span id="groupname"></span></h1>
|
||||
<p>
|
||||
Byla vám doručena pozvánka k instalaci softwaru, který umožňuje vzdálenou správu zařízení.
|
||||
Postupujte podle níže uvedených pokynů, pokud jste si vědom toho, že tato pozvánka je legitimní a chcete tento přístup umožnit.
|
||||
Vyberte si operační systém a postupujte dle pokynů níže.
|
||||
</p>
|
||||
<div>
|
||||
<div class="tab">
|
||||
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64bit</button>
|
||||
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32bit</button>
|
||||
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
|
||||
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">MacOS</button>
|
||||
</div>
|
||||
|
||||
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 64bit</h3>
|
||||
<p><a id="win64url">Stáhnout software zde</a>, spusťte soubor a zvolte "Install" nebo "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 32bit</h3>
|
||||
<p><a id="win32url">Stáhnout software zde</a>, spusťte soubor a zvolte "Install" nebo "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Linux</h3>
|
||||
<p>Pro instalaci spusťte následující příkaz s právy uživatele root.</p>
|
||||
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Zkopírovat do schránky" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
|
||||
<p>Pro odinstalování spustťe tento příkaz pod s uživatelskými právy root.</p>
|
||||
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Zkopírovat do schránky" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Apple™ MacOS</h3>
|
||||
<p><a id="macosurl">Stáhnout instalaci zde</a>, poté spusťe instalaci. Postupujte dle instrukcí.</p>
|
||||
<div style="text-align:center">
|
||||
<img src="images/macosagent.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var meshid = '{{{meshid}}}';
|
||||
var serverPort = '{{{serverport}}}';
|
||||
var serverHttps = '{{{serverhttps}}}';
|
||||
var serverNoProxy = '{{{servernoproxy}}}';
|
||||
var installFlags = '{{{installflags}}}';
|
||||
var groupName = decodeURIComponent('{{{meshname}}}');
|
||||
if (groupName != '') { QH('groupname', ' for ' + groupName); }
|
||||
userInterfaceSelectMenu();
|
||||
setup();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 openTab(evt, tabname) {
|
||||
// Declare all variables
|
||||
var i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
document.getElementById(tabname).style.display = 'block';
|
||||
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
|
||||
}
|
||||
|
||||
var linuxInstall, linuxUnInstall;
|
||||
function setup() {
|
||||
var servername = window.location.hostname;
|
||||
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
|
||||
|
||||
// Windows 64bit Setup
|
||||
var url = 'meshagents?id=4&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win64url').href = url;
|
||||
|
||||
// Windows 32bit Setup
|
||||
url = 'meshagents?id=3&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win32url').href = url;
|
||||
|
||||
// MacOS Setup
|
||||
url = 'meshosxagent?id=16&meshid=' + meshid;
|
||||
Q('macosurl').href = url;
|
||||
|
||||
// Linux Setup
|
||||
if (serverHttps == 1) {
|
||||
var portStr = (serverPort == 443) ? '' : (":" + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
} else {
|
||||
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
}
|
||||
QH('linuxinstall', linuxInstall);
|
||||
QH('unlinuxinstall', linuxUnInstall);
|
||||
|
||||
// Attempt to detect the most likely operating system for this browser
|
||||
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
|
||||
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
|
||||
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
|
||||
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
|
||||
else { openTab(null, 'wintab64'); }
|
||||
}
|
||||
|
||||
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
|
||||
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
|
||||
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,295 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}} - Agent Installation</title>
|
||||
<style>
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="User interface selection" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Left bar interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Top bar interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface à largeur fixe"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Basculer mode nuit"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<h1>Installation de l'agent<span id="groupname"></span></h1>
|
||||
<p>
|
||||
You have been invited to install a software that will allow a remote operator to fully access your computer remotely including the desktop and files.
|
||||
Only follow the instructions below if this invitation was expected and you know who will be accessing your computer.
|
||||
Selecting your operation system and follow the instructions below.
|
||||
</p>
|
||||
<div>
|
||||
<div class="tab">
|
||||
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64bit</button>
|
||||
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32bit</button>
|
||||
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
|
||||
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">MacOS</button>
|
||||
</div>
|
||||
|
||||
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 64bit</h3>
|
||||
<p><a id="win64url">Download the software here</a>, run it and press "Install" or "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 32bit</h3>
|
||||
<p><a id="win32url">Download the software here</a>, run it and press "Install" or "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Linux</h3>
|
||||
<p>To install, cut and paste the following command in a root terminal.</p>
|
||||
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Copy to clipboard" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
|
||||
<p>To uninstall, cut and paste the following command as root.</p>
|
||||
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Copy to clipboard" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Apple™ MacOS</h3>
|
||||
<p><a id="macosurl">Download the installer here</a>, right click on it or press "control" and click on the file. Then select "Open" and follow the instructions.</p>
|
||||
<div style="text-align:center">
|
||||
<img src="images/macosagent.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var meshid = '{{{meshid}}}';
|
||||
var serverPort = '{{{serverport}}}';
|
||||
var serverHttps = '{{{serverhttps}}}';
|
||||
var serverNoProxy = '{{{servernoproxy}}}';
|
||||
var installFlags = '{{{installflags}}}';
|
||||
var groupName = decodeURIComponent('{{{meshname}}}');
|
||||
if (groupName != '') { QH('groupname', ' for ' + groupName); }
|
||||
userInterfaceSelectMenu();
|
||||
setup();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 openTab(evt, tabname) {
|
||||
// Declare all variables
|
||||
var i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
document.getElementById(tabname).style.display = 'block';
|
||||
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
|
||||
}
|
||||
|
||||
var linuxInstall, linuxUnInstall;
|
||||
function setup() {
|
||||
var servername = window.location.hostname;
|
||||
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
|
||||
|
||||
// Windows 64bit Setup
|
||||
var url = 'meshagents?id=4&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win64url').href = url;
|
||||
|
||||
// Windows 32bit Setup
|
||||
url = 'meshagents?id=3&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win32url').href = url;
|
||||
|
||||
// MacOS Setup
|
||||
url = 'meshosxagent?id=16&meshid=' + meshid;
|
||||
Q('macosurl').href = url;
|
||||
|
||||
// Linux Setup
|
||||
if (serverHttps == 1) {
|
||||
var portStr = (serverPort == 443) ? '' : (":" + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
} else {
|
||||
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
}
|
||||
QH('linuxinstall', linuxInstall);
|
||||
QH('unlinuxinstall', linuxUnInstall);
|
||||
|
||||
// Attempt to detect the most likely operating system for this browser
|
||||
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
|
||||
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
|
||||
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
|
||||
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
|
||||
else { openTab(null, 'wintab64'); }
|
||||
}
|
||||
|
||||
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
|
||||
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
|
||||
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,295 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}} - Agent Installation</title>
|
||||
<style>
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<h1>リモートエージェントのインストール<span id="groupname"></span></h1>
|
||||
<p>
|
||||
You have been invited to install a software that will allow a remote operator to fully access your computer remotely including the desktop and files.
|
||||
Only follow the instructions below if this invitation was expected and you know who will be accessing your computer.
|
||||
Selecting your operation system and follow the instructions below.
|
||||
</p>
|
||||
<div>
|
||||
<div class="tab">
|
||||
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64ビット</button>
|
||||
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32ビット</button>
|
||||
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
|
||||
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">マックOS</button>
|
||||
</div>
|
||||
|
||||
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™Windows 64ビット</h3>
|
||||
<p><a id="win64url">ここからソフトウェアをダウンロードしてください</a>、実行して「インストール」または「接続」を押します。</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™Windows 32ビット</h3>
|
||||
<p><a id="win32url">ここからソフトウェアをダウンロードしてください</a>、実行して「インストール」または「接続」を押します。</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Linux</h3>
|
||||
<p>インストールするには、ルートターミナルで次のコマンドをカットアンドペーストします。</p>
|
||||
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="クリップボードにコピー" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
|
||||
<p>アンインストールするには、次のコマンドをルートとしてカットアンドペーストします。</p>
|
||||
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="クリップボードにコピー" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Apple™MacOS</h3>
|
||||
<p><a id="macosurl">ここからインストーラーをダウンロードしてください</a>、それを右クリックするか、「control」を押してファイルをクリックします。次に、「開く」を選択し、指示に従います。</p>
|
||||
<div style="text-align:center">
|
||||
<img src="images/macosagent.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var meshid = '{{{meshid}}}';
|
||||
var serverPort = '{{{serverport}}}';
|
||||
var serverHttps = '{{{serverhttps}}}';
|
||||
var serverNoProxy = '{{{servernoproxy}}}';
|
||||
var installFlags = '{{{installflags}}}';
|
||||
var groupName = decodeURIComponent('{{{meshname}}}');
|
||||
if (groupName != '') { QH('groupname', ' for ' + groupName); }
|
||||
userInterfaceSelectMenu();
|
||||
setup();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 openTab(evt, tabname) {
|
||||
// Declare all variables
|
||||
var i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
document.getElementById(tabname).style.display = 'block';
|
||||
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
|
||||
}
|
||||
|
||||
var linuxInstall, linuxUnInstall;
|
||||
function setup() {
|
||||
var servername = window.location.hostname;
|
||||
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
|
||||
|
||||
// Windows 64bit Setup
|
||||
var url = 'meshagents?id=4&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win64url').href = url;
|
||||
|
||||
// Windows 32bit Setup
|
||||
url = 'meshagents?id=3&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win32url').href = url;
|
||||
|
||||
// MacOS Setup
|
||||
url = 'meshosxagent?id=16&meshid=' + meshid;
|
||||
Q('macosurl').href = url;
|
||||
|
||||
// Linux Setup
|
||||
if (serverHttps == 1) {
|
||||
var portStr = (serverPort == 443) ? '' : (":" + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
} else {
|
||||
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
}
|
||||
QH('linuxinstall', linuxInstall);
|
||||
QH('unlinuxinstall', linuxUnInstall);
|
||||
|
||||
// Attempt to detect the most likely operating system for this browser
|
||||
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
|
||||
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
|
||||
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
|
||||
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
|
||||
else { openTab(null, 'wintab64'); }
|
||||
}
|
||||
|
||||
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
|
||||
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
|
||||
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,293 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}} - Agent Installation</title>
|
||||
<style>
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Selectie gebruikersinterface" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Linkerbalk interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Boven werkbalk interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface met vaste breedte"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Wissel nachtmodus"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<h1>Remote Agent installatie<span id="groupname"></span></h1>
|
||||
<p>
|
||||
U bent uitgenodigd om software te installeren waarmee een externe operator op afstand volledige toegang heeft tot uw computer, inclusief het bureaublad en de bestanden. Volg de onderstaande instructies alleen als deze uitnodiging werd verwacht en u weet wie toegang krijgt tot uw computer. Selecteer uw besturingssysteem en volg de onderstaande instructies.
|
||||
</p>
|
||||
<div>
|
||||
<div class="tab">
|
||||
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64bit</button>
|
||||
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32bit</button>
|
||||
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
|
||||
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">MacOS</button>
|
||||
</div>
|
||||
|
||||
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 64bit</h3>
|
||||
<p><a id="win64url">Download de software hier</a>, open het en klik op "installeren" of "verbinden".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 32bit</h3>
|
||||
<p><a id="win32url">Download de software hier</a>, open het en klik op "installeren" of "verbinden".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Linux</h3>
|
||||
<p>Om de volgende opdracht te installeren, knippen en plakken in een root-terminal.</p>
|
||||
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Kopieer naar het klembord" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
|
||||
<p>Om de installatie ongedaan te maken, knip en plak je de volgende opdracht als root.</p>
|
||||
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Kopieer naar het klembord" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Apple™ MacOS</h3>
|
||||
<p><a id="macosurl">Download het installatieprogramma hier</a>, klik er met de rechtermuisknop op of druk op "beheer" en klik op het bestand. Daarna op "open" en volg de instructies.</p>
|
||||
<div style="text-align:center">
|
||||
<img src="images/macosagent.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var meshid = '{{{meshid}}}';
|
||||
var serverPort = '{{{serverport}}}';
|
||||
var serverHttps = '{{{serverhttps}}}';
|
||||
var serverNoProxy = '{{{servernoproxy}}}';
|
||||
var installFlags = '{{{installflags}}}';
|
||||
var groupName = decodeURIComponent('{{{meshname}}}');
|
||||
if (groupName != '') { QH('groupname', ' for ' + groupName); }
|
||||
userInterfaceSelectMenu();
|
||||
setup();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 openTab(evt, tabname) {
|
||||
// Declare all variables
|
||||
var i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
document.getElementById(tabname).style.display = 'block';
|
||||
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
|
||||
}
|
||||
|
||||
var linuxInstall, linuxUnInstall;
|
||||
function setup() {
|
||||
var servername = window.location.hostname;
|
||||
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
|
||||
|
||||
// Windows 64bit Setup
|
||||
var url = 'meshagents?id=4&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win64url').href = url;
|
||||
|
||||
// Windows 32bit Setup
|
||||
url = 'meshagents?id=3&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win32url').href = url;
|
||||
|
||||
// MacOS Setup
|
||||
url = 'meshosxagent?id=16&meshid=' + meshid;
|
||||
Q('macosurl').href = url;
|
||||
|
||||
// Linux Setup
|
||||
if (serverHttps == 1) {
|
||||
var portStr = (serverPort == 443) ? '' : (":" + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
} else {
|
||||
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
}
|
||||
QH('linuxinstall', linuxInstall);
|
||||
QH('unlinuxinstall', linuxUnInstall);
|
||||
|
||||
// Attempt to detect the most likely operating system for this browser
|
||||
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
|
||||
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
|
||||
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
|
||||
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
|
||||
else { openTab(null, 'wintab64'); }
|
||||
}
|
||||
|
||||
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
|
||||
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
|
||||
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,295 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}} - Agent Installation</title>
|
||||
<style>
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #8f8;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:14px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
<p id="logoutControl" style="color:white;font-size:11px;margin: 10px 10px 0;">{{{logoutControl}}}</p>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Seleção da interface do usuário" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Interface da barra esquerda"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Interface da barra superior"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface de largura fixa"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Alternar modo noturno"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<h1>Instalação remota do agente<span id="groupname"></span></h1>
|
||||
<p>
|
||||
Você foi convidado a instalar um software que permitirá que um operador remoto acesse totalmente seu computador remotamente, incluindo a área de trabalho e os arquivos.
|
||||
Siga apenas as instruções abaixo se esse convite for esperado e você sabe quem acessará seu computador.
|
||||
Selecionando seu sistema operacional e siga as instruções abaixo.
|
||||
</p>
|
||||
<div>
|
||||
<div class="tab">
|
||||
<button id="twintab64" class="tablinks" onclick="openTab(event, 'wintab64')">Windows 64 Bits</button>
|
||||
<button id="twintab32" class="tablinks" onclick="openTab(event, 'wintab32')">Windows 32 Bits</button>
|
||||
<button id="tlinuxtab" class="tablinks" onclick="openTab(event, 'linuxtab')">Linux</button>
|
||||
<button id="tmacostab" class="tablinks" onclick="openTab(event, 'macostab')">MacOS</button>
|
||||
</div>
|
||||
|
||||
<div id="wintab64" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 64 bits</h3>
|
||||
<p><a id="win64url">Faça o download do software aqui</a>, execute-o e pressione "Install" or "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wintab32" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Microsoft™ Windows 32 bits</h3>
|
||||
<p><a id="win32url">Faça o download do software aqui</a>, execute-o e pressione "Install" or "Connect".</p>
|
||||
<div style="text-align:center">
|
||||
<img class="winagent-img" src="images/winagent.png">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="linuxtab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Linux</h3>
|
||||
<p>Para instalar, recorte e cole o seguinte comando em um terminal raiz.</p>
|
||||
<div id="linuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Copiar para área de transferência" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxInstall()">
|
||||
<p>Para desinstalar, recorte e cole o seguinte comando como raiz.</p>
|
||||
<div id="unlinuxinstall" style="font-family:courier,'courier new',monospace;margin-left:30px"></div>
|
||||
<input type="button" value="Copiar para área de transferência" style="margin-left:30px;margin-top:4px" onclick="copyToClipLinuxUnInstall()">
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
<div id="macostab" class="tabcontent" style="background-color:white;color:black">
|
||||
<h3>Apple™ MacOS</h3>
|
||||
<p><a id="macosurl">Faça o download do instalador aqui</a>, clique com o botão direito do mouse ou pressione "control".Em seguida, selecione "Open".</p>
|
||||
<div style="text-align:center">
|
||||
<img src="images/macosagent.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var meshid = '{{{meshid}}}';
|
||||
var serverPort = '{{{serverport}}}';
|
||||
var serverHttps = '{{{serverhttps}}}';
|
||||
var serverNoProxy = '{{{servernoproxy}}}';
|
||||
var installFlags = '{{{installflags}}}';
|
||||
var groupName = decodeURIComponent('{{{meshname}}}');
|
||||
if (groupName != '') { QH('groupname', ' for ' + groupName); }
|
||||
userInterfaceSelectMenu();
|
||||
setup();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 openTab(evt, tabname) {
|
||||
// Declare all variables
|
||||
var i, tabcontent, tablinks;
|
||||
|
||||
// Get all elements with class="tabcontent" and hide them
|
||||
tabcontent = document.getElementsByClassName('tabcontent');
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = 'none';
|
||||
}
|
||||
|
||||
// Get all elements with class="tablinks" and remove the class "active"
|
||||
tablinks = document.getElementsByClassName('tablinks');
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(' active', '');
|
||||
}
|
||||
|
||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||
document.getElementById(tabname).style.display = 'block';
|
||||
if (evt != null) { evt.currentTarget.className += ' active'; } else { document.getElementById('t' + tabname).className += ' active'; }
|
||||
}
|
||||
|
||||
var linuxInstall, linuxUnInstall;
|
||||
function setup() {
|
||||
var servername = window.location.hostname;
|
||||
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
|
||||
|
||||
// Windows 64bit Setup
|
||||
var url = 'meshagents?id=4&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win64url').href = url;
|
||||
|
||||
// Windows 32bit Setup
|
||||
url = 'meshagents?id=3&meshid=' + meshid;
|
||||
if (installFlags != 0) { url += ('&installflags=' + installFlags); }
|
||||
Q('win32url').href = url;
|
||||
|
||||
// MacOS Setup
|
||||
url = 'meshosxagent?id=16&meshid=' + meshid;
|
||||
Q('macosurl').href = url;
|
||||
|
||||
// Linux Setup
|
||||
if (serverHttps == 1) {
|
||||
var portStr = (serverPort == 443) ? '' : (":" + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-check-certificate -O ./meshinstall.sh || wget https://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget https://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
} else {
|
||||
var portStr = (serverPort == 80) ? '' : (':' + serverPort);
|
||||
if (serverNoProxy == 0) {
|
||||
linuxInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = '(wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 -O ./meshinstall.sh || wget http://" + servername + portStr + domainUrl + "meshagents?script=1 --no-proxy -O ./meshinstall.sh) && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
} else {
|
||||
// Server asked that agent be installed to preferably not use a HTTP proxy.
|
||||
linuxInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://' + servername + portStr + domainUrlNoSlash + ' \'' + meshid + '\'\r\n';
|
||||
linuxUnInstall = 'wget http://' + servername + portStr + domainUrl + 'meshagents?script=1 --no-proxy -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n';
|
||||
}
|
||||
}
|
||||
QH('linuxinstall', linuxInstall);
|
||||
QH('unlinuxinstall', linuxUnInstall);
|
||||
|
||||
// Attempt to detect the most likely operating system for this browser
|
||||
if (navigator.userAgent.indexOf('Win64') >= 0) { openTab(null, 'wintab64'); }
|
||||
else if (navigator.userAgent.indexOf('Windows') >= 0) { openTab(null, 'wintab32'); }
|
||||
else if (navigator.userAgent.indexOf('Linux') >= 0) { openTab(null, 'linuxtab'); }
|
||||
else if (navigator.userAgent.indexOf('Macintosh') >= 0) { openTab(null, 'macostab'); }
|
||||
else { openTab(null, 'wintab64'); }
|
||||
}
|
||||
|
||||
function copyToClipLinuxInstall() { copyTextToClip(linuxInstall); }
|
||||
function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); }
|
||||
function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title1}}} - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>Stažení</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} <a href=terms>Podmínky & soukromí</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title1}}} - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>Télécharger</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} <a href=terms>Terms & Privacy</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title1}}} - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>ダウンロード</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} <a href=terms>利用規約とプライバシー</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title1}}} - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>Download</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} <a href=terms>Voorwaarden & Privacy</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title1}}} - Download</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>Baixar</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right>{{{rootCertLink}}} <a href=terms>Termos & Privacidade</a></table></div></div></div>
|
@ -1,42 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title1}}} - Download</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>Stažení</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Podmínky & soukromí</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,42 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title1}}} - Download</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>Télécharger</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Terms & Privacy</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,42 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title1}}} - Download</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>ダウンロード</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">利用規約とプライバシー</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,42 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title1}}} - Download</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>Download</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Voorwaarden & Privacy</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,42 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title1}}} - Download</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>Baixar</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Termos & Privacidade</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>{{{title}}}</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:16px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title="Výběr rozhraní uživatele"onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title="Rozhraní levé lišty"><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title="Rozhraní horní lišty"><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title="Rozhraní s pevnou šířkou"><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title="Přepnout na noční mód"><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>Tato stránka neexistuje</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Zpět na hlavní stránku</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >Zpět</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>{{{title}}}</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:16px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title="User interface selection"onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title="Left bar interface"><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title="Top bar interface"><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title="Interface à largeur fixe"><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title="Basculer mode nuit"><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>This page does not exist</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Aller sur le site principal</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >Retour</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>{{{title}}}</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:16px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title=ユーザーインターフェイスの選択 onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title=左バーインターフェイス><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title=トップバーインターフェース><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title=固定幅インターフェイス><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title=ナイトモードを切り替える><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>このページは存在しません</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>メインサイトに行く</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >バック</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>{{{title}}}</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:16px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title="Selectie gebruikersinterface"onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title="Linkerbalk interface"><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title="Boven werkbalk interface"><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title="Interface met vaste breedte"><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title="Wissel nachtmodus"><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>This page does not exist</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Ga naar hoofdsite</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >Terug</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=styles/style.css media=screen rel=stylesheet title=CSS><script src=scripts/common-0.0.1.js></script><title>{{{title}}}</title><body id=body onload='"undefined"!=typeof startup&&startup()'style=display:none;overflow:hidden><div id=container><div id=masthead class=noselect style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:16px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_leftbar><div style=height:16px></div></div><div id=topbar class="noselect style3"style=height:24px;position:relative><div id=uiMenuButton title="Seleção da interface do usuário"onclick=showUserInterfaceSelectMenu()>♦<div id=uiMenu style=display:none><div id=uiViewButton1 class=uiSelector onclick=userInterfaceSelectMenu(1) title="Interface da barra esquerda"><div class=uiSelector1></div></div><div id=uiViewButton2 class=uiSelector onclick=userInterfaceSelectMenu(2) title="Interface da barra superior"><div class=uiSelector2></div></div><div id=uiViewButton3 class=uiSelector onclick=userInterfaceSelectMenu(3) title="Interface de largura fixa"><div class=uiSelector3></div></div><div id=uiViewButton4 class=uiSelector onclick=toggleNightMode() title="Alternar modo noturno"><div class=uiSelector4></div></div></div></div></div><div id=column_l style="max-height:calc(100vh - 135px);overflow-y:auto"><div style=text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:20px;font-family:Arial;color:#999>Esta página não existe</div><div style=text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Ir para o site principal</b></a></div></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=/ >Voltar</a></table></div></div><script>"use strict";var uiMode=parseInt(getstore("uiMode",1)),webPageStackMenu=!1,webPageFullScreen=!0,nightMode="1"==getstore("_nightMode","0"),terms="{{{terms}}}";function showUserInterfaceSelectMenu(){Q("uiViewButton1").classList.remove("uiSelectorSel"),Q("uiViewButton2").classList.remove("uiSelectorSel"),Q("uiViewButton3").classList.remove("uiSelectorSel"),Q("uiViewButton4").classList.remove("uiSelectorSel");try{Q("uiViewButton"+uiMode).classList.add("uiSelectorSel")}catch(e){}QV("uiMenu","none"==QS("uiMenu").display),nightMode&&Q("uiViewButton4").classList.add("uiSelectorSel")}function userInterfaceSelectMenu(e){e&&putstore("uiMode",uiMode=e),webPageFullScreen=uiMode<3,webPageStackMenu=!0,toggleFullScreen(0),toggleStackMenu(0),QC("column_l").add("room4submenu")}function toggleNightMode(){(nightMode=!nightMode)?QC("body").add("night"):QC("body").remove("night"),putstore("_nightMode",nightMode?"1":"0")}function toggleFullScreen(e){1===e&&putstore("webPageFullScreen",webPageFullScreen=!webPageFullScreen);0==webPageFullScreen?(QC("body").remove("menu_stack"),QC("body").remove("fullscreen"),QC("body").remove("arg_hide")):QC("body").add("fullscreen"),QV("body",!0)}function toggleStackMenu(e){1==webPageFullScreen&&(1===e&&putstore("webPageStackMenu",webPageStackMenu=!webPageStackMenu),0==webPageStackMenu?QC("body").remove("menu_stack"):QC("body").add("menu_stack"))}function putstore(e,t){try{if("undefined"==typeof localStorage)return;localStorage.setItem(e,t)}catch(e){}}function getstore(e,t){try{if("undefined"==typeof localStorage)return t;var o=localStorage.getItem(e);return null==o||null==o?t:o}catch(e){return t}}""!=terms&&QH("column_l",decodeURIComponent(terms)),QV("column_l",!0),userInterfaceSelectMenu()</script>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>{{{title}}}</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><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:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>Tato stránka neexistuje</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Zpět na hlavní stránku</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}} <a href=/ >Zpět</a></table></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>{{{title}}}</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><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:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>This page does not exist</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Aller sur le site principal</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}} <a href=/ >Retour</a></table></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>{{{title}}}</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><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:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>このページは存在しません</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>メインサイトに行く</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}} <a href=/ >バック</a></table></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>{{{title}}}</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><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:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>This page does not exist</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Ga naar hoofdsite</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}} <a href=/ >Terug</a></table></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><title>{{{title}}}</title><style type=text/css>a{color:#036;text-decoration:underline}#footer a{color:#fff;text-decoration:underline}#footer a:hover{color:#fff;text-decoration:none}</style><body onload='"undefined"!=typeof startup&&startup()'style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:#000;font-size:13px;font-family:\'Trebuchet MS\',Arial,Helvetica,sans-serif"><div id=container><div id=masthead style="background:url(logo.png) 0 0;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"><div style=float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px><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:7px><strong><font style=font-size:12px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%><div id=column_l style=padding-left:10px;padding-right:10px><div style=text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb><b>404</b></div><div style=text-align:center;font-size:16px;font-family:Arial;color:#999>Esta página não existe</div><div style=text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999><a href=/ style=text-decoration:none><b>Ir para o site principal</b></a></div></div></div><div id=footer style=height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0><table cellpadding=0 cellspacing=6 style=width:100%><tr><td style=text-align:left;color:#fff>{{{footer}}}<td style=text-align:right>{{{rootCertLink}}} <a href=/ >Voltar</a></table></div></div>
|
@ -1,54 +0,0 @@
|
||||
<!DOCTYPE html><html><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">
|
||||
<title>{{{title}}}</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<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="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
|
||||
<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:7px">
|
||||
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
||||
<div id="column_l" style="padding-left:10px;padding-right:10px">
|
||||
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">Tato stránka neexistuje</div>
|
||||
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Zpět na hlavní stránku</b></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="/">Zpět</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,54 +0,0 @@
|
||||
<!DOCTYPE html><html><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">
|
||||
<title>{{{title}}}</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<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="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
|
||||
<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:7px">
|
||||
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
||||
<div id="column_l" style="padding-left:10px;padding-right:10px">
|
||||
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">This page does not exist</div>
|
||||
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Aller sur le site principal</b></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="/">Retour</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,54 +0,0 @@
|
||||
<!DOCTYPE html><html><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">
|
||||
<title>{{{title}}}</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<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="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
|
||||
<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:7px">
|
||||
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
||||
<div id="column_l" style="padding-left:10px;padding-right:10px">
|
||||
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">このページは存在しません</div>
|
||||
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>メインサイトに行く</b></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="/">バック</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,54 +0,0 @@
|
||||
<!DOCTYPE html><html><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">
|
||||
<title>{{{title}}}</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<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="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
|
||||
<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:7px">
|
||||
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
||||
<div id="column_l" style="padding-left:10px;padding-right:10px">
|
||||
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">This page does not exist</div>
|
||||
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Ga naar hoofdsite</b></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="/">Terug</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,54 +0,0 @@
|
||||
<!DOCTYPE html><html><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">
|
||||
<title>{{{title}}}</title>
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;max-width:100%;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<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="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:4px">
|
||||
<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:7px">
|
||||
<strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%">
|
||||
<div id="column_l" style="padding-left:10px;padding-right:10px">
|
||||
<div style="text-align:center;padding-top:30px;font-size:100px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:16px;font-family:Arial;color:#999">Esta página não existe</div>
|
||||
<div style="text-align:center;padding-top:16px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Ir para o site principal</b></a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="/">Voltar</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}}</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:16px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Výběr rozhraní uživatele" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Rozhraní levé lišty"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Rozhraní horní lišty"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Rozhraní s pevnou šířkou"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Přepnout na noční mód"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">Tato stránka neexistuje</div>
|
||||
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Zpět na hlavní stránku</b></a></div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"><a href="/">Zpět</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
|
||||
var terms = '{{{terms}}}';
|
||||
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
|
||||
QV('column_l', true);
|
||||
userInterfaceSelectMenu();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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; } }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}}</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:16px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="User interface selection" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Left bar interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Top bar interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface à largeur fixe"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Basculer mode nuit"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">This page does not exist</div>
|
||||
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Aller sur le site principal</b></a></div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"><a href="/">Retour</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
|
||||
var terms = '{{{terms}}}';
|
||||
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
|
||||
QV('column_l', true);
|
||||
userInterfaceSelectMenu();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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; } }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}}</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:16px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">このページは存在しません</div>
|
||||
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>メインサイトに行く</b></a></div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"><a href="/">バック</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
|
||||
var terms = '{{{terms}}}';
|
||||
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
|
||||
QV('column_l', true);
|
||||
userInterfaceSelectMenu();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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; } }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}}</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:16px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Selectie gebruikersinterface" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Linkerbalk interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Boven werkbalk interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface met vaste breedte"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Wissel nachtmodus"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">This page does not exist</div>
|
||||
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Ga naar hoofdsite</b></a></div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"><a href="/">Terug</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
|
||||
var terms = '{{{terms}}}';
|
||||
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
|
||||
QV('column_l', true);
|
||||
userInterfaceSelectMenu();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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; } }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html><html><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 type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<title>{{{title}}}</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" style="display:none;overflow:hidden">
|
||||
<div id="container">
|
||||
<!-- Begin Masthead -->
|
||||
<div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden;">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:16px; padding-top:7px">
|
||||
<strong><font style="font-size:46px; font-family: Arial, Helvetica, sans-serif;">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left; height: 66px; color:#c8c8c8; padding-left:5px; padding-top:14px">
|
||||
<strong><font style="font-size:14px; font-family: Arial, Helvetica, sans-serif;">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_leftbar">
|
||||
<div style="height:16px"></div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px;position:relative">
|
||||
<div id="uiMenuButton" title="Seleção da interface do usuário" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Interface da barra esquerda"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Interface da barra superior"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface de largura fixa"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Alternar modo noturno"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l" style="max-height:calc(100vh - 135px);overflow-y:auto">
|
||||
<div style="text-align:center;padding-top:30px;font-size:200px;font-family:Arial;color:#bbb"><b>404</b></div>
|
||||
<div style="text-align:center;font-size:20px;font-family:Arial;color:#999">Esta página não existe</div>
|
||||
<div style="text-align:center;padding-top:20px;font-size:20px;font-family:Arial;color:#999"><a href="/" style="text-decoration:none"><b>Ir para o site principal</b></a></div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width: 100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right"><a href="/">Voltar</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var uiMode = parseInt(getstore('uiMode', 1));
|
||||
var webPageStackMenu = false;
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
|
||||
var terms = '{{{terms}}}';
|
||||
if (terms != '') { QH('column_l', decodeURIComponent(terms)); }
|
||||
QV('column_l', true);
|
||||
userInterfaceSelectMenu();
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton4').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
webPageStackMenu = true;//(uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
toggleStackMenu(0);
|
||||
QC('column_l').add('room4submenu');
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', nightMode ? '1' : '0');
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
var hide = 0;
|
||||
//if (args.hide) { hide = parseInt(args.hide); }
|
||||
if (webPageFullScreen == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
QC('body').remove('fullscreen');
|
||||
QC('body').remove('arg_hide');
|
||||
//if (xxcurrentView >= 10) QC('column_l').add('room4submenu');
|
||||
//QV('UserDummyMenuSpan', false);
|
||||
//QV('page_leftbar', false);
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
if (hide & 16) QC('body').add('arg_hide'); // This is replacement for QV('page_leftbar', !(hide & 16));
|
||||
//QV('UserDummyMenuSpan', (xxcurrentView < 10) && webPageFullScreen);
|
||||
//QV('page_leftbar', true);
|
||||
}
|
||||
QV('body', true);
|
||||
}
|
||||
|
||||
// If FullScreen, toggle menu to be horisontal or vertical
|
||||
function toggleStackMenu(toggle) {
|
||||
if (webPageFullScreen == true) {
|
||||
if (toggle === 1) {
|
||||
webPageStackMenu = !webPageStackMenu;
|
||||
putstore('webPageStackMenu', webPageStackMenu);
|
||||
}
|
||||
if (webPageStackMenu == false) {
|
||||
QC('body').remove('menu_stack');
|
||||
} else {
|
||||
QC('body').add('menu_stack');
|
||||
//if (xxcurrentView >= 10) QC('column_l').remove('room4submenu');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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; } }
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,647 +0,0 @@
|
||||
<!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/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
<style>
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</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="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>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
|
||||
<div id="column_l" style="padding:10px;width:100%">
|
||||
<table style="width:100%">
|
||||
<tbody><tr>
|
||||
<td align="center">
|
||||
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Přihlásit</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Uživatel:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Heslo:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Zobrazit nápovědu</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Přihlásit" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Zapomenuté jméno/heslo?</span> <a onclick="xgo(3)" style="cursor:pointer">Reset účtu</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Nemáte účet? <a onclick="xgo(2)" style="cursor:pointer">Vytvořit</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Vytvoření účtu</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td align="right" width="100">Uživatel:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Heslo:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Heslo:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td align="right">Nápověda k heslu:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Zadejte token pro vytvoření účtu">
|
||||
<td align="right">Vytvoření tokenu:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Vytvořit účet" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Reset hesla</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Reset účtu" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Přihlašovací token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Zapamatovat toto zařízení 30 dní.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Přihlášení" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Použít bezpečnostní klíč" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Přihlašovací token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Přihlášení" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Heslo:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Heslo:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Nápověda k heslu:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Reset hesla" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="terms">Podmínky & soukromí</a></td>
|
||||
</tr>
|
||||
</tbody></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:180px;width:400px;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>
|
||||
<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>
|
||||
<script>
|
||||
'use strict';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var features = parseInt('{{{features}}}');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
var currentpanel = 0;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Vydržte, email je na cestě."];
|
||||
var failmessages = ["Nelze vytvořit účet.", "Maximální počet účtů dosažen.", "Existuje účet s tímto emailem.", "Neplatný token pro vytvoření účtu.", "Uživatel již existuje.", "Heslo odmítnuto, zkuste jiné.", "Neplatný email.", "Účet nenalezen.", "Neplatný token, zkuste znovu.", "Nelze poslat email.", "Účet uzamknut.", "Přístup zamítnut", "Neplatné přihlášení, zkontrolujte jméno a heslo.", "Vyžaduje se změna hesla.", "IP adresa blokována, zkuste to později."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Zapomenuté heslo?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
if (passRequirements.hint === true) { messagebox("Nápověda k heslu", passhint); }
|
||||
}
|
||||
|
||||
function xgo(x) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box,e) {
|
||||
setDialogMode(0);
|
||||
var ok = false;
|
||||
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Silné heslo" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Dobré heslo" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Slabé heslo" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
//QS('nuPass1').color = '#7b241c';
|
||||
//QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<span style=color:red><b>' + "Politia hesla" + '</b><span>'); // TODO: Display problem hint
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
QE('createButton', ok);
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 1) { Q('aemail').focus(); }
|
||||
if (box == 2) { Q('apassword1').focus(); }
|
||||
if (box == 3) { Q('apassword2').focus(); }
|
||||
if (box == 4) { Q('apasswordhint').focus(); }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Silné heslo" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Dobré heslo" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Slabé heslo" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Politia hesla" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimální délka {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Maximální délka {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} velkých písmen", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} malých písmen", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} čísel", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} speciálních znaků", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
var xcheckTokenTimer = null;
|
||||
function checkTokenTimer(enter) {
|
||||
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
|
||||
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); } // New version
|
||||
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; }); };
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,647 +0,0 @@
|
||||
<!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/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
<style>
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</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="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>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
|
||||
<div id="column_l" style="padding:10px;width:100%">
|
||||
<table style="width:100%">
|
||||
<tbody><tr>
|
||||
<td align="center">
|
||||
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Log In</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Nom d'utilisateur:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Mot de passe:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Dévoiler indice</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Forgot user/password?</span> <a onclick="xgo(3)" style="cursor:pointer">Réinitialiser le compte</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Don't have an account? <a onclick="xgo(2)" style="cursor:pointer">Create one</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Account Creation</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td align="right" width="100">Nom d'utilisateur:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Mot de passe:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Mot de passe:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td align="right">Pass Hint:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Enter the account creation token">
|
||||
<td align="right">Creation Token:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Account Reset</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Réinitialiser le Compte" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Login token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Rappelez cet appareil pour 30 jours.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Utiliser clé de sécurité" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Login token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Mot de passe:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Mot de passe:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Password Hint:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Réinitialiser le mot de passe" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="terms">Terms & Privacy</a></td>
|
||||
</tr>
|
||||
</tbody></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:180px;width:400px;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>
|
||||
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Annuler" 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>
|
||||
<script>
|
||||
'use strict';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var features = parseInt('{{{features}}}');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
var currentpanel = 0;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Attends, le courrier est envoyé."];
|
||||
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Ce nom d'utilisateur existe déjà.", "Mot de passe rejeté, utilisez-en un autre.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Changement de mot de passe demandé.", "IP address blocked, try again later."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Mot de passe oublié?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
|
||||
}
|
||||
|
||||
function xgo(x) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box,e) {
|
||||
setDialogMode(0);
|
||||
var ok = false;
|
||||
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Mot de passe fort" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Bon mot de passe" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Mot de passe faible" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
//QS('nuPass1').color = '#7b241c';
|
||||
//QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<span style=color:red><b>' + "Password Policy" + '</b><span>'); // TODO: Display problem hint
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
QE('createButton', ok);
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 1) { Q('aemail').focus(); }
|
||||
if (box == 2) { Q('apassword1').focus(); }
|
||||
if (box == 3) { Q('apassword2').focus(); }
|
||||
if (box == 4) { Q('apasswordhint').focus(); }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Mot de passe fort" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Bon mot de passe" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Mot de passe faible" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Password Policy" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimum length of {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Longueur maximale de {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} upper case", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} lower case", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numeric", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} non-alphanumeric", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
var xcheckTokenTimer = null;
|
||||
function checkTokenTimer(enter) {
|
||||
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
|
||||
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); } // New version
|
||||
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; }); };
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,647 +0,0 @@
|
||||
<!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/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
<style>
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</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="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>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
|
||||
<div id="column_l" style="padding:10px;width:100%">
|
||||
<table style="width:100%">
|
||||
<tbody><tr>
|
||||
<td align="center">
|
||||
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>ログイン</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">ユーザー名:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">パスワード:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">ヒントを見せて</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="ログイン" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">ユーザー/パスワードを忘れましたか?</span> <a onclick="xgo(3)" style="cursor:pointer">アカウントをリセット</a>。
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
アカウントを持っていないのですか? <a onclick="xgo(2)" style="cursor:pointer">一つ作る</a>。
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>アカウント作成</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td align="right" width="100">ユーザー名:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="100">Eメール:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">パスワード:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">パスワード:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td align="right">ヒントを渡す:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="アカウント作成トークンを入力してください">
|
||||
<td align="right">作成トークン:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="アカウントを作成する" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>アカウントのリセット</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Eメール:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="アカウントをリセット" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">ログイントークン:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">このデバイスを30日間記憶します。</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="セキュリティキーを使用" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">ログイントークン:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">パスワード:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">パスワード:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">パスワードのヒント:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="パスワードを再設定する" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="terms">利用規約とプライバシー</a></td>
|
||||
</tr>
|
||||
</tbody></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:180px;width:400px;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>バツ</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>
|
||||
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
|
||||
<input id="idx_dlgCancelButton" type="button" value="キャンセル" 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>
|
||||
<script>
|
||||
'use strict';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var features = parseInt('{{{features}}}');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
var currentpanel = 0;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "お待ちください、送信されたメールをリセットします。"];
|
||||
var failmessages = ["アカウントを作成できません。", "アカウントの上限に達しました。", "このメールアドレスを持つ既存のアカウント。", "アカウント作成トークンが無効です。", "ユーザー名は既に存在します。", "パスワードが拒否されました。別のパスワードを使用してください。", "無効なメール。", "アカウントが見つかりませんでした。", "トークンが無効です。もう一度お試しください。", "メールを送信できません。", "アカウントがロックされました。", "アクセスが拒否されました。", "ログインに失敗しました。ユーザー名とパスワードを確認してください。", "パスワードの変更が要求されました。", "IPアドレスがブロックされています。しばらくしてからもう一度お試しください。"];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Eメール:");
|
||||
QH('resetAccountSpan', "パスワードをお忘れですか?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
if (passRequirements.hint === true) { messagebox("パスワードのヒント", passhint); }
|
||||
}
|
||||
|
||||
function xgo(x) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box,e) {
|
||||
setDialogMode(0);
|
||||
var ok = false;
|
||||
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
//QS('nuPass1').color = '#7b241c';
|
||||
//QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<span style=color:red><b>' + "パスワードポリシー" + '</b><span>'); // TODO: Display problem hint
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
QE('createButton', ok);
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 1) { Q('aemail').focus(); }
|
||||
if (box == 2) { Q('apassword1').focus(); }
|
||||
if (box == 3) { Q('apassword2').focus(); }
|
||||
if (box == 4) { Q('apasswordhint').focus(); }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("最小長{0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("{0}の最大長", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0}大文字", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0}小文字", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0}数値", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0}英数字以外", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
var xcheckTokenTimer = null;
|
||||
function checkTokenTimer(enter) {
|
||||
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
|
||||
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); } // New version
|
||||
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; }); };
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,647 +0,0 @@
|
||||
<!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/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
<style>
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</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="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>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
|
||||
<div id="column_l" style="padding:10px;width:100%">
|
||||
<table style="width:100%">
|
||||
<tbody><tr>
|
||||
<td align="center">
|
||||
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Inloggen</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Gebruikersnaam:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Wachtwoord:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Toon hint</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Inloggen" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Gebruiker / wachtwoord vergeten?</span> <a onclick="xgo(3)" style="cursor:pointer">Account opnieuw instellen</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Heb je nog geen account? <a onclick="xgo(2)" style="cursor:pointer">Creëer er een</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Gebruikersaccount aanmaken</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td align="right" width="100">Gebruikersnaam:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Wachtwoord:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Wachtwoord:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td align="right">wachtwoord hint:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Voer het token voor het maken van een account in">
|
||||
<td align="right">Token aanmaken:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Account aanmaken" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Gebruikersaccount resetten</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Account opnieuw instellen" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Inlog token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Onthoud dit apparaat gedurende 30 dagen.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Inloggen" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Gebruik beveiligingssleutel" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Inlog token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Inloggen" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Wachtwoord:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Wachtwoord:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">wachtwoord hint:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Reset wachtwoord" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="terms">Voorwaarden & Privacy</a></td>
|
||||
</tr>
|
||||
</tbody></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:180px;width:400px;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>
|
||||
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Afbreken" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="Oke" style="float:right;width:80px" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var features = parseInt('{{{features}}}');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
var currentpanel = 0;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "even wachten, reset e-mail verzonden."];
|
||||
var failmessages = ["Kan geen account maken.", "Gebruikersaccount limiet bereikt.", "Bestaand account met dit e-mailadres.", "Ongeldig token voor het maken van een account.", "Gebruikersnaam bestaat al.", "Wachtwoord geweigerd, gebruik een ander.", "Ongeldige e-mail.", "Gebruikersaccount niet gevonden", "Ongeldig token, probeer het opnieuw.", "Kan geen e-mail verzenden.", "Gebruikersaccount vergrendeld", "Toegang geweigerd.", "Inloggen mislukt, controleer gebruikersnaam en wachtwoord.", "Wachtwoordwijziging aangevraagd.", "IP-adres geblokkeerd, probeer het later opnieuw."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Wachtwoord vergeten?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
if (passRequirements.hint === true) { messagebox("wachtwoord hint", passhint); }
|
||||
}
|
||||
|
||||
function xgo(x) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box,e) {
|
||||
setDialogMode(0);
|
||||
var ok = false;
|
||||
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Sterk wachtwoord" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Goed wachtwoord" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Zwak wachtwoord" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
//QS('nuPass1').color = '#7b241c';
|
||||
//QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<span style=color:red><b>' + "Wachtwoord beleid" + '</b><span>'); // TODO: Display problem hint
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
QE('createButton', ok);
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 1) { Q('aemail').focus(); }
|
||||
if (box == 2) { Q('apassword1').focus(); }
|
||||
if (box == 3) { Q('apassword2').focus(); }
|
||||
if (box == 4) { Q('apasswordhint').focus(); }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Sterk wachtwoord" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Goed wachtwoord" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Zwak wachtwoord" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Wachtwoord beleid" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimale lengte van {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Maximale lengte van {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} hoofdletters", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} kleine letters", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numeriek", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} niet-alfanumeriek", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
var xcheckTokenTimer = null;
|
||||
function checkTokenTimer(enter) {
|
||||
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
|
||||
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); } // New version
|
||||
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; }); };
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,647 +0,0 @@
|
||||
<!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/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
<style>
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer a:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
</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="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>
|
||||
<div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center">
|
||||
<div id="column_l" style="padding:10px;width:100%">
|
||||
<table style="width:100%">
|
||||
<tbody><tr>
|
||||
<td align="center">
|
||||
<div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Entrar</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Nome de usuário:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Senha:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Mostrar dica</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Entrar" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Esqueceu usuário / senha?</span> <a onclick="xgo(3)" style="cursor:pointer">Redefinir conta</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Não possui uma conta? <a onclick="xgo(2)" style="cursor:pointer">Crie um</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none">
|
||||
<div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Criação de conta</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td align="right" width="100">Nome de usuário:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Senha:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Senha:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td align="right">Dica de passe:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Insira o token de criação da conta">
|
||||
<td align="right">Token de criação</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Criar conta" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Redefinição de conta</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Redefinir Conta" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Token de logon:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)">
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Remember this device for 30 days.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Entrar" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Use Security Key" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Token de logon:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Entrar" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Senha:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Senha:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Dica de senha</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Redefinir senha" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="xgo(1)" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px">
|
||||
<table cellpadding="0" cellspacing="6" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left;color:white">{{{footer}}}</td>
|
||||
<td style="text-align:right">{{{rootCertLink}}} <a href="terms">Termos & Privacidade</a></td>
|
||||
</tr>
|
||||
</tbody></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:180px;width:400px;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>
|
||||
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Cancelar" 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>
|
||||
<script>
|
||||
'use strict';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var features = parseInt('{{{features}}}');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
var currentpanel = 0;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Hold on, reset mail sent."];
|
||||
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Username already exists.", "Password rejected, use a different one.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Password change requested.", "IP address blocked, try again later."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Esqueceu a senha?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint() {
|
||||
if (passRequirements.hint === true) { messagebox("Dica de Senha", passhint); }
|
||||
}
|
||||
|
||||
function xgo(x) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box,e) {
|
||||
setDialogMode(0);
|
||||
var ok = false;
|
||||
if (features & 0x200000) { ok = true; } else { ok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
ok &= ((validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
|
||||
if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Senha forte" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Boa senha" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Senha fraca" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
//QS('nuPass1').color = '#7b241c';
|
||||
//QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<span style=color:red><b>' + "Política de senha" + '</b><span>'); // TODO: Display problem hint
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
QE('createButton', ok);
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 1) { Q('aemail').focus(); }
|
||||
if (box == 2) { Q('apassword1').focus(); }
|
||||
if (box == 3) { Q('apassword2').focus(); }
|
||||
if (box == 4) { Q('apasswordhint').focus(); }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Senha forte" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Boa senha" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Senha fraca" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Política de senha" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) { Q('eresetButton').click(); }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Comprimento mínimo de {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Comprimento máximo de {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} maiúsculas", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} letras minúsculas", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numérico", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} não alfanumérico", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
var xcheckTokenTimer = null;
|
||||
function checkTokenTimer(enter) {
|
||||
if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
|
||||
if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + 'px'); }
|
||||
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); } // New version
|
||||
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; }); };
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,728 +0,0 @@
|
||||
<!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">
|
||||
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
|
||||
<div id="container">
|
||||
<div id="masthead">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div class="title">{{{title1}}}</div>
|
||||
<div class="title2">{{{title2}}}</div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px">
|
||||
<div id="uiMenuButton" title="Výběr rozhraní uživatele" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Rozhraní levé lišty"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Rozhraní horní lišty"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Rozhraní s pevnou šířkou"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Přepnout na noční mód"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l">
|
||||
<h1>Vítejte</h1>
|
||||
<div id="welcomeText" style="display:none">Přihlašte se na různá svá nebo firemní zařízení odkudkoliv z celého světa pomocí technologie MeshCentral. Jednoduchá správa přes web. Jediné co potřebujete je agent na daném zařízení. Po instalaci uvidíte zařízení v sekci "Moje zařízení" a můžete toto zařízení ovládat.</div>
|
||||
<table id="centralTable" style="">
|
||||
<tbody><tr>
|
||||
<td id="welcomeimage">
|
||||
<picture>
|
||||
<img alt="" src="welcome.jpg" style="border-radius:20px">
|
||||
</picture>
|
||||
</td>
|
||||
<td id="logincell">
|
||||
<div id="loginpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Přihlásit</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Uživatel:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Heslo:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Zobrazit nápovědu</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Přihlásit" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Zapomenuté jméno/heslo?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">Reset účtu</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Nemáte účet? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">Vytvořit</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Vytvoření účtu</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td id="nuUser" align="right" width="100">Uživatel:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuEmail" align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass1" align="right">Heslo:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass2" align="right">Heslo:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td id="nuHint" align="right">Nápověda k heslu:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Zadejte token pro vytvoření účtu">
|
||||
<td id="nuToken" align="right">Vytvoření tokenu:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Vytvořit účet" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Reset hesla</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Reset účtu" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="display:none">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Přihlašovací token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Zapamatovat toto zařízení 30 dní.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Přihlášení" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Použít bezpečnostní klíč" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resettokenpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Přihlašovací token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Přihlášení" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpasswordpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Heslo:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Heslo:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Nápověda k heslu:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Reset hesla" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Zpět na přihlášení</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="footer1">{{{footer}}}</div>
|
||||
<div class="footer2">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Podmínky & soukromí</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="dialog" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<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 id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar" style="">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Zrušit" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var features = parseInt('{{{features}}}');
|
||||
var welcomeText = decodeURIComponent('{{{welcometext}}}');
|
||||
var currentpanel = 0;
|
||||
var uiMode = parseInt(getstore('uiMode', '1'));
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Vydržte, email je na cestě."];
|
||||
var failmessages = ["Nelze vytvořit účet.", "Maximální počet účtů dosažen.", "Existuje účet s tímto emailem.", "Neplatný token pro vytvoření účtu.", "Uživatel již existuje.", "Heslo odmítnuto, zkuste jiné.", "Neplatný email.", "Účet nenalezen.", "Neplatný token, zkuste znovu.", "Nelze poslat email.", "Účet uzamknut.", "Přístup zamítnut", "Neplatné přihlášení, zkontrolujte jméno a heslo.", "Vyžaduje se změna hesla.", "IP adresa blokována, zkuste to později."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||
//toggleFullScreen();
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Zapomenuté heslo?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
if (nightMode) { QC('body').add('night'); }
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
|
||||
QV('welcomeText', true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the user interface in the right mode
|
||||
userInterfaceSelectMenu();
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint(e) {
|
||||
messagebox("Nápověda k heslu", passhint);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function xgo(x, e) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box, e) {
|
||||
setDialogMode(0);
|
||||
var userok = false;
|
||||
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
var emailok = (validateEmail(Q('aemail').value) == true);
|
||||
var pass1ok = (Q('apassword1').value.length > 0);
|
||||
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
|
||||
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
|
||||
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
|
||||
|
||||
// Color the fields
|
||||
QS('nuUser').color = userok?'black':'#7b241c';
|
||||
QS('nuEmail').color = emailok?'black':'#7b241c';
|
||||
QS('nuPass1').color = pass1ok?'black':'#7b241c';
|
||||
QS('nuPass2').color = pass2ok?'black':'#7b241c';
|
||||
QS('nuToken').color = newAccOk?'black':'#7b241c';
|
||||
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Silné heslo" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Dobré heslo" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Slabé heslo" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('nuPass1').color = '#7b241c';
|
||||
QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Politia hesla" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
|
||||
if ((box == 1) && userok) { Q('aemail').focus(); }
|
||||
if ((box == 2) && emailok) { Q('apassword1').focus(); }
|
||||
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
|
||||
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('createButton', ok);
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Silné heslo" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Dobré heslo" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Slabé heslo" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Politia hesla" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimální délka {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Maximální délka {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} velkých písmen", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} malých písmen", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} čísel", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} speciálních znaků", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
function showPasswordPolicy() {
|
||||
messagebox("Politia hesla", passwordPolicyText());
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) {
|
||||
Q('eresetButton').click();
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
if (webPageFullScreen == false) {
|
||||
// By adding body class, it will change a style of all ellements using CSS selector
|
||||
// No need for JS anymore and it will be consistent style for all the templates.
|
||||
QC('body').remove('fullscreen');
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
}
|
||||
QV('body', true);
|
||||
center();
|
||||
}
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
//webPageStackMenu = (uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
//toggleStackMenu(0);
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', (nightMode ? '1' : '0'));
|
||||
}
|
||||
|
||||
function center() {
|
||||
/* Now we use CSS media to achive the same effect as deleted JS */
|
||||
if (webPageFullScreen == false) {
|
||||
QS('centralTable')['margin-top'] = '';
|
||||
} else {
|
||||
var h = ((Q('column_l').clientHeight) / 2) - 220;
|
||||
if (h < 0) h = 0;
|
||||
QS('centralTable')['margin-top'] = h + 'px';
|
||||
}
|
||||
}
|
||||
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); } // New version
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,728 +0,0 @@
|
||||
<!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">
|
||||
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
|
||||
<div id="container">
|
||||
<div id="masthead">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div class="title">{{{title1}}}</div>
|
||||
<div class="title2">{{{title2}}}</div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px">
|
||||
<div id="uiMenuButton" title="User interface selection" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Left bar interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Top bar interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface à largeur fixe"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Basculer mode nuit"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l">
|
||||
<h1>Bienvenue</h1>
|
||||
<div id="welcomeText" style="display:none">Connectez-vous à vos ordinateurs à la maison ou au bureau depuis n'importe où dans le monde avec MeshCentral, le site web open source de surveillance et de gestion d’ordinateur à distance en temps réel. Vous devrez télécharger et installer un agent de gestion sur vos ordinateurs. Une fois installés, les ordinateurs apparaîtront dans la section "Mes appareils" de ce site et vous pourrez les surveiller et en prendre le contrôle.</div>
|
||||
<table id="centralTable" style="">
|
||||
<tbody><tr>
|
||||
<td id="welcomeimage">
|
||||
<picture>
|
||||
<img alt="" src="welcome.jpg" style="border-radius:20px">
|
||||
</picture>
|
||||
</td>
|
||||
<td id="logincell">
|
||||
<div id="loginpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Log In</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Nom d'utilisateur:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Mot de passe:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Dévoiler indice</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Forgot username/password?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">Réinitialiser le compte</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Don't have an account? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">Create one</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Account Creation</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td id="nuUser" align="right" width="100">Nom d'utilisateur:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuEmail" align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass1" align="right">Mot de passe:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass2" align="right">Mot de passe:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td id="nuHint" align="right">Password Hint:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Enter the account creation token">
|
||||
<td id="nuToken" align="right">Creation Token:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Back to login</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Account Reset</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Réinitialiser le Compte" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Back to login</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="display:none">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Login token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Rappelez cet appareil pour 30 jours.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Utiliser clé de sécurité" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Back to login</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resettokenpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Login token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Back to login</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpasswordpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Mot de passe:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Mot de passe:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Password Hint:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Réinitialiser le mot de passe" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Back to login</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="footer1">{{{footer}}}</div>
|
||||
<div class="footer2">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Terms & Privacy</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="dialog" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<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 id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar" style="">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Annuler" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var features = parseInt('{{{features}}}');
|
||||
var welcomeText = decodeURIComponent('{{{welcometext}}}');
|
||||
var currentpanel = 0;
|
||||
var uiMode = parseInt(getstore('uiMode', '1'));
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Attends, le courrier est envoyé."];
|
||||
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Ce nom d'utilisateur existe déjà.", "Mot de passe rejeté, utilisez-en un autre.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Changement de mot de passe demandé.", "IP address blocked, try again later."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||
//toggleFullScreen();
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Mot de passe oublié?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
if (nightMode) { QC('body').add('night'); }
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
|
||||
QV('welcomeText', true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the user interface in the right mode
|
||||
userInterfaceSelectMenu();
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint(e) {
|
||||
messagebox("Password Hint", passhint);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function xgo(x, e) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box, e) {
|
||||
setDialogMode(0);
|
||||
var userok = false;
|
||||
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
var emailok = (validateEmail(Q('aemail').value) == true);
|
||||
var pass1ok = (Q('apassword1').value.length > 0);
|
||||
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
|
||||
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
|
||||
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
|
||||
|
||||
// Color the fields
|
||||
QS('nuUser').color = userok?'black':'#7b241c';
|
||||
QS('nuEmail').color = emailok?'black':'#7b241c';
|
||||
QS('nuPass1').color = pass1ok?'black':'#7b241c';
|
||||
QS('nuPass2').color = pass2ok?'black':'#7b241c';
|
||||
QS('nuToken').color = newAccOk?'black':'#7b241c';
|
||||
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Mot de passe fort" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Bon mot de passe" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Mot de passe faible" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('nuPass1').color = '#7b241c';
|
||||
QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Password Policy" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
|
||||
if ((box == 1) && userok) { Q('aemail').focus(); }
|
||||
if ((box == 2) && emailok) { Q('apassword1').focus(); }
|
||||
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
|
||||
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('createButton', ok);
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Mot de passe fort" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Bon mot de passe" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Mot de passe faible" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Password Policy" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimum length of {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Longueur maximale de {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} upper case", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} lower case", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numeric", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} non-alphanumeric", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
function showPasswordPolicy() {
|
||||
messagebox("Password Policy", passwordPolicyText());
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) {
|
||||
Q('eresetButton').click();
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
if (webPageFullScreen == false) {
|
||||
// By adding body class, it will change a style of all ellements using CSS selector
|
||||
// No need for JS anymore and it will be consistent style for all the templates.
|
||||
QC('body').remove('fullscreen');
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
}
|
||||
QV('body', true);
|
||||
center();
|
||||
}
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
//webPageStackMenu = (uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
//toggleStackMenu(0);
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', (nightMode ? '1' : '0'));
|
||||
}
|
||||
|
||||
function center() {
|
||||
/* Now we use CSS media to achive the same effect as deleted JS */
|
||||
if (webPageFullScreen == false) {
|
||||
QS('centralTable')['margin-top'] = '';
|
||||
} else {
|
||||
var h = ((Q('column_l').clientHeight) / 2) - 220;
|
||||
if (h < 0) h = 0;
|
||||
QS('centralTable')['margin-top'] = h + 'px';
|
||||
}
|
||||
}
|
||||
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); } // New version
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,728 +0,0 @@
|
||||
<!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">
|
||||
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
|
||||
<div id="container">
|
||||
<div id="masthead">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div class="title">{{{title1}}}</div>
|
||||
<div class="title2">{{{title2}}}</div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px">
|
||||
<div id="uiMenuButton" title="ユーザーインターフェイスの選択" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="左バーインターフェイス"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="トップバーインターフェース"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="固定幅インターフェイス"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="ナイトモードを切り替える"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l">
|
||||
<h1>ようこそ</h1>
|
||||
<div id="welcomeText" style="display:none">リアルタイムのオープンソースのリモート監視および管理WebサイトであるMeshCentralを使用して、世界中のどこからでも自宅またはオフィスのデバイスに接続します。コンピューターに管理エージェントをダウンロードしてインストールする必要があります。インストールすると、コンピューターはこのWebサイトの[デバイス]セクションに表示され、コンピューターを監視して制御できるようになります。</div>
|
||||
<table id="centralTable" style="">
|
||||
<tbody><tr>
|
||||
<td id="welcomeimage">
|
||||
<picture>
|
||||
<img alt="" src="welcome.jpg" style="border-radius:20px">
|
||||
</picture>
|
||||
</td>
|
||||
<td id="logincell">
|
||||
<div id="loginpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>ログイン</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">ユーザー名:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">パスワード:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">ヒントを見せて</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="ログイン" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">ユーザー名/パスワードを忘れましたか?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">アカウントをリセット</a>。
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
アカウントを持っていないのですか? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">一つ作る</a>。
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>アカウント作成</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td id="nuUser" align="right" width="100">ユーザー名:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuEmail" align="right" width="100">Eメール:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass1" align="right">パスワード:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass2" align="right">パスワード:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td id="nuHint" align="right">パスワードのヒント:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="アカウント作成トークンを入力してください">
|
||||
<td id="nuToken" align="right">作成トークン:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="アカウントを作成する" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>アカウントのリセット</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Eメール:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="アカウントをリセット" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="display:none">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">ログイントークン:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">このデバイスを30日間記憶します。</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="セキュリティキーを使用" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resettokenpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">ログイントークン:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="ログイン" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpasswordpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">パスワード:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">パスワード:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">パスワードのヒント:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="パスワードを再設定する" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">ログインに戻る</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="footer1">{{{footer}}}</div>
|
||||
<div class="footer2">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">利用規約とプライバシー</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="dialog" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>バツ</b></div>
|
||||
<div id="id_dialogtitle" style="padding:5px"></div>
|
||||
<div style="width:100%;margin:6px"></div>
|
||||
</div>
|
||||
<div id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar" style="">
|
||||
<input id="idx_dlgCancelButton" type="button" value="キャンセル" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="OK" style="" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var features = parseInt('{{{features}}}');
|
||||
var welcomeText = decodeURIComponent('{{{welcometext}}}');
|
||||
var currentpanel = 0;
|
||||
var uiMode = parseInt(getstore('uiMode', '1'));
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "お待ちください、送信されたメールをリセットします。"];
|
||||
var failmessages = ["アカウントを作成できません。", "アカウントの上限に達しました。", "このメールアドレスを持つ既存のアカウント。", "アカウント作成トークンが無効です。", "ユーザー名は既に存在します。", "パスワードが拒否されました。別のパスワードを使用してください。", "無効なメール。", "アカウントが見つかりませんでした。", "トークンが無効です。もう一度お試しください。", "メールを送信できません。", "アカウントがロックされました。", "アクセスが拒否されました。", "ログインに失敗しました。ユーザー名とパスワードを確認してください。", "パスワードの変更が要求されました。", "IPアドレスがブロックされています。しばらくしてからもう一度お試しください。"];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||
//toggleFullScreen();
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Eメール:");
|
||||
QH('resetAccountSpan', "パスワードをお忘れですか?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
if (nightMode) { QC('body').add('night'); }
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
|
||||
QV('welcomeText', true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the user interface in the right mode
|
||||
userInterfaceSelectMenu();
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint(e) {
|
||||
messagebox("パスワードのヒント", passhint);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function xgo(x, e) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box, e) {
|
||||
setDialogMode(0);
|
||||
var userok = false;
|
||||
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
var emailok = (validateEmail(Q('aemail').value) == true);
|
||||
var pass1ok = (Q('apassword1').value.length > 0);
|
||||
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
|
||||
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
|
||||
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
|
||||
|
||||
// Color the fields
|
||||
QS('nuUser').color = userok?'black':'#7b241c';
|
||||
QS('nuEmail').color = emailok?'black':'#7b241c';
|
||||
QS('nuPass1').color = pass1ok?'black':'#7b241c';
|
||||
QS('nuPass2').color = pass2ok?'black':'#7b241c';
|
||||
QS('nuToken').color = newAccOk?'black':'#7b241c';
|
||||
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('nuPass1').color = '#7b241c';
|
||||
QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
|
||||
if ((box == 1) && userok) { Q('aemail').focus(); }
|
||||
if ((box == 2) && emailok) { Q('apassword1').focus(); }
|
||||
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
|
||||
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('createButton', ok);
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "強力なパスワード" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "良いパスワード" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "弱いパスワード" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "パスワードポリシー" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("最小長{0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("{0}の最大長", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0}大文字", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0}小文字", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0}数値", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0}英数字以外", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
function showPasswordPolicy() {
|
||||
messagebox("パスワードポリシー", passwordPolicyText());
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) {
|
||||
Q('eresetButton').click();
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
if (webPageFullScreen == false) {
|
||||
// By adding body class, it will change a style of all ellements using CSS selector
|
||||
// No need for JS anymore and it will be consistent style for all the templates.
|
||||
QC('body').remove('fullscreen');
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
}
|
||||
QV('body', true);
|
||||
center();
|
||||
}
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
//webPageStackMenu = (uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
//toggleStackMenu(0);
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', (nightMode ? '1' : '0'));
|
||||
}
|
||||
|
||||
function center() {
|
||||
/* Now we use CSS media to achive the same effect as deleted JS */
|
||||
if (webPageFullScreen == false) {
|
||||
QS('centralTable')['margin-top'] = '';
|
||||
} else {
|
||||
var h = ((Q('column_l').clientHeight) / 2) - 220;
|
||||
if (h < 0) h = 0;
|
||||
QS('centralTable')['margin-top'] = h + 'px';
|
||||
}
|
||||
}
|
||||
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); } // New version
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,728 +0,0 @@
|
||||
<!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">
|
||||
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
|
||||
<div id="container">
|
||||
<div id="masthead">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div class="title">{{{title1}}}</div>
|
||||
<div class="title2">{{{title2}}}</div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px">
|
||||
<div id="uiMenuButton" title="Selectie gebruikersinterface" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Linkerbalk interface"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Boven werkbalk interface"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface met vaste breedte"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Wissel nachtmodus"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l">
|
||||
<h1>Welkom</h1>
|
||||
<div id="welcomeText" style="display:none">Maak overal ter wereld verbinding met uw thuis- of kantoorapparatuur via MeshCentral, de realtime, open source externe monitoring- en managementwebsite. U moet een beheeragent op uw computers downloaden en installeren. Na installatie verschijnen computers in het gedeelte "Mijn apparaten" van deze website en kunt u ze volgen en de controle over hen nemen.</div>
|
||||
<table id="centralTable" style="">
|
||||
<tbody><tr>
|
||||
<td id="welcomeimage">
|
||||
<picture>
|
||||
<img alt="" src="welcome.jpg" style="border-radius:20px">
|
||||
</picture>
|
||||
</td>
|
||||
<td id="logincell">
|
||||
<div id="loginpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Inloggen</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Gebruikersnaam:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Wachtwoord:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Toon hint</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Inloggen" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Gebruikersnaam / wachtwoord vergeten?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">Account opnieuw instellen</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Heb je nog geen account? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">Creëer er een</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Gebruikersaccount aanmaken</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td id="nuUser" align="right" width="100">Gebruikersnaam:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuEmail" align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass1" align="right">Wachtwoord:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass2" align="right">Wachtwoord:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td id="nuHint" align="right">wachtwoord hint:</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Voer het token voor het maken van een account in">
|
||||
<td id="nuToken" align="right">Token aanmaken:</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Account aanmaken" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Gebruikersaccount resetten</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Account opnieuw instellen" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="display:none">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Inlog token:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Onthoud dit apparaat gedurende 30 dagen.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Inloggen" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Gebruik beveiligingssleutel" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resettokenpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Inlog token:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Inloggen" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpasswordpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Wachtwoord:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Wachtwoord:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">wachtwoord hint:</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Reset wachtwoord" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Terug naar inloggen</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="footer1">{{{footer}}}</div>
|
||||
<div class="footer2">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Voorwaarden & Privacy</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="dialog" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<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 id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar" style="">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Afbreken" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="Oke" style="" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var features = parseInt('{{{features}}}');
|
||||
var welcomeText = decodeURIComponent('{{{welcometext}}}');
|
||||
var currentpanel = 0;
|
||||
var uiMode = parseInt(getstore('uiMode', '1'));
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "even wachten, reset e-mail verzonden."];
|
||||
var failmessages = ["Kan geen account maken.", "Gebruikersaccount limiet bereikt.", "Bestaand account met dit e-mailadres.", "Ongeldig token voor het maken van een account.", "Gebruikersnaam bestaat al.", "Wachtwoord geweigerd, gebruik een ander.", "Ongeldige e-mail.", "Gebruikersaccount niet gevonden", "Ongeldig token, probeer het opnieuw.", "Kan geen e-mail verzenden.", "Gebruikersaccount vergrendeld", "Toegang geweigerd.", "Inloggen mislukt, controleer gebruikersnaam en wachtwoord.", "Wachtwoordwijziging aangevraagd.", "IP-adres geblokkeerd, probeer het later opnieuw."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||
//toggleFullScreen();
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Wachtwoord vergeten?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
if (nightMode) { QC('body').add('night'); }
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
|
||||
QV('welcomeText', true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the user interface in the right mode
|
||||
userInterfaceSelectMenu();
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint(e) {
|
||||
messagebox("wachtwoord hint", passhint);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function xgo(x, e) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box, e) {
|
||||
setDialogMode(0);
|
||||
var userok = false;
|
||||
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
var emailok = (validateEmail(Q('aemail').value) == true);
|
||||
var pass1ok = (Q('apassword1').value.length > 0);
|
||||
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
|
||||
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
|
||||
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
|
||||
|
||||
// Color the fields
|
||||
QS('nuUser').color = userok?'black':'#7b241c';
|
||||
QS('nuEmail').color = emailok?'black':'#7b241c';
|
||||
QS('nuPass1').color = pass1ok?'black':'#7b241c';
|
||||
QS('nuPass2').color = pass2ok?'black':'#7b241c';
|
||||
QS('nuToken').color = newAccOk?'black':'#7b241c';
|
||||
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Sterk wachtwoord" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Goed wachtwoord" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Zwak wachtwoord" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('nuPass1').color = '#7b241c';
|
||||
QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Wachtwoord beleid" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
|
||||
if ((box == 1) && userok) { Q('aemail').focus(); }
|
||||
if ((box == 2) && emailok) { Q('apassword1').focus(); }
|
||||
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
|
||||
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('createButton', ok);
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Sterk wachtwoord" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Goed wachtwoord" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Zwak wachtwoord" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Wachtwoord beleid" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Minimale lengte van {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Maximale lengte van {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} hoofdletters", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} kleine letters", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numeriek", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} niet-alfanumeriek", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
function showPasswordPolicy() {
|
||||
messagebox("Wachtwoord beleid", passwordPolicyText());
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) {
|
||||
Q('eresetButton').click();
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
if (webPageFullScreen == false) {
|
||||
// By adding body class, it will change a style of all ellements using CSS selector
|
||||
// No need for JS anymore and it will be consistent style for all the templates.
|
||||
QC('body').remove('fullscreen');
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
}
|
||||
QV('body', true);
|
||||
center();
|
||||
}
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
//webPageStackMenu = (uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
//toggleStackMenu(0);
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', (nightMode ? '1' : '0'));
|
||||
}
|
||||
|
||||
function center() {
|
||||
/* Now we use CSS media to achive the same effect as deleted JS */
|
||||
if (webPageFullScreen == false) {
|
||||
QS('centralTable')['margin-top'] = '';
|
||||
} else {
|
||||
var h = ((Q('column_l').clientHeight) / 2) - 220;
|
||||
if (h < 0) h = 0;
|
||||
QS('centralTable')['margin-top'] = h + 'px';
|
||||
}
|
||||
}
|
||||
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); } // New version
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1,728 +0,0 @@
|
||||
<!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">
|
||||
<link keeplink="1" type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
|
||||
<script keeplink="1" type="text/javascript" src="scripts/u2f-api.js"></script>
|
||||
<title>{{{title}}} - Login</title>
|
||||
</head>
|
||||
<body id="body" onload="if (typeof(startup) !== 'undefined') startup();" class="arg_hide login">
|
||||
<div id="container">
|
||||
<div id="masthead">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div class="title">{{{title1}}}</div>
|
||||
<div class="title2">{{{title2}}}</div>
|
||||
</div>
|
||||
<div id="topbar" class="noselect style3" style="height:24px">
|
||||
<div id="uiMenuButton" title="Seleção da interface do usuário" onclick="showUserInterfaceSelectMenu()">
|
||||
♦
|
||||
<div id="uiMenu" style="display:none">
|
||||
<div id="uiViewButton1" class="uiSelector" onclick="userInterfaceSelectMenu(1)" title="Interface da barra esquerda"><div class="uiSelector1"></div></div>
|
||||
<div id="uiViewButton2" class="uiSelector" onclick="userInterfaceSelectMenu(2)" title="Interface da barra superior"><div class="uiSelector2"></div></div>
|
||||
<div id="uiViewButton3" class="uiSelector" onclick="userInterfaceSelectMenu(3)" title="Interface de largura fixa"><div class="uiSelector3"></div></div>
|
||||
<div id="uiViewButton4" class="uiSelector" onclick="toggleNightMode()" title="Alternar modo noturno"><div class="uiSelector4"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="column_l">
|
||||
<h1>Bem vindo</h1>
|
||||
<div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using MeshCentral, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the "My Devices" section of this web site and you will be able to monitor them and take control of them.</div>
|
||||
<table id="centralTable" style="">
|
||||
<tbody><tr>
|
||||
<td id="welcomeimage">
|
||||
<picture>
|
||||
<img alt="" src="welcome.jpg" style="border-radius:20px">
|
||||
</picture>
|
||||
</td>
|
||||
<td id="logincell">
|
||||
<div id="loginpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="login">
|
||||
<div id="message1"></div>
|
||||
<div>
|
||||
<b>Entrar</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="loginusername" align="right" width="100">Nome de usuário:</td>
|
||||
<td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">Senha:</td>
|
||||
<td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="showPassHintLink" style="display:none"><a onclick="return showPassHint(event);" href="#" style="cursor:pointer">Mostrar dica</a></div></td>
|
||||
<td align="right"><input id="loginButton" type="submit" value="Entrar" disabled="disabled"></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<div id="hrAccountDiv" style="display:none"><hr></div>
|
||||
<div id="resetAccountDiv" style="display:none;padding:2px">
|
||||
<span id="resetAccountSpan">Esqueceu seu nome de usuário / senha?</span> <a onclick="return xgo(3,event);" href="#" style="cursor:pointer">Redefinir conta</a>.
|
||||
</div>
|
||||
<div id="newAccountDiv" style="display:none;padding:2px">
|
||||
Não possui uma conta? <a onclick="return xgo(2,event);" href="#" style="cursor:pointer">Crie um</a>.
|
||||
</div>
|
||||
<input id="loginformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="createpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="createaccount">
|
||||
<div id="message2"></div>
|
||||
<div>
|
||||
<b>Criação de conta</b>
|
||||
</div>
|
||||
<div id="passwordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr id="nuUserRow">
|
||||
<td id="nuUser" align="right" width="100">Nome de usuário:</td>
|
||||
<td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuEmail" align="right" width="100">Email:</td>
|
||||
<td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass1" align="right">Senha:</td>
|
||||
<td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nuPass2" align="right">Senha:</td>
|
||||
<td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="createPanelHint" style="display:none">
|
||||
<td id="nuHint" align="right">Dica de senha</td>
|
||||
<td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td>
|
||||
</tr>
|
||||
<tr id="newAccountPass" title="Insira o token de criação da conta">
|
||||
<td id="nuToken" align="right">Token de criação</td>
|
||||
<td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="createButton" type="submit" value="Criar conta" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="createformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message3"></div>
|
||||
<div>
|
||||
<b>Redefinição de conta</b>
|
||||
</div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Email:</td>
|
||||
<td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="eresetButton" type="submit" value="Redefinir Conta" disabled="disabled"></div>
|
||||
<div id="passWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resetformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="tokenpanel" style="display:none">
|
||||
<form method="post" autocomplete="off">
|
||||
<input type="hidden" name="action" value="tokenlogin">
|
||||
<input type="hidden" name="hwstate" value="{{{hwstate}}}">
|
||||
<div id="message4"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Token de logon:</td>
|
||||
<td>
|
||||
<input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"><br>
|
||||
<input id="hwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="align-content:center">
|
||||
<label><input id="tokenInputRemember" name="remembertoken" type="checkbox">Remember this device for 30 days.</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="tokenOkButton" type="submit" value="Entrar" disabled="disabled"></div>
|
||||
<div style="float:right"><input style="display:none;float:right" id="securityKeyButton" type="button" value="Use Security Key" onclick="useSecurityKey()"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="tokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resettokenpanel" style="display:none">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetaccount">
|
||||
<div id="message5"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td align="right" width="100">Token de logon:</td>
|
||||
<td>
|
||||
<input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)">
|
||||
<input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetTokenOkButton" type="submit" value="Entrar" disabled="disabled"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resettokenformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
<div id="resetpasswordpanel" style="display:none;position:relative">
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="resetpassword">
|
||||
<div id="message6"></div>
|
||||
<div id="rpasswordPolicyCallout" style="display:none"></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td id="rnuPass1" width="100" align="right">Senha:</td>
|
||||
<td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="rnuPass2" align="right">Senha:</td>
|
||||
<td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td>
|
||||
</tr>
|
||||
<tr id="resetpasswordpanelHint" style="display:none">
|
||||
<td id="rnuHint" align="right">Dica de senha</td>
|
||||
<td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div style="float:right"><input id="resetPassButton" type="submit" value="Redefinir senha" disabled="disabled"></div>
|
||||
<div id="rpassWarning" style="padding-top:6px"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<hr><a onclick="return xgo(1,event);" href="#" style="cursor:pointer">Volte ao login</a>
|
||||
<input id="resetpasswordformargs" name="urlargs" type="hidden" value="">
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="footer1">{{{footer}}}</div>
|
||||
<div class="footer2">
|
||||
{{{rootCertLink}}}
|
||||
<a href="terms">Termos & Privacidade</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="dialog" style="display:none">
|
||||
<div id="dialogHeader">
|
||||
<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 id="dialogBody">
|
||||
<div id="dialog1">
|
||||
<div id="id_dialogMessage" style=""></div>
|
||||
</div>
|
||||
<div id="dialog2" style="">
|
||||
<div id="id_dialogOptions"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="idx_dlgButtonBar" style="">
|
||||
<input id="idx_dlgCancelButton" type="button" value="Cancelar" style="" onclick="dialogclose(0)">
|
||||
<input id="idx_dlgOkButton" type="button" value="Ok" style="" onclick="dialogclose(1)">
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
'use strict';
|
||||
var passhint = '{{{passhint}}}';
|
||||
var loginMode = '{{{loginmode}}}';
|
||||
var newAccount = '{{{newAccount}}}';
|
||||
var newAccountPass = parseInt('{{{newAccountPass}}}');
|
||||
var emailCheck = ('{{{emailcheck}}}' == 'true');
|
||||
var passRequirements = '{{{passRequirements}}}';
|
||||
var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
|
||||
if (passRequirements != '') { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
|
||||
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
|
||||
var features = parseInt('{{{features}}}');
|
||||
var welcomeText = decodeURIComponent('{{{welcometext}}}');
|
||||
var currentpanel = 0;
|
||||
var uiMode = parseInt(getstore('uiMode', '1'));
|
||||
var webPageFullScreen = true;
|
||||
var nightMode = (getstore('_nightMode', '0') == '1');
|
||||
var publicKeyCredentialRequestOptions = null;
|
||||
|
||||
// Display the right server message
|
||||
var messageid = parseInt('{{{messageid}}}');
|
||||
var okmessages = ['', "Hold on, reset mail sent."];
|
||||
var failmessages = ["Unable to create account.", "Account limit reached.", "Existing account with this email address.", "Invalid account creation token.", "Username already exists.", "Password rejected, use a different one.", "Invalid email.", "Account not found.", "Invalid token, try again.", "Unable to sent email.", "Account locked.", "Access denied.", "Login failed, check username and password.", "Password change requested.", "IP address blocked, try again later."];
|
||||
if (messageid > 0) {
|
||||
var msg = '';
|
||||
if ((messageid < 100) && (messageid < okmessages.length)) { msg = okmessages[messageid]; }
|
||||
else if ((messageid >= 100) && ((messageid - 100) < failmessages.length)) { msg = failmessages[messageid - 100]; }
|
||||
if (msg != '') {
|
||||
if (messageid >= 100) { msg = ('<span class="msg error"><b style=color:#8C001A>' + msg + '<b></span><br /><br />'); } else { msg = ('<span class="msg success"><b>' + msg + '</b></span><br /><br />'); }
|
||||
for (var i = 1; i < 7; i++) { QH('message' + i, msg); }
|
||||
}
|
||||
}
|
||||
|
||||
// If URL arguments are provided, add them to form posts
|
||||
if (window.location.href.indexOf('?') > 0) {
|
||||
var urlargs = window.location.href.substring(window.location.href.indexOf('?'));
|
||||
Q('loginformargs').value = urlargs;
|
||||
Q('createformargs').value = urlargs;
|
||||
Q('resetformargs').value = urlargs;
|
||||
Q('tokenformargs').value = urlargs;
|
||||
Q('resettokenformargs').value = urlargs;
|
||||
Q('resetpasswordformargs').value = urlargs;
|
||||
}
|
||||
|
||||
//var webPageFullScreen = getstore('webPageFullScreen', true);
|
||||
//if (webPageFullScreen == 'false') { webPageFullScreen = false; }
|
||||
//if (webPageFullScreen == 'true') { webPageFullScreen = true; }
|
||||
//toggleFullScreen();
|
||||
|
||||
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 (features & 0x200000) { // Email is username
|
||||
QH('loginusername', "Email:");
|
||||
QH('resetAccountSpan', "Esqueceu a senha?");
|
||||
QV('nuUserRow', false);
|
||||
}
|
||||
|
||||
if (nightMode) { QC('body').add('night'); }
|
||||
|
||||
QV('createPanelHint', passRequirements.hint === true);
|
||||
QV('resetpasswordpanelHint', passRequirements.hint === true);
|
||||
|
||||
// Display the welcome text
|
||||
if (welcomeText) { QH('welcomeText', welcomeText); }
|
||||
QH('welcomeText', addTextLink('MeshCentral', Q('welcomeText').innerHTML, 'http://www.meshcommander.com/meshcentral2'));
|
||||
QV('welcomeText', true);
|
||||
|
||||
window.onresize = center;
|
||||
center();
|
||||
|
||||
validateLogin();
|
||||
validateCreate();
|
||||
if (loginMode.length != 0) { go(parseInt(loginMode)); } else { go(1); }
|
||||
QV('newAccountDiv', (newAccount === '1') || (newAccount === 'true')); // If new accounts are not allowed, don't display the new account link.
|
||||
if ((passhint != null) && (passhint.length > 0)) { QV('showPassHintLink', true); }
|
||||
QV('newAccountPass', (newAccountPass == 1));
|
||||
QV('resetAccountDiv', (emailCheck == true));
|
||||
QV('hrAccountDiv', (emailCheck == true) || (newAccountPass == 1));
|
||||
|
||||
if (loginMode == '4') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
QV('securityKeyButton', (hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn'));
|
||||
}
|
||||
|
||||
if (loginMode == '5') {
|
||||
try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('resetHwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('resetTokenOkButton', true);
|
||||
Q('resetTokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the user interface in the right mode
|
||||
userInterfaceSelectMenu();
|
||||
}
|
||||
|
||||
// Use a hardware security key
|
||||
function useSecurityKey() {
|
||||
if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
|
||||
if (typeof hardwareKeyChallenge.challenge == 'string') { hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer; }
|
||||
|
||||
publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
|
||||
for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
|
||||
publicKeyCredentialRequestOptions.allowCredentials.push(
|
||||
{ id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
|
||||
);
|
||||
}
|
||||
|
||||
// New WebAuthn hardware keys
|
||||
navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
|
||||
function (rawAssertion) {
|
||||
var assertion = {
|
||||
id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
|
||||
clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
|
||||
userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
|
||||
signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
|
||||
authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
|
||||
};
|
||||
Q('hwtokenInput').value = JSON.stringify(assertion);
|
||||
QE('tokenOkButton', true);
|
||||
Q('tokenOkButton').click();
|
||||
},
|
||||
function (error) { console.log('credentials-get error', error); }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function showPassHint(e) {
|
||||
messagebox("Dica de Senha", passhint);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function xgo(x, e) {
|
||||
QV('message1', false);
|
||||
QV('message2', false);
|
||||
QV('message3', false);
|
||||
QV('message4', false);
|
||||
QV('message5', false);
|
||||
QV('message6', false);
|
||||
go(x);
|
||||
haltEvent(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
function go(x) {
|
||||
currentpanel = x;
|
||||
setDialogMode(0);
|
||||
QV('showPassHintLink', false);
|
||||
QV('loginpanel', x == 1);
|
||||
QV('createpanel', x == 2);
|
||||
QV('resetpanel', x == 3);
|
||||
QV('tokenpanel', x == 4);
|
||||
QV('resettokenpanel', x == 5);
|
||||
QV('resetpasswordpanel', x == 6);
|
||||
if (x == 1) { Q('username').focus(); }
|
||||
if (x == 2) { if (features & 0x200000) { Q('aemail').focus(); } else { Q('ausername').focus(); } } // Email is username
|
||||
if (x == 3) { Q('remail').focus(); }
|
||||
if (x == 4) { Q('tokenInput').focus(); }
|
||||
if (x == 5) { Q('resetTokenInput').focus(); }
|
||||
if (x == 6) { Q('rapassword1').focus(); }
|
||||
}
|
||||
|
||||
function validateLogin(box, e) {
|
||||
var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
|
||||
QE('loginButton', ok);
|
||||
setDialogMode(0);
|
||||
if ((e != null) && (e.keyCode == 13)) { if ((box == 1) && (Q('username').value != '')) { Q('password').focus(); } else if ((box == 2) && (Q('password').value != '')) { Q('loginButton').click(); } }
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
function validateCreate(box, e) {
|
||||
setDialogMode(0);
|
||||
var userok = false;
|
||||
if (features & 0x200000) { userok = true; } else { userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (Q('ausername').value.indexOf('"') == -1) && (Q('ausername').value.indexOf(',') == -1); }
|
||||
var emailok = (validateEmail(Q('aemail').value) == true);
|
||||
var pass1ok = (Q('apassword1').value.length > 0);
|
||||
var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
|
||||
var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
|
||||
var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
|
||||
|
||||
// Color the fields
|
||||
QS('nuUser').color = userok?'black':'#7b241c';
|
||||
QS('nuEmail').color = emailok?'black':'#7b241c';
|
||||
QS('nuPass1').color = pass1ok?'black':'#7b241c';
|
||||
QS('nuPass2').color = pass2ok?'black':'#7b241c';
|
||||
QS('nuToken').color = newAccOk?'black':'#7b241c';
|
||||
|
||||
if (Q('apassword1').value == '') {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('apassword1').value);
|
||||
if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>' + "Senha forte" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>' + "Boa senha" + '</b><span>'); }
|
||||
else { QH('passWarning', '<span style=color:red><b>' + "Senha fraca" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('nuPass1').color = '#7b241c';
|
||||
QS('nuPass2').color = '#7b241c';
|
||||
QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Política de senha" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('passwordPolicyCallout', true);
|
||||
QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
|
||||
} else {
|
||||
QH('passWarning', '');
|
||||
QV('passwordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
|
||||
if ((box == 1) && userok) { Q('aemail').focus(); }
|
||||
if ((box == 2) && emailok) { Q('apassword1').focus(); }
|
||||
if ((box == 3) && pass1ok) { Q('apassword2').focus(); }
|
||||
if ((box == 4) && pass2ok) { if (passRequirements.hint === true) { Q('apasswordhint').focus(); } else { box = 5; } }
|
||||
if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { box = 6; } }
|
||||
if (box == 6) { Q('createButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('createButton', ok);
|
||||
}
|
||||
|
||||
function validatePassReset(box, e) {
|
||||
setDialogMode(0);
|
||||
var pass1ok = (Q('rapassword1').value.length > 0);
|
||||
var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
|
||||
var ok = (pass1ok && pass2ok);
|
||||
|
||||
// Color the fields
|
||||
QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
|
||||
QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
|
||||
|
||||
if (Q('rapassword1').value == '') {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
} else {
|
||||
if (!passRequirementsEx) {
|
||||
// No password requirements, display password strength
|
||||
var passStrength = checkPasswordStrength(Q('rapassword1').value);
|
||||
if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>' + "Senha forte" + '</b><span>'); }
|
||||
else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>' + "Boa senha" + '</b><span>'); }
|
||||
else { QH('rpassWarning', '<span style=color:red><b>' + "Senha fraca" + '</b><span>'); }
|
||||
} else {
|
||||
// Password requirements provided, use that
|
||||
var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
|
||||
if (passReq == false) {
|
||||
ok = false;
|
||||
QS('rnuPass1').color = '#7b241c';
|
||||
QS('rnuPass2').color = '#7b241c';
|
||||
QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>' + "Política de senha" + '</b><div>'); // This is also a link to the password policy
|
||||
QV('rpasswordPolicyCallout', true);
|
||||
QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
|
||||
} else {
|
||||
QH('rpassWarning', '');
|
||||
QV('rpasswordPolicyCallout', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((e != null) && (e.keyCode == 13)) {
|
||||
if (box == 2) { Q('rapassword1').focus(); }
|
||||
if (box == 3) { Q('rapassword2').focus(); }
|
||||
if (box == 4) { Q('rapasswordhint').focus(); }
|
||||
if (box == 6) { Q('resetPassButton').click(); }
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
QE('resetPassButton', ok);
|
||||
}
|
||||
|
||||
function passwordPolicyText(pass) {
|
||||
var policy = '<div style=text-align:left>';
|
||||
var counts = strCount(pass);
|
||||
if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += format("Comprimento mínimo de {0}", passRequirements.min) + '<br />'; }
|
||||
if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += format("Comprimento máximo de {0}", passRequirements.max) + '<br />'; }
|
||||
if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += format("{0} maiúsculas", passRequirements.upper) + '<br />'; }
|
||||
if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += format("{0} letras minúsculas", passRequirements.lower) + '<br />'; }
|
||||
if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += format("{0} numérico", passRequirements.numeric) + '<br />'; }
|
||||
if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += format("{0} não alfanumérico", passRequirements.nonalpha) + '<br />'; }
|
||||
policy += '</div>';
|
||||
return policy;
|
||||
}
|
||||
|
||||
function showPasswordPolicy() {
|
||||
messagebox("Política de senha", passwordPolicyText());
|
||||
}
|
||||
|
||||
function validateReset(e) {
|
||||
setDialogMode(0);
|
||||
var x = validateEmail(Q('remail').value);
|
||||
QE('eresetButton', x);
|
||||
if ((e != null) && (e.keyCode == 13) && (x == true)) {
|
||||
Q('eresetButton').click();
|
||||
}
|
||||
if (e != null) { haltEvent(e); }
|
||||
}
|
||||
|
||||
// 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 counts = strCount(password);
|
||||
if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
|
||||
if (requirements.lower && (counts.lower < requirements.lower)) return false;
|
||||
if (requirements.upper && (counts.upper < requirements.upper)) return false;
|
||||
if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function strCount(password) {
|
||||
var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
|
||||
if (typeof password != 'string') return counts;
|
||||
for (var i = 0; i < password.length; i++) {
|
||||
if (/\d/.test(password[i])) { counts.numeric++; }
|
||||
if (/[a-z]/.test(password[i])) { counts.lower++; }
|
||||
if (/[A-Z]/.test(password[i])) { counts.upper++; }
|
||||
if (/\W/.test(password[i])) { counts.nonalpha++; }
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function checkToken() {
|
||||
var t1 = Q('tokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('tokenInput').value = t2; }
|
||||
QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
function resetCheckToken() {
|
||||
var t1 = Q('resetTokenInput').value;
|
||||
var t2 = t1.split(' ').join('');
|
||||
if (t1 != t2) { Q('resetTokenInput').value = t2; }
|
||||
QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
|
||||
}
|
||||
|
||||
//
|
||||
// POPUP DIALOG
|
||||
//
|
||||
|
||||
// undefined = Hidden, 1 = Generic Message
|
||||
var xxdialogMode;
|
||||
var xxdialogFunc;
|
||||
var xxdialogButtons;
|
||||
var xxdialogTag;
|
||||
var xxcurrentView = 0;
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
var f = xxdialogFunc;
|
||||
var b = xxdialogButtons;
|
||||
var t = xxdialogTag;
|
||||
setDialogMode();
|
||||
if (((b & 8) || x) && f) f(x, t);
|
||||
}
|
||||
|
||||
// Toggle the web page to full screen
|
||||
function toggleFullScreen(toggle) {
|
||||
//if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
|
||||
if (webPageFullScreen == false) {
|
||||
// By adding body class, it will change a style of all ellements using CSS selector
|
||||
// No need for JS anymore and it will be consistent style for all the templates.
|
||||
QC('body').remove('fullscreen');
|
||||
} else {
|
||||
QC('body').add('fullscreen');
|
||||
}
|
||||
QV('body', true);
|
||||
center();
|
||||
}
|
||||
|
||||
// Toggle user interface menu
|
||||
function showUserInterfaceSelectMenu() {
|
||||
Q('uiViewButton1').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton2').classList.remove('uiSelectorSel');
|
||||
Q('uiViewButton3').classList.remove('uiSelectorSel');
|
||||
try { Q('uiViewButton' + uiMode).classList.add('uiSelectorSel'); } catch (ex) { }
|
||||
QV('uiMenu', (QS('uiMenu').display == 'none'));
|
||||
if (nightMode) { Q('uiViewButton4').classList.add('uiSelectorSel'); }
|
||||
}
|
||||
|
||||
function userInterfaceSelectMenu(s) {
|
||||
if (s) { uiMode = s; putstore('uiMode', uiMode); }
|
||||
webPageFullScreen = (uiMode < 3);
|
||||
//webPageStackMenu = (uiMode > 1);
|
||||
toggleFullScreen(0);
|
||||
//toggleStackMenu(0);
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
nightMode = !nightMode;
|
||||
if (nightMode) { QC('body').add('night'); } else { QC('body').remove('night'); }
|
||||
putstore('_nightMode', (nightMode ? '1' : '0'));
|
||||
}
|
||||
|
||||
function center() {
|
||||
/* Now we use CSS media to achive the same effect as deleted JS */
|
||||
if (webPageFullScreen == false) {
|
||||
QS('centralTable')['margin-top'] = '';
|
||||
} else {
|
||||
var h = ((Q('column_l').clientHeight) / 2) - 220;
|
||||
if (h < 0) h = 0;
|
||||
QS('centralTable')['margin-top'] = h + 'px';
|
||||
}
|
||||
}
|
||||
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); } // New version
|
||||
function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
|
||||
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 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href=\"' + link + '\">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
||||
</script>
|
||||
|
||||
</body></html>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title}}} - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>Podmínky & soukromí</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title}}} - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>Terms & Privacy</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title}}} - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>利用規約とプライバシー</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title}}} - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>Voorwaarden & Privacy</a></table></div></div></div>
|
@ -1 +0,0 @@
|
||||
<!doctypehtml><html dir=ltr xmlns=http://www.w3.org/1999/xhtml><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,initial-scale=1,minimum-scale=1,maximum-scale=1"><meta name=apple-mobile-web-app-capable content=yes><meta name=format-detection content="telephone=no"><link type=text/css href=/styles/style.css media=screen rel=stylesheet title=CSS><title>{{{title}}} - {{{title3}}}</title><div id=container style=max-height:100vh><div id=mastheadx></div><div id=masthead style="background:url(logo.png) 0 0;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"><div style=float:left>{{{titlehtml}}}</div><div style=float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px><strong><font style=font-size:46px;font-family:Arial,Helvetica,sans-serif>{{{title1}}}</font></strong></div><div style=float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px><strong><font style=font-size:14px;font-family:Arial,Helvetica,sans-serif>{{{title2}}}</font></strong></div></div><div id=page_content style=max-height:calc(100vh-138px)><div id=column_l><h1>{{{title3}}}</h1><p style=margin-left:20px>{{{message}}}</p><br></div><div id=footer><table cellpadding=0 cellspacing=10 style=width:100%><tr><td style=text-align:left><td style=text-align:right><a href=terms>Termos & Privacidade</a></table></div></div></div>
|
@ -1,41 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title}}} - {{{title3}}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>{{{title3}}}</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
<a href="terms">Podmínky & soukromí</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,41 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title}}} - {{{title3}}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>{{{title3}}}</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
<a href="terms">Terms & Privacy</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,41 +0,0 @@
|
||||
<!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 type="text/css" href="/styles/style.css" media="screen" rel="stylesheet" title="CSS">
|
||||
<title>{{{title}}} - {{{title3}}}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container" style="max-height:100vh">
|
||||
<div id="mastheadx"></div>
|
||||
<div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden">
|
||||
<div style="float:left">{{{titlehtml}}}</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:14px;padding-top:7px">
|
||||
<strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title1}}}</font></strong>
|
||||
</div>
|
||||
<div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px">
|
||||
<strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page_content" style="max-height:calc(100vh-138px)">
|
||||
<div id="column_l">
|
||||
<h1>{{{title3}}}</h1>
|
||||
<p style="margin-left:20px">{{{message}}}</p>
|
||||
<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<table cellpadding="0" cellspacing="10" style="width:100%">
|
||||
<tbody><tr>
|
||||
<td style="text-align:left"></td>
|
||||
<td style="text-align:right">
|
||||
<a href="terms">利用規約とプライバシー</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body></html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user