diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 048921af2..aa15005b7 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1622,6 +1622,8 @@ pref("browser.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4"); pref("browser.pocket.useLocaleList", true); pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu it ja ja-JP-mac ko nl pl pt-BR pt-PT ru zh-CN zh-TW"); +pref("signon.privateBrowsingCapture.enabled", true); + pref("view_source.tab", true); pref("dom.webnotifications.serviceworker.enabled", true); diff --git a/browser/components/preferences/in-content/security.js b/browser/components/preferences/in-content/security.js index fea9f5292..914f70a0e 100644 --- a/browser/components/preferences/in-content/security.js +++ b/browser/components/preferences/in-content/security.js @@ -99,23 +99,15 @@ var gSecurityPane = { /** * Enables/disables the Exceptions button used to configure sites where - * passwords are never saved. When browser is set to start in Private - * Browsing mode, the "Remember passwords" UI is useless, so we disable it. + * passwords are never saved. */ readSavePasswords: function () { - var pref = document.getElementById("signon.rememberSignons"); - var excepts = document.getElementById("passwordExceptions"); + var prefValue = document.getElementById("signon.rememberSignons").value; + document.getElementById("passwordExceptions").disabled = !prefValue; - if (PrivateBrowsingUtils.permanentPrivateBrowsing) { - document.getElementById("savePasswords").disabled = true; - excepts.disabled = true; - return false; - } else { - excepts.disabled = !pref.value; - // don't override pref value in UI - return undefined; - } + // don't override pref value in UI + return undefined; }, /** diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 00b731304..6e5c237e0 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4098,6 +4098,7 @@ pref("signon.rememberSignons.visibilityToggle", false); #endif pref("signon.autofillForms", true); pref("signon.autologin.proxy", false); +pref("signon.privateBrowsingCapture.enabled", false); pref("signon.storeWhenAutocompleteOff", true); pref("signon.ui.experimental", false); pref("signon.debug", false); diff --git a/toolkit/components/passwordmgr/LoginHelper.jsm b/toolkit/components/passwordmgr/LoginHelper.jsm index b9ff8b010..3ccc63553 100644 --- a/toolkit/components/passwordmgr/LoginHelper.jsm +++ b/toolkit/components/passwordmgr/LoginHelper.jsm @@ -37,6 +37,8 @@ this.LoginHelper = { * Warning: this only updates if a logger was created. */ debug: Services.prefs.getBoolPref("signon.debug"), + privateBrowsingCaptureEnabled: + Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"), createLogger(aLogPrefix) { let getMaxLogLevel = () => { @@ -54,6 +56,8 @@ this.LoginHelper = { // Watch for pref changes and update this.debug and the maxLogLevel for created loggers Services.prefs.addObserver("signon.", () => { this.debug = Services.prefs.getBoolPref("signon.debug"); + this.privateBrowsingCaptureEnabled = + Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"); logger.maxLogLevel = getMaxLogLevel(); }, false); diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index 75fc97cf6..dcd661f75 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -752,7 +752,8 @@ var LoginManagerContent = { var doc = form.ownerDocument; var win = doc.defaultView; - if (PrivateBrowsingUtils.isContentWindowPrivate(win)) { + if (PrivateBrowsingUtils.isContentWindowPrivate(win) && + !LoginHelper.privateBrowsingCaptureEnabled) { // We won't do anything in private browsing mode anyway, // so there's no need to perform further checks. log("(form submission ignored in private browsing mode)"); diff --git a/toolkit/components/passwordmgr/LoginManagerParent.jsm b/toolkit/components/passwordmgr/LoginManagerParent.jsm index c17f3b619..6fe72744c 100644 --- a/toolkit/components/passwordmgr/LoginManagerParent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm @@ -21,6 +21,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginDoorhangers", "resource://gre/modules/LoginDoorhangers.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", "resource://gre/modules/LoginHelper.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", + "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "log", () => { let logger = LoginHelper.createLogger("LoginManagerParent"); @@ -435,6 +437,10 @@ var LoginManagerParent = { } function recordLoginUse(login) { + if (!target || PrivateBrowsingUtils.isBrowserPrivate(target)) { + // don't record non-interactive use in private browsing + return; + } // Update the lastUsed timestamp and increment the use count. let propBag = Cc["@mozilla.org/hash-property-bag;1"]. createInstance(Ci.nsIWritablePropertyBag); diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js index e5f0b8407..245e18490 100644 --- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js +++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js @@ -326,6 +326,12 @@ LoginManagerPrompter.prototype = { } }, + get _allowRememberLogin() { + if (!this._inPrivateBrowsing) { + return true; + } + return LoginHelper.privateBrowsingCaptureEnabled; + }, @@ -376,10 +382,8 @@ LoginManagerPrompter.prototype = { // If hostname is null, we can't save this login. if (hostname) { - var canRememberLogin; - if (this._inPrivateBrowsing) - canRememberLogin = false; - else + var canRememberLogin = false; + if (this._allowRememberLogin) canRememberLogin = (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) && this._pwmgr.getLoginSavingEnabled(hostname); @@ -614,7 +618,7 @@ LoginManagerPrompter.prototype = { } var canRememberLogin = this._pwmgr.getLoginSavingEnabled(hostname); - if (this._inPrivateBrowsing) + if (!this._allowRememberLogin) canRememberLogin = false; // if checkboxLabel is null, the checkbox won't be shown at all. @@ -828,7 +832,7 @@ LoginManagerPrompter.prototype = { * This is "password-save" or "password-change" depending on the * original notification type. This is used for telemetry and tests. */ - _showLoginCaptureDoorhanger(login, type) { + _showLoginCaptureDoorhanger(login, type, options = {}) { let { browser } = this._getNotifyWindow(); let saveMsgNames = { @@ -1036,7 +1040,7 @@ LoginManagerPrompter.prototype = { "password-notification-icon", mainAction, secondaryActions, - { + Object.assign({ timeout: Date.now() + 10000, displayURI: Services.io.newURI(login.hostname, null, null), persistWhileVisible: true, @@ -1080,7 +1084,7 @@ LoginManagerPrompter.prototype = { } return false; }, - } + }, options) ); }, @@ -1120,7 +1124,9 @@ LoginManagerPrompter.prototype = { // Notification is a PopupNotification if (aNotifyObj == this._getPopupNote()) { - this._showLoginCaptureDoorhanger(aLogin, "password-save"); + this._showLoginCaptureDoorhanger(aLogin, "password-save", { + dismissed: this._inPrivateBrowsing, + }); } else { var notNowButtonText = this._getLocalizedString("notifyBarNotNowButtonText");