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)
|
* reference to existing timeout warning dialog, if any
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
var session_timeout_warning = null;
|
||||||
|
|
||||||
function get_dialog(id, callback) {
|
|
||||||
var dialog = $('#'+id+'-dialog');
|
/**
|
||||||
if (! dialog.length) {
|
* Warn user of impending session timeout.
|
||||||
dialog = $('<div class="dialog" id="'+id+'-dialog"></div>');
|
*/
|
||||||
|
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) {
|
session_timeout_warning.find('.seconds').text('60');
|
||||||
dialog.attr('callback', callback);
|
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
|
return referrer
|
||||||
request.get_referrer = get_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):
|
def includeme(config):
|
||||||
config.add_subscriber(add_rattail_config_attribute_to_request, 'pyramid.events.NewRequest')
|
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.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.loadmask.min.js'))}
|
||||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.ui.timepicker.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'))}
|
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.js'))}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,12 @@ class AuthenticationView(View):
|
||||||
def mobile_logout(self):
|
def mobile_logout(self):
|
||||||
return self.logout(mobile=True)
|
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):
|
def change_password(self):
|
||||||
"""
|
"""
|
||||||
Allows a user to change his or her password.
|
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_route('mobile.logout', '/mobile/logout')
|
||||||
config.add_view(cls, attr='mobile_logout', route_name='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
|
# change password
|
||||||
config.add_route('change_password', '/change-password')
|
config.add_route('change_password', '/change-password')
|
||||||
config.add_view(cls, attr='change_password', route_name='change_password', renderer='/change_password.mako')
|
config.add_view(cls, attr='change_password', route_name='change_password', renderer='/change_password.mako')
|
||||||
|
|
Loading…
Reference in a new issue