Is it possible to determine if a user is inactive and automatically log them out after say 10 minutes of inactivity using angularjs?
I was trying to avoid using jQue
I would like to expand the answers to whoever might be using this in a bigger project, you could accidentally attach multiple event handlers and the program would behave weirdly.
To get rid of that, I used a singleton function exposed by a factory, from which you would call inactivityTimeoutFactory.switchTimeoutOn() and inactivityTimeoutFactory.switchTimeoutOff() in your angular application to respectively activate and deactivate the logout due to inactivity functionality.
This way you make sure you are only running a single instance of the event handlers, no matter how many times you try to activate the timeout procedure, making it easier to use in applications where the user might login from different routes.
Here is my code:
'use strict';
angular.module('YOURMODULENAME')
.factory('inactivityTimeoutFactory', inactivityTimeoutFactory);
inactivityTimeoutFactory.$inject = ['$document', '$timeout', '$state'];
function inactivityTimeoutFactory($document, $timeout, $state) {
function InactivityTimeout () {
// singleton
if (InactivityTimeout.prototype._singletonInstance) {
return InactivityTimeout.prototype._singletonInstance;
}
InactivityTimeout.prototype._singletonInstance = this;
// Timeout timer value
const timeToLogoutMs = 15*1000*60; //15 minutes
const timeToWarnMs = 13*1000*60; //13 minutes
// variables
let warningTimer;
let timeoutTimer;
let isRunning;
function switchOn () {
if (!isRunning) {
switchEventHandlers("on");
startTimeout();
isRunning = true;
}
}
function switchOff() {
switchEventHandlers("off");
cancelTimersAndCloseMessages();
isRunning = false;
}
function resetTimeout() {
cancelTimersAndCloseMessages();
// reset timeout threads
startTimeout();
}
function cancelTimersAndCloseMessages () {
// stop any pending timeout
$timeout.cancel(timeoutTimer);
$timeout.cancel(warningTimer);
// remember to close any messages
}
function startTimeout () {
warningTimer = $timeout(processWarning, timeToWarnMs);
timeoutTimer = $timeout(processLogout, timeToLogoutMs);
}
function processWarning() {
// show warning using popup modules, toasters etc...
}
function processLogout() {
// go to logout page. The state might differ from project to project
$state.go('authentication.logout');
}
function switchEventHandlers(toNewStatus) {
const body = angular.element($document);
const trackedEventsList = [
'keydown',
'keyup',
'click',
'mousemove',
'DOMMouseScroll',
'mousewheel',
'mousedown',
'touchstart',
'touchmove',
'scroll',
'focus'
];
trackedEventsList.forEach((eventName) => {
if (toNewStatus === 'off') {
body.off(eventName, resetTimeout);
} else if (toNewStatus === 'on') {
body.on(eventName, resetTimeout);
}
});
}
// expose switch methods
this.switchOff = switchOff;
this.switchOn = switchOn;
}
return {
switchTimeoutOn () {
(new InactivityTimeout()).switchOn();
},
switchTimeoutOff () {
(new InactivityTimeout()).switchOff();
}
};
}