diff --git a/.gitignore b/.gitignore
index a4be63a..fd75410 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+dist
+
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..fa173a4
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,20 @@
+language: node_js
+node_js:
+ - 0.10
+ - 4
+ - 6
+ - 8
+
+before_install:
+ - npm install bower -g
+ - npm install gulp -g
+
+script:
+ - npm install
+ - bower install
+ - gulp
+
+cache:
+ directories:
+ - bower_components
+ - node_modules
diff --git a/dist/css/jquery-idleTimeout-plus.css b/dist/css/jquery-idleTimeout-plus.css
deleted file mode 100644
index a335c40..0000000
--- a/dist/css/jquery-idleTimeout-plus.css
+++ /dev/null
@@ -1,92 +0,0 @@
-.jitp-lock-back {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: #e9e9e9;
- cursor: no-drop;
- text-align: center;
-}
-
-.jitp-lock-panel {
- position: absolute;
- width: 40%;
- max-width: 400px;
-
- top: 50%;
- left: 50%;
- /*margin-top: -130px;*/
- /*margin-left: -180px;*/
- transform: translate(-50%, -50%);
-
- cursor: auto;
-}
-
-#jitp-lock-logout {
- display: block;
- padding-top: 8px;
-}
-
-.jitp-lock-panel .jitp-countdown-holder {
- font-weight: bold;
-}
-
-.jitp-lock-panel .panel-footer {
- font-size: 13px;
- padding-top: 5px;
- padding-bottom: 5px;
-}
-
-.jitp-lock-jqpanel {
- background-color: white;
- box-shadow: 0 0 20px rgba(0, 0, 0, 0.7);
- font-size: 16px;
- font-family: lato, serif;
- position: relative;
- color: #333;
- border-radius: 10px;
-}
-
-.jitp-lock-jqpanel header {
- background: #ED2553;
- padding: 15px 20px;
- color: white;
- font-size: 1.5em;
- font-weight: 600;
- border-radius: 10px 10px 0 0;
-}
-
-.jitp-lock-jqpanel #jitp-lock-pass {
- font-size: 1em;
-}
-
-
-.jitp-lock-jqpanel button {
- margin-top: 20px;
- margin-bottom: 5px;
- left: 50%;
- font-family: inherit;
- color: white;
- background: #FF3838;
- outline: none;
- border: none;
- padding: 5px 15px;
- font-size: 1.3em;
- font-weight: 400;
- border-radius: 3px;
- box-shadow: 0 0 10px rgba(51, 51, 51, 0.4);
- cursor: pointer;
- transition: all 0.15s ease-in-out;
-}
-
-.jitp-lock-jqpanel #jitp-lock-logout {
- padding-bottom: 8px;
-}
-
-.jitp-lock-jqpanel footer {
- background: #ED2553;
- padding: 8px 20px;
- color: white;
- border-radius: 0 0 10px 10px;
-}
\ No newline at end of file
diff --git a/dist/css/jquery-idleTimeout-plus.min.css b/dist/css/jquery-idleTimeout-plus.min.css
deleted file mode 100644
index 986ae71..0000000
--- a/dist/css/jquery-idleTimeout-plus.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.jitp-lock-back{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#e9e9e9;cursor:no-drop;text-align:center}.jitp-lock-panel{position:absolute;width:40%;max-width:400px;top:50%;left:50%;transform:translate(-50%,-50%);cursor:auto}#jitp-lock-logout{display:block;padding-top:8px}.jitp-lock-panel .jitp-countdown-holder{font-weight:700}.jitp-lock-panel .panel-footer{font-size:13px;padding-top:5px;padding-bottom:5px}.jitp-lock-jqpanel{background-color:#fff;box-shadow:0 0 20px rgba(0,0,0,.7);font-size:16px;font-family:lato,serif;position:relative;color:#333;border-radius:10px}.jitp-lock-jqpanel header{background:#ED2553;padding:15px 20px;color:#fff;font-size:1.5em;font-weight:600;border-radius:10px 10px 0 0}.jitp-lock-jqpanel #jitp-lock-pass{font-size:1em}.jitp-lock-jqpanel button{margin-top:20px;margin-bottom:5px;left:50%;font-family:inherit;color:#fff;background:#FF3838;outline:0;border:none;padding:5px 15px;font-size:1.3em;font-weight:400;border-radius:3px;box-shadow:0 0 10px rgba(51,51,51,.4);cursor:pointer;transition:all .15s ease-in-out}.jitp-lock-jqpanel #jitp-lock-logout{padding-bottom:8px}.jitp-lock-jqpanel footer{background:#ED2553;padding:8px 20px;color:#fff;border-radius:0 0 10px 10px}
\ No newline at end of file
diff --git a/dist/js/jquery-idleTimeout-plus-iframe.js b/dist/js/jquery-idleTimeout-plus-iframe.js
deleted file mode 100644
index 29f19e4..0000000
--- a/dist/js/jquery-idleTimeout-plus-iframe.js
+++ /dev/null
@@ -1,889 +0,0 @@
-/**
- * This work is licensed under the Creative Commons Attribution-Share Alike 3.0
- * United States License. To view a copy of this license,
- * visit http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter
- * to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
- *
- * Modified by: Jason Abraham (CrashSensei)
- * Email: jason@linearsoft.com
- *
- * Configurable idle (no activity) timer and logout redirect for jQuery.
- * Supports both jQueryUI dialogs or Bootstrap modals
- * Works across multiple windows, tabs from the same domain.
- * Additional support for iFrames (not extensively tested)
- *
- * Initially forked from Jill Elaine's jquery-idleTimeout
- * Bootstrap code and other code influenced by bootstrap-session-timeout by orangehill
- *
- * Dependencies: JQuery v1.7+,
- * Multi-window support requires JQuery Storage API
- * Dialogs require either jQueryUI or Bootstrap
- *
- * version 0.5.0
- **/
-
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- module.exports = factory(require('jquery'));
- } else {
- root.IdleTimeoutPlus = factory(root.jQuery);
- }
-}(this, function($) {
- //#########################################################################
- //### Config & Vars
- //#########################################################################
- var config = {
- // Idle settings
- idleTimeLimit: 1200, // 'No activity' time limit in seconds. 1200 = 20 Minutes
- idleCallback: false, // Called when the idleTimer is started (you can use this to close your custom warn/lock screens if needed)
- idleCheckHeartbeat: 2, // Frequency to check for idle timeouts in seconds
- bootstrap: false, // Use bootstrap framework instead of jQuery
- activityEvents: 'click keypress scroll wheel mousewheel mousemove touchmove', // configure which activity events to detect separate each event with a space, set to false for none
-
- // Warning settings
- warnEnabled: true, // set to false to skip warning period
- warnTimeLimit: 180, // 3 Minutes
- warnCallback: false, // Called when warning timer starts (wait dialog will only be shown if this returns true)
- warnContentCallback: false, // Called for content of warning dialog box (SEE DOCUMENTATION!)
- warnTitle: 'Session Timeout', // setting to null will remove the title bar
- warnMessage: 'Your session is about to expire!',
- warnStayAliveButton: 'Stay Connected',
- warnLogoutButton: 'Logout', // Set to null to disable
- warnCountdownMessage: 'Time remaining: {timer}', // Set to null to disable see doc on how to set
- warnCountdownBar: false,
-
- // Auto-Url settings (NOTE: if a callback is defined auto url redirection will only occur if the callback returns true)
- redirectUrl: '/timed-out', // URL if no action is taken after the warning/lock screen timeout
- logoutUrl: '/logout', // URL if the user clicks "Logout" on the warning/lock screen
- logoutAutoUrl: 'null', // URL for secondary tabs that received an automatic logout trigger (to help avoid race conditions)
- redirectCallback: false,
- logoutCallback: false,
- logoutAutoCallback: false,
-
- // Session keep alive settings
- keepAliveInterval: 600, // ping the server at this interval in seconds. 600 = 10 Minutes. Set to false to disable pings
- keepAliveUrl: window.location.href, // set URL to ping - does not apply if keepAliveInterval: false
- keepAliveAjaxType: 'GET',
- keepAliveAjaxData: '',
-
- // Lock Screen settings
- lockEnabled: false, // Set to true to enable lock screen before redirecting
- lockTimeLimit: 7200, // 2 hrs
- lockHaltKeepAlive: true, // Stop the keepAlive functionality during the lock screen timeout
- lockCallback: false, // Called when lock screen timer starts (lock screen will only be shown if this returns true)
- lockContentCallback: false, // Called for content of lock screen (SEE DOCUMENTATION!)
- lockPassCallback: false, // Required if using any of the internal lock screen functions (This accepts one param)
- lockTitle: null, // Lock title null=no title
- lockUsername: 'System User', // Set to current user name (otherwise the internal lock screen will look crappy)
- lockMessage: 'Enter your password to unlock the screen',
- lockUnlockButton: 'UnLock',
- lockLogoutButton: 'Not {username} ?', // This is actually an href link
- lockCountdownMessage: 'Auto-logout in: {timer}',
- lockBlockUiConfig: {}, // Customize the blockUI options
- lockLoadActive: false, // If true the lock screen is automatically started
-
- // Extensions
- iframesSupport: false, // Enable iframe support (also requires multiWindow support to work)
- multiWindowSupport: false // Requires jquery-storage-api
- };
- var bodyElm = $('body'); // Store for jQuery optimization
- var dataStore = null;
- //#########################################################################
- // ### Public API Functions
- //#########################################################################
- var api = {}; //Create return object
- /**
- * Starts the timers and initializes the config
- *
- * @param {object} userConfig - User config object
- * @return {boolean} - Returns true if successfully initialized
- */
- api.start = function(userConfig) {
- //--Merge default and user configs
- config = $.extend(config, userConfig);
- if (config.logoutAutoUrl === null) config.logoutAutoUrl = config.logoutUrl;
- //--Convert secs to millisecs
- config.idleTimeLimit *= 1000;
- config.idleCheckHeartbeat *= 1000;
- config.warnTimeLimit *= 1000;
- config.lockTimeLimit *= 1000;
- config.keepAliveInterval *= 1000;
- //--Validate config options
- if (config.multiWindowSupport) {
- if (!$.localStorage) {
- console.error('jitp: Multi-Window support requested but JQuery Storage API is unavailable.');
- return false;
- }
- }
- if ((config.warnEnabled && config.warnCallback === false) ||
- (config.lockEnabled && config.lockCallback === false)) {
- if (config.bootstrap) {
- if (typeof $.fn.modal === 'undefined') {
- console.error('jitp: Bootstrap library is unavailable');
- return false;
- }
- } else {
- if (typeof $.ui === 'undefined') {
- console.error('jitp: jQueryUI library is unavailable');
- return false;
- }
- }
- }
- if (config.lockEnabled && !config.multiWindowSupport) {
- console.error('jitp: Lock screen requested but multi-window support is not enabled.');
- return false;
- }
- if (config.lockEnabled && config.lockCallback === false) {
- if (typeof $.blockUI === 'undefined') {
- console.error('jitp: Lock screen requested but blockUI library is unavailable.');
- return false;
- }
- if (config.lockPassCallback === false) {
- console.error('jitp: Lock screen requested but lockPassCallback function is not set.');
- return false;
- }
- }
-
- if (config.iframesSupport && !config.multiWindowSupport) {
- console.error('jitp: IFrame support requested but Multi-Window support disabled.');
- return false;
- }
- initDataStore();
- //--Check if we are already in lockdown
- if (config.lockEnabled && (config.lockLoadActive || loadData('lockStartTime', -1) > 0)) {
- initSubLock();
- } else {
- //--Initialize and start idle timer
- storeData('logoutTriggered', false);
- storeData('warningStartTime', -1);
- storeData('lockStartTime', -1);
- storeData('lastActivity', $.now());
- startIdleTimer();
- if (config.keepAliveInterval) {
- startKeepSessionAlive();
- }
- }
-
- if (config.keepAliveInterval) {
- startKeepSessionAlive();
- }
- storeActivityEvents();
- dialogListener();
- activityDetector();
- checkForIframes();
- return true;
- };
- /**
- * @name cleanUpLockScreen
- * @description Call this on your login screen to avert a lock screen bug
- */
- api.cleanUpLockScreen = function() {
- initDataStore();
- if ($.localStorage) dataStore.set('lockStartTime', -99); //Because settings are not initialized bypass storeData
- };
- /**
- * @name logout
- * @description Call this to cause a logout of all windows
- */
- api.logout = function() {
- handleLogout();
- };
- /**
- * @name displayWarning
- * @description Displays the warning dialog (meant to be used by your warnCallback function)
- */
- api.displayWarning = function() {
- openWarningDialog();
- };
- /**
- * @name displayLockScreen
- * @description Displays the lock screen (meant to be used by your lockCallback function)
- */
- api.displayLockScreen = function() {
- openLockScreen();
- };
- /**
- * @name initLockScreen
- * @description Initiates the full lock screen procedure (use this if you wish to lock immediately)
- */
- api.initLockScreen = function() {
- stopIdleTimer();
- stopWarningTimer();
- initLock();
- };
- /**
- * @name setIdleTimeLimit
- * @param {number} seconds - New value for idleTimeLimit
- * @description Updates the idleTimeLimit config value & calls api.rollback
- */
- api.setIdleTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.idleTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * @name setWarnTimeLimit
- * @param {number} seconds - New value for warnTimeLimit
- * @description Updates the warnTimeLimit config value & calls api.rollback
- */
- api.setWarnTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.warnTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * @name setLockTimeLimit
- * @param {number} seconds - New value for lockTimeLimit
- * @description Updates the lockTimeLimit config value & calls api.rollback
- */
- api.setLockTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.lockTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * Clears warning/lock timers and reverts back to idleTimeout
- */
- api.rollback = function() {
- rollbackLock();
- rollbackWarning();
- };
- /**
- * trigger a recheck for iframes
- * use this after an iframe is inserted into the document
- */
- api.iframeRecheck = function() {
- checkForIframes();
- };
- //#########################################################################
- //## Private Functions
- //#########################################################################
-
- function initDataStore() {
- if (dataStore !== null) return;
- if ($.localStorage) dataStore = ($.initNamespaceStorage('jqueryIdleTimeoutPlus')).localStorage;
- else dataStore = {};
- }
- function storeData(key, value) {
- if (config.multiWindowSupport) {
- dataStore.set(key, value);
- } else {
- dataStore[key] = value;
- }
- }
-
- function loadData(key, defaultValue) {
- defaultValue = typeof defaultValue === 'undefined' ? null : defaultValue;
- if (config.multiWindowSupport) {
- if (dataStore.isSet(key)) return dataStore.get(key);
- } else {
- if (key in dataStore) return dataStore[key];
- }
- return defaultValue;
- }
- // -------------------------- Idle Monitoring --------------------------//
- var idleTimer;
- var mousePosition = [-1, -1];
- function initIdle() {
- storeData('warningStartTime', -1);
- storeData('lockStartTime', -1);
- startIdleTimer();
- if (config.idleCallback !== false) config.idleCallback(config);
- }
- function startIdleTimer() {
- stopIdleTimer();
- storeData('lastActivity', $.now());
- idleTimer = setInterval(checkIdleTimeout, config.idleCheckHeartbeat);
- }
- function stopIdleTimer() {
- clearInterval(idleTimer);
- }
- function checkIdleTimeout() {
- // Note: lastActivity stops being updated once the warning/lock period starts
- var idleTimeoutTime = (loadData('lastActivity', $.now()) + config.idleTimeLimit);
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- return handleLogoutTrigger();
- }
- //Check to see to see if lock initiated
- if (loadData('lockStartTime', -1) !== -1) {
- stopIdleTimer();
- return initSubLock();
- }
- if ($.now() >= idleTimeoutTime) {
- stopIdleTimer();
- if (!config.warnEnabled) { // warning dialog is disabled
- if (config.lockEnabled) return initLock();
- return handleRedirect(); // immediately redirect user when user is idle for idleTimeLimit
- }
- return initWarning();
- }
- }
-
- function activityDetector() {
- $(document).on(config.activityEvents, function(e) {
- if (e.type === 'mousemove') {
- // Solves mousemove even when mouse not moving issue on Chrome:
- // https://code.google.com/p/chromium/issues/detail?id=241476
- if (e.clientX === mousePosition[0] && e.clientY === mousePosition[1]) {
- return;
- }
- mousePosition[0] = e.clientX;
- mousePosition[1] = e.clientY;
- }
- if (loadData('warningStartTime', -1) === -1 && loadData('lockStartTime', -1) === -1) {
- startIdleTimer();
- }
- });
- }
- // -------------------------- Session Keep Alive --------------------------//
- var keepAliveInterval;
- function startKeepSessionAlive() {
- stopKeepSessionAlive();
- keepAliveInterval = setInterval(function() {
- $.ajax({
- type: config.keepAliveAjaxType,
- url: config.keepAliveUrl,
- data: config.keepAliveAjaxData
- });
- }, config.keepAliveInterval);
- }
- function stopKeepSessionAlive() {
- clearInterval(keepAliveInterval);
- }
- // -------------------------- Warning Functions --------------------------//
-
- var warningTimer;
- var warningDialogEnabled = true;
- var warningDialogActive = false;
- var warningDialogElm = null;
- var warningCountdownElm = null;
- var warningCountdownBarElm = null;
- function initWarning() {
- startWarningTimer();
- if (config.warnCallback !== false) warningDialogEnabled = config.warnCallback(config);
- openWarningDialog();
- }
- function rollbackWarning() {
- stopWarningTimer();
- closeWarningDialog();
- storeData('warningStartTime', -1);
- initIdle();
- }
- function startWarningTimer() {
- storeData('warningStartTime', $.now());
- warningTimer = setInterval(checkWarningTimeout, 500);
- }
- function stopWarningTimer() {
- clearInterval(warningTimer);
- }
- function checkWarningTimeout() {
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- stopWarningTimer();
- return handleLogoutTrigger();
- }
- //Has the warning been cleared (possibly by another tab/window)
- if (loadData('warningStartTime', -1) === -1) {
- return rollbackWarning();
- }
- //Check if timeout exceeded
- var warningTimeout = (loadData('warningStartTime') + config.warnTimeLimit) - 1;
- if ($.now() >= warningTimeout) {
- stopWarningTimer();
- if (config.lockEnabled) {
- //warningStart is not set to -1 to avoid having other tabs/windows do a rollback
- closeWarningDialog();
- return initLock();
- }
- return handleRedirect();
- }
- //Update dialog
- updateWarningDialog();
- }
- function openWarningDialog() {
- if (!warningDialogEnabled) return;
- initializeWarningDialog();
- updateWarningDialog();
- if (config.bootstrap) {
- warningDialogElm.modal('show');
- warningDialogElm.focus();
- } else {
- warningDialogElm.dialog('open');
- }
- warningDialogActive = true;
- }
- function closeWarningDialog() {
- warningDialogActive = false;
- if (warningDialogElm === null) return;
- if (config.bootstrap) {
- warningDialogElm.modal('hide'); //Despite modal being self-closing this is used if warning is cleared on another window
- // http://stackoverflow.com/questions/11519660/twitter-bootstrap-modal-backdrop-doesnt-disappear
- bodyElm.removeClass('modal-open');
- $('div.modal-backdrop').remove();
- } else {
- warningDialogElm.dialog('close');
- }
- }
-
- function updateWarningDialog() {
- if (warningDialogElm === null) return;
- if (warningCountdownElm === null && warningCountdownBarElm === null) return;
- var currTime = $.now();
- var totalSecsLeft = Math.floor(((loadData('warningStartTime', currTime) + config.warnTimeLimit) - currTime) / 1000);
- if (warningCountdownElm !== null) {
- warningCountdownElm.html(time2txt(totalSecsLeft));
- }
- if (warningCountdownBarElm !== null) {
- var percentLeft = Math.floor(totalSecsLeft / (config.warnTimeLimit / 1000) * 100);
- if (config.bootstrap) {
- warningCountdownBarElm.css('width', percentLeft + '%');
- } else {
- warningCountdownBarElm.progressbar('value', percentLeft);
- }
- }
- }
-
- function initializeWarningDialog() {
- if (warningDialogElm !== null) return;
- var content = '';
- if (config.warnContentCallback === false) {
- if (config.bootstrap)content = getWarningContentBootstrap();
- else content = getWarningContentJqueryUI();
- } else {
- content = config.warnContentCallback(config);
- }
- if (config.bootstrap) createWarningBootstrap(content);
- else createWarningJqueryUI(content);
- }
- function createWarningBootstrap(content) {
- bodyElm.append(content);
- if (config.warnLogoutButton !== null) {
- $('#jitp-warn-logout').on('click', function() {
- onWarningLogoutButton();
- });
- }
- $('#jitp-warn-alive').on('click', function() {
- onStayAliveButton();
- });
- warningDialogElm = $('#jitp-warn-display');
- if (config.warnCountdownMessage !== null || config.warnCountdownBar) {
- warningCountdownElm = warningDialogElm.find('.jitp-countdown-holder');
- }
- if (config.warnCountdownBar) {
- warningCountdownBarElm = $('#jitp-warn-bar');
- }
- }
-
- function createWarningJqueryUI(content) {
- var theButtons = [];
- if (config.warnLogoutButton !== null) {
- theButtons.push({
- text: config.warnLogoutButton,
- click: function() {
- onWarningLogoutButton();
- }
- });
- }
- theButtons.push({
- text: config.warnStayAliveButton,
- click: function() {
- onStayAliveButton();
- }
- });
- $(content).dialog({
- buttons: theButtons,
- closeOnEscape: false,
- modal: true,
- title: config.warnTitle,
- minWidth: 320,
- autoOpen: false,
- open: function() {
- //hide the dialog's title bar or the upper right corner "x" close button
- if (config.warnTitle === null) $(this).closest('.ui-dialog').find('.ui-dialog-titlebar').hide();
- else $(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide();
- $(this).parent().find('button:nth-child(2)').focus(); //Focus StayAlive button
- }
- });
- warningDialogElm = $('#jitp-warn-display');
- if (config.warnCountdownMessage !== null) {
- warningCountdownElm = warningDialogElm.find('.jitp-countdown-holder');
- }
- if (config.warnCountdownBar) {
- warningCountdownBarElm = $('#jitp-warn-bar');
- warningCountdownBarElm.progressbar({
- value: 0,
- max: 100
- });
- }
- }
-
- function getWarningContentBootstrap() {
- var title = config.warnTitle === null ? '' :
- '
';
- var countdownMsg = config.warnCountdownMessage === null ? '' :
- '' + config.warnCountdownMessage.replace(/\{timer}/g, '') + '
';
- var logoutBtn = config.warnLogoutButton === null ? '' :
- '';
- var countdownBar = config.warnCountdownBar === null ? '' :
- '' +
- '
' +
- '' +
- '
' +
- '
';
- return (
- '' +
- '
' +
- '
' +
- title +
- '
' +
- '
' + config.warnMessage + '
' +
- countdownMsg +
- countdownBar +
- '
' +
- '' +
- '
' +
- '
' +
- '
'
- );
- }
- function getWarningContentJqueryUI() {
- var countdownMsg = config.warnCountdownMessage === null ? '' :
- '' + config.warnCountdownMessage.replace(/\{timer}/g, '') + '
';
- var countdownBar = config.warnCountdownBar === null ? '' :
- '';
- return (
- '' +
- '
' + config.warnMessage + '
' +
- countdownMsg +
- countdownBar +
- '
'
- );
- }
- function onWarningLogoutButton() {
- stopWarningTimer();
- handleLogout();
- }
- function onStayAliveButton() {
- rollbackWarning();
- }
- // -------------------------- LockScreen Functions --------------------------//
- var lockTimer;
- var lockScreenEnabled = true;
- var lockScreenActive = false;
- var lockScreenElm = null;
- var lockScreenCountdownElm = null;
- function initLock() {
- if (config.lockHaltKeepAlive) stopKeepSessionAlive();
- startLockTimer();
- if (config.lockCallback !== false) lockScreenEnabled = config.lockCallback(config);
- openLockScreen();
- }
- function initSubLock() {
- if (config.lockHaltKeepAlive) stopKeepSessionAlive();
- else if (config.keepAliveInterval) startKeepSessionAlive();
- if (loadData('lockStartTime', -1) === -1) startLockTimer(); //Missing lockStartTime
- else lockTimer = setInterval(checkLockTimeout, 500);
- openLockScreen();
- }
- function rollbackLock() {
- stopLockTimer();
- closeLockScreen();
- $('#jitp-lock-pass').val(''); //Don't want the password to stay in the field
- if (config.keepAliveInterval) startKeepSessionAlive();
- storeData('lockStartTime', -1);
- initIdle();
- }
- function startLockTimer() {
- storeData('lockStartTime', $.now());
- lockTimer = setInterval(checkLockTimeout, 500);
- }
- function stopLockTimer() {
- clearInterval(lockTimer);
- }
- function checkLockTimeout() {
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- stopLockTimer();
- return handleLogoutTrigger();
- }
- //Has the lock been cleared (possibly by another tab/window)
- if (loadData('lockStartTime', -1) === -1) {
- return rollbackLock();
- }
- //Check if timeout exceeded
- var lockTimeout = (loadData('lockStartTime') + config.lockTimeLimit) - 1;
- if ($.now() >= lockTimeout) {
- stopLockTimer();
- //Trying to prevent a race condition with regards to lockTimeLimit being set to -99 (TRY being the operative word)
- if (loadData('logoutTriggered') === true) return handleLogoutTrigger();
- return handleRedirect();
- }
- //Update dialog if open
- updateLockScreen();
- }
- function openLockScreen() {
- if (!lockScreenEnabled) return;
- initializeLockScreen();
- updateLockScreen();
- var blockConfig = {
- message: $('#jitp-lock-display')
- };
- blockConfig = $.extend(blockConfig, config.lockBlockUiConfig);
- $.blockUI(blockConfig);
- lockScreenActive = true;
- }
- function closeLockScreen() {
- $.unblockUI();
- lockScreenActive = false;
- }
- function updateLockScreen() {
- if (lockScreenCountdownElm !== null) {
- var currTime = $.now();
- var totalSecsLeft = Math.floor(((loadData('lockStartTime', currTime) + config.lockTimeLimit) - currTime) / 1000);
- lockScreenCountdownElm.html(time2txt(totalSecsLeft));
- }
- }
-
- function initializeLockScreen() {
- if (lockScreenElm !== null) return;
- var content = '';
- if (config.lockContentCallback === false) {
- if (config.bootstrap) content = getLockContentBootstrap();
- else content = getLockContentJqueryUI();
- } else {
- content = config.lockContentCallback(config);
- }
- bodyElm.append(content);
- lockScreenElm = $('#jitp-lock-display');
- if (config.lockCountdownMessage !== false) {
- lockScreenCountdownElm = lockScreenElm.find('.jitp-countdown-holder');
- }
- $('#jitp-lock-logout').on('click', function() {
- onLockLogoutButton();
- });
- $('#jitp-lock-unlock').on('click', function() {
- onUnlockButton();
- });
- //noinspection JSJQueryEfficiency
- if ($('#jitp-lock-form').length) {
- $('#jitp-lock-form').submit(function() {
- onUnlockButton();
- return false;
- });
- }
- updateLockScreen();
- }
- function getLockContentBootstrap() {
- var title = config.lockTitle === null ? '' :
- '' + config.lockTitle + '
';
- var logoutMsg = config.lockLogoutButton.replace(/\{username}/g, config.lockUsername);
- var countdownMsg = config.lockCountdownMessage === null ? '' :
- '';
- return (
- '' +
- '
' +
- title +
- '
' +
- '
' + config.lockUsername + '
' +
- '
' + config.lockMessage + '
' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '
' +
- '
' + logoutMsg + '' +
- '
' +
- countdownMsg +
- '
' +
- '
'
- );
- }
- function getLockContentJqueryUI() {
- var title = config.lockTitle === null ? '' :
- '';
- var logoutMsg = config.lockLogoutButton.replace(/\{username}/g, config.lockUsername);
- var countdownMsg = config.lockCountdownMessage === null ? '' :
- '';
- return (
- '' +
- '
' +
- title +
- '
' +
- '
' + config.lockUsername + '
' +
- '
' + config.lockMessage + '
' +
- '
' +
- '' +
- '
' +
- '
' +
- '
' + logoutMsg + '' +
- '
' +
- countdownMsg +
- '
' +
- '
'
- );
- }
- function onLockLogoutButton() {
- stopLockTimer();
- handleLogout();
- }
- function onUnlockButton() {
- config.lockPassCallback($('#jitp-lock-pass').val());
- }
- // -------------------------- Logout & Redirect --------------------------//
-
- function stopIt() {
- stopKeepSessionAlive();
- stopIdleTimer();
- stopWarningTimer();
- stopLockTimer();
- }
- function handleLogout() {
- stopIt();
- storeData('logoutTriggered', true);
- if (typeof config.logoutCallback === 'function') {
- if (!config.logoutCallback(config)) return; //Redirect only done on true return
- }
- window.location.replace(config.logoutUrl);
- }
- function handleLogoutTrigger() {
- stopIt();
- if (typeof config.logoutAutoCallback === 'function') {
- if (!config.logoutAutoCallback(config)) return;
- }
- window.location.replace(config.logoutAutoUrl);
- }
- function handleRedirect() {
- stopIt();
- if (!config.multiWindowSupport) return handleRedirectAction();
- //Another attempt to avoid race conditions
- setTimeout(handleRedirectAction, getRandomInt(100, 500));
- }
- function handleRedirectAction() {
- //Check logoutTriggered flag
- if (loadData('logoutTriggered', false)) return handleLogoutTrigger();
- storeData('logoutTriggered', true);
- if (typeof config.redirectCallback === 'function') {
- if (!config.redirectCallback(config)) return;
- }
- window.location.replace(config.redirectUrl);
- }
- // -------------------------- IFrames Code --------------------------//
-
- // WORK AROUND - save config.activityEvents value to interWindow storage for use in function: attachEventIframe
- function storeActivityEvents() {
- storeData('activityEvents', config.activityEvents);
- }
- // Recheck for iframes when a dialog is opened
- function dialogListener() {
- $(document).on('dialogopen shown.bs.modal', function() {
- if (!warningDialogActive && !lockScreenActive) {
- checkForIframes();
- }
- });
- }
- function checkForIframes() {
- // document must be in readyState 'complete' before checking for iframes - $(document).ready() is not good enough!
- var docReadyInterval;
- var docReadyCheck = function() {
- if (document.readyState === "complete") {
- clearInterval(docReadyInterval);
- includeIframes();
- }
- };
- //Use of anon function prevents clearing of docReadyInterval
- docReadyInterval = setInterval(docReadyCheck, 1000); // check once a second to see if document is complete
- }
-
- function includeIframes(elementContents) {
- if (!elementContents) {
- elementContents = $(document);
- }
- var iframeCount = 0;
- elementContents.find('iframe,frame').each(function() {
- if ($(this).hasClass('jitp-inspected') === false) {
- try {
- includeIframes($(this).contents()); // recursive call to include nested iframes
- // attach event code for most modern browsers
- $(this).on('load', attachEventIframe($(this))); // Browser NOT IE < 11
- // attach event code for older Internet Explorer browsers
-
- var domElement = $(this)[iframeCount]; // convert jquery object to dom element
- if (domElement.attachEvent) { // Older IE Browser < 11
- domElement.attachEvent('onload', attachEventIframe($(this)));
- }
- iframeCount++;
- } catch (err) {
- /* Unfortunately, if the 'includeIframes' function is manually triggered multiple times in quick succession,
- * this 'try/catch' block may not have time to complete,
- * and so it might error out,
- * and iframes that are NOT cross-site may be set to "cross-site"
- * and activity may or may not bubble to parent page.
- * Fortunately, this is a rare occurrence!
- */
-
- $(this).addClass('jitp-inspected cross-site');
- }
- } else {
- }
- });
- }
- function attachEventIframe(iframeItem) {
- // retrieve stored value as config will not include private config
- // when this function is called by public function, iframeRecheck
-
- var iframeContents = iframeItem.contents();
- var storeActivityEvents = loadData('activityEvents', '');
- try {
- iframeContents.on(storeActivityEvents, function(event) {
- $('body').trigger(event);
- });
- iframeItem.addClass('jitp-inspected'); // add "jitp-inspected" class, so we don't need to check this iframe again
- } catch (err) {
- }
- }
-
-
- // -------------------------- Utility Functions --------------------------//
-
- function time2txt(secs) {
- var minLeft = Math.floor(secs / 60);
- if (minLeft <= 15) {
- var secsLeft = secs % 60;
- var timeTxt = minLeft > 0 ? minLeft + 'm ' : '';
- timeTxt += secsLeft + 's';
- return timeTxt;
- }
- if (minLeft <= 75) {
- if (minLeft <= 22) return 'about 15 mins';
- if (minLeft <= 37) return 'about 30 mins';
- if (minLeft <= 52) return 'about 25 mins';
- return 'about 1 hour';
- }
- var hoursLeft = Math.floor(minLeft / 60);
- minLeft %= 60;
- if (minLeft <= 15) return 'about ' + hoursLeft + ' hours';
- if (minLeft > 52) return 'about ' + (hoursLeft + 1) + ' hours';
- return 'about ' + hoursLeft + '½ hours';
- }
- // Returns a random integer between min (included) and max (excluded)
- function getRandomInt(min, max) {
- return Math.floor(Math.random() * (max - min)) + min;
- }
- return api;
-}));
diff --git a/dist/js/jquery-idleTimeout-plus-iframe.min.js b/dist/js/jquery-idleTimeout-plus-iframe.min.js
deleted file mode 100644
index e3437c1..0000000
--- a/dist/js/jquery-idleTimeout-plus-iframe.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(t,o){"function"==typeof define&&define.amd?define(["jquery"],o):"object"==typeof exports?module.exports=o(require("jquery")):t.IdleTimeoutPlus=o(t.jQuery)}(this,function(t){function o(){null===tt&&(tt=t.localStorage?t.initNamespaceStorage("jqueryIdleTimeoutPlus").localStorage:{})}function n(t,o){$.multiWindowSupport?tt.set(t,o):tt[t]=o}function e(t,o){if(o="undefined"==typeof o?null:o,$.multiWindowSupport){if(tt.isSet(t))return tt.get(t)}else if(t in tt)return tt[t];return o}function l(){n("warningStartTime",-1),n("lockStartTime",-1),i(),$.idleCallback!==!1&&$.idleCallback($)}function i(){a(),n("lastActivity",t.now()),nt=setInterval(r,$.idleCheckHeartbeat)}function a(){clearInterval(nt)}function r(){var o=e("lastActivity",t.now())+$.idleTimeLimit;return e("logoutTriggered")===!0?N():e("lockStartTime",-1)!==-1?(a(),A()):t.now()>=o?(a(),$.warnEnabled?d():$.lockEnabled?L():O()):void 0}function c(){t(document).on($.activityEvents,function(t){if("mousemove"===t.type){if(t.clientX===at[0]&&t.clientY===at[1])return;at[0]=t.clientX,at[1]=t.clientY}e("warningStartTime",-1)===-1&&e("lockStartTime",-1)===-1&&i()})}function u(){s(),et=setInterval(function(){t.ajax({type:$.keepAliveAjaxType,url:$.keepAliveUrl,data:$.keepAliveAjaxData})},$.keepAliveInterval)}function s(){clearInterval(et)}function d(){k(),$.warnCallback!==!1&&(rt=$.warnCallback($)),v()}function p(){f(),w(),n("warningStartTime",-1),l()}function k(){n("warningStartTime",t.now()),lt=setInterval(m,500)}function f(){clearInterval(lt)}function m(){if(e("logoutTriggered")===!0)return f(),N();if(e("warningStartTime",-1)===-1)return p();var o=e("warningStartTime")+$.warnTimeLimit-1;return t.now()>=o?(f(),$.lockEnabled?(w(),L()):O()):void b()}function v(){rt&&(g(),b(),$.bootstrap?(ut.modal("show"),ut.focus()):ut.dialog("open"),ct=!0)}function w(){ct=!1,null!==ut&&($.bootstrap?(ut.modal("hide"),_.removeClass("modal-open"),t("div.modal-backdrop").remove()):ut.dialog("close"))}function b(){if(null!==ut&&(null!==st||null!==dt)){var o=t.now(),n=Math.floor((e("warningStartTime",o)+$.warnTimeLimit-o)/1e3);if(null!==st&&st.html(V(n)),null!==dt){var l=Math.floor(n/($.warnTimeLimit/1e3)*100);$.bootstrap?dt.css("width",l+"%"):dt.progressbar("value",l)}}}function g(){if(null===ut){var t="";t=$.warnContentCallback===!1?$.bootstrap?j():C():$.warnContentCallback($),$.bootstrap?h(t):y(t)}}function h(o){_.append(o),null!==$.warnLogoutButton&&t("#jitp-warn-logout").on("click",function(){T()}),t("#jitp-warn-alive").on("click",function(){S()}),ut=t("#jitp-warn-display"),(null!==$.warnCountdownMessage||$.warnCountdownBar)&&(st=ut.find(".jitp-countdown-holder")),$.warnCountdownBar&&(dt=t("#jitp-warn-bar"))}function y(o){var n=[];null!==$.warnLogoutButton&&n.push({text:$.warnLogoutButton,click:function(){T()}}),n.push({text:$.warnStayAliveButton,click:function(){S()}}),t(o).dialog({buttons:n,closeOnEscape:!1,modal:!0,title:$.warnTitle,minWidth:320,autoOpen:!1,open:function(){null===$.warnTitle?t(this).closest(".ui-dialog").find(".ui-dialog-titlebar").hide():t(this).closest(".ui-dialog").find(".ui-dialog-titlebar-close").hide(),t(this).parent().find("button:nth-child(2)").focus()}}),ut=t("#jitp-warn-display"),null!==$.warnCountdownMessage&&(st=ut.find(".jitp-countdown-holder")),$.warnCountdownBar&&(dt=t("#jitp-warn-bar"),dt.progressbar({value:0,max:100}))}function j(){var t=null===$.warnTitle?"":'",o=null===$.warnCountdownMessage?"":""+$.warnCountdownMessage.replace(/\{timer}/g,'')+"
",n=null===$.warnLogoutButton?"":'",e=null===$.warnCountdownBar?"":'';return'"}function C(){var t=null===$.warnCountdownMessage?"":""+$.warnCountdownMessage.replace(/\{timer}/g,'')+"
",o=null===$.warnCountdownBar?"":'';return'"}function T(){f(),D()}function S(){p()}function L(){$.lockHaltKeepAlive&&s(),I(),$.lockCallback!==!1&&(pt=$.lockCallback($)),E()}function A(){$.lockHaltKeepAlive?s():$.keepAliveInterval&&u(),e("lockStartTime",-1)===-1?I():it=setInterval(B,500),E()}function U(){M(),x(),t("#jitp-lock-pass").val(""),$.keepAliveInterval&&u(),n("lockStartTime",-1),l()}function I(){n("lockStartTime",t.now()),it=setInterval(B,500)}function M(){clearInterval(it)}function B(){if(e("logoutTriggered")===!0)return M(),N();if(e("lockStartTime",-1)===-1)return U();var o=e("lockStartTime")+$.lockTimeLimit-1;return t.now()>=o?(M(),e("logoutTriggered")===!0?N():O()):void W()}function E(){if(pt){q(),W();var o={message:t("#jitp-lock-display")};o=t.extend(o,$.lockBlockUiConfig),t.blockUI(o),kt=!0}}function x(){t.unblockUI(),kt=!1}function W(){if(null!==mt){var o=t.now(),n=Math.floor((e("lockStartTime",o)+$.lockTimeLimit-o)/1e3);mt.html(V(n))}}function q(){if(null===ft){var o="";o=$.lockContentCallback===!1?$.bootstrap?P():H():$.lockContentCallback($),_.append(o),ft=t("#jitp-lock-display"),$.lockCountdownMessage!==!1&&(mt=ft.find(".jitp-countdown-holder")),t("#jitp-lock-logout").on("click",function(){K()}),t("#jitp-lock-unlock").on("click",function(){Q()}),t("#jitp-lock-form").length&&t("#jitp-lock-form").submit(function(){return Q(),!1}),W()}}function P(){var t=null===$.lockTitle?"":''+$.lockTitle+"
",o=$.lockLogoutButton.replace(/\{username}/g,$.lockUsername),n=null===$.lockCountdownMessage?"":'";return'"}function H(){var t=null===$.lockTitle?"":"",o=$.lockLogoutButton.replace(/\{username}/g,$.lockUsername),n=null===$.lockCountdownMessage?"":"";return'"}function K(){M(),D()}function Q(){$.lockPassCallback(t("#jitp-lock-pass").val())}function Y(){s(),a(),f(),M()}function D(){Y(),n("logoutTriggered",!0),("function"!=typeof $.logoutCallback||$.logoutCallback($))&&window.location.replace($.logoutUrl)}function N(){Y(),("function"!=typeof $.logoutAutoCallback||$.logoutAutoCallback($))&&window.location.replace($.logoutAutoUrl)}function O(){return Y(),$.multiWindowSupport?void setTimeout(X,Z(100,500)):X()}function X(){return e("logoutTriggered",!1)?N():(n("logoutTriggered",!0),void(("function"!=typeof $.redirectCallback||$.redirectCallback($))&&window.location.replace($.redirectUrl)))}function F(){n("activityEvents",$.activityEvents)}function G(){t(document).on("dialogopen shown.bs.modal",function(){ct||kt||J()})}function J(){var t,o=function(){"complete"===document.readyState&&(clearInterval(t),R())};t=setInterval(o,1e3)}function R(o){o||(o=t(document));var n=0;o.find("iframe,frame").each(function(){if(t(this).hasClass("jitp-inspected")===!1)try{R(t(this).contents()),t(this).on("load",z(t(this)));var o=t(this)[n];o.attachEvent&&o.attachEvent("onload",z(t(this))),n++}catch(e){t(this).addClass("jitp-inspected cross-site")}})}function z(o){var n=o.contents(),l=e("activityEvents","");try{n.on(l,function(o){t("body").trigger(o)}),o.addClass("jitp-inspected")}catch(i){}}function V(t){var o=Math.floor(t/60);if(o<=15){var n=t%60,e=o>0?o+"m ":"";return e+=n+"s"}if(o<=75)return o<=22?"about 15 mins":o<=37?"about 30 mins":o<=52?"about 25 mins":"about 1 hour";var l=Math.floor(o/60);return o%=60,o<=15?"about "+l+" hours":o>52?"about "+(l+1)+" hours":"about "+l+"½ hours"}function Z(t,o){return Math.floor(Math.random()*(o-t))+t}var $={idleTimeLimit:1200,idleCallback:!1,idleCheckHeartbeat:2,bootstrap:!1,activityEvents:"click keypress scroll wheel mousewheel mousemove touchmove",warnEnabled:!0,warnTimeLimit:180,warnCallback:!1,warnContentCallback:!1,warnTitle:"Session Timeout",warnMessage:"Your session is about to expire!",warnStayAliveButton:"Stay Connected",warnLogoutButton:"Logout",warnCountdownMessage:"Time remaining: {timer}",warnCountdownBar:!1,redirectUrl:"/timed-out",logoutUrl:"/logout",logoutAutoUrl:"null",redirectCallback:!1,logoutCallback:!1,logoutAutoCallback:!1,keepAliveInterval:600,keepAliveUrl:window.location.href,keepAliveAjaxType:"GET",keepAliveAjaxData:"",lockEnabled:!1,lockTimeLimit:7200,lockHaltKeepAlive:!0,lockCallback:!1,lockContentCallback:!1,lockPassCallback:!1,lockTitle:null,lockUsername:"System User",lockMessage:"Enter your password to unlock the screen",lockUnlockButton:"UnLock",lockLogoutButton:"Not {username} ?",lockCountdownMessage:"Auto-logout in: {timer}",lockBlockUiConfig:{},lockLoadActive:!1,iframesSupport:!1,multiWindowSupport:!1},_=t("body"),tt=null,ot={};ot.start=function(l){if($=t.extend($,l),null===$.logoutAutoUrl&&($.logoutAutoUrl=$.logoutUrl),$.idleTimeLimit*=1e3,$.idleCheckHeartbeat*=1e3,$.warnTimeLimit*=1e3,$.lockTimeLimit*=1e3,$.keepAliveInterval*=1e3,$.multiWindowSupport&&!t.localStorage)return console.error("jitp: Multi-Window support requested but JQuery Storage API is unavailable."),!1;if($.warnEnabled&&$.warnCallback===!1||$.lockEnabled&&$.lockCallback===!1)if($.bootstrap){if("undefined"==typeof t.fn.modal)return console.error("jitp: Bootstrap library is unavailable"),!1}else if("undefined"==typeof t.ui)return console.error("jitp: jQueryUI library is unavailable"),!1;if($.lockEnabled&&!$.multiWindowSupport)return console.error("jitp: Lock screen requested but multi-window support is not enabled."),!1;if($.lockEnabled&&$.lockCallback===!1){if("undefined"==typeof t.blockUI)return console.error("jitp: Lock screen requested but blockUI library is unavailable."),!1;if($.lockPassCallback===!1)return console.error("jitp: Lock screen requested but lockPassCallback function is not set."),!1}return $.iframesSupport&&!$.multiWindowSupport?(console.error("jitp: IFrame support requested but Multi-Window support disabled."),!1):(o(),$.lockEnabled&&($.lockLoadActive||e("lockStartTime",-1)>0)?A():(n("logoutTriggered",!1),n("warningStartTime",-1),n("lockStartTime",-1),n("lastActivity",t.now()),i(),$.keepAliveInterval&&u()),$.keepAliveInterval&&u(),F(),G(),c(),J(),!0)},ot.cleanUpLockScreen=function(){o(),t.localStorage&&tt.set("lockStartTime",-99)},ot.logout=function(){D()},ot.displayWarning=function(){v()},ot.displayLockScreen=function(){E()},ot.initLockScreen=function(){a(),f(),L()},ot.setIdleTimeLimit=function(t){"number"==typeof t&&($.idleTimeLimit=1e3*t,ot.rollback())},ot.setWarnTimeLimit=function(t){"number"==typeof t&&($.warnTimeLimit=1e3*t,ot.rollback())},ot.setLockTimeLimit=function(t){"number"==typeof t&&($.lockTimeLimit=1e3*t,ot.rollback())},ot.rollback=function(){U(),p()},ot.iframeRecheck=function(){J()};var nt,et,lt,it,at=[-1,-1],rt=!0,ct=!1,ut=null,st=null,dt=null,pt=!0,kt=!1,ft=null,mt=null;return ot});
\ No newline at end of file
diff --git a/dist/js/jquery-idleTimeout-plus.js b/dist/js/jquery-idleTimeout-plus.js
deleted file mode 100644
index d8da996..0000000
--- a/dist/js/jquery-idleTimeout-plus.js
+++ /dev/null
@@ -1,799 +0,0 @@
-/**
- * This work is licensed under the Creative Commons Attribution-Share Alike 3.0
- * United States License. To view a copy of this license,
- * visit http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter
- * to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
- *
- * Modified by: Jason Abraham (CrashSensei)
- * Email: jason@linearsoft.com
- *
- * Configurable idle (no activity) timer and logout redirect for jQuery.
- * Supports both jQueryUI dialogs or Bootstrap modals
- * Works across multiple windows, tabs from the same domain.
-
- *
- * Initially forked from Jill Elaine's jquery-idleTimeout
- * Bootstrap code and other code influenced by bootstrap-session-timeout by orangehill
- *
- * Dependencies: JQuery v1.7+,
- * Multi-window support requires JQuery Storage API
- * Dialogs require either jQueryUI or Bootstrap
- *
- * version 0.5.0
- **/
-
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- module.exports = factory(require('jquery'));
- } else {
- root.IdleTimeoutPlus = factory(root.jQuery);
- }
-}(this, function($) {
- //#########################################################################
- //### Config & Vars
- //#########################################################################
- var config = {
- // Idle settings
- idleTimeLimit: 1200, // 'No activity' time limit in seconds. 1200 = 20 Minutes
- idleCallback: false, // Called when the idleTimer is started (you can use this to close your custom warn/lock screens if needed)
- idleCheckHeartbeat: 2, // Frequency to check for idle timeouts in seconds
- bootstrap: false, // Use bootstrap framework instead of jQuery
- activityEvents: 'click keypress scroll wheel mousewheel mousemove touchmove', // configure which activity events to detect separate each event with a space, set to false for none
-
- // Warning settings
- warnEnabled: true, // set to false to skip warning period
- warnTimeLimit: 180, // 3 Minutes
- warnCallback: false, // Called when warning timer starts (wait dialog will only be shown if this returns true)
- warnContentCallback: false, // Called for content of warning dialog box (SEE DOCUMENTATION!)
- warnTitle: 'Session Timeout', // setting to null will remove the title bar
- warnMessage: 'Your session is about to expire!',
- warnStayAliveButton: 'Stay Connected',
- warnLogoutButton: 'Logout', // Set to null to disable
- warnCountdownMessage: 'Time remaining: {timer}', // Set to null to disable see doc on how to set
- warnCountdownBar: false,
-
- // Auto-Url settings (NOTE: if a callback is defined auto url redirection will only occur if the callback returns true)
- redirectUrl: '/timed-out', // URL if no action is taken after the warning/lock screen timeout
- logoutUrl: '/logout', // URL if the user clicks "Logout" on the warning/lock screen
- logoutAutoUrl: 'null', // URL for secondary tabs that received an automatic logout trigger (to help avoid race conditions)
- redirectCallback: false,
- logoutCallback: false,
- logoutAutoCallback: false,
-
- // Session keep alive settings
- keepAliveInterval: 600, // ping the server at this interval in seconds. 600 = 10 Minutes. Set to false to disable pings
- keepAliveUrl: window.location.href, // set URL to ping - does not apply if keepAliveInterval: false
- keepAliveAjaxType: 'GET',
- keepAliveAjaxData: '',
-
- // Lock Screen settings
- lockEnabled: false, // Set to true to enable lock screen before redirecting
- lockTimeLimit: 7200, // 2 hrs
- lockHaltKeepAlive: true, // Stop the keepAlive functionality during the lock screen timeout
- lockCallback: false, // Called when lock screen timer starts (lock screen will only be shown if this returns true)
- lockContentCallback: false, // Called for content of lock screen (SEE DOCUMENTATION!)
- lockPassCallback: false, // Required if using any of the internal lock screen functions (This accepts one param)
- lockTitle: null, // Lock title null=no title
- lockUsername: 'System User', // Set to current user name (otherwise the internal lock screen will look crappy)
- lockMessage: 'Enter your password to unlock the screen',
- lockUnlockButton: 'UnLock',
- lockLogoutButton: 'Not {username} ?', // This is actually an href link
- lockCountdownMessage: 'Auto-logout in: {timer}',
- lockBlockUiConfig: {}, // Customize the blockUI options
- lockLoadActive: false, // If true the lock screen is automatically started
-
- // Extensions
-
- multiWindowSupport: false // Requires jquery-storage-api
- };
- var bodyElm = $('body'); // Store for jQuery optimization
- var dataStore = null;
- //#########################################################################
- // ### Public API Functions
- //#########################################################################
- var api = {}; //Create return object
- /**
- * Starts the timers and initializes the config
- *
- * @param {object} userConfig - User config object
- * @return {boolean} - Returns true if successfully initialized
- */
- api.start = function(userConfig) {
- //--Merge default and user configs
- config = $.extend(config, userConfig);
- if (config.logoutAutoUrl === null) config.logoutAutoUrl = config.logoutUrl;
- //--Convert secs to millisecs
- config.idleTimeLimit *= 1000;
- config.idleCheckHeartbeat *= 1000;
- config.warnTimeLimit *= 1000;
- config.lockTimeLimit *= 1000;
- config.keepAliveInterval *= 1000;
- //--Validate config options
- if (config.multiWindowSupport) {
- if (!$.localStorage) {
- console.error('jitp: Multi-Window support requested but JQuery Storage API is unavailable.');
- return false;
- }
- }
- if ((config.warnEnabled && config.warnCallback === false) ||
- (config.lockEnabled && config.lockCallback === false)) {
- if (config.bootstrap) {
- if (typeof $.fn.modal === 'undefined') {
- console.error('jitp: Bootstrap library is unavailable');
- return false;
- }
- } else {
- if (typeof $.ui === 'undefined') {
- console.error('jitp: jQueryUI library is unavailable');
- return false;
- }
- }
- }
- if (config.lockEnabled && !config.multiWindowSupport) {
- console.error('jitp: Lock screen requested but multi-window support is not enabled.');
- return false;
- }
- if (config.lockEnabled && config.lockCallback === false) {
- if (typeof $.blockUI === 'undefined') {
- console.error('jitp: Lock screen requested but blockUI library is unavailable.');
- return false;
- }
- if (config.lockPassCallback === false) {
- console.error('jitp: Lock screen requested but lockPassCallback function is not set.');
- return false;
- }
- }
-
- initDataStore();
- //--Check if we are already in lockdown
- if (config.lockEnabled && (config.lockLoadActive || loadData('lockStartTime', -1) > 0)) {
- initSubLock();
- } else {
- //--Initialize and start idle timer
- storeData('logoutTriggered', false);
- storeData('warningStartTime', -1);
- storeData('lockStartTime', -1);
- storeData('lastActivity', $.now());
- startIdleTimer();
- if (config.keepAliveInterval) {
- startKeepSessionAlive();
- }
- }
-
- if (config.keepAliveInterval) {
- startKeepSessionAlive();
- }
- activityDetector();
- return true;
- };
- /**
- * @name cleanUpLockScreen
- * @description Call this on your login screen to avert a lock screen bug
- */
- api.cleanUpLockScreen = function() {
- initDataStore();
- if ($.localStorage) dataStore.set('lockStartTime', -99); //Because settings are not initialized bypass storeData
- };
- /**
- * @name logout
- * @description Call this to cause a logout of all windows
- */
- api.logout = function() {
- handleLogout();
- };
- /**
- * @name displayWarning
- * @description Displays the warning dialog (meant to be used by your warnCallback function)
- */
- api.displayWarning = function() {
- openWarningDialog();
- };
- /**
- * @name displayLockScreen
- * @description Displays the lock screen (meant to be used by your lockCallback function)
- */
- api.displayLockScreen = function() {
- openLockScreen();
- };
- /**
- * @name initLockScreen
- * @description Initiates the full lock screen procedure (use this if you wish to lock immediately)
- */
- api.initLockScreen = function() {
- stopIdleTimer();
- stopWarningTimer();
- initLock();
- };
- /**
- * @name setIdleTimeLimit
- * @param {number} seconds - New value for idleTimeLimit
- * @description Updates the idleTimeLimit config value & calls api.rollback
- */
- api.setIdleTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.idleTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * @name setWarnTimeLimit
- * @param {number} seconds - New value for warnTimeLimit
- * @description Updates the warnTimeLimit config value & calls api.rollback
- */
- api.setWarnTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.warnTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * @name setLockTimeLimit
- * @param {number} seconds - New value for lockTimeLimit
- * @description Updates the lockTimeLimit config value & calls api.rollback
- */
- api.setLockTimeLimit = function(seconds) {
- if (typeof seconds === 'number') {
- config.lockTimeLimit = seconds * 1000;
- api.rollback();
- }
- };
- /**
- * Clears warning/lock timers and reverts back to idleTimeout
- */
- api.rollback = function() {
- rollbackLock();
- rollbackWarning();
- };
- //#########################################################################
- //## Private Functions
- //#########################################################################
-
- function initDataStore() {
- if (dataStore !== null) return;
- if ($.localStorage) dataStore = ($.initNamespaceStorage('jqueryIdleTimeoutPlus')).localStorage;
- else dataStore = {};
- }
- function storeData(key, value) {
- if (config.multiWindowSupport) {
- dataStore.set(key, value);
- } else {
- dataStore[key] = value;
- }
- }
-
- function loadData(key, defaultValue) {
- defaultValue = typeof defaultValue === 'undefined' ? null : defaultValue;
- if (config.multiWindowSupport) {
- if (dataStore.isSet(key)) return dataStore.get(key);
- } else {
- if (key in dataStore) return dataStore[key];
- }
- return defaultValue;
- }
- // -------------------------- Idle Monitoring --------------------------//
- var idleTimer;
- var mousePosition = [-1, -1];
- function initIdle() {
- storeData('warningStartTime', -1);
- storeData('lockStartTime', -1);
- startIdleTimer();
- if (config.idleCallback !== false) config.idleCallback(config);
- }
- function startIdleTimer() {
- stopIdleTimer();
- storeData('lastActivity', $.now());
- idleTimer = setInterval(checkIdleTimeout, config.idleCheckHeartbeat);
- }
- function stopIdleTimer() {
- clearInterval(idleTimer);
- }
- function checkIdleTimeout() {
- // Note: lastActivity stops being updated once the warning/lock period starts
- var idleTimeoutTime = (loadData('lastActivity', $.now()) + config.idleTimeLimit);
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- return handleLogoutTrigger();
- }
- //Check to see to see if lock initiated
- if (loadData('lockStartTime', -1) !== -1) {
- stopIdleTimer();
- return initSubLock();
- }
- if ($.now() >= idleTimeoutTime) {
- stopIdleTimer();
- if (!config.warnEnabled) { // warning dialog is disabled
- if (config.lockEnabled) return initLock();
- return handleRedirect(); // immediately redirect user when user is idle for idleTimeLimit
- }
- return initWarning();
- }
- }
-
- function activityDetector() {
- $(document).on(config.activityEvents, function(e) {
- if (e.type === 'mousemove') {
- // Solves mousemove even when mouse not moving issue on Chrome:
- // https://code.google.com/p/chromium/issues/detail?id=241476
- if (e.clientX === mousePosition[0] && e.clientY === mousePosition[1]) {
- return;
- }
- mousePosition[0] = e.clientX;
- mousePosition[1] = e.clientY;
- }
- if (loadData('warningStartTime', -1) === -1 && loadData('lockStartTime', -1) === -1) {
- startIdleTimer();
- }
- });
- }
- // -------------------------- Session Keep Alive --------------------------//
- var keepAliveInterval;
- function startKeepSessionAlive() {
- stopKeepSessionAlive();
- keepAliveInterval = setInterval(function() {
- $.ajax({
- type: config.keepAliveAjaxType,
- url: config.keepAliveUrl,
- data: config.keepAliveAjaxData
- });
- }, config.keepAliveInterval);
- }
- function stopKeepSessionAlive() {
- clearInterval(keepAliveInterval);
- }
- // -------------------------- Warning Functions --------------------------//
-
- var warningTimer;
- var warningDialogEnabled = true;
- var warningDialogActive = false;
- var warningDialogElm = null;
- var warningCountdownElm = null;
- var warningCountdownBarElm = null;
- function initWarning() {
- startWarningTimer();
- if (config.warnCallback !== false) warningDialogEnabled = config.warnCallback(config);
- openWarningDialog();
- }
- function rollbackWarning() {
- stopWarningTimer();
- closeWarningDialog();
- storeData('warningStartTime', -1);
- initIdle();
- }
- function startWarningTimer() {
- storeData('warningStartTime', $.now());
- warningTimer = setInterval(checkWarningTimeout, 500);
- }
- function stopWarningTimer() {
- clearInterval(warningTimer);
- }
- function checkWarningTimeout() {
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- stopWarningTimer();
- return handleLogoutTrigger();
- }
- //Has the warning been cleared (possibly by another tab/window)
- if (loadData('warningStartTime', -1) === -1) {
- return rollbackWarning();
- }
- //Check if timeout exceeded
- var warningTimeout = (loadData('warningStartTime') + config.warnTimeLimit) - 1;
- if ($.now() >= warningTimeout) {
- stopWarningTimer();
- if (config.lockEnabled) {
- //warningStart is not set to -1 to avoid having other tabs/windows do a rollback
- closeWarningDialog();
- return initLock();
- }
- return handleRedirect();
- }
- //Update dialog
- updateWarningDialog();
- }
- function openWarningDialog() {
- if (!warningDialogEnabled) return;
- initializeWarningDialog();
- updateWarningDialog();
- if (config.bootstrap) {
- warningDialogElm.modal('show');
- warningDialogElm.focus();
- } else {
- warningDialogElm.dialog('open');
- }
- warningDialogActive = true;
- }
- function closeWarningDialog() {
- warningDialogActive = false;
- if (warningDialogElm === null) return;
- if (config.bootstrap) {
- warningDialogElm.modal('hide'); //Despite modal being self-closing this is used if warning is cleared on another window
- // http://stackoverflow.com/questions/11519660/twitter-bootstrap-modal-backdrop-doesnt-disappear
- bodyElm.removeClass('modal-open');
- $('div.modal-backdrop').remove();
- } else {
- warningDialogElm.dialog('close');
- }
- }
-
- function updateWarningDialog() {
- if (warningDialogElm === null) return;
- if (warningCountdownElm === null && warningCountdownBarElm === null) return;
- var currTime = $.now();
- var totalSecsLeft = Math.floor(((loadData('warningStartTime', currTime) + config.warnTimeLimit) - currTime) / 1000);
- if (warningCountdownElm !== null) {
- warningCountdownElm.html(time2txt(totalSecsLeft));
- }
- if (warningCountdownBarElm !== null) {
- var percentLeft = Math.floor(totalSecsLeft / (config.warnTimeLimit / 1000) * 100);
- if (config.bootstrap) {
- warningCountdownBarElm.css('width', percentLeft + '%');
- } else {
- warningCountdownBarElm.progressbar('value', percentLeft);
- }
- }
- }
-
- function initializeWarningDialog() {
- if (warningDialogElm !== null) return;
- var content = '';
- if (config.warnContentCallback === false) {
- if (config.bootstrap)content = getWarningContentBootstrap();
- else content = getWarningContentJqueryUI();
- } else {
- content = config.warnContentCallback(config);
- }
- if (config.bootstrap) createWarningBootstrap(content);
- else createWarningJqueryUI(content);
- }
- function createWarningBootstrap(content) {
- bodyElm.append(content);
- if (config.warnLogoutButton !== null) {
- $('#jitp-warn-logout').on('click', function() {
- onWarningLogoutButton();
- });
- }
- $('#jitp-warn-alive').on('click', function() {
- onStayAliveButton();
- });
- warningDialogElm = $('#jitp-warn-display');
- if (config.warnCountdownMessage !== null || config.warnCountdownBar) {
- warningCountdownElm = warningDialogElm.find('.jitp-countdown-holder');
- }
- if (config.warnCountdownBar) {
- warningCountdownBarElm = $('#jitp-warn-bar');
- }
- }
-
- function createWarningJqueryUI(content) {
- var theButtons = [];
- if (config.warnLogoutButton !== null) {
- theButtons.push({
- text: config.warnLogoutButton,
- click: function() {
- onWarningLogoutButton();
- }
- });
- }
- theButtons.push({
- text: config.warnStayAliveButton,
- click: function() {
- onStayAliveButton();
- }
- });
- $(content).dialog({
- buttons: theButtons,
- closeOnEscape: false,
- modal: true,
- title: config.warnTitle,
- minWidth: 320,
- autoOpen: false,
- open: function() {
- //hide the dialog's title bar or the upper right corner "x" close button
- if (config.warnTitle === null) $(this).closest('.ui-dialog').find('.ui-dialog-titlebar').hide();
- else $(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide();
- $(this).parent().find('button:nth-child(2)').focus(); //Focus StayAlive button
- }
- });
- warningDialogElm = $('#jitp-warn-display');
- if (config.warnCountdownMessage !== null) {
- warningCountdownElm = warningDialogElm.find('.jitp-countdown-holder');
- }
- if (config.warnCountdownBar) {
- warningCountdownBarElm = $('#jitp-warn-bar');
- warningCountdownBarElm.progressbar({
- value: 0,
- max: 100
- });
- }
- }
-
- function getWarningContentBootstrap() {
- var title = config.warnTitle === null ? '' :
- '';
- var countdownMsg = config.warnCountdownMessage === null ? '' :
- '' + config.warnCountdownMessage.replace(/\{timer}/g, '') + '
';
- var logoutBtn = config.warnLogoutButton === null ? '' :
- '';
- var countdownBar = config.warnCountdownBar === null ? '' :
- '' +
- '
' +
- '' +
- '
' +
- '
';
- return (
- '' +
- '
' +
- '
' +
- title +
- '
' +
- '
' + config.warnMessage + '
' +
- countdownMsg +
- countdownBar +
- '
' +
- '' +
- '
' +
- '
' +
- '
'
- );
- }
- function getWarningContentJqueryUI() {
- var countdownMsg = config.warnCountdownMessage === null ? '' :
- '' + config.warnCountdownMessage.replace(/\{timer}/g, '') + '
';
- var countdownBar = config.warnCountdownBar === null ? '' :
- '';
- return (
- '' +
- '
' + config.warnMessage + '
' +
- countdownMsg +
- countdownBar +
- '
'
- );
- }
- function onWarningLogoutButton() {
- stopWarningTimer();
- handleLogout();
- }
- function onStayAliveButton() {
- rollbackWarning();
- }
- // -------------------------- LockScreen Functions --------------------------//
- var lockTimer;
- var lockScreenEnabled = true;
- var lockScreenActive = false;
- var lockScreenElm = null;
- var lockScreenCountdownElm = null;
- function initLock() {
- if (config.lockHaltKeepAlive) stopKeepSessionAlive();
- startLockTimer();
- if (config.lockCallback !== false) lockScreenEnabled = config.lockCallback(config);
- openLockScreen();
- }
- function initSubLock() {
- if (config.lockHaltKeepAlive) stopKeepSessionAlive();
- else if (config.keepAliveInterval) startKeepSessionAlive();
- if (loadData('lockStartTime', -1) === -1) startLockTimer(); //Missing lockStartTime
- else lockTimer = setInterval(checkLockTimeout, 500);
- openLockScreen();
- }
- function rollbackLock() {
- stopLockTimer();
- closeLockScreen();
- $('#jitp-lock-pass').val(''); //Don't want the password to stay in the field
- if (config.keepAliveInterval) startKeepSessionAlive();
- storeData('lockStartTime', -1);
- initIdle();
- }
- function startLockTimer() {
- storeData('lockStartTime', $.now());
- lockTimer = setInterval(checkLockTimeout, 500);
- }
- function stopLockTimer() {
- clearInterval(lockTimer);
- }
- function checkLockTimeout() {
- //Check to see if other windows/tabs have had a critical event
- if (loadData('logoutTriggered') === true) {
- stopLockTimer();
- return handleLogoutTrigger();
- }
- //Has the lock been cleared (possibly by another tab/window)
- if (loadData('lockStartTime', -1) === -1) {
- return rollbackLock();
- }
- //Check if timeout exceeded
- var lockTimeout = (loadData('lockStartTime') + config.lockTimeLimit) - 1;
- if ($.now() >= lockTimeout) {
- stopLockTimer();
- //Trying to prevent a race condition with regards to lockTimeLimit being set to -99 (TRY being the operative word)
- if (loadData('logoutTriggered') === true) return handleLogoutTrigger();
- return handleRedirect();
- }
- //Update dialog if open
- updateLockScreen();
- }
- function openLockScreen() {
- if (!lockScreenEnabled) return;
- initializeLockScreen();
- updateLockScreen();
- var blockConfig = {
- message: $('#jitp-lock-display')
- };
- blockConfig = $.extend(blockConfig, config.lockBlockUiConfig);
- $.blockUI(blockConfig);
- lockScreenActive = true;
- }
- function closeLockScreen() {
- $.unblockUI();
- lockScreenActive = false;
- }
- function updateLockScreen() {
- if (lockScreenCountdownElm !== null) {
- var currTime = $.now();
- var totalSecsLeft = Math.floor(((loadData('lockStartTime', currTime) + config.lockTimeLimit) - currTime) / 1000);
- lockScreenCountdownElm.html(time2txt(totalSecsLeft));
- }
- }
-
- function initializeLockScreen() {
- if (lockScreenElm !== null) return;
- var content = '';
- if (config.lockContentCallback === false) {
- if (config.bootstrap) content = getLockContentBootstrap();
- else content = getLockContentJqueryUI();
- } else {
- content = config.lockContentCallback(config);
- }
- bodyElm.append(content);
- lockScreenElm = $('#jitp-lock-display');
- if (config.lockCountdownMessage !== false) {
- lockScreenCountdownElm = lockScreenElm.find('.jitp-countdown-holder');
- }
- $('#jitp-lock-logout').on('click', function() {
- onLockLogoutButton();
- });
- $('#jitp-lock-unlock').on('click', function() {
- onUnlockButton();
- });
- //noinspection JSJQueryEfficiency
- if ($('#jitp-lock-form').length) {
- $('#jitp-lock-form').submit(function() {
- onUnlockButton();
- return false;
- });
- }
- updateLockScreen();
- }
- function getLockContentBootstrap() {
- var title = config.lockTitle === null ? '' :
- '' + config.lockTitle + '
';
- var logoutMsg = config.lockLogoutButton.replace(/\{username}/g, config.lockUsername);
- var countdownMsg = config.lockCountdownMessage === null ? '' :
- '';
- return (
- '' +
- '
' +
- title +
- '
' +
- '
' + config.lockUsername + '
' +
- '
' + config.lockMessage + '
' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '
' +
- '
' + logoutMsg + '' +
- '
' +
- countdownMsg +
- '
' +
- '
'
- );
- }
- function getLockContentJqueryUI() {
- var title = config.lockTitle === null ? '' :
- '';
- var logoutMsg = config.lockLogoutButton.replace(/\{username}/g, config.lockUsername);
- var countdownMsg = config.lockCountdownMessage === null ? '' :
- '';
- return (
- '' +
- '
' +
- title +
- '
' +
- '
' + config.lockUsername + '
' +
- '
' + config.lockMessage + '
' +
- '
' +
- '' +
- '
' +
- '
' +
- '
' + logoutMsg + '' +
- '
' +
- countdownMsg +
- '
' +
- '
'
- );
- }
- function onLockLogoutButton() {
- stopLockTimer();
- handleLogout();
- }
- function onUnlockButton() {
- config.lockPassCallback($('#jitp-lock-pass').val());
- }
- // -------------------------- Logout & Redirect --------------------------//
-
- function stopIt() {
- stopKeepSessionAlive();
- stopIdleTimer();
- stopWarningTimer();
- stopLockTimer();
- }
- function handleLogout() {
- stopIt();
- storeData('logoutTriggered', true);
- if (typeof config.logoutCallback === 'function') {
- if (!config.logoutCallback(config)) return; //Redirect only done on true return
- }
- window.location.replace(config.logoutUrl);
- }
- function handleLogoutTrigger() {
- stopIt();
- if (typeof config.logoutAutoCallback === 'function') {
- if (!config.logoutAutoCallback(config)) return;
- }
- window.location.replace(config.logoutAutoUrl);
- }
- function handleRedirect() {
- stopIt();
- if (!config.multiWindowSupport) return handleRedirectAction();
- //Another attempt to avoid race conditions
- setTimeout(handleRedirectAction, getRandomInt(100, 500));
- }
- function handleRedirectAction() {
- //Check logoutTriggered flag
- if (loadData('logoutTriggered', false)) return handleLogoutTrigger();
- storeData('logoutTriggered', true);
- if (typeof config.redirectCallback === 'function') {
- if (!config.redirectCallback(config)) return;
- }
- window.location.replace(config.redirectUrl);
- }
- // -------------------------- Utility Functions --------------------------//
-
- function time2txt(secs) {
- var minLeft = Math.floor(secs / 60);
- if (minLeft <= 15) {
- var secsLeft = secs % 60;
- var timeTxt = minLeft > 0 ? minLeft + 'm ' : '';
- timeTxt += secsLeft + 's';
- return timeTxt;
- }
- if (minLeft <= 75) {
- if (minLeft <= 22) return 'about 15 mins';
- if (minLeft <= 37) return 'about 30 mins';
- if (minLeft <= 52) return 'about 25 mins';
- return 'about 1 hour';
- }
- var hoursLeft = Math.floor(minLeft / 60);
- minLeft %= 60;
- if (minLeft <= 15) return 'about ' + hoursLeft + ' hours';
- if (minLeft > 52) return 'about ' + (hoursLeft + 1) + ' hours';
- return 'about ' + hoursLeft + '½ hours';
- }
- // Returns a random integer between min (included) and max (excluded)
- function getRandomInt(min, max) {
- return Math.floor(Math.random() * (max - min)) + min;
- }
- return api;
-}));
diff --git a/dist/js/jquery-idleTimeout-plus.min.js b/dist/js/jquery-idleTimeout-plus.min.js
deleted file mode 100644
index b7cf1e1..0000000
--- a/dist/js/jquery-idleTimeout-plus.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(t,o){"function"==typeof define&&define.amd?define(["jquery"],o):"object"==typeof exports?module.exports=o(require("jquery")):t.IdleTimeoutPlus=o(t.jQuery)}(this,function(t){function o(){null===R&&(R=t.localStorage?t.initNamespaceStorage("jqueryIdleTimeoutPlus").localStorage:{})}function n(t,o){z.multiWindowSupport?R.set(t,o):R[t]=o}function e(t,o){if(o="undefined"==typeof o?null:o,z.multiWindowSupport){if(R.isSet(t))return R.get(t)}else if(t in R)return R[t];return o}function l(){n("warningStartTime",-1),n("lockStartTime",-1),i(),z.idleCallback!==!1&&z.idleCallback(z)}function i(){a(),n("lastActivity",t.now()),Z=setInterval(r,z.idleCheckHeartbeat)}function a(){clearInterval(Z)}function r(){var o=e("lastActivity",t.now())+z.idleTimeLimit;return e("logoutTriggered")===!0?N():e("lockStartTime",-1)!==-1?(a(),A()):t.now()>=o?(a(),z.warnEnabled?d():z.lockEnabled?L():O()):void 0}function c(){t(document).on(z.activityEvents,function(t){if("mousemove"===t.type){if(t.clientX===ot[0]&&t.clientY===ot[1])return;ot[0]=t.clientX,ot[1]=t.clientY}e("warningStartTime",-1)===-1&&e("lockStartTime",-1)===-1&&i()})}function u(){s(),$=setInterval(function(){t.ajax({type:z.keepAliveAjaxType,url:z.keepAliveUrl,data:z.keepAliveAjaxData})},z.keepAliveInterval)}function s(){clearInterval($)}function d(){k(),z.warnCallback!==!1&&(nt=z.warnCallback(z)),w()}function p(){f(),b(),n("warningStartTime",-1),l()}function k(){n("warningStartTime",t.now()),_=setInterval(m,500)}function f(){clearInterval(_)}function m(){if(e("logoutTriggered")===!0)return f(),N();if(e("warningStartTime",-1)===-1)return p();var o=e("warningStartTime")+z.warnTimeLimit-1;return t.now()>=o?(f(),z.lockEnabled?(b(),L()):O()):void v()}function w(){nt&&(g(),v(),z.bootstrap?(lt.modal("show"),lt.focus()):lt.dialog("open"),et=!0)}function b(){et=!1,null!==lt&&(z.bootstrap?(lt.modal("hide"),F.removeClass("modal-open"),t("div.modal-backdrop").remove()):lt.dialog("close"))}function v(){if(null!==lt&&(null!==it||null!==at)){var o=t.now(),n=Math.floor((e("warningStartTime",o)+z.warnTimeLimit-o)/1e3);if(null!==it&&it.html(G(n)),null!==at){var l=Math.floor(n/(z.warnTimeLimit/1e3)*100);z.bootstrap?at.css("width",l+"%"):at.progressbar("value",l)}}}function g(){if(null===lt){var t="";t=z.warnContentCallback===!1?z.bootstrap?j():C():z.warnContentCallback(z),z.bootstrap?y(t):T(t)}}function y(o){F.append(o),null!==z.warnLogoutButton&&t("#jitp-warn-logout").on("click",function(){h()}),t("#jitp-warn-alive").on("click",function(){S()}),lt=t("#jitp-warn-display"),(null!==z.warnCountdownMessage||z.warnCountdownBar)&&(it=lt.find(".jitp-countdown-holder")),z.warnCountdownBar&&(at=t("#jitp-warn-bar"))}function T(o){var n=[];null!==z.warnLogoutButton&&n.push({text:z.warnLogoutButton,click:function(){h()}}),n.push({text:z.warnStayAliveButton,click:function(){S()}}),t(o).dialog({buttons:n,closeOnEscape:!1,modal:!0,title:z.warnTitle,minWidth:320,autoOpen:!1,open:function(){null===z.warnTitle?t(this).closest(".ui-dialog").find(".ui-dialog-titlebar").hide():t(this).closest(".ui-dialog").find(".ui-dialog-titlebar-close").hide(),t(this).parent().find("button:nth-child(2)").focus()}}),lt=t("#jitp-warn-display"),null!==z.warnCountdownMessage&&(it=lt.find(".jitp-countdown-holder")),z.warnCountdownBar&&(at=t("#jitp-warn-bar"),at.progressbar({value:0,max:100}))}function j(){var t=null===z.warnTitle?"":'",o=null===z.warnCountdownMessage?"":""+z.warnCountdownMessage.replace(/\{timer}/g,'')+"
",n=null===z.warnLogoutButton?"":'",e=null===z.warnCountdownBar?"":'';return'"}function C(){var t=null===z.warnCountdownMessage?"":""+z.warnCountdownMessage.replace(/\{timer}/g,'')+"
",o=null===z.warnCountdownBar?"":'';return'"}function h(){f(),D()}function S(){p()}function L(){z.lockHaltKeepAlive&&s(),M(),z.lockCallback!==!1&&(rt=z.lockCallback(z)),x()}function A(){z.lockHaltKeepAlive?s():z.keepAliveInterval&&u(),e("lockStartTime",-1)===-1?M():tt=setInterval(B,500),x()}function U(){I(),E(),t("#jitp-lock-pass").val(""),z.keepAliveInterval&&u(),n("lockStartTime",-1),l()}function M(){n("lockStartTime",t.now()),tt=setInterval(B,500)}function I(){clearInterval(tt)}function B(){if(e("logoutTriggered")===!0)return I(),N();if(e("lockStartTime",-1)===-1)return U();var o=e("lockStartTime")+z.lockTimeLimit-1;return t.now()>=o?(I(),e("logoutTriggered")===!0?N():O()):void q()}function x(){if(rt){W(),q();var o={message:t("#jitp-lock-display")};o=t.extend(o,z.lockBlockUiConfig),t.blockUI(o),ct=!0}}function E(){t.unblockUI(),ct=!1}function q(){if(null!==st){var o=t.now(),n=Math.floor((e("lockStartTime",o)+z.lockTimeLimit-o)/1e3);st.html(G(n))}}function W(){if(null===ut){var o="";o=z.lockContentCallback===!1?z.bootstrap?P():H():z.lockContentCallback(z),F.append(o),ut=t("#jitp-lock-display"),z.lockCountdownMessage!==!1&&(st=ut.find(".jitp-countdown-holder")),t("#jitp-lock-logout").on("click",function(){K()}),t("#jitp-lock-unlock").on("click",function(){Q()}),t("#jitp-lock-form").length&&t("#jitp-lock-form").submit(function(){return Q(),!1}),q()}}function P(){var t=null===z.lockTitle?"":''+z.lockTitle+"
",o=z.lockLogoutButton.replace(/\{username}/g,z.lockUsername),n=null===z.lockCountdownMessage?"":'";return'"}function H(){var t=null===z.lockTitle?"":"",o=z.lockLogoutButton.replace(/\{username}/g,z.lockUsername),n=null===z.lockCountdownMessage?"":"";return'"}function K(){I(),D()}function Q(){z.lockPassCallback(t("#jitp-lock-pass").val())}function Y(){s(),a(),f(),I()}function D(){Y(),n("logoutTriggered",!0),("function"!=typeof z.logoutCallback||z.logoutCallback(z))&&window.location.replace(z.logoutUrl)}function N(){Y(),("function"!=typeof z.logoutAutoCallback||z.logoutAutoCallback(z))&&window.location.replace(z.logoutAutoUrl)}function O(){return Y(),z.multiWindowSupport?void setTimeout(X,J(100,500)):X()}function X(){return e("logoutTriggered",!1)?N():(n("logoutTriggered",!0),void(("function"!=typeof z.redirectCallback||z.redirectCallback(z))&&window.location.replace(z.redirectUrl)))}function G(t){var o=Math.floor(t/60);if(o<=15){var n=t%60,e=o>0?o+"m ":"";return e+=n+"s"}if(o<=75)return o<=22?"about 15 mins":o<=37?"about 30 mins":o<=52?"about 25 mins":"about 1 hour";var l=Math.floor(o/60);return o%=60,o<=15?"about "+l+" hours":o>52?"about "+(l+1)+" hours":"about "+l+"½ hours"}function J(t,o){return Math.floor(Math.random()*(o-t))+t}var z={idleTimeLimit:1200,idleCallback:!1,idleCheckHeartbeat:2,bootstrap:!1,activityEvents:"click keypress scroll wheel mousewheel mousemove touchmove",warnEnabled:!0,warnTimeLimit:180,warnCallback:!1,warnContentCallback:!1,warnTitle:"Session Timeout",warnMessage:"Your session is about to expire!",warnStayAliveButton:"Stay Connected",warnLogoutButton:"Logout",warnCountdownMessage:"Time remaining: {timer}",warnCountdownBar:!1,redirectUrl:"/timed-out",logoutUrl:"/logout",logoutAutoUrl:"null",redirectCallback:!1,logoutCallback:!1,logoutAutoCallback:!1,keepAliveInterval:600,keepAliveUrl:window.location.href,keepAliveAjaxType:"GET",keepAliveAjaxData:"",lockEnabled:!1,lockTimeLimit:7200,lockHaltKeepAlive:!0,lockCallback:!1,lockContentCallback:!1,lockPassCallback:!1,lockTitle:null,lockUsername:"System User",lockMessage:"Enter your password to unlock the screen",lockUnlockButton:"UnLock",lockLogoutButton:"Not {username} ?",lockCountdownMessage:"Auto-logout in: {timer}",lockBlockUiConfig:{},lockLoadActive:!1,multiWindowSupport:!1},F=t("body"),R=null,V={};V.start=function(l){if(z=t.extend(z,l),null===z.logoutAutoUrl&&(z.logoutAutoUrl=z.logoutUrl),z.idleTimeLimit*=1e3,z.idleCheckHeartbeat*=1e3,z.warnTimeLimit*=1e3,z.lockTimeLimit*=1e3,z.keepAliveInterval*=1e3,z.multiWindowSupport&&!t.localStorage)return console.error("jitp: Multi-Window support requested but JQuery Storage API is unavailable."),!1;if(z.warnEnabled&&z.warnCallback===!1||z.lockEnabled&&z.lockCallback===!1)if(z.bootstrap){if("undefined"==typeof t.fn.modal)return console.error("jitp: Bootstrap library is unavailable"),!1}else if("undefined"==typeof t.ui)return console.error("jitp: jQueryUI library is unavailable"),!1;if(z.lockEnabled&&!z.multiWindowSupport)return console.error("jitp: Lock screen requested but multi-window support is not enabled."),!1;if(z.lockEnabled&&z.lockCallback===!1){if("undefined"==typeof t.blockUI)return console.error("jitp: Lock screen requested but blockUI library is unavailable."),!1;if(z.lockPassCallback===!1)return console.error("jitp: Lock screen requested but lockPassCallback function is not set."),!1}return o(),z.lockEnabled&&(z.lockLoadActive||e("lockStartTime",-1)>0)?A():(n("logoutTriggered",!1),n("warningStartTime",-1),n("lockStartTime",-1),n("lastActivity",t.now()),i(),z.keepAliveInterval&&u()),z.keepAliveInterval&&u(),c(),!0},V.cleanUpLockScreen=function(){o(),t.localStorage&&R.set("lockStartTime",-99)},V.logout=function(){D()},V.displayWarning=function(){w()},V.displayLockScreen=function(){x()},V.initLockScreen=function(){a(),f(),L()},V.setIdleTimeLimit=function(t){"number"==typeof t&&(z.idleTimeLimit=1e3*t,V.rollback())},V.setWarnTimeLimit=function(t){"number"==typeof t&&(z.warnTimeLimit=1e3*t,V.rollback())},V.setLockTimeLimit=function(t){"number"==typeof t&&(z.lockTimeLimit=1e3*t,V.rollback())},V.rollback=function(){U(),p()};var Z,$,_,tt,ot=[-1,-1],nt=!0,et=!1,lt=null,it=null,at=null,rt=!0,ct=!1,ut=null,st=null;return V});
\ No newline at end of file