From 278a1e42bc5d6d298f936413b1daae4395583c6c Mon Sep 17 00:00:00 2001 From: Stuart Colville Date: Fri, 2 Aug 2013 11:41:19 +0000 Subject: [PATCH] Force retry error message if error hangs logout (bug 886742) --- media/js/pay/pay.js | 103 +++++++++++++++++++++++--------- webpay/base/templates/base.html | 14 +++++ webpay/pay/tests/test_views.py | 7 ++- webpay/settings/base.py | 3 + 4 files changed, 98 insertions(+), 29 deletions(-) diff --git a/media/js/pay/pay.js b/media/js/pay/pay.js index 5708460f7..4bf6d882d 100644 --- a/media/js/pay/pay.js +++ b/media/js/pay/pay.js @@ -2,7 +2,14 @@ require(['cli', 'id', 'auth', 'pay/bango', 'lib/longtext'], function(cli, id, au "use strict"; var bodyData = cli.bodyData; + + var LOGOUTTIMEOUT = parseInt(bodyData.logoutTimeout, 10); + var $doc = cli.doc; + var $body = $doc.find('body'); + var $pinEntry = $('#enter-pin'); + var $errorScreen = $('#full-screen-error'); + // Elements to be labelled if longtext is detected. var $longTextElms = $('footer, body'); // Elements to be checked for overflowing text. @@ -17,6 +24,7 @@ require(['cli', 'id', 'auth', 'pay/bango', 'lib/longtext'], function(cli, id, au console.log('[pay] default onLogout'); auth.resetUser(); cli.hideProgress(); + $pinEntry.hide(); $('#login').fadeIn(); }; @@ -122,42 +130,81 @@ require(['cli', 'id', 'auth', 'pay/bango', 'lib/longtext'], function(cli, id, au } $('#forgot-pin').click(function(evt) { - var anchor = $(this); - var bangoReq; - var personaLoggedOut = $.Deferred(); + var anchor = $(this); evt.stopPropagation(); evt.preventDefault(); + cli.showProgress(); - // Define a new logout handler. - onLogout = function() { - console.log('[pay] forgot-pin onLogout'); - // It seems necessary to nullify the logout handler because - // otherwise it is held in memory and called on the next page. + function runForgotPinLogout() { + var bangoReq; + var personaLoggedOut = $.Deferred(); + + // Define a new logout handler. onLogout = function() { - console.log('[pay] null onLogout'); + console.log('[pay] forgot-pin onLogout'); + // It seems necessary to nullify the logout handler because + // otherwise it is held in memory and called on the next page. + onLogout = function() { + console.log('[pay] null onLogout'); + }; + personaLoggedOut.resolve(); }; - personaLoggedOut.resolve(); - }; - - $.when(auth.resetUser(), bango.logout(), personaLoggedOut) - .done(function _allLoggedOut() { - // Redirect to the original destination. - var dest = anchor.attr('href'); - console.log('[pay] forgot-pin logout done; redirect to', dest); - window.location.href = dest; - }); - - // Finally, log out of Persona so that the user has to - // re-authenticate before resetting a PIN. - if (loggedIn) { - console.log('[pay] Logging out of Persona'); - navigator.id.logout(); - } else { - console.log('[pay] Already logged out of Persona, calling onLogout ourself.'); - onLogout(); + + // Logout promises. + var authResetUser = auth.resetUser(); + var bangoLogout = bango.logout(); + + var resetLogoutTimeout = window.setTimeout(function() { + // If the log-out times-out then abort/reject the requests/deferred. + console.log('[pay] logout timed-out'); + authResetUser.abort(); + bangoLogout.abort(); + personaLoggedOut.reject(); + }, LOGOUTTIMEOUT); + + $.when(authResetUser, bangoLogout, personaLoggedOut) + .done(function _allLoggedOut() { + window.clearTimeout(resetLogoutTimeout); + // Redirect to the original destination. + var dest = anchor.attr('href'); + console.log('[pay] forgot-pin logout done; redirect to', dest); + window.location.href = dest; + }) + .fail(function _failedLogout() { + // Called when we manually abort everything + // or if something fails. + window.clearTimeout(resetLogoutTimeout); + cli.hideProgress(); + $pinEntry.hide(); + $body.addClass('full-error'); + $errorScreen.show(); + + // Setup click handler for one time use. + $errorScreen.find('.button').one('click', function(e){ + e.stopPropagation(); + e.preventDefault(); + + cli.showProgress(); + $errorScreen.hide(); + $body.removeClass('full-error'); + $pinEntry.show(); + runForgotPinLogout(); + }); + }); + + // Finally, log out of Persona so that the user has to + // re-authenticate before resetting a PIN. + if (loggedIn) { + console.log('[pay] Logging out of Persona'); + navigator.id.logout(); + } else { + console.log('[pay] Already logged out of Persona, calling onLogout ourself.'); + onLogout(); + } } + runForgotPinLogout(); }); }); diff --git a/webpay/base/templates/base.html b/webpay/base/templates/base.html index b8e5e87ba..fc6793c5b 100644 --- a/webpay/base/templates/base.html +++ b/webpay/base/templates/base.html @@ -32,6 +32,7 @@ data-persona-msg="{{ _('Connecting to Persona') }}" data-complete-msg="{{ _('Payment complete') }}" data-cancelled-msg="{{ _('Payment cancelled') }}" + data-logout-timeout="{{ settings.LOGOUT_TIMEOUT }}" >
@@ -43,9 +44,22 @@ {% endfor %} {% endif %} + + {# Full screen error html #} + +
+ {# Progress indicator html #}