A Rails 5 Engine to prompt the user when their session is about to timeout and allow them to extend it.
This only works with Bootstrap 3 at present, but we would be happy to receive a pull request for Bootstrap 4 compatibility.
Add the gem to your Gemfile:
gem 'session_timeout_prompter'
Run bundle install
bundle install
Mount the engine in your routes:
mount SessionTimeoutPrompter::Engine, at: "/session_timeout_prompter"
Require the js:
//= session_timeout_prompter
Require the css:
*= require session_timeout_prompter
Note: Currently depends on jQuery for ajax / event handling.
Add the following after the body tag in your layout or on any page you wish to display the timeout prompt:
= init_session_timeout_prompter(session_timeout_in_seconds: User.timeout_in.to_i, seconds_to_warn_before_timeout: 305, scope: :user)
(The example values assume you are using Devise timeoutable and are using a scope/model called User. The scope is purely so you can use multiple in the same application if necessary.)
By default, clicking the "Log in again" button will go to your application's root path. Due to the inherent inaccuracy of timing in Javascript it is advisable to make sure they're actually logged out to avoid confusion. To do this, simple override the controller action in your application:
# app/controllers/session_timeout_prompter/sessions_controller.rb
module SessionTimeoutPrompter
class SessionsController < ActionController::Base
def new
sign_out current_user
redirect_to new_user_session_path
end
end
end
You can bind your own events to ping the server as follows:
$(function(){
if(sessionTimeoutPrompter) {
// Ping server on scroll
$(window).on('scroll', function() {
serverPinger.pingServerWithThrottling();
});
// Ping server when typing or clicking
$(document).on('keydown click', function() {
serverPinger.pingServerWithThrottling();
});
// Ping server when scrolling inside a modal window
// (the ajax-modal-show event in this example is from ajax_modal in the epiJs gem)
$(document).on('ajax-modal-show', function() {
$('#modalWindow').scroll( function() {
serverPinger.pingServerWithThrottling();
});
});
// Ping server when a key is pressed in CKEditor
CKEDITOR.on('instanceCreated', function(e) {
e.editor.on('change', function() {
serverPinger.pingServerWithThrottling();
});
});
}
});
All of the text is rendered via Rails' standard I18n library. See config/locales/en.yml
After checking out the repo, run bin/setup
to install dependencies.
The Javascript is written in ES6 and transpiled with Babel. The ES6 should be modified in src/javascripts
and then transpiled to app/assets/javascripts/session_timeout_prompter.js
. Currently we don't make use of modules (we'd need webpack or similar), but this would probably be an improvement going forward to control scope.
There is a handy script ./build
that will do the transpilation and run the tests. Run with --help for options.
Uses RSpec and Jasmine for automated testing. To run the Jasmine tests for the Javascript run rake jasmine
and go to localhost:8888
in your browser. The suite will run every time the page is reloaded.
To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/session_timeout_prompter.
The gem is available as open source under the terms of the MIT License.