diff --git a/app/views/session_timeout/_ping.js.erb b/app/views/session_timeout/_ping.js.erb index c20f737ae97..0c93da338a5 100644 --- a/app/views/session_timeout/_ping.js.erb +++ b/app/views/session_timeout/_ping.js.erb @@ -1,3 +1,9 @@ +var frequency = <%= frequency %> * 1000; +var warning = <%= warning %> * 1000; +var start = <%= start %> * 1000; +var warning_info = "<%= j render('session_timeout/warning') %>"; + + function ping() { var request = new XMLHttpRequest(); request.open('GET', '/active', true); @@ -10,7 +16,7 @@ function ping() { }; request.send(); - setTimeout(ping, (<%= frequency %> * 1000)); + setTimeout(ping, frequency); } @@ -19,12 +25,13 @@ function success(data) { cntnr = document.getElementById('session-timeout-cntnr'); var time_timeout = new Date(data.timeout).getTime(), - time_cutoff = new Date().getTime() + <%= warning %> * 1000, + time_cutoff = new Date().getTime() + warning, show_warning = time_timeout < time_cutoff; - var warning_info = "<%= j render('session_timeout/warning') %>"; - - if (show_warning & !el) cntnr.insertAdjacentHTML('afterbegin', warning_info); + if (show_warning & !el) { + cntnr.insertAdjacentHTML('afterbegin', warning_info); + initTimer(warning); + } if (!show_warning & el) el.remove(); if (data.live == false) { window.onbeforeunload = null; @@ -34,4 +41,30 @@ function success(data) { } -setTimeout(ping, (<%= start %> * 1000)); +function initTimer(duration) { + var ctdn = document.getElementById('ctdn'); + var time_left = duration; + var interval = 1000; + + var format = function(ms) { + var s = ms / 1000; + var min = parseInt(s / 60, 10); + var sec = parseInt(s % 60, 10); + + return (min == 0 ? '' : + min + ' minute' + (min !== 1 ? 's' : '') + ' and ') + + sec + ' second' + (sec !== 1 ? 's' : ''); + } + + function tick() { + ctdn.innerHTML = format(time_left); + if (time_left <= 0) return; + time_left -= interval; + setTimeout(tick, interval); + } + + tick(); +} + + +setTimeout(ping, start); diff --git a/app/views/session_timeout/_warning.html.slim b/app/views/session_timeout/_warning.html.slim index e27d824db5f..4a88ba7bcd5 100644 --- a/app/views/session_timeout/_warning.html.slim +++ b/app/views/session_timeout/_warning.html.slim @@ -4,7 +4,6 @@ .mx-auto.p4.cntnr-skinny.border-box.bg-white.rounded.relative = image_tag(asset_url('clock.svg'), class: 'modal-ico') h3.mt0.mb2 = t('headings.session_timeout_warning') - p.mb3 = t('session_timeout_warning', - time_left_in_session: time_left_in_session) + p.mb3 == t('session_timeout_warning', time_left_in_session: time_left_in_session) = link_to t('forms.buttons.continue_browsing'), request.original_url, class: 'btn btn-primary' diff --git a/config/locales/en.yml b/config/locales/en.yml index d9ca7509bfd..de6215b76de 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -125,8 +125,8 @@ en: session_timedout: > For your security, you’ve been logged out due to inactivity. Please log in again. session_timeout_warning: >- - You’ll be logged out of your account in %{time_left_in_session} due to - inactivity. If you’d like to remain logged in, please click the button below. + You’ll be logged out of your account in %{time_left_in_session} + due to inactivity. If you’d like to remain logged in, please click the button below. titles: confirmations: diff --git a/spec/features/users/sign_in_spec.rb b/spec/features/users/sign_in_spec.rb index 76b701799c8..a18a13ce0b0 100644 --- a/spec/features/users/sign_in_spec.rb +++ b/spec/features/users/sign_in_spec.rb @@ -82,14 +82,10 @@ end scenario 'user sees warning before session times out' do - def warning_content - t('session_timeout_warning', time_left_in_session: time_left_in_session) - end - sign_in_and_2fa_user visit root_path - expect(page).to have_css('#session-timeout-msg', text: warning_content) + expect(page).to have_css('#session-timeout-msg') request_headers = page.driver.network_traffic.flat_map(&:headers).uniq