Commit bdf80956 by Renzo Lucioni

Prevent accidental resubmission of payment form

Adds JavaScript to the receipt page that manipulates the contents of the history stack using the URL fragment to prevent users from accidentally resubmitting the payment form by discouraging them from using their browser's back button.

LEARNER-1671
parent 14051cd2
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-30 01:19+0000\n"
"POT-Creation-Date: 2017-06-30 17:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-30 01:19+0000\n"
"POT-Creation-Date: 2017-06-30 17:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -238,6 +238,12 @@ msgstr ""
msgid "Redeem"
msgstr ""
#: ecommerce/static/js/pages/receipt_page.js:25
msgid ""
"Caution! Using the back button on this page may cause you to be charged "
"again."
msgstr ""
#: ecommerce/static/js/utils/utils.js:184
msgid "Trailing comma not allowed."
msgstr ""
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-30 01:19+0000\n"
"POT-Creation-Date: 2017-06-30 17:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-30 01:19+0000\n"
"POT-Creation-Date: 2017-06-30 17:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -262,6 +262,14 @@ msgstr "Çöürsés Ⱡ'σяєм ιρѕυм #"
msgid "Redeem"
msgstr "Rédéém Ⱡ'σяєм ιρѕυ#"
#: ecommerce/static/js/pages/receipt_page.js
msgid ""
"Caution! Using the back button on this page may cause you to be charged "
"again."
msgstr ""
"Çäütïön! Ûsïng thé ßäçk ßüttön ön thïs pägé mäý çäüsé ýöü tö ßé çhärgéd "
"ägäïn. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
#: ecommerce/static/js/utils/utils.js
msgid "Trailing comma not allowed."
msgstr "Träïlïng çömmä nöt ällöwéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
......
......@@ -8,6 +8,39 @@ define([
function($) {
'use strict';
function disableBackButton() {
/*
* This function uses the URL fragment to prevent users from accidentally
* resubmitting the payment form by discouraging them from using their
* browser's back button on this page. This is a necessary precaution
* when dealing with CyberSource. For more, please see LEARNER-1671.
*/
var initialHash = location.hash,
// Deriving the replacement hash from a timestamp helps keep this
// logic working as expected if a user uses the back button in their
// browser to return to this page after the replacement hash has
// been pushed onto the history stack.
replacementHash = '#' + Date.now().toString(36),
warningMessage = gettext(
'Caution! Using the back button on this page may cause you to be charged again.'
);
// We push the initial hash onto the top of the browser history stack.
history.pushState(null, '', replacementHash);
window.onhashchange = function() {
if (location.hash === initialHash) {
// If the initial hash is popped off the history stack, alert
// the user that going back may cause them to be charged again,
// then push the initial hash back onto the history stack.
// eslint-disable-next-line no-alert
alert(warningMessage);
history.pushState(null, '', replacementHash);
}
};
}
function trackPurchase(orderId, totalAmount, currency) {
window.analytics.track('Completed Purchase', {
orderId: orderId,
......@@ -18,9 +51,12 @@ define([
function onReady() {
var $el = $('#receipt-container'),
currency = $el.data('currency'),
orderId = $el.data('order-id'),
totalAmount = $el.data('total-amount'),
currency = $el.data('currency');
totalAmount = $el.data('total-amount');
disableBackButton();
if (orderId) {
trackPurchase(orderId, totalAmount, currency);
}
......
......@@ -24,6 +24,16 @@ define([
});
describe('onReady', function() {
it('should disable the back button by manipulating the fragment', function() {
ReceiptPage.onReady();
expect(location.hash).toContain('#');
history.back();
expect(location.hash).toContain('#');
});
it('should trigger track purchase', function() {
spyOn(window.analytics, 'track');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment