From e189583718bc874dd4054ec8f9a9d53acae31bc1 Mon Sep 17 00:00:00 2001 From: Benjamin Beurdouche Date: Tue, 21 Jul 2026 16:01:16 +0200 Subject: [PATCH] Bug 2040302 - Disable primary password controls in the Settings Redesign for enterprise-managed profiles In enterprise builds the primary password is managed transparently and the user must not be able to add, change or remove it. The legacy about:preferences pane disables the controls imperatively in _initMasterPasswordUI(), but the Settings Redesign renders them through the declarative Preferences.addSetting() framework, whose disabled state is driven solely by each setting's disabled() callback. The addPrimaryPassword, changePrimaryPassword and turnOffPrimaryPassword settings never consulted LoginHelper.isEnterpriseManagedPrimaryPassword(), so the redesign left them enabled. Add the enterprise check to those callbacks, restore it on the shared _initMasterPasswordUI() button (dropped in an earlier refactor), and cover the redesign behaviour with a browser-chrome test. --- .../preferences/config/passwords-autofill.mjs | 16 ++++-- .../credentials/browser_primaryPassword.js | 53 +++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/browser/components/preferences/config/passwords-autofill.mjs b/browser/components/preferences/config/passwords-autofill.mjs index 9529c6b265796..90642de76571e 100644 --- a/browser/components/preferences/config/passwords-autofill.mjs +++ b/browser/components/preferences/config/passwords-autofill.mjs @@ -162,7 +162,7 @@ export class PasswordSettingHelpers { var button = document.getElementById(buttonId); if (button) { - button.disabled = noMP; + button.disabled = noMP || isEnterpriseManagedPrimaryPassword; } var checkbox = document.getElementById(checkboxId); @@ -635,7 +635,10 @@ Preferences.addSetting({ PasswordSettingHelpers.changeMasterPassword(); }, disabled: () => { - return !Services.policies.isAllowed("createMasterPassword"); + return ( + LoginHelper.isEnterpriseManagedPrimaryPassword() || + !Services.policies.isAllowed("createMasterPassword") + ); }, }); @@ -663,7 +666,11 @@ Preferences.addSetting({ const button = config.options?.find( o => o.key === "turnOffPrimaryPassword" ); - if (button && !Services.policies.isAllowed("removeMasterPassword")) { + if ( + button && + (LoginHelper.isEnterpriseManagedPrimaryPassword() || + !Services.policies.isAllowed("removeMasterPassword")) + ) { button.controlAttrs = { ...button.controlAttrs, disabled: "" }; } return config; @@ -676,6 +683,9 @@ Preferences.addSetting({ onUserClick: () => { PasswordSettingHelpers.changeMasterPassword(); }, + disabled: () => { + return LoginHelper.isEnterpriseManagedPrimaryPassword(); + }, }); Preferences.addSetting({ diff --git a/browser/components/preferences/tests/credentials/browser_primaryPassword.js b/browser/components/preferences/tests/credentials/browser_primaryPassword.js index a865e0903f7af..6fc657cd87477 100644 --- a/browser/components/preferences/tests/credentials/browser_primaryPassword.js +++ b/browser/components/preferences/tests/credentials/browser_primaryPassword.js @@ -140,3 +140,56 @@ add_task(async function () { BrowserTestUtils.removeTab(gBrowser.selectedTab); }); + +// When the primary password is managed by enterprise storage encryption the +// user must not be able to add, change or turn it off from the redesigned +// Passwords and Autofill settings. +add_task(async function enterprise_managed_primary_password_is_disabled() { + await openPreferencesViaOpenPreferencesAPI("panePasswordsAutofill", { + leaveOpen: true, + }); + + let doc = gBrowser.contentDocument; + let win = doc.defaultView; + + // Simulate an enterprise-managed browser whose primary password is set + // transparently and cannot be modified by the user. + win.LoginHelper = { + isPrimaryPasswordSet() { + return true; + }, + getOSAuthEnabled() { + return true; + }, + isEnterpriseManagedPrimaryPassword() { + return true; + }, + }; + + // Force the primary-password settings to re-evaluate their disabled state. + Services.obs.notifyObservers(null, "passwordmgr-primary-pw-changed"); + + let addButton = doc.getElementById("addPrimaryPassword"); + let changeButton = doc.getElementById("changePrimaryPassword"); + let turnOffButton = doc.querySelector("#turnOffPrimaryPassword"); + + await TestUtils.waitForCondition( + () => addButton.disabled && changeButton.disabled && turnOffButton.disabled, + "waiting for the primary password controls to become disabled" + ); + + ok( + addButton.disabled, + "'Add primary password' button should be disabled when enterprise-managed" + ); + ok( + changeButton.disabled, + "'Change primary password' button should be disabled when enterprise-managed" + ); + ok( + turnOffButton.disabled, + "'Turn off primary password' button should be disabled when enterprise-managed" + ); + + BrowserTestUtils.removeTab(gBrowser.selectedTab); +});