18874: Add 'services/workbench2/' from commit 'f6f88d9ca9cdeeeebfadcfe999789bfb9f69e5c6'
[arvados.git] / services / workbench2 / public / webshell / index.html
diff --git a/services/workbench2/public/webshell/index.html b/services/workbench2/public/webshell/index.html
new file mode 100644 (file)
index 0000000..aae70a9
--- /dev/null
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+    <head>
+    <title></title>
+    <link rel="stylesheet" href="styles.css" type="text/css">
+    <style type="text/css">
+      body {
+        margin: 0px;
+      }
+      #notoken {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        text-align: center;
+        vertical-align: middle;
+        line-height: 100vh;
+        z-index: 100;
+        font-family: sans;
+      }
+    </style>
+    <script type="text/javascript"><!--
+      (function() {
+        // We would like to hide overflowing lines as this can lead to
+        // visually jarring results if the browser substitutes oversized
+        // Unicode characters from different fonts. Unfortunately, a bug
+        // in Firefox prevents it from allowing multi-line text
+        // selections whenever we change the "overflow" style. So, only
+        // do so for non-Netscape browsers.
+        if (typeof navigator.appName == 'undefined' ||
+            navigator.appName != 'Netscape') {
+          document.write('<style type="text/css">' +
+                         '#vt100 #console div, #vt100 #alt_console div {' +
+                         '  overflow: hidden;' +
+                         '}' +
+                         '</style>');
+        }
+      })();
+      var sh;
+      var urlParams = new URLSearchParams(window.location.search);
+      var token = urlParams.get('token');
+      var user = urlParams.get('login');
+      var host = urlParams.get('host');
+      var timeout = urlParams.get('timeout');
+      urlParams = null;
+
+      var idleTimeoutMs = timeout * 1000;
+
+      function updateIdleTimer() {
+        var currentTime = Date.now();
+        var lastTime = localStorage.getItem('lastActiveTimestamp');
+        if (currentTime - lastTime > 1000) {
+          localStorage.setItem('lastActiveTimestamp', currentTime);
+        }
+      }
+
+      function checkIdleTimer() {
+        var currentTime = Date.now();
+        var lastTime = localStorage.getItem('lastActiveTimestamp');
+        if (currentTime - lastTime > idleTimeoutMs) {
+          //logout
+          sh.reset();
+          sh.sessionClosed("Session timed out after " + timeout + " seconds.");
+          document.body.onmousemove = undefined;
+          document.body.onkeydown = undefined;
+        } else {
+          setTimeout(checkIdleTimer, 1000);
+        }
+      }
+
+      function login() {
+        sh = new ShellInABox(host);
+
+        var findText = function(txt) {
+          var a = document.querySelectorAll("span.ansi0");
+          for (var i = 0; i < a.length; i++) {
+            if (a[i].textContent.indexOf(txt) > -1) {
+              return true;
+            }
+          }
+          return false;
+        }
+
+        var trySendToken = function() {
+          // change this text when PAM is reconfigured to present a
+          // password prompt that we can wait for.
+          if (findText("assword:")) {
+             sh.keysPressed(token + "\n");
+             sh.vt100('(sent authentication token)\n');
+             token = null;
+             if (timeout > 0) {
+               updateIdleTimer();
+               document.body.onmousemove = updateIdleTimer;
+               document.body.onkeydown = updateIdleTimer;
+               setTimeout(checkIdleTimer, 1000);
+             }
+          } else {
+            setTimeout(trySendToken, 200);
+          }
+        };
+
+        var trySendLogin = function() {
+          if (findText("login:")) {
+            sh.keysPressed(user + "\n");
+            // Make this wait shorter when PAM is reconfigured to
+            // present a password prompt that we can wait for.
+            setTimeout(trySendToken, 200);
+          } else {
+            setTimeout(trySendLogin, 200);
+          }
+        };
+
+        trySendLogin();
+      }
+
+      function init() {
+        if (token) {
+          history.replaceState(null, "", `/webshell/?host=${encodeURIComponent(host)}&timeout=${timeout}&login=${encodeURIComponent(user)}`);
+        } else if (localStorage.getItem('apiToken')) {
+          token = localStorage.getItem('apiToken');
+        } else {
+          document.getElementById("notoken").style.display = "block";
+          return;
+        }
+        login();
+      }
+    // -->
+</script>
+    <script type="text/javascript" src="shell_in_a_box.js"></script>
+  </head>
+  <!-- Load ShellInABox from a timer as Konqueror sometimes fails to
+       correctly deal with the enclosing frameset (if any), if we do not
+       do this
+   -->
+<body onload="setTimeout(init, 1000)"
+    scroll="no"><noscript>JavaScript must be enabled for ShellInABox</noscript>
+    <div id="notoken" style="display: none;">
+      Error: No token found. Please return to <a href="/virtual-machines-user">Virtual Machines</a> and try again.
+    </div>
+</body>
+</html>