Skip to content

Commit

Permalink
Bug 1667257 - Detect credit card type by examining IIN part of credit…
Browse files Browse the repository at this point in the history
… card number r=sgalich

Differential Revision: https://phabricator.services.mozilla.com/D164904
  • Loading branch information
DimiDL committed Jan 3, 2023
1 parent c88334f commit 4915cb3
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 189 deletions.
20 changes: 0 additions & 20 deletions browser/extensions/formautofill/content/autofillEditForms.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,6 @@ class EditCreditCard extends EditAutofillForm {
),
month: this._elements.form.querySelector("#cc-exp-month"),
year: this._elements.form.querySelector("#cc-exp-year"),
ccType: this._elements.form.querySelector("#cc-type"),
billingAddress: this._elements.form.querySelector("#billingAddressGUID"),
billingAddressRow: this._elements.form.querySelector(
".billingAddressRow"
Expand All @@ -531,8 +530,6 @@ class EditCreditCard extends EditAutofillForm {
this._addresses = addresses;
this.generateBillingAddressOptions(preserveFieldValues);
if (!preserveFieldValues) {
// Re-populating the networks will reset the selected option.
this.populateNetworks();
// Re-generating the months will reset the selected option.
this.generateMonths();
// Re-generating the years will reset the selected option.
Expand Down Expand Up @@ -591,23 +588,6 @@ class EditCreditCard extends EditAutofillForm {
}
}

populateNetworks() {
// Clear the list
this._elements.ccType.textContent = "";
let frag = document.createDocumentFragment();
// include an empty first option
frag.appendChild(new Option("", ""));

let supportedNetworks = FormAutofillUtils.getCreditCardNetworks();
for (let id of supportedNetworks) {
const option = new Option(undefined, id);
// autofill-card-network-amex, ..., autofill-card-network-visa
option.dataset.l10nId = `autofill-card-network-${id}`;
frag.appendChild(option);
}
this._elements.ccType.appendChild(frag);
}

generateBillingAddressOptions(preserveFieldValues) {
let billingAddressGUID;
if (preserveFieldValues && this._elements.billingAddress.value) {
Expand Down
5 changes: 0 additions & 5 deletions browser/extensions/formautofill/content/editCreditCard.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@
<input id="cc-name" type="text" required="required"/>
<span data-l10n-id="autofill-card-name-on-card" class="label-text"/>
</label>
<label id="cc-type-container" class="container">
<select id="cc-type" required="required">
</select>
<span data-l10n-id="autofill-card-network" class="label-text"/>
</label>
<label id="cc-csc-container" class="container" hidden="hidden">
<!-- The CSC container will get filled in by forms that need a CSC (using csc-input.js) -->
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
display: grid;
grid-template-areas:
"cc-number cc-exp-month cc-exp-year"
"cc-name cc-type cc-csc"
"cc-name cc-csc ."
"billingAddressGUID billingAddressGUID billingAddressGUID";
grid-template-columns: 4fr 2fr 2fr;
grid-row-gap: var(--grid-column-row-gap);
Expand Down Expand Up @@ -40,10 +40,6 @@
grid-area: cc-name;
}

#cc-type-container {
grid-area: cc-type;
}

#cc-csc-container {
grid-area: cc-csc;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ skip-if = ((os == "mac") || (os == 'linux') || (os == 'win'))
skip-if = ((!debug && os == "mac") || (os == 'linux') || (os == 'win'))
[browser_creditCard_heuristics.js]
skip-if = apple_silicon && !debug # Bug 1714221
[browser_creditCard_submission_autodetect_type.js]
skip-if = apple_silicon && !debug
[browser_creditCard_submission_normalized.js]
skip-if = apple_silicon && !debug
[browser_editCreditCardDialog.js]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ add_task(async function test_submit_creditCard_saved() {
focusSelector: "#cc-name",
newValues: {
"#cc-name": "User 1",
"#cc-number": "5038146897157463",
"#cc-number": "5577000055770004",
"#cc-exp-month": "12",
"#cc-exp-year": "2017",
"#cc-type": "mastercard",
Expand Down Expand Up @@ -918,7 +918,6 @@ add_task(async function test_submit_third_party_creditCard_logo() {
add_task(async function test_update_third_party_creditCard_logo() {
const amexCard = {
"cc-number": "374542158116607",
"cc-type": "amex",
"cc-name": "John Doe",
};

Expand Down Expand Up @@ -1070,7 +1069,6 @@ add_task(async function test_save_panel_spaces_in_cc_number_logo() {
add_task(async function test_update_panel_with_spaces_in_cc_number_logo() {
const amexCard = {
"cc-number": "374 54215 8116607",
"cc-type": "amex",
"cc-name": "John Doe",
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

add_task(async function test_autodetect_credit_not_set() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "John Doe",
"cc-number": "4012888888881881",
"cc-exp-month": "06",
"cc-exp-year": "2044",
};
const expectedData = {
...testCard,
...{ "cc-type": "visa" },
};
let onChanged = waitForStorageChangedEvents("add");

await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = waitForPopupShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": testCard["cc-exp-month"],
"#cc-exp-year": testCard["cc-exp-year"],
"#cc-type": testCard["cc-type"],
},
});

await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);

await onChanged;

let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
let decryptedNumber = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
savedCreditCard["cc-number"] = decryptedNumber;
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}
await removeAllRecords();
});

add_task(async function test_autodetect_credit_overwrite() {
await SpecialPowers.pushPrefEnv({
set: [[CREDITCARDS_USED_STATUS_PREF, 0]],
});
const testCard = {
"cc-name": "John Doe",
"cc-number": "4012888888881881",
"cc-exp-month": "06",
"cc-exp-year": "2044",
"cc-type": "master", // Wrong credit card type
};
const expectedData = {
...testCard,
...{ "cc-type": "visa" },
};
let onChanged = waitForStorageChangedEvents("add");

await BrowserTestUtils.withNewTab(
{ gBrowser, url: CREDITCARD_FORM_URL },
async function(browser) {
let promiseShown = waitForPopupShown();
await focusUpdateSubmitForm(browser, {
focusSelector: "#cc-name",
newValues: {
"#cc-name": testCard["cc-name"],
"#cc-number": testCard["cc-number"],
"#cc-exp-month": testCard["cc-exp-month"],
"#cc-exp-year": testCard["cc-exp-year"],
"#cc-type": testCard["cc-type"],
},
});

await promiseShown;
await clickDoorhangerButton(MAIN_BUTTON);
}
);

await onChanged;

let creditCards = await getCreditCards();
let savedCreditCard = creditCards[0];
let decryptedNumber = await OSKeyStore.decrypt(
savedCreditCard["cc-number-encrypted"]
);
savedCreditCard["cc-number"] = decryptedNumber;
for (let key in testCard) {
let expected = expectedData[key];
let actual = savedCreditCard[key];
Assert.equal(expected, actual, `${key} should match`);
}

await removeAllRecords();
});
Original file line number Diff line number Diff line change
Expand Up @@ -663,8 +663,6 @@ add_task(async function test_saveCreditCard() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
Expand Down Expand Up @@ -693,7 +691,6 @@ add_task(async function test_editCreditCard() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_RIGHT", {}, win);
EventUtils.synthesizeKey("test", {}, win);
win.document.querySelector("#save").click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ add_task(async function test_saveCreditCard() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
Expand Down Expand Up @@ -87,9 +85,6 @@ add_task(async function test_saveCreditCardWithMaxYear() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_2["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD_1["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
EventUtils.synthesizeKey("VK_RETURN", {}, win);
});
Expand Down Expand Up @@ -133,8 +128,6 @@ add_task(async function test_saveCreditCardWithBillingAddress() {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD["cc-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(TEST_CREDIT_CARD["cc-type"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey(billingAddress["given-name"], {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
info("saving credit card");
Expand Down Expand Up @@ -271,54 +264,6 @@ add_task(async function test_addInvalidCreditCard() {
is(creditCards.length, 0, "Credit card storage is empty");
});

add_task(async function test_editCardWithInvalidNetwork() {
const TEST_CREDIT_CARD = Object.assign({}, TEST_CREDIT_CARD_2, {
"cc-type": "asiv",
});
await setStorage(TEST_CREDIT_CARD);

let creditCards = await getCreditCards();
is(creditCards.length, 1, "one credit card in storage");
is(
creditCards[0]["cc-type"],
TEST_CREDIT_CARD["cc-type"],
"Check saved cc-type"
);
await testDialog(
EDIT_CREDIT_CARD_DIALOG_URL,
win => {
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_TAB", {}, win);
EventUtils.synthesizeKey("VK_RIGHT", {}, win);
EventUtils.synthesizeKey("test", {}, win);
win.document.querySelector("#save").click();
},
{
record: creditCards[0],
}
);
ok(true, "Edit credit card dialog is closed");
creditCards = await getCreditCards();

is(creditCards.length, 1, "only one credit card is in storage");
is(
creditCards[0]["cc-name"],
TEST_CREDIT_CARD["cc-name"] + "test",
"cc name changed"
);
is(
creditCards[0]["cc-type"],
"visa",
"unknown cc-type removed and next autodetected to visa upon manual save"
);
await removeCreditCards([creditCards[0].guid]);

creditCards = await getCreditCards();
is(creditCards.length, 0, "Credit card storage is empty");
});

add_task(async function test_editInvalidCreditCardNumber() {
await setStorage(TEST_ADDRESS_4);
let addresses = await getAddresses();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,7 @@ add_task(async function test_showCreditCardIcons() {
set: [["privacy.reduceTimerPrecision", false]],
});
await setStorage(TEST_CREDIT_CARD_1);
let unknownCard = Object.assign({}, TEST_CREDIT_CARD_3, {
"cc-type": "gringotts",
});
await setStorage(unknownCard);
await setStorage(TEST_CREDIT_CARD_3);

let win = window.openDialog(
MANAGE_CREDIT_CARDS_DIALOG_URL,
Expand All @@ -216,7 +213,7 @@ add_task(async function test_showCreditCardIcons() {

is(
option0.getAttribute("cc-type"),
"gringotts",
"mastercard",
"Option has the expected cc-type"
);
is(
Expand Down
5 changes: 0 additions & 5 deletions browser/extensions/formautofill/test/browser/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,33 +148,28 @@ const TEST_CREDIT_CARD_1 = {
"cc-number": "4111111111111111",
"cc-exp-month": 4,
"cc-exp-year": new Date().getFullYear(),
"cc-type": "visa",
};

const TEST_CREDIT_CARD_2 = {
"cc-name": "Timothy Berners-Lee",
"cc-number": "4929001587121045",
"cc-exp-month": 12,
"cc-exp-year": new Date().getFullYear() + 10,
"cc-type": "visa",
};

const TEST_CREDIT_CARD_3 = {
"cc-number": "5103059495477870",
"cc-exp-month": 1,
"cc-exp-year": 2000,
"cc-type": "mastercard",
};

const TEST_CREDIT_CARD_4 = {
"cc-number": "5105105105105100",
"cc-type": "mastercard",
};

const TEST_CREDIT_CARD_5 = {
"cc-name": "Chris P. Bacon",
"cc-number": "4012888888881881",
"cc-type": "visa",
};

const MAIN_BUTTON = "button";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
"cc-number": "4929001587121045",
"cc-exp-month": 4,
"cc-exp-year": 2017,
"cc-type": "visa",
}, {
"cc-name": "Timothy Berners-Lee",
"cc-number": "5103059495477870",
"cc-exp-month": 12,
"cc-exp-year": 2022,
"cc-type": "mastercard",
}];

const reducedMockRecord = {
Expand Down
Loading

0 comments on commit 4915cb3

Please sign in to comment.