Skip to content
This repository has been archived by the owner on Jan 25, 2018. It is now read-only.

Commit

Permalink
Merge pull request #223 from muffinresearch/timeout-if-logout-fails-8…
Browse files Browse the repository at this point in the history
…86742

Force retry error message if error hangs logout (bug 886742)
  • Loading branch information
muffinresearch committed Aug 9, 2013
2 parents cb559cb + 278a1e4 commit 082de66
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 29 deletions.
103 changes: 75 additions & 28 deletions media/js/pay/pay.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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();
};

Expand Down Expand Up @@ -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();
});

});
14 changes: 14 additions & 0 deletions webpay/base/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
>
<section class="pay">
<div id="content">
Expand All @@ -43,9 +44,22 @@
{% endfor %}
</ul>
{% endif %}

{# Full screen error html #}
<div id="full-screen-error" class="hidden">
<div class="msg">
<h2 class="heading">{{ _('Oops&hellip;') }}</h2>
<p class="detail">{{ _('An unexpected error occurred. Please try again.') }}</p>
</div>
<footer>
<a href="#" class="button">{{ _('OK') }}</a>
</footer>
</div>

</div>
</section>

{# Progress indicator html #}
<div id="progress" class="progress hidden">
<div class="throbber"></div>
<span class="txt"></span>
Expand Down
7 changes: 6 additions & 1 deletion webpay/pay/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.core.exceptions import ObjectDoesNotExist

import mock
from nose.tools import eq_
from nose.tools import eq_, ok_

from lib.marketplace.api import UnknownPricePoint
from lib.solitude import constants
Expand Down Expand Up @@ -319,6 +319,11 @@ def test_pin_ui(self):
eq_(res.status_code, 200)
self.assertTemplateUsed(res, 'pay/lobby.html')

def test_logout_timeout_data_attr(self):
with self.settings(LOGOUT_TIMEOUT=300, TEST_PIN_UI=True):
res = self.client.get(self.url)
ok_('data-logout-timeout="300"' in res.content)

def test_wrong_icons_type(self):
payjwt = self.payload()
payjwt['request']['icons'] = '...' # must be a dict
Expand Down
3 changes: 3 additions & 0 deletions webpay/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,6 @@
# 'name') that have an implied short length. Values that exceed the maximum will
# trigger form errors.
SHORT_FIELD_MAX_LENGTH = 255

# The timeout for the client-side logout in pay.js in millseconds.
LOGOUT_TIMEOUT = 30000

0 comments on commit 082de66

Please sign in to comment.