Add support for client-side session timeout warning
This commit is contained in:
parent
4ae70de339
commit
e3ec3be03b
|
@ -69,28 +69,69 @@ function get_uuid(obj) {
|
|||
|
||||
|
||||
/*
|
||||
* get_dialog(id, callback)
|
||||
*
|
||||
* Returns a <DIV> element suitable for use as a jQuery dialog.
|
||||
*
|
||||
* ``id`` is used to construct a proper ID for the element and allows the
|
||||
* dialog to be resused if possible.
|
||||
*
|
||||
* ``callback``, if specified, should be a callback function for the dialog.
|
||||
* This function will be called whenever the dialog has been closed
|
||||
* "successfully" (i.e. data submitted) by the user, and should accept a single
|
||||
* ``data`` object which is the JSON response returned by the server.
|
||||
* reference to existing timeout warning dialog, if any
|
||||
*/
|
||||
var session_timeout_warning = null;
|
||||
|
||||
function get_dialog(id, callback) {
|
||||
var dialog = $('#'+id+'-dialog');
|
||||
if (! dialog.length) {
|
||||
dialog = $('<div class="dialog" id="'+id+'-dialog"></div>');
|
||||
|
||||
/**
|
||||
* Warn user of impending session timeout.
|
||||
*/
|
||||
function timeout_warning() {
|
||||
if (! session_timeout_warning) {
|
||||
session_timeout_warning = $('<div id="session-timeout-warning">' +
|
||||
'You will be logged out in <span class="seconds"></span> ' +
|
||||
'seconds...</div>');
|
||||
}
|
||||
if (callback) {
|
||||
dialog.attr('callback', callback);
|
||||
session_timeout_warning.find('.seconds').text('60');
|
||||
session_timeout_warning.dialog({
|
||||
title: "Session Timeout Warning",
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Stay Logged In": function() {
|
||||
session_timeout_warning.dialog('close');
|
||||
$.get(noop_url, set_timeout_warning_timer);
|
||||
},
|
||||
"Logout Now": function() {
|
||||
location.href = logout_url;
|
||||
}
|
||||
}
|
||||
});
|
||||
window.setTimeout(timeout_warning_update, 1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrement the 'seconds' counter for the current timeout warning
|
||||
*/
|
||||
function timeout_warning_update() {
|
||||
if (session_timeout_warning.is(':visible')) {
|
||||
var span = session_timeout_warning.find('.seconds');
|
||||
var seconds = parseInt(span.text()) - 1;
|
||||
if (seconds) {
|
||||
span.text(seconds.toString());
|
||||
window.setTimeout(timeout_warning_update, 1000);
|
||||
} else {
|
||||
location.href = logout_url;
|
||||
}
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Warn user of impending session timeout.
|
||||
*/
|
||||
function set_timeout_warning_timer() {
|
||||
// TODO: are we calculating timer ok here? (effective timeout - 60 seconds)
|
||||
window.setTimeout(timeout_warning, session_timeout * 1000 - 60000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set initial timer for timeout warning, if applicable
|
||||
*/
|
||||
if (session_timeout) {
|
||||
set_timeout_warning_timer();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -154,6 +154,13 @@ def context_found(event):
|
|||
return referrer
|
||||
request.get_referrer = get_referrer
|
||||
|
||||
def get_session_timeout():
|
||||
"""
|
||||
Returns the timeout in effect for the current session
|
||||
"""
|
||||
return request.session.get('_timeout')
|
||||
request.get_session_timeout = get_session_timeout
|
||||
|
||||
|
||||
def includeme(config):
|
||||
config.add_subscriber(add_rattail_config_attribute_to_request, 'pyramid.events.NewRequest')
|
||||
|
|
|
@ -133,6 +133,11 @@
|
|||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.ui.menubar.js'))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.loadmask.min.js'))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.ui.timepicker.js'))}
|
||||
<script type="text/javascript">
|
||||
var session_timeout = ${request.get_session_timeout() or 'null'};
|
||||
var logout_url = '${request.route_url('logout')}';
|
||||
var noop_url = '${request.route_url('noop')}';
|
||||
</script>
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.js'))}
|
||||
</%def>
|
||||
|
||||
|
|
|
@ -149,6 +149,12 @@ class AuthenticationView(View):
|
|||
def mobile_logout(self):
|
||||
return self.logout(mobile=True)
|
||||
|
||||
def noop(self):
|
||||
"""
|
||||
View to serve as "no-op" / ping action to reset current user's session timer
|
||||
"""
|
||||
return {'status': 'ok'}
|
||||
|
||||
def change_password(self):
|
||||
"""
|
||||
Allows a user to change his or her password.
|
||||
|
@ -201,6 +207,10 @@ class AuthenticationView(View):
|
|||
config.add_route('mobile.logout', '/mobile/logout')
|
||||
config.add_view(cls, attr='mobile_logout', route_name='mobile.logout')
|
||||
|
||||
# no-op
|
||||
config.add_route('noop', '/noop')
|
||||
config.add_view(cls, attr='noop', route_name='noop', renderer='json')
|
||||
|
||||
# change password
|
||||
config.add_route('change_password', '/change-password')
|
||||
config.add_view(cls, attr='change_password', route_name='change_password', renderer='/change_password.mako')
|
||||
|
|
Loading…
Reference in a new issue