Bug 1435274 - Stop form autofilling if the master password prompt is cancelled. r=johannh
MozReview-Commit-ID: HnFbcWYX6QL
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -110,18 +110,21 @@ class FormAutofillSection {
preparePreviewProfile(profile) {}
/**
* Override this method if the profile is needed to be customized for filling
* values.
*
* @param {Object} profile
* A profile for pre-processing before filling values.
+ * @returns {boolean} Whether the profile should be filled.
*/
- async prepareFillingProfile(profile) {}
+ async prepareFillingProfile(profile) {
+ return true;
+ }
/*
* Override this methid if any data for `createRecord` is needed to be
* normailized before submitting the record.
*
* @param {Object} profile
* A record for normalization.
*/
@@ -243,17 +246,20 @@ class FormAutofillSection {
* A profile to be filled in.
*/
async autofillFields(profile) {
let focusedDetail = this._focusedDetail;
if (!focusedDetail) {
throw new Error("No fieldDetail for the focused input.");
}
- await this.prepareFillingProfile(profile);
+ if (!await this.prepareFillingProfile(profile)) {
+ log.debug("profile cannot be filled", profile);
+ return;
+ }
log.debug("profile in autofillFields:", profile);
this.filledRecordGUID = profile.guid;
for (let fieldDetail of this.fieldDetails) {
// Avoid filling field value in the following cases:
// 1. a non-empty input field for an unfocused input
// 2. the invalid value set
// 3. value already chosen in select element
@@ -848,33 +854,35 @@ class FormAutofillCreditCardSection exte
}
}
/**
* Customize for filling prorifle.
*
* @param {Object} profile
* A profile for pre-processing before filling values.
+ * @returns {boolean} Whether the profile should be filled.
* @override
*/
async prepareFillingProfile(profile) {
// When Master Password is enabled by users, the decryption process
// should prompt Master Password dialog to get the decrypted credit
// card number. Otherwise, the number can be decrypted with the default
// password.
if (profile["cc-number-encrypted"]) {
let decrypted = await this._decrypt(profile["cc-number-encrypted"], true);
if (!decrypted) {
// Early return if the decrypted is empty or undefined
- return;
+ return false;
}
profile["cc-number"] = decrypted;
}
+ return true;
}
}
/**
* Handles profile autofill for a DOM Form element.
*/
class FormAutofillHandler {
/**
--- a/browser/extensions/formautofill/test/browser/browser.ini
+++ b/browser/extensions/formautofill/test/browser/browser.ini
@@ -7,16 +7,17 @@ support-files =
../fixtures/autocomplete_simple_basic.html
../fixtures/autocomplete_creditcard_basic.html
[browser_autocomplete_footer.js]
[browser_autocomplete_marked_back_forward.js]
[browser_autocomplete_marked_detached_tab.js]
[browser_check_installed.js]
[browser_creditCard_doorhanger.js]
+[browser_creditCard_fill_master_password.js]
[browser_dropdown_layout.js]
[browser_editAddressDialog.js]
[browser_editCreditCardDialog.js]
[browser_first_time_use_doorhanger.js]
[browser_insecure_form.js]
[browser_manageAddressesDialog.js]
[browser_manageCreditCardsDialog.js]
[browser_privacyPreferences.js]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/browser_creditCard_fill_master_password.js
@@ -0,0 +1,25 @@
+"use strict";
+
+add_task(async function test_fill_creditCard_with_mp_enabled_but_canceled() {
+ await saveCreditCard(TEST_CREDIT_CARD_2);
+
+ LoginTestUtils.masterPassword.enable();
+ registerCleanupFunction(() => {
+ LoginTestUtils.masterPassword.disable();
+ });
+
+ let masterPasswordDialogShown = waitForMasterPasswordDialog(false); // cancel
+ await BrowserTestUtils.withNewTab({gBrowser, url: CREDITCARD_FORM_URL},
+ async function(browser) {
+ await openPopupOn(browser, "#cc-name");
+ const ccItem = getDisplayedPopupItems(browser)[0];
+ await EventUtils.synthesizeMouseAtCenter(ccItem, {});
+ await Promise.all([masterPasswordDialogShown, expectPopupClose(browser)]);
+
+ await ContentTask.spawn(browser, {}, async function() {
+ is(content.document.querySelector("#cc-name").value, "", "Check name");
+ is(content.document.querySelector("#cc-number").value, "", "Check number");
+ });
+ }
+ );
+});