зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1348791 - Add a timeout to master password prompt when searching logins. r=MattN
The login manager searching logins for autofill may trap the user in an infinite loop of master password prompts until the user enters the correct master password. To prevent that, we're adding a timeout to showing the master password prompt for autofill after it was last cancelled. MozReview-Commit-ID: JcmTDU6CKKA --HG-- extra : rebase_source : 6f4d2c59360963f53972b812d999756637434415
This commit is contained in:
Родитель
4baa8cc9a2
Коммит
43e38cffa3
|
@ -4434,6 +4434,8 @@ pref("signon.storeWhenAutocompleteOff", true);
|
||||||
pref("signon.debug", false);
|
pref("signon.debug", false);
|
||||||
pref("signon.recipes.path", "chrome://passwordmgr/content/recipes.json");
|
pref("signon.recipes.path", "chrome://passwordmgr/content/recipes.json");
|
||||||
pref("signon.schemeUpgrades", false);
|
pref("signon.schemeUpgrades", false);
|
||||||
|
// This temporarily prevents the master password to reprompt for autocomplete.
|
||||||
|
pref("signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
|
||||||
|
|
||||||
// Satchel (Form Manager) prefs
|
// Satchel (Form Manager) prefs
|
||||||
pref("browser.formfill.debug", false);
|
pref("browser.formfill.debug", false);
|
||||||
|
|
|
@ -36,6 +36,37 @@ var LoginManagerParent = {
|
||||||
*/
|
*/
|
||||||
_recipeManager: null,
|
_recipeManager: null,
|
||||||
|
|
||||||
|
// Tracks the last time the user cancelled the master password prompt,
|
||||||
|
// to avoid spamming master password prompts on autocomplete searches.
|
||||||
|
_lastMPLoginCancelled: Math.NEGATIVE_INFINITY,
|
||||||
|
|
||||||
|
_searchAndDedupeLogins(formOrigin, actionOrigin) {
|
||||||
|
let logins;
|
||||||
|
try {
|
||||||
|
logins = LoginHelper.searchLoginsWithObject({
|
||||||
|
hostname: formOrigin,
|
||||||
|
formSubmitURL: actionOrigin,
|
||||||
|
schemeUpgrades: LoginHelper.schemeUpgrades,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
// Record the last time the user cancelled the MP prompt
|
||||||
|
// to avoid spamming them with MP prompts for autocomplete.
|
||||||
|
if (e.result == Cr.NS_ERROR_ABORT) {
|
||||||
|
log("User cancelled master password prompt.");
|
||||||
|
this._lastMPLoginCancelled = Date.now();
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dedupe so the length checks below still make sense with scheme upgrades.
|
||||||
|
let resolveBy = [
|
||||||
|
"scheme",
|
||||||
|
"timePasswordChanged",
|
||||||
|
];
|
||||||
|
return LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin);
|
||||||
|
},
|
||||||
|
|
||||||
// This should only be called on Android. Listeners are added in
|
// This should only be called on Android. Listeners are added in
|
||||||
// nsBrowserGlue.js on desktop. Please make sure that the list of
|
// nsBrowserGlue.js on desktop. Please make sure that the list of
|
||||||
// listeners added here stays in sync with the listeners added in
|
// listeners added here stays in sync with the listeners added in
|
||||||
|
@ -201,16 +232,8 @@ var LoginManagerParent = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let logins = LoginHelper.searchLoginsWithObject({
|
let logins = this._searchAndDedupeLogins(formOrigin, actionOrigin);
|
||||||
formSubmitURL: actionOrigin,
|
|
||||||
hostname: formOrigin,
|
|
||||||
schemeUpgrades: LoginHelper.schemeUpgrades,
|
|
||||||
});
|
|
||||||
let resolveBy = [
|
|
||||||
"scheme",
|
|
||||||
"timePasswordChanged",
|
|
||||||
];
|
|
||||||
logins = LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin);
|
|
||||||
log("sendLoginDataToChild:", logins.length, "deduped logins");
|
log("sendLoginDataToChild:", logins.length, "deduped logins");
|
||||||
// Convert the array of nsILoginInfo to vanilla JS objects since nsILoginInfo
|
// Convert the array of nsILoginInfo to vanilla JS objects since nsILoginInfo
|
||||||
// doesn't support structured cloning.
|
// doesn't support structured cloning.
|
||||||
|
@ -229,6 +252,22 @@ var LoginManagerParent = {
|
||||||
// Note: previousResult is a regular object, not an
|
// Note: previousResult is a regular object, not an
|
||||||
// nsIAutoCompleteResult.
|
// nsIAutoCompleteResult.
|
||||||
|
|
||||||
|
// Cancel if we unsuccessfully prompted for the master password too recently.
|
||||||
|
if (!Services.logins.isLoggedIn) {
|
||||||
|
let timeDiff = Date.now() - this._lastMPLoginCancelled;
|
||||||
|
if (timeDiff < this._repromptTimeout) {
|
||||||
|
log("Not searching logins for autocomplete since the master password " +
|
||||||
|
`prompt was last cancelled ${Math.round(timeDiff / 1000)} seconds ago.`);
|
||||||
|
// Send an empty array to make LoginManagerContent clear the
|
||||||
|
// outstanding request it has temporarily saved.
|
||||||
|
target.messageManager.sendAsyncMessage("RemoteLogins:loginsAutoCompleted", {
|
||||||
|
requestId,
|
||||||
|
logins: [],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let searchStringLower = searchString.toLowerCase();
|
let searchStringLower = searchString.toLowerCase();
|
||||||
let logins;
|
let logins;
|
||||||
if (previousResult &&
|
if (previousResult &&
|
||||||
|
@ -241,17 +280,7 @@ var LoginManagerParent = {
|
||||||
} else {
|
} else {
|
||||||
log("Creating new autocomplete search result.");
|
log("Creating new autocomplete search result.");
|
||||||
|
|
||||||
// Grab the logins from the database.
|
logins = this._searchAndDedupeLogins(formOrigin, actionOrigin);
|
||||||
logins = LoginHelper.searchLoginsWithObject({
|
|
||||||
formSubmitURL: actionOrigin,
|
|
||||||
hostname: formOrigin,
|
|
||||||
schemeUpgrades: LoginHelper.schemeUpgrades,
|
|
||||||
});
|
|
||||||
let resolveBy = [
|
|
||||||
"scheme",
|
|
||||||
"timePasswordChanged",
|
|
||||||
];
|
|
||||||
logins = LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let matchingLogins = logins.filter(function(fullMatch) {
|
let matchingLogins = logins.filter(function(fullMatch) {
|
||||||
|
@ -310,20 +339,9 @@ var LoginManagerParent = {
|
||||||
(usernameField ? usernameField.name : ""),
|
(usernameField ? usernameField.name : ""),
|
||||||
newPasswordField.name);
|
newPasswordField.name);
|
||||||
|
|
||||||
let logins = LoginHelper.searchLoginsWithObject({
|
|
||||||
formSubmitURL,
|
|
||||||
hostname,
|
|
||||||
schemeUpgrades: LoginHelper.schemeUpgrades,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dedupe so the length checks below still make sense with scheme upgrades.
|
|
||||||
// Below here we have one login per hostPort + action + username with the
|
// Below here we have one login per hostPort + action + username with the
|
||||||
// matching scheme being preferred.
|
// matching scheme being preferred.
|
||||||
let resolveBy = [
|
let logins = this._searchAndDedupeLogins(hostname, formSubmitURL);
|
||||||
"scheme",
|
|
||||||
"timePasswordChanged",
|
|
||||||
];
|
|
||||||
logins = LoginHelper.dedupeLogins(logins, ["username"], resolveBy, hostname);
|
|
||||||
|
|
||||||
// If we didn't find a username field, but seem to be changing a
|
// If we didn't find a username field, but seem to be changing a
|
||||||
// password, allow the user to select from a list of applicable
|
// password, allow the user to select from a list of applicable
|
||||||
|
@ -483,3 +501,6 @@ XPCOMUtils.defineLazyGetter(LoginManagerParent, "recipeParentPromise", function(
|
||||||
});
|
});
|
||||||
return this._recipeManager.initializationPromise;
|
return this._recipeManager.initializationPromise;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyPreferenceGetter(LoginManagerParent, "_repromptTimeout",
|
||||||
|
"signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
|
||||||
|
|
Загрузка…
Ссылка в новой задаче