Bug 1287202 - Run login capture code upon page navigation if there are password fields present in a <form> draft
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 22 Jun 2017 21:55:45 -0700
changeset 599441 52f2f2799ffa7c55487203a913482a90aea0c958
parent 599440 7c32e1f005a16ea145d4aabfe29e766cdb6e688c
child 634774 9bde8398c4a6ff82521c973dc5b875d98eeff4ee
push id65523
push usermozilla@noorenberghe.ca
push dateFri, 23 Jun 2017 05:03:08 +0000
bugs1287202
milestone56.0a1
Bug 1287202 - Run login capture code upon page navigation if there are password fields present in a <form> MozReview-Commit-ID: JkNq8bahbJZ
toolkit/components/passwordmgr/LoginManagerContent.jsm
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -876,24 +876,16 @@ var LoginManagerContent = {
    */
   _onNavigation(aDocument) {
     let state = this.stateForDocument(aDocument);
     let loginFormRootElements = state.loginFormRootElements;
     log("_onNavigation: state:", state, "loginFormRootElements size:", loginFormRootElements.size,
         "document:", aDocument);
 
     for (let formRoot of state.loginFormRootElements) {
-      if (formRoot instanceof Ci.nsIDOMHTMLFormElement) {
-        // For now only perform capture upon navigation for FormLike's without
-        // a <form> to avoid capture from both an earlyformsubmit and
-        // navigation for the same "form".
-        log("Ignoring navigation for the form root to avoid multiple prompts " +
-            "since it was for a real <form>");
-        continue;
-      }
       let formLike = this._formLikeByRootElement.get(formRoot);
       this._onFormSubmit(formLike);
     }
   },
 
   /**
    * Called by our observer when notified of a form submission.
    * [Note that this happens before any DOM onsubmit handlers are invoked.]
@@ -959,16 +951,28 @@ var LoginManagerContent = {
                          null;
     let mockPassword = { name: newPasswordField.name,
                          value: newPasswordField.value };
     let mockOldPassword = oldPasswordField ?
                             { name: oldPasswordField.name,
                               value: oldPasswordField.value } :
                             null;
 
+    let usernameValue = usernameField ? usernameField.value : null;
+    if (form.promptedUsername == usernameValue &&
+        form.promptedPassword == newPasswordField.value) {
+      log("(form submission ignored -- already submitted with the same username and password)");
+      return;
+    }
+
+    // Save the last values used to prompt so we don't prompt twice for the same values using
+    // different capture methods e.g. a form submit event and upon navigation.
+    form.promptedUsername = usernameValue;
+    form.promptedPassword = newPasswordField.value;
+
     // Make sure to pass the opener's top in case it was in a frame.
     let openerTopWindow = win.opener ? win.opener.top : null;
 
     messageManager.sendAsyncMessage("RemoteLogins:onFormSubmit",
                                     { hostname,
                                       formSubmitURL,
                                       usernameField: mockUsername,
                                       newPasswordField: mockPassword,