Blog

Power Pages Building a Global Session Timeout Across Multiple Browser Tabs with jQuery and Bootstrap3.3

When developing web applications that require authentication, handling session timeouts is a crucial part of maintaining both security and a smooth user experience. A common challenge arises when a user opens multiple tabs of the same site: how do you ensure that session timeouts apply globally across all open tabs, not just one?

In this article, we’ll explore how to implement a global idle timeout system that:

  • Tracks user activity across all tabs.
  • Displays a warning popup after 50 minutes of inactivity.
  • Gives the user 10 minutes to continue their session.
  • Shows a session expired popup at 60 minutes of inactivity.
  • Synchronizes these behaviors across all open tabs.

We’ll build this solution with jQuery and Bootstrap 3.3, but the concepts apply to modern frontends as well.

Step 1: HTML Modals

We’ll create two Bootstrap modals:

  • Warning Modal (appears at 50 minutes)
  • Expired Modal (appears at 60 minutes)
<!-- Warning Modal -->
<div class="modal fade" id="sessionWarningModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-warning">
<h4 class="modal-title">Session Expiring Soon</h4>
</div>
<div class="modal-body">
<p>Your session will expire in <span id="timeRemaining">600</span> seconds.</p>
</div>
<div class="modal-footer">
<button type="button" id="continueSession" class="btn btn-success">Continue</button>
<button type="button" id="endSession" class="btn btn-danger">Logout</button>
</div>
</div>
</div>
</div>


<!-- Expired Modal -->
<div class="modal fade" id="sessionExpiredModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h4 class="modal-title">Session Expired</h4>
</div>
<div class="modal-body">
<p>Your session has expired due to inactivity.</p>
</div>
<div class="modal-footer">
<button type="button" id="redirectLogin" class="btn btn-primary">Login Again</button>
</div>
</div>
</div>
</div>

Step 2: JavaScript Logic

Here’s the jQuery code that:

  • Tracks user activity.
  • Shares last activity timestamp via localStorage.
  • Triggers the modals at the right times.
$(function () {
// Production values:
var warningTime = 50 * 60 * 1000; // 50 minutes
var expireTime = 60 * 60 * 1000; // 60 minutes


var countdownInterval;


function updateLastActivity() {
localStorage.setItem("lastActivity", Date.now());
}


function checkIdle() {
var last = parseInt(localStorage.getItem("lastActivity") || Date.now(), 10);
var idleTime = Date.now() - last;


if (idleTime >= expireTime) {
// Expired
clearInterval(countdownInterval);
$("#sessionWarningModal").modal("hide");
if (!$("#sessionExpiredModal").hasClass("in")) {
$("#sessionExpiredModal").modal({ backdrop: "static", keyboard: false });
}
} else if (idleTime >= warningTime) {
// Warning
if (!$("#sessionWarningModal").hasClass("in")) {
var remaining = Math.floor((expireTime - idleTime) / 1000);
$("#timeRemaining").text(remaining);
$("#sessionWarningModal").modal({ backdrop: "static", keyboard: false });


clearInterval(countdownInterval);
countdownInterval = setInterval(function () {
remaining--;
$("#timeRemaining").text(remaining);
if (remaining <= 0) {
clearInterval(countdownInterval);
$("#sessionWarningModal").modal("hide");
$("#sessionExpiredModal").modal({ backdrop: "static", keyboard: false });
}
}, 1000);
}
} else {
// Active
if (!$("#sessionExpiredModal").hasClass("in")) {
$("#sessionWarningModal").modal("hide");
}
}
}


// User actions reset timer
$(document).on("mousemove keypress click scroll", function () {
updateLastActivity();
});


// Modal button actions
$("#continueSession").on("click", function () {
clearInterval(countdownInterval);
$("#sessionWarningModal").modal("hide");
});

Leave a Reply