зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1145754 - Allow per-site recipes to adjust the username/password field detection for capture. r=dolske
This commit is contained in:
Родитель
f477884299
Коммит
b0162ea257
|
@ -654,11 +654,8 @@ var LoginManagerContent = {
|
|||
return false;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* _onFormSubmit
|
||||
*
|
||||
* Called by the our observer when notified of a form submission.
|
||||
/**
|
||||
* Called by our observer when notified of a form submission.
|
||||
* [Note that this happens before any DOM onsubmit handlers are invoked.]
|
||||
* Looks for a password change in the submitted form, so we can update
|
||||
* our stored password.
|
||||
|
@ -692,11 +689,17 @@ var LoginManagerContent = {
|
|||
return;
|
||||
}
|
||||
|
||||
var formSubmitURL = LoginUtils._getActionOrigin(form)
|
||||
let formSubmitURL = LoginUtils._getActionOrigin(form);
|
||||
let messageManager = messageManagerFromWindow(win);
|
||||
|
||||
let recipesArray = messageManager.sendSyncMessage("RemoteLogins:findRecipes", {
|
||||
formOrigin: hostname,
|
||||
})[0];
|
||||
let recipes = new Set(recipesArray);
|
||||
|
||||
// Get the appropriate fields from the form.
|
||||
var [usernameField, newPasswordField, oldPasswordField] =
|
||||
this._getFormFields(form, true);
|
||||
this._getFormFields(form, true, recipes);
|
||||
|
||||
// Need at least 1 valid password field to do anything.
|
||||
if (newPasswordField == null)
|
||||
|
@ -730,7 +733,6 @@ var LoginManagerContent = {
|
|||
// Make sure to pass the opener's top in case it was in a frame.
|
||||
let opener = win.opener ? win.opener.top : null;
|
||||
|
||||
let messageManager = messageManagerFromWindow(win);
|
||||
messageManager.sendAsyncMessage("RemoteLogins:onFormSubmit",
|
||||
{ hostname: hostname,
|
||||
formSubmitURL: formSubmitURL,
|
||||
|
|
|
@ -166,10 +166,21 @@ Services.prefs.addObserver("signon.debug", prefChanged, false);
|
|||
prefChanged();
|
||||
|
||||
var LoginManagerParent = {
|
||||
/**
|
||||
* Reference to the default LoginRecipesParent (instead of the initialization promise) for
|
||||
* synchronous access. This is a temporary hack and new consumers should yield on
|
||||
* recipeParentPromise instead.
|
||||
*
|
||||
* @type LoginRecipesParent
|
||||
* @deprecated
|
||||
*/
|
||||
_recipeManager: null,
|
||||
|
||||
init: function() {
|
||||
let mm = Cc["@mozilla.org/globalmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
mm.addMessageListener("RemoteLogins:findLogins", this);
|
||||
mm.addMessageListener("RemoteLogins:findRecipes", this);
|
||||
mm.addMessageListener("RemoteLogins:onFormSubmit", this);
|
||||
mm.addMessageListener("RemoteLogins:autoCompleteLogins", this);
|
||||
mm.addMessageListener("RemoteLogins:updateLoginFormPresence", this);
|
||||
|
@ -179,8 +190,8 @@ var LoginManagerParent = {
|
|||
|
||||
XPCOMUtils.defineLazyGetter(this, "recipeParentPromise", () => {
|
||||
const { LoginRecipesParent } = Cu.import("resource://gre/modules/LoginRecipes.jsm", {});
|
||||
let parent = new LoginRecipesParent();
|
||||
return parent.initializationPromise;
|
||||
this._recipeManager = new LoginRecipesParent();
|
||||
return this._recipeManager.initializationPromise;
|
||||
});
|
||||
|
||||
},
|
||||
|
@ -209,6 +220,11 @@ var LoginManagerParent = {
|
|||
break;
|
||||
}
|
||||
|
||||
case "RemoteLogins:findRecipes": {
|
||||
let formHost = (new URL(data.formOrigin)).host;
|
||||
return this._recipeManager.getRecipesForHost(formHost);
|
||||
}
|
||||
|
||||
case "RemoteLogins:onFormSubmit": {
|
||||
// TODO Verify msg.target's principals against the formOrigin?
|
||||
this.onFormSubmit(data.hostname,
|
||||
|
|
|
@ -14,6 +14,7 @@ support-files =
|
|||
subtst_notifications_11_popup.html
|
||||
subtst_notifications_2.html
|
||||
subtst_notifications_2pw_0un.html
|
||||
subtst_notifications_2pw_1un_1text.html
|
||||
subtst_notifications_3.html
|
||||
subtst_notifications_4.html
|
||||
subtst_notifications_5.html
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Subtest for Login Manager notifications with 2 password fields and 1 username field and one other text field before the first password field</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>1 username field followed by a text field followed by 2 username fields</h2>
|
||||
<form id="form" action="formsubmit.sjs">
|
||||
<input id="user" name="user" value="staticpw">
|
||||
<input id="city" name="city" value="city">
|
||||
<input id="pass" name="pass" type="password">
|
||||
<input id="pin" name="pin" type="password" value="static-pin">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function submitForm() {
|
||||
userField.value = "notifyu1";
|
||||
passField.value = "notifyp1";
|
||||
form.submit();
|
||||
}
|
||||
|
||||
window.onload = submitForm;
|
||||
var form = document.getElementById("form");
|
||||
var userField = document.getElementById("user");
|
||||
var passField = document.getElementById("pass");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,8 +1,9 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Login Manager</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="pwmgr_common.js"></script>
|
||||
<script type="text/javascript" src="notification_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
@ -16,7 +17,7 @@ Login Manager test: notifications
|
|||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<script class="testbody" type="application/javascript;version=1.8">
|
||||
|
||||
/** Test for Login Manager: notifications. **/
|
||||
|
||||
|
@ -53,6 +54,8 @@ var subtests = [
|
|||
"subtst_notifications_2pw_0un.html", // 26
|
||||
"subtst_notifications_2pw_0un.html", // 27
|
||||
"subtst_notifications_2pw_0un.html", // 28
|
||||
"http://example.org" + testpath + "subtst_notifications_2pw_1un_1text.html", // 29
|
||||
"http://example.org" + testpath + "subtst_notifications_2pw_1un_1text.html", // 30
|
||||
];
|
||||
|
||||
|
||||
|
@ -472,6 +475,44 @@ function checkTest() {
|
|||
pwmgr.removeLogin(login2);
|
||||
break;
|
||||
|
||||
case 29: {
|
||||
// Check that we capture the proper fields when a field recipe is in use.
|
||||
is(gotUser, "notifyu1", "Checking submitted username");
|
||||
is(gotPass, "notifyp1", "Checking submitted password");
|
||||
popup = getPopup(popupNotifications, "password-save");
|
||||
ok(popup, "got notification popup");
|
||||
|
||||
// Sanity check, no logins should exist yet.
|
||||
let logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 0, "Should not have any logins yet");
|
||||
|
||||
clickPopupButton(popup, kRememberButton);
|
||||
break;
|
||||
}
|
||||
|
||||
case 30: {
|
||||
// Same subtest, make sure we didn't prompt for an existing login.
|
||||
is(gotUser, "notifyu1", "Checking submitted username");
|
||||
is(gotPass, "notifyp1", "Checking submitted password");
|
||||
popup = getPopup(popupNotifications, "password-save");
|
||||
ok(!popup, "checking for no notification popup");
|
||||
|
||||
// Check to make sure we updated the timestamps and use count on the
|
||||
// existing login that was submitted for this form.
|
||||
let logins = pwmgr.getAllLogins();
|
||||
is(logins.length, 1, "Should only have 1 login");
|
||||
ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
|
||||
is(logins[0].username, "notifyu1", "check .username for existing login submission");
|
||||
is(logins[0].password, "notifyp1", "check .password for existing login submission");
|
||||
is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
|
||||
ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
|
||||
ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
|
||||
|
||||
// remove the added login
|
||||
pwmgr.removeAllLogins();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ok(false, "Unexpected call to checkTest for test #" + testNum);
|
||||
|
||||
|
@ -509,6 +550,9 @@ var login1B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888"
|
|||
var login2B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
|
||||
"", "notifyp1B", "", "pass");
|
||||
|
||||
var parentScriptURL = SimpleTest.getTestFileURL("pwmgr_common.js");
|
||||
var mm = SpecialPowers.loadChromeScript(parentScriptURL);
|
||||
|
||||
var iframe = document.getElementById("iframe");
|
||||
iframe.onload = handleLoad;
|
||||
|
||||
|
@ -518,8 +562,20 @@ var popupNotifications = getPopupNotifications(window.top);
|
|||
ok(popupNotifications, "Got popupNotifications");
|
||||
|
||||
var testNum = 1;
|
||||
ok(true, "Starting test #" + testNum);
|
||||
iframe.src = subtests[testNum-1];
|
||||
|
||||
// Load recipes for this test.
|
||||
mm.sendAsyncMessage("loadRecipes", {
|
||||
siteRecipes: [{
|
||||
hosts: ["example.org"],
|
||||
usernameSelector: "#user",
|
||||
passwordSelector: "#pass",
|
||||
}],
|
||||
});
|
||||
|
||||
mm.addMessageListener("loadedRecipes", function loadedRecipes() {
|
||||
ok(true, "Starting test #" + testNum);
|
||||
iframe.src = subtests[testNum-1];
|
||||
})
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
|
Загрузка…
Ссылка в новой задаче