Git Product home page Git Product logo

Comments (9)

JillElaine avatar JillElaine commented on July 20, 2024

First of all, there is nothing in the jquery-idleTimeout plugin's code that does anything directly to the user's session. The plugin can 'ping' the server regularly (configurable via sessionKeepAliveTimer & sessionKeepAliveUrl variables) to let the server know the user is still alive, and, hopefully, keep the server from 'killing' the user's session before the user is 'done'.

You can turn this ping off completely: set sessionKeepAliveTimer=false. By default, the plugin pings the server every 10 minutes.

Make sure the sessionKeepAliveUrl variable is set to a page within your site. The server must 'see' the pings, so it 'thinks' the user is still alive and active. The sessionKeepAliveUrl default is '/'.

Note that the plugin does not ping the server while the warning dialog (countdown timer) is visible. Your server (sometimes) kills the session when the warning dialog is visible, so this indicates to me that your server session timeout setting is shorter than the interval between pings. Or maybe the plugin's pings are not 'seen' by the server for some reason?

ASP's default session timeout is 20 minutes. Typically, you'd want to set the server's session timeout to greater than your app's session timeout. For example, if you want users to be 'timed out' after 30 minutes of inactivity, set the server's session timeout to 35 minutes. A basic ASP session tutorial is here: http://www.w3schools.com/asp/asp_ref_session.asp

Sometimes the session can be lost even though the user is active (pings, new pages, etc). This page gives some other possibilities for timeouts: http://machinesaredigging.com/2013/10/29/how-does-a-web-session-work/

Make sure you use the correct variable names to configure the plugin: spelling and case matters. It's idleTimeLimit, not 'idleTimeActivity', though I think that's just a typo above, right? https://github.com/JillElaine/jquery-idleTimeout/wiki/Public-Configuration-Variables

Post back what you learn so that others may benefit! Thank you!

from jquery-idletimeout.

JillElaine avatar JillElaine commented on July 20, 2024

Also, please read this: http://stackoverflow.com/questions/648992/session-timeout-in-asp-net

from jquery-idletimeout.

nicolenielsen avatar nicolenielsen commented on July 20, 2024

Hi,

Thank you for your reply. I have set the sessionKeepAliveTimer = 600 but did not specify a sessionKeepAliveUrl. I believe this will get the current url instead right? I have also checked in firebug that the url is successfully being 'ping-ed'. Also my session timeout (set in web.config and IIS) is already set to 30 minutes, so it's larger than the interval between the pings. And you're right, the idleTimeActivity is only a typo. I'm using the correct name.

I tried setting the idleTimeLimit to a value less than 30 minutes, however, I still get timed out if clicking on Stay Logged In with only a few seconds left (<=5). I'm using MVC and OWIN authentication, the cookie being created by OWIN is also set to 30 minutes timespan expiration. Is there any chance someone have encountered this issue?

Many thanks!

from jquery-idletimeout.

JillElaine avatar JillElaine commented on July 20, 2024

You should load the jquery-idleTimeout-for-testing.js and watch the console in Firebug. What happens when you click the Stay Logged In button? Are you redirected to the logout page anyway?

Again, there is nothing in the jquery-idleTimeout code that actually causes a user timeout: all it does is track idleness.

It is up to the implementer (you) to cause your idle users to timeout. Typically this is done with code that executes when the user is redirected to the logout page...or with code added to the optional customCallback variable. How have you implemented this timeout for your idle users? How do you log out your idle users? Are you using the customCallback?

No one else has reported this problem, so I am puzzled. I am not familiar with ASP,sorry. Is the OWIN cookie set to expire after 30 minutes even if the user is not idle? What happens if you set all your server side timeouts to 35 minutes?

from jquery-idletimeout.

JillElaine avatar JillElaine commented on July 20, 2024

Okay, I can confirm that there is a bug. The plugin does 'time out' just a few seconds before the 'countdown' completes. In other words, Time Remaining may display 2-3 seconds left when timeout occurs. I will patch this as soon as possible. Thank you for your patience.

from jquery-idletimeout.

clevelandj avatar clevelandj commented on July 20, 2024

Hello,

I was wondering whether any progress has been made on this issue? I am running into the same problem.

Thanks!

from jquery-idletimeout.

JillElaine avatar JillElaine commented on July 20, 2024

I have not had time to work on code recently, but I think the code below will fix the problem. Would you please try it, and let me know?

The problem occurred because there is typically a several second delay between the starting of the dialog timer and the display of the warning dialog. The only change in the code below is to test that the warning dialog 'Time Remaining' display has reached zero before logging out the user. The result will be that the user will be given a few seconds 'grace' before being logged out.

/**
 * 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: Jill Elaine
 * Email: [email protected]
 *
 * Configurable idle (no activity) timer and logout redirect for jQuery.
 * Works across multiple windows and tabs from the same domain.
 *
 * Dependencies: JQuery v1.7+, JQuery UI, store.js from https://github.com/marcuswestin/store.js - v1.3.4+
 *
 * version 1.0.10
 **/

