Files
guacamole-client/guacamole/src/main/webapp/index.xhtml
2012-11-05 10:48:10 -08:00

322 lines
12 KiB
HTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<!--
Guacamole - Clientless Remote Desktop
Copyright (C) 2010 Michael Jumper
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="icon" type="image/png" href="images/guacamole-logo-64.png"/>
<link rel="apple-touch-icon" type="image/png" href="images/guacamole-logo-144.png"/>
<link rel="stylesheet" type="text/css" href="styles/login.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>Guacamole ${project.version}</title>
</head>
<body>
<div id="login-ui" style="display: none">
<div id="login-dialog-middle">
<div id="login-dialog">
<p id="login-error"></p>
<form id="login-form" action="#" method="post">
<div id="login-fields">
<table>
<tr>
<th>Username</th>
<td><input type="text" name="username" id="username" autofocus="autofocus"/></td>
</tr>
<tr>
<th>Password</th>
<td><input type="password" name="password" id="password"/></td>
</tr>
</table>
<img class="logo" src="images/guac-mono-192.png" alt=""/>
</div>
<div id="buttons">
<input type="submit" name="login" id="login" value="Login"/>
</div>
</form>
</div>
</div>
</div>
<!-- Connection list UI -->
<div id="connection-list-ui" style="display: none">
<div id="logout-panel">
<button id="logout">Logout</button>
</div>
<h2>Recent Connections</h2>
<div id="recent-connections">
<p id="no-recent">No recent connections.</p>
</div>
<h2>Other Connections</h2>
<div id="other-connections">
</div>
<h2>Clipboard</h2>
<div id="clipboardDiv">
<p>
Text copied/cut within Guacamole will appear here. Changes to the text will affect the remote clipboard, and will be pastable within the remote desktop. Use the textbox below as an interface between the client and server clipboards.
</p>
<textarea rows="10" cols="40" id="clipboard"></textarea>
</div>
</div>
<div id="version-dialog">
Guacamole ${project.version}
</div>
<script type="text/javascript" src="scripts/connections.js"></script>
<script type="text/javascript" src="scripts/session.js"></script>
<!-- Init -->
<script type="text/javascript"> /* <![CDATA[ */
var state = new GuacamoleSessionState();
var clipboard = document.getElementById("clipboard");
clipboard.onchange = function() {
state.setProperty("clipboard", clipboard.value);
};
state.onchange = function(old_state, new_state, name) {
if (name == "clipboard")
clipboard.value = new_state[name];
};
// Update clipboard with current data
if (state.getProperty("clipboard"))
clipboard.value = state.getProperty("clipboard");
// Constructs the URL for a client which connects to the connection
// with the given id.
function getClientURL(id) {
// Construct URL for client with given id
return "client.xhtml?id=" + encodeURIComponent(id);
}
// Resets the interface such that the login UI is displayed if
// the user is not authenticated (or authentication fails) and
// the connection list UI (or the client for the only available
// connection, if there is only one) is displayed if the user is
// authenticated.
function resetUI() {
// Get parameters from query string
var parameters = window.location.search.substring(1);
var configs;
try {
configs = getConfigList(parameters);
}
catch (e) {
// Show login UI if unable to get configs
loginUI.style.display = "";
connectionListUI.style.display = "none";
return;
}
// Remove all rows from connections list
var recent_connections = document.getElementById("recent-connections");
var other_connections = document.getElementById("other-connections");
var no_recent_connections = document.getElementById("no-recent");
// Get thumbnail set from local storage
if (localStorage) {
var thumbnails = {};
try {
var thumbnail_json = localStorage.getItem("GUAC_THUMBNAILS");
if (thumbnail_json)
thumbnails = JSON.parse(thumbnail_json);
}
catch (e) {}
}
else
document.body.className += " history-unavailable";
// Add connection icons
for (var i=0; i<configs.length; i++) {
// Create connection display elements
var connection = document.createElement("div");
connection.className = "connection";
var caption = document.createElement("div");
caption.className = "caption";
var protocol = document.createElement("div");
protocol.className = "protocol";
var id = document.createElement("span");
id.className = "name";
var protocolIcon = document.createElement("div");
protocolIcon.className = "icon " + configs[i].protocol;
var thumbnail = document.createElement("div");
thumbnail.className = "thumbnail";
function new_client(id) {
// Get URL
var url = getClientURL(id)
return function() {
// Attempt to focus existing window
var current = window.open(null, id);
// If window did not already exist, set up as
// Guacamole client
if (!current.GuacamoleUI)
window.open(url, id);
};
}
// Create link to client
connection.onclick = new_client(configs[i].id);
protocol.appendChild(protocolIcon);
id.textContent = configs[i].id;
// Assemble caption
caption.appendChild(protocol);
caption.appendChild(id);
// Assemble connection icon
connection.appendChild(thumbnail);
connection.appendChild(caption);
// Add screenshot if available
var thumbnail_url = thumbnails[configs[i].id];
if (thumbnail_url) {
var img = document.createElement("img");
img.src = thumbnail_url;
thumbnail.appendChild(img);
recent_connections.appendChild(connection);
no_recent_connections.style.display = "none";
}
else
other_connections.appendChild(connection);
}
// If configs could be retrieved, display list
loginUI.style.display = "none";
connectionListUI.style.display = "";
}
var loginForm = document.getElementById("login-form");
var loginUI = document.getElementById("login-ui");
var connectionListUI = document.getElementById("connection-list-ui");
var logout = document.getElementById("logout");
var username = document.getElementById("username");
var password = document.getElementById("password");
logout.onclick = function() {
window.location.href = "logout";
};
loginForm.onsubmit = function() {
// Get parameters from query string
var parameters = window.location.search.substring(1);
// Get username and password from form
var data =
"username=" + encodeURIComponent(username.value)
+ "&password=" + encodeURIComponent(password.value)
// Include query parameters in submission data
if (parameters) data += "&" + parameters;
try {
// Log in
var xhr = new XMLHttpRequest();
xhr.open("POST", "login", false);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(data);
// Handle failures
if (xhr.status != 200)
throw new Error("Invalid login");
// Ensure username/password fiels are blurred after submit
username.blur();
password.blur();
resetUI();
}
catch (e) {
var loginError = document.getElementById("login-error");
// Display error, reset and refocus password field
loginError.textContent = e.message;
password.value = "";
password.focus();
return false;
}
// On success, hide loginUI, get and show connection list.
return false;
}
// Turn off autocorrect and autocapitalization on usename
username.setAttribute("autocorrect", "off");
username.setAttribute("autocapitalize", "off");
resetUI();
/* ]]> */ </script>
</body>
</html>