From ea76bd74a7d11f6aa2f65da3c56251a4aa40cf12 Mon Sep 17 00:00:00 2001 From: Stephen Smith Date: Mon, 20 Sep 2021 13:03:44 -0400 Subject: [PATCH] 17229: Webshell add idle timer and auto log out Arvados-DCO-1.1-Signed-off-by: Stephen Smith --- public/webshell/index.html | 29 ++++++++++++++++++- .../virtual-machine-user-panel.tsx | 7 +++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/public/webshell/index.html b/public/webshell/index.html index 722cab5a..126962b6 100644 --- a/public/webshell/index.html +++ b/public/webshell/index.html @@ -41,8 +41,31 @@ 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.sendKeys('03'); // Ctrl + c + sh.sendKeys('04'); // Ctrl + d + } else { + setTimeout(checkIdleTimer, 1000); + } + } + function login() { sh = new ShellInABox(host); @@ -63,6 +86,10 @@ sh.keysPressed(token + "\n"); sh.vt100('(sent authentication token)\n'); token = null; + updateIdleTimer(); + document.body.onmousemove = updateIdleTimer; + document.body.onkeydown = updateIdleTimer; + setTimeout(checkIdleTimer, 1000); } else { setTimeout(trySendToken, 200); } @@ -84,7 +111,7 @@ function init() { if (token) { - history.replaceState(null, "", `/webshell/?host=${encodeURIComponent(host)}&login=${encodeURIComponent(user)}`); + history.replaceState(null, "", `/webshell/?host=${encodeURIComponent(host)}&timeout=${timeout}&login=${encodeURIComponent(user)}`); } else if (localStorage.getItem('apiToken')) { token = localStorage.getItem('apiToken'); } else { diff --git a/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx b/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx index 196cba16..c0f33644 100644 --- a/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx +++ b/src/views/virtual-machine-panel/virtual-machine-user-panel.tsx @@ -14,6 +14,7 @@ import { ListResults } from 'services/common-service/common-service'; import { HelpIcon } from 'components/icon/icon'; import { SESSION_STORAGE } from "services/auth-service/auth-service"; // import * as CopyToClipboard from 'react-copy-to-clipboard'; +import parse from "parse-duration"; type CssRules = 'button' | 'codeSnippet' | 'link' | 'linkIcon' | 'rightAlign' | 'cardWithoutMachines' | 'icon'; @@ -67,6 +68,7 @@ const mapStateToProps = (state: RootState) => { token: state.auth.extraApiToken || state.auth.apiToken || '', tokenLocation: state.auth.extraApiToken ? EXTRA_TOKEN : (state.auth.apiTokenLocation || ''), webshellUrl: state.auth.config.clusterConfig.Services.WebShell.ExternalURL, + idleTimeout: parse(state.auth.config.clusterConfig.Workbench.IdleTimeout, 's') || 0, ...state.virtualMachines }; }; @@ -84,8 +86,9 @@ interface VirtualMachinesPanelDataProps { helpText: string; hostSuffix: string; token: string; - tokenLocation: string, + tokenLocation: string; webshellUrl: string; + idleTimeout: number; } interface VirtualMachinesPanelActionProps { @@ -192,7 +195,7 @@ const virtualMachinesTable = (props: VirtualMachineProps) => {command} - + Log in as {username} -- 2.30.2