18978: Disable webshell idle timeout when 0.
[arvados-workbench2.git] / public / webshell / index.html
index 3f25aed59b4447a9817f66d1fdd5a722211f19de..aae70a97afab13a30a553eb2a6196d2a074f9484 100644 (file)
@@ -6,6 +6,18 @@
       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() {
                          '</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 login(username, token) {
-        const urlParams = new URLSearchParams(window.location.search);
-        var sh = new ShellInABox(urlParams.get('host'));
+      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");
         }
 
         var trySendToken = function() {
-          var token = urlParams.get('token');
-          if (token) {
-            history.replaceState(null, "", `/webshell/?host=${encodeURIComponent(urlParams.get('host'))}&login=${encodeURIComponent(urlParams.get('login'))}`)
-          } else if (localStorage.getItem('apiToken')) {
-            token = localStorage.getItem('apiToken');
-          } else {
-            // No token
-          }
           // 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() {
-          var login = urlParams.get('login');
           if (findText("login:")) {
-            sh.keysPressed(login + "\n");
+            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);
 
         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>
        correctly deal with the enclosing frameset (if any), if we do not
        do this
    -->
-<body onload="setTimeout(login, 1000)"
+<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>