/*global jQuery: false, document: false, store: false, clearInterval: false, setInterval: false, setTimeout: false, clearTimeout: false, window: false, alert: false*/
/*jslint indent: 2, sloppy: true, plusplus: true*/

(function ($) {

  $.fn.idleTimeout = function (userRuntimeConfig) {

    //##############################
    //## Public Configuration Variables
    //##############################
    var defaultConfig = {
      redirectUrl: '/logout',      // redirect to this url on logout. Set to "redirectUrl: false" to disable redirect

      // idle settings
      idleTimeLimit: 1200,           // 'No activity' time limit in seconds. 1200 = 20 Minutes
      idleCheckHeartbeat: 2,       // Frequency to check for idle timeouts in seconds

      // optional custom callback to perform before logout
      customCallback: false,       // set to false for no customCallback
      // customCallback:    function () {    // define optional custom js function
          // perform custom action before logout
      // },

      // configure which activity events to detect
      // http://www.quirksmode.org/dom/events/
      // https://developer.mozilla.org/en-US/docs/Web/Reference/Events
      activityEvents: 'click keypress scroll wheel mousewheel mousemove', // separate each event with a space

      // warning dialog box configuration
      enableDialog: true,           // set to false for logout without warning dialog
      dialogDisplayLimit: 180,       // Time to display the warning dialog before logout (and optional callback) in seconds. 180 = 3 Minutes
      dialogTitle: 'Session Expiration Warning', // also displays on browser title bar
      dialogText: 'Because you have been inactive, your session is about to expire.',
      dialogTimeRemaining: 'Time remaining',
      dialogStayLoggedInButton: 'Stay Logged In',
      dialogLogOutNowButton: 'Log Out Now',

      // error message if https://github.com/marcuswestin/store.js not enabled
      errorAlertMessage: 'Please disable "Private Mode", or upgrade to a modern browser. Or perhaps a dependent file missing. Please see: https://github.com/marcuswestin/store.js',

      // server-side session keep-alive timer
      sessionKeepAliveTimer: 600,   // ping the server at this interval in seconds. 600 = 10 Minutes. Set to false to disable pings
      sessionKeepAliveUrl: window.location.href // set URL to ping - does not apply if sessionKeepAliveTimer: false
    },

    //##############################
    //## Private Variables
    //##############################
      currentConfig = $.extend(defaultConfig, userRuntimeConfig), // merge default and user runtime configuration
      origTitle = document.title, // save original browser title
      activityDetector,
      startKeepSessionAlive, stopKeepSessionAlive, keepSession, keepAlivePing, // session keep alive
      idleTimer, remainingTimer, checkIdleTimeout, checkIdleTimeoutLoop, startIdleTimer, stopIdleTimer, // idle timer
      openWarningDialog, dialogTimer, checkDialogTimeout, startDialogTimer, stopDialogTimer, isDialogOpen, destroyWarningDialog, countdownDisplay, dialogDisplaySeconds, // warning dialog
      logoutUser;

    //##############################
    //## Public Functions
    //##############################
    // trigger a manual user logout
    // use this code snippet on your site's Logout button: $.fn.idleTimeout().logout();
    this.logout = function () {
      store.set('idleTimerLoggedOut', true);
    };

    //##############################
    //## Private Functions
    //##############################

    //----------- KEEP SESSION ALIVE FUNCTIONS --------------//
    startKeepSessionAlive = function () {

      keepSession = function () {
        $.get(currentConfig.sessionKeepAliveUrl);
        startKeepSessionAlive();
      };

      keepAlivePing = setTimeout(keepSession, (currentConfig.sessionKeepAliveTimer * 1000));
    };

    stopKeepSessionAlive = function () {
      clearTimeout(keepAlivePing);
    };

    //----------- ACTIVITY DETECTION FUNCTION --------------//
    activityDetector = function () {

      $('body').on(currentConfig.activityEvents, function () {

        if (!currentConfig.enableDialog || (currentConfig.enableDialog && isDialogOpen() !== true)) {
          startIdleTimer();
        }
      });
    };

    //----------- IDLE TIMER FUNCTIONS --------------//
    checkIdleTimeout = function () {

      var timeIdleTimeout = (store.get('idleTimerLastActivity') + (currentConfig.idleTimeLimit * 1000));

      if ($.now() > timeIdleTimeout) {

        if (!currentConfig.enableDialog) { // warning dialog is disabled
          logoutUser(); // immediately log out user when user is idle for idleTimeLimit
        } else if (currentConfig.enableDialog && isDialogOpen() !== true) {
          openWarningDialog();
          startDialogTimer(); // start timing the warning dialog
        }
      } else if (store.get('idleTimerLoggedOut') === true) { //a 'manual' user logout?
        logoutUser();
      } else {

        if (currentConfig.enableDialog && isDialogOpen() === true) {
          destroyWarningDialog();
          stopDialogTimer();
        }
      }
    };

    startIdleTimer = function () {
      stopIdleTimer();
      store.set('idleTimerLastActivity', $.now());
      checkIdleTimeoutLoop();
    };

    checkIdleTimeoutLoop = function () {
      checkIdleTimeout();
      idleTimer = setTimeout(checkIdleTimeoutLoop, (currentConfig.idleCheckHeartbeat * 1000));
    };

    stopIdleTimer = function () {
      clearTimeout(idleTimer);
    };

    //----------- WARNING DIALOG FUNCTIONS --------------//
    openWarningDialog = function () {

      var dialogContent = "<div id='idletimer_warning_dialog'><p>" + currentConfig.dialogText + "</p><p style='display:inline'>" + currentConfig.dialogTimeRemaining + ": <div style='display:inline' id='countdownDisplay'></div></p></div>";

      $(dialogContent).dialog({
        buttons: [{
          text: currentConfig.dialogStayLoggedInButton,
          click: function () {
            destroyWarningDialog();
            stopDialogTimer();
            startIdleTimer();
          }
        },
          {
            text: currentConfig.dialogLogOutNowButton,
            click: function () {
              logoutUser();
            }
          }
          ],
        closeOnEscape: false,
        modal: true,
        title: currentConfig.dialogTitle,
        open: function () {
          $(this).closest('.ui-dialog').find('.ui-dialog-titlebar-close').hide();
        }
      });

      countdownDisplay();

      document.title = currentConfig.dialogTitle;

      if (currentConfig.sessionKeepAliveTimer) {
        stopKeepSessionAlive();
      }
    };

    checkDialogTimeout = function () {
      var timeDialogTimeout = (store.get('idleTimerLastActivity') + (currentConfig.idleTimeLimit * 1000) + (currentConfig.dialogDisplayLimit * 1000));

      if ((($.now() > timeDialogTimeout) && (dialogDisplaySeconds <= 0)) || (store.get('idleTimerLoggedOut') === true)) {
        logoutUser();
      }
    };

    startDialogTimer = function () {
      dialogTimer = setInterval(checkDialogTimeout, (currentConfig.idleCheckHeartbeat * 1000));
    };

    stopDialogTimer = function () {
      clearInterval(dialogTimer);
      clearInterval(remainingTimer);
    };

    isDialogOpen = function () {
      var dialogOpen = $("#idletimer_warning_dialog").is(":visible");

      if (dialogOpen === true) {
        return true;
      }
      return false;
    };

    destroyWarningDialog = function () {
      $("#idletimer_warning_dialog").dialog('destroy').remove();
      document.title = origTitle;

      if (currentConfig.sessionKeepAliveTimer) {
        startKeepSessionAlive();
      }
    };

    countdownDisplay = function () {
      dialogDisplaySeconds = currentConfig.dialogDisplayLimit, mins, secs;

      remainingTimer = setInterval(function () {
        mins = Math.floor(dialogDisplaySeconds / 60); // minutes
        if (mins < 10) { mins = '0' + mins; }
        secs = dialogDisplaySeconds - (mins * 60); // seconds
        if (secs < 10) { secs = '0' + secs; }
        $('#countdownDisplay').html(mins + ':' + secs);
        dialogDisplaySeconds -= 1;
      }, 1000);
    };

    //----------- LOGOUT USER FUNCTION --------------//
    logoutUser = function () {
      store.set('idleTimerLoggedOut', true);

      if (currentConfig.sessionKeepAliveTimer) {
        stopKeepSessionAlive();
      }

      if (currentConfig.customCallback) {
        currentConfig.customCallback();
      }

      if (currentConfig.redirectUrl) {
        window.location.href = currentConfig.redirectUrl;
      }
    };

    //###############################
    // Build & Return the instance of the item as a plugin
    // This is your construct.
    //###############################
    return this.each(function () {

      if (store.enabled) {

        store.set('idleTimerLastActivity', $.now());
        store.set('idleTimerLoggedOut', false);

        activityDetector();

        if (currentConfig.sessionKeepAliveTimer) {
          startKeepSessionAlive();
        }

        startIdleTimer();

      } else {
        alert(currentConfig.errorAlertMessage);
      }

    });
  };
}(jQuery));

from jquery-idletimeout.

clevelandj avatar clevelandj commented on July 20, 2024

Thanks @JillElaine! The fix you posted above mostly worked. I made two slight modifications and submitted a pull request (#31). The changes:

    countdownDisplay = function () {
      dialogDisplaySeconds = currentConfig.dialogDisplayLimit, mins, secs;

changed to

    countdownDisplay = function () {
      dialogDisplaySeconds = currentConfig.dialogDisplayLimit;
      var mins, secs;

as an error was thrown otherwise (claiming 'mins' wasn't defined). I also changed

    countdownDisplay = function () {
        ...
        dialogDisplaySeconds -= 1;
      }, 1000);
    };

to

    countdownDisplay = function () {
        ...
        if (dialogDisplaySeconds) { dialogDisplaySeconds -= 1; }
      }, 1000);
    };

in order to avoid displaying 'NaN' in the dialog after the counter had reached 0.

from jquery-idletimeout.

JillElaine avatar JillElaine commented on July 20, 2024

Thank you for this suggested change for the countdownDisplay to avoid NaN. I don't have time to work on my code now, but hope to improve it in the future.

from jquery-idletimeout.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.