Skip to content

Commit

Permalink
Merge pull request #232 from constantine2nd/develop
Browse files Browse the repository at this point in the history
Add user inactivity log off feature
  • Loading branch information
simonredfern authored Nov 17, 2023
2 parents 76f2603 + 28d9433 commit 6fa267e
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 1 deletion.
36 changes: 36 additions & 0 deletions src/main/webapp/media/js/inactivity-timer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
function addSeconds(date, seconds) {
date.setSeconds(date.getSeconds() + seconds);
return date;
}

export function showCountdownTimer() {

// Get current date and time
var now = new Date().getTime();
let distance = countDownDate - now;

// Output the result in an element with id="countdown-timer-span"
let elementId = ("countdown-timer-span");
document.getElementById(elementId).innerHTML = "in " + Math.floor(distance / 1000) + "s";

// If the count down is over release resources
if (distance < 0) {
destroyCountdownTimer();
}
}


// Set the date we're counting down to
let countDownDate = addSeconds(new Date(), 5);

let showTimerInterval = null;

export function destroyCountdownTimer() {
clearInterval(showTimerInterval);
}

export function resetCountdownTimer(seconds) {
destroyCountdownTimer(); // Destroy previous timer if any
countDownDate = addSeconds(new Date(), seconds); // Set the date we're counting down to
showTimerInterval = setInterval(showCountdownTimer, 1000); // Update the count down every 1 second
}
105 changes: 105 additions & 0 deletions src/main/webapp/media/js/inactivity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import * as countdownTimer from './inactivity-timer.js'

// holds the idle duration in ms (current value = 301 seconds)
var timeoutIntervalInMillis = 5 * 60 * 1000 + 1000;
// holds the timeout variables for easy destruction and reconstruction of the setTimeout hooks
var timeHook = null;

function initializeTimeHook() {
// this method has the purpose of creating our timehooks and scheduling the call to our logout function when the idle time has been reached
if (timeHook == null) {
timeHook = setTimeout( function () { destroyTimeHook(); logout(); }.bind(this), timeoutIntervalInMillis);
}
}

function destroyTimeHook() {
// this method has the sole purpose of destroying any time hooks we might have created
clearTimeout(timeHook);
timeHook = null;
}

function resetTimeHook(event) {
// this method replaces the current time hook with a new time hook
destroyTimeHook();
initializeTimeHook();
countdownTimer.resetCountdownTimer(timeoutIntervalInMillis / 1000);
// show event type, element and coordinates of the click
// console.log(event.type + " at " + event.currentTarget);
// console.log("Coordinates: " + event.clientX + ":" + event.clientY);
console.log("Reset inactivity of a user");
}

function setupListeners() {
// here we setup the event listener for the mouse click operation
document.addEventListener("click", resetTimeHook);
document.addEventListener("mousemove", resetTimeHook);
document.addEventListener("mousedown", resetTimeHook);
document.addEventListener("keypress", resetTimeHook);
document.addEventListener("touchmove", resetTimeHook);
console.log("Listeners for user inactivity activated");
}

function destroyListeners() {
// here we destroy event listeners for the mouse click operation
document.removeEventListener("click", resetTimeHook);
document.removeEventListener("mousemove", resetTimeHook);
document.removeEventListener("mousedown", resetTimeHook);
document.removeEventListener("keypress", resetTimeHook);
document.removeEventListener("touchmove", resetTimeHook);
console.log("Listeners for user inactivity deactivated");
}

function logout() {
destroyListeners();
countdownTimer.destroyCountdownTimer();
console.log("Logging you out due to inactivity..");
const logoffButton = document.getElementById("logout");
logoffButton.click();
}

async function makeObpApiCall() {
let timeoutInSeconds;
try {
let obpApiHost = document.getElementById("api_home_link");
if(obpApiHost) {
obpApiHost = obpApiHost.href.split("?")[0];
}
console.log(obpApiHost);
const response = await fetch(`${obpApiHost}/obp/v5.1.0/ui/suggested-session-timeout`);
const json = await response.json();
if(json.timeout_in_seconds) {
timeoutInSeconds = json.timeout_in_seconds;
console.log(`Suggested value ${timeoutInSeconds} is used`);
} else {
timeoutInSeconds = 5 * 60 + 1; // Set default value to 301 seconds
console.log(`Default value ${timeoutInSeconds} is used`);
}
} catch (e) {
console.error(e);
}
return timeoutInSeconds;
}

async function getSuggestedSessionTimeout() {
if(!sessionStorage.getItem("suggested-session-timeout-in-seconds")) {
let timeoutInSeconds = await makeObpApiCall();
sessionStorage.setItem("suggested-session-timeout-in-seconds", timeoutInSeconds);
}
return sessionStorage.getItem("suggested-session-timeout-in-seconds") * 1000 + 1000; // We need timeout in millis
}

// self executing function to trigger the operation on page load
(async function () {
timeoutIntervalInMillis = await getSuggestedSessionTimeout(); // Try to get suggested value
const logoffButton = document.getElementById("countdown-timer-span");
if(logoffButton) {
// to prevent any lingering timeout handlers preventing memory leaks
destroyTimeHook();
// setup a fresh time hook
initializeTimeHook();
// setup initial event listeners
setupListeners();
// Reset countdown timer
countdownTimer.resetCountdownTimer(timeoutIntervalInMillis / 1000);
}
})();
5 changes: 4 additions & 1 deletion src/main/webapp/templates-hidden/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
<script src="/media/js/scripts.js"></script>
<script src="/media/js/select2.min.js"></script>
<script src="/media/js/website.js"></script>

<!-- The script loads “in the background”, and then runs when the DOM is fully built. -->
<script type="module" defer src="/media/js/inactivity.js"></script>
</head>


Expand Down Expand Up @@ -93,7 +96,7 @@
<div class="logged-in">
<span class="username"></span>
<a class="settings-imgs__link" id="logout" href="#">
<span class="logout-link"><lift:loc locid="logoff">Log off</lift:loc></span>
<span class="logout-link"><lift:loc locid="logoff">Log off <span id="countdown-timer-span" class="badge text-bg-primary"></span></lift:loc></span>
</a>
</div>
</div>
Expand Down

0 comments on commit 6fa267e

Please sign in to comment.