summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/preferences
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/mozapps/preferences/changemp.js220
-rw-r--r--toolkit/mozapps/preferences/changemp.xhtml96
-rw-r--r--toolkit/mozapps/preferences/fontbuilder.js120
-rw-r--r--toolkit/mozapps/preferences/jar.mn11
-rw-r--r--toolkit/mozapps/preferences/moz.build10
-rw-r--r--toolkit/mozapps/preferences/removemp.js52
-rw-r--r--toolkit/mozapps/preferences/removemp.xhtml54
7 files changed, 563 insertions, 0 deletions
diff --git a/toolkit/mozapps/preferences/changemp.js b/toolkit/mozapps/preferences/changemp.js
new file mode 100644
index 0000000000..2062d497df
--- /dev/null
+++ b/toolkit/mozapps/preferences/changemp.js
@@ -0,0 +1,220 @@
+// -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
+const nsIPK11TokenDB = Ci.nsIPK11TokenDB;
+const nsIDialogParamBlock = Ci.nsIDialogParamBlock;
+const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
+const nsIPKCS11ModuleDB = Ci.nsIPKCS11ModuleDB;
+const nsIPKCS11Slot = Ci.nsIPKCS11Slot;
+const nsIPK11Token = Ci.nsIPK11Token;
+
+var params;
+var pw1;
+
+function init() {
+ pw1 = document.getElementById("pw1");
+
+ process();
+ document.addEventListener("dialogaccept", setPassword);
+}
+
+function process() {
+ // If the token is unitialized, don't use the old password box.
+ // Otherwise, do.
+
+ let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
+ Ci.nsIPK11TokenDB
+ );
+ let token = tokenDB.getInternalKeyToken();
+ if (token) {
+ let oldpwbox = document.getElementById("oldpw");
+ let msgBox = document.getElementById("message");
+ if ((token.needsLogin() && token.needsUserInit) || !token.needsLogin()) {
+ oldpwbox.hidden = true;
+ msgBox.hidden = false;
+
+ if (!token.needsLogin()) {
+ oldpwbox.setAttribute("inited", "empty");
+ } else {
+ oldpwbox.setAttribute("inited", "true");
+ }
+
+ // Select first password field
+ document.getElementById("pw1").focus();
+ } else {
+ // Select old password field
+ oldpwbox.hidden = false;
+ msgBox.hidden = true;
+ oldpwbox.setAttribute("inited", "false");
+ oldpwbox.focus();
+ }
+ }
+
+ if (
+ !token.hasPassword &&
+ !Services.policies.isAllowed("removeMasterPassword")
+ ) {
+ document.getElementById("admin").hidden = false;
+ }
+
+ if (params) {
+ // Return value 0 means "canceled"
+ params.SetInt(1, 0);
+ }
+
+ checkPasswords();
+}
+
+async function createAlert(titleL10nId, messageL10nId) {
+ const [title, message] = await document.l10n.formatValues([
+ { id: titleL10nId },
+ { id: messageL10nId },
+ ]);
+ Services.prompt.alert(window, title, message);
+}
+
+function setPassword() {
+ var pk11db = Cc[nsPK11TokenDB].getService(nsIPK11TokenDB);
+ var token = pk11db.getInternalKeyToken();
+
+ var oldpwbox = document.getElementById("oldpw");
+ var initpw = oldpwbox.getAttribute("inited");
+
+ if (initpw == "false" || initpw == "empty") {
+ try {
+ var oldpw = "";
+ var passok = 0;
+
+ if (initpw == "empty") {
+ passok = 1;
+ } else {
+ oldpw = oldpwbox.value;
+ passok = token.checkPassword(oldpw);
+ }
+
+ if (passok) {
+ if (initpw == "empty" && pw1.value == "") {
+ // This makes no sense that we arrive here,
+ // we reached a case that should have been prevented by checkPasswords.
+ } else {
+ if (pw1.value == "") {
+ var secmoddb = Cc[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
+ if (secmoddb.isFIPSEnabled) {
+ // empty passwords are not allowed in FIPS mode
+ createAlert(
+ "pw-change-failed-title",
+ "pp-change2empty-in-fips-mode"
+ );
+ passok = 0;
+ }
+ }
+ if (passok) {
+ token.changePassword(oldpw, pw1.value);
+ if (pw1.value == "") {
+ createAlert("pw-change-success-title", "settings-pp-erased-ok");
+ } else {
+ createAlert("pw-change-success-title", "pp-change-ok");
+ }
+ }
+ }
+ } else {
+ oldpwbox.focus();
+ oldpwbox.setAttribute("value", "");
+ createAlert("pw-change-failed-title", "incorrect-pp");
+ }
+ } catch (e) {
+ console.error(e);
+ createAlert("pw-change-failed-title", "failed-pp-change");
+ }
+ } else {
+ token.initPassword(pw1.value);
+ if (pw1.value == "") {
+ createAlert("pw-change-success-title", "settings-pp-not-wanted");
+ }
+ }
+}
+
+function setPasswordStrength() {
+ // Here is how we weigh the quality of the password
+ // number of characters
+ // numbers
+ // non-alpha-numeric chars
+ // upper and lower case characters
+
+ var pw = document.getElementById("pw1").value;
+
+ // length of the password
+ var pwlength = pw.length;
+ if (pwlength > 5) {
+ pwlength = 5;
+ }
+
+ // use of numbers in the password
+ var numnumeric = pw.replace(/[0-9]/g, "");
+ var numeric = pw.length - numnumeric.length;
+ if (numeric > 3) {
+ numeric = 3;
+ }
+
+ // use of symbols in the password
+ var symbols = pw.replace(/\W/g, "");
+ var numsymbols = pw.length - symbols.length;
+ if (numsymbols > 3) {
+ numsymbols = 3;
+ }
+
+ // use of uppercase in the password
+ var numupper = pw.replace(/[A-Z]/g, "");
+ var upper = pw.length - numupper.length;
+ if (upper > 3) {
+ upper = 3;
+ }
+
+ var pwstrength =
+ pwlength * 10 - 20 + numeric * 10 + numsymbols * 15 + upper * 10;
+
+ // make sure we're give a value between 0 and 100
+ if (pwstrength < 0) {
+ pwstrength = 0;
+ }
+
+ if (pwstrength > 100) {
+ pwstrength = 100;
+ }
+
+ var mymeter = document.getElementById("pwmeter");
+ mymeter.value = pwstrength;
+}
+
+function checkPasswords() {
+ var pw1 = document.getElementById("pw1").value;
+ var pw2 = document.getElementById("pw2").value;
+ var ok = document.getElementById("changemp").getButton("accept");
+
+ var oldpwbox = document.getElementById("oldpw");
+ if (oldpwbox) {
+ var initpw = oldpwbox.getAttribute("inited");
+
+ if (initpw == "empty" && pw1 == "") {
+ // The token has already been initialized, therefore this dialog
+ // was called with the intention to change the password.
+ // The token currently uses an empty password.
+ // We will not allow changing the password from empty to empty.
+ ok.setAttribute("disabled", "true");
+ return;
+ }
+ }
+
+ if (
+ pw1 == pw2 &&
+ (pw1 != "" || Services.policies.isAllowed("removeMasterPassword"))
+ ) {
+ ok.setAttribute("disabled", "false");
+ } else {
+ ok.setAttribute("disabled", "true");
+ }
+}
diff --git a/toolkit/mozapps/preferences/changemp.xhtml b/toolkit/mozapps/preferences/changemp.xhtml
new file mode 100644
index 0000000000..c2c6d75677
--- /dev/null
+++ b/toolkit/mozapps/preferences/changemp.xhtml
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<window
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ style="min-width: 40em"
+ onload="init()"
+ data-l10n-id="primary-password-dialog"
+>
+ <dialog id="changemp">
+ <script src="chrome://mozapps/content/preferences/changemp.js" />
+
+ <linkset>
+ <html:link rel="stylesheet" href="chrome://global/skin/global.css" />
+
+ <html:link rel="localization" href="branding/brand.ftl" />
+ <html:link
+ rel="localization"
+ href="toolkit/preferences/preferences.ftl"
+ />
+ </linkset>
+
+ <description
+ id="admin"
+ class="header"
+ data-l10n-id="primary-password-required-by-policy"
+ hidden="true"
+ ></description>
+ <description
+ control="pw1"
+ data-l10n-id="primary-password-description"
+ ></description>
+
+ <vbox>
+ <hbox>
+ <label
+ flex="1"
+ control="oldpw"
+ data-l10n-id="set-password-old-password"
+ ></label>
+ <html:input id="oldpw" type="password" />
+ <!-- This textbox is inserted as a workaround to the fact that making the 'type'
+ & 'disabled' property of the 'oldpw' textbox toggle between ['password' &
+ 'false'] and ['text' & 'true'] - as would be necessary if the menu has more
+ than one tokens, some initialized and some not - does not work properly. So,
+ either the textbox 'oldpw' or the textbox 'message' would be displayed,
+ depending on the state of the token selected
+ -->
+ <html:input
+ type="text"
+ data-l10n-attrs="value"
+ data-l10n-id="password-not-set"
+ id="message"
+ disabled="true"
+ />
+ </hbox>
+ <hbox>
+ <label
+ flex="1"
+ control="pw1"
+ data-l10n-id="set-password-new-password"
+ ></label>
+ <html:input
+ id="pw1"
+ type="password"
+ oninput="setPasswordStrength(); checkPasswords();"
+ />
+ </hbox>
+ <hbox>
+ <label
+ flex="1"
+ control="pw2"
+ data-l10n-id="set-password-reenter-password"
+ ></label>
+ <html:input id="pw2" type="password" oninput="checkPasswords();" />
+ </hbox>
+ </vbox>
+
+ <html:label
+ for="pwmeter"
+ style="display: flex"
+ data-l10n-id="set-password-meter"
+ ></html:label>
+ <html:progress id="pwmeter" value="0" max="100" />
+
+ <description
+ control="pw2"
+ class="header"
+ data-l10n-id="primary-password-warning"
+ ></description>
+ </dialog>
+</window>
diff --git a/toolkit/mozapps/preferences/fontbuilder.js b/toolkit/mozapps/preferences/fontbuilder.js
new file mode 100644
index 0000000000..5e264bfa53
--- /dev/null
+++ b/toolkit/mozapps/preferences/fontbuilder.js
@@ -0,0 +1,120 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* import-globals-from ../../content/preferencesBindings.js */
+
+var FontBuilder = {
+ _enumerator: null,
+ get enumerator() {
+ if (!this._enumerator) {
+ this._enumerator = Cc["@mozilla.org/gfx/fontenumerator;1"].createInstance(
+ Ci.nsIFontEnumerator
+ );
+ }
+ return this._enumerator;
+ },
+
+ _allFonts: null,
+ _langGroupSupported: false,
+ async buildFontList(aLanguage, aFontType, aMenuList) {
+ // Remove the original <menupopup>
+ if (aMenuList.menupopup) {
+ aMenuList.menupopup.remove();
+ }
+
+ let defaultFont = null;
+ // Load Font Lists
+ let fonts = await this.enumerator.EnumerateFontsAsync(aLanguage, aFontType);
+ if (fonts.length) {
+ defaultFont = this.enumerator.getDefaultFont(aLanguage, aFontType);
+ } else {
+ fonts = await this.enumerator.EnumerateFontsAsync(aLanguage, "");
+ if (fonts.length) {
+ defaultFont = this.enumerator.getDefaultFont(aLanguage, "");
+ }
+ }
+
+ if (!this._allFonts) {
+ this._allFonts = await this.enumerator.EnumerateAllFontsAsync({});
+ }
+
+ // Build the UI for the Default Font and Fonts for this CSS type.
+ const popup = document.createXULElement("menupopup");
+ let separator;
+ if (fonts.length) {
+ let menuitem = document.createXULElement("menuitem");
+ if (defaultFont) {
+ document.l10n.setAttributes(menuitem, "fonts-label-default", {
+ name: defaultFont,
+ });
+ } else {
+ document.l10n.setAttributes(menuitem, "fonts-label-default-unnamed");
+ }
+ menuitem.setAttribute("value", ""); // Default Font has a blank value
+ popup.appendChild(menuitem);
+
+ separator = document.createXULElement("menuseparator");
+ popup.appendChild(separator);
+
+ for (let font of fonts) {
+ menuitem = document.createXULElement("menuitem");
+ menuitem.setAttribute("value", font);
+ menuitem.setAttribute("label", font);
+ popup.appendChild(menuitem);
+ }
+ }
+
+ // Build the UI for the remaining fonts.
+ if (this._allFonts.length > fonts.length) {
+ this._langGroupSupported = true;
+ // Both lists are sorted, and the Fonts-By-Type list is a subset of the
+ // All-Fonts list, so walk both lists side-by-side, skipping values we've
+ // already created menu items for.
+ let builtItem = separator ? separator.nextSibling : popup.firstChild;
+ let builtItemValue = builtItem ? builtItem.getAttribute("value") : null;
+
+ separator = document.createXULElement("menuseparator");
+ popup.appendChild(separator);
+
+ for (let font of this._allFonts) {
+ if (font != builtItemValue) {
+ const menuitem = document.createXULElement("menuitem");
+ menuitem.setAttribute("value", font);
+ menuitem.setAttribute("label", font);
+ popup.appendChild(menuitem);
+ } else {
+ builtItem = builtItem.nextSibling;
+ builtItemValue = builtItem ? builtItem.getAttribute("value") : null;
+ }
+ }
+ }
+ aMenuList.appendChild(popup);
+ },
+
+ readFontSelection(aElement) {
+ // Determine the appropriate value to select, for the following cases:
+ // - there is no setting
+ // - the font selected by the user is no longer present (e.g. deleted from
+ // fonts folder)
+ const preference = Preferences.get(aElement.getAttribute("preference"));
+ if (preference.value) {
+ const fontItems = aElement.getElementsByAttribute(
+ "value",
+ preference.value
+ );
+
+ // There is a setting that actually is in the list. Respect it.
+ if (fontItems.length) {
+ return undefined;
+ }
+ }
+
+ // Otherwise, use "default" font of current system which is computed
+ // with "font.name-list.*". If "font.name.*" is empty string, it means
+ // "default". So, return empty string in this case.
+ return "";
+ },
+};
diff --git a/toolkit/mozapps/preferences/jar.mn b/toolkit/mozapps/preferences/jar.mn
new file mode 100644
index 0000000000..0c41ea0c79
--- /dev/null
+++ b/toolkit/mozapps/preferences/jar.mn
@@ -0,0 +1,11 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+toolkit.jar:
+% content mozapps %content/mozapps/
+ content/mozapps/preferences/fontbuilder.js
+ content/mozapps/preferences/changemp.js
+ content/mozapps/preferences/changemp.xhtml
+ content/mozapps/preferences/removemp.js
+ content/mozapps/preferences/removemp.xhtml
diff --git a/toolkit/mozapps/preferences/moz.build b/toolkit/mozapps/preferences/moz.build
new file mode 100644
index 0000000000..199926b764
--- /dev/null
+++ b/toolkit/mozapps/preferences/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Toolkit", "Preferences")
+
+JAR_MANIFESTS += ["jar.mn"]
diff --git a/toolkit/mozapps/preferences/removemp.js b/toolkit/mozapps/preferences/removemp.js
new file mode 100644
index 0000000000..a5cf729459
--- /dev/null
+++ b/toolkit/mozapps/preferences/removemp.js
@@ -0,0 +1,52 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var gRemovePasswordDialog = {
+ _token: null,
+ _okButton: null,
+ _password: null,
+ init() {
+ this._okButton = document.getElementById("removemp").getButton("accept");
+ document.l10n.setAttributes(this._okButton, "pw-remove-button");
+
+ this._password = document.getElementById("password");
+
+ var pk11db = Cc["@mozilla.org/security/pk11tokendb;1"].getService(
+ Ci.nsIPK11TokenDB
+ );
+ this._token = pk11db.getInternalKeyToken();
+
+ // Initialize the enabled state of the Remove button by checking the
+ // initial value of the password ("" should be incorrect).
+ this.validateInput();
+ document.addEventListener("dialogaccept", function () {
+ gRemovePasswordDialog.removePassword();
+ });
+ },
+
+ validateInput() {
+ this._okButton.disabled = !this._token.checkPassword(this._password.value);
+ },
+
+ async createAlert(titleL10nId, messageL10nId) {
+ const [title, message] = await document.l10n.formatValues([
+ { id: titleL10nId },
+ { id: messageL10nId },
+ ]);
+ Services.prompt.alert(window, title, message);
+ },
+
+ removePassword() {
+ if (this._token.checkPassword(this._password.value)) {
+ this._token.changePassword(this._password.value, "");
+ this.createAlert("pw-change-success-title", "settings-pp-erased-ok");
+ } else {
+ this._password.value = "";
+ this._password.focus();
+ this.createAlert("pw-change-failed-title", "incorrect-pp");
+ }
+ },
+};
diff --git a/toolkit/mozapps/preferences/removemp.xhtml b/toolkit/mozapps/preferences/removemp.xhtml
new file mode 100644
index 0000000000..6ecceff31b
--- /dev/null
+++ b/toolkit/mozapps/preferences/removemp.xhtml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<window
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ style="min-width: 35em"
+ onload="gRemovePasswordDialog.init()"
+ data-l10n-id="remove-primary-password"
+>
+ <dialog id="removemp">
+ <script src="chrome://mozapps/content/preferences/removemp.js" />
+
+ <linkset>
+ <html:link rel="stylesheet" href="chrome://global/skin/global.css" />
+
+ <html:link rel="localization" href="branding/brand.ftl" />
+ <html:link
+ rel="localization"
+ href="toolkit/preferences/preferences.ftl"
+ />
+ </linkset>
+
+ <vbox id="warnings">
+ <description
+ data-l10n-id="remove-primary-password-warning1"
+ ></description>
+ <description
+ class="header"
+ data-l10n-id="remove-primary-password-warning2"
+ ></description>
+ </vbox>
+
+ <separator class="thin" />
+
+ <groupbox>
+ <label data-l10n-id="remove-info" />
+
+ <hbox align="center">
+ <label control="password" data-l10n-id="remove-password-old-password" />
+ <html:input
+ id="password"
+ type="password"
+ oninput="gRemovePasswordDialog.validateInput();"
+ aria-describedby="warnings"
+ />
+ </hbox>
+ </groupbox>
+
+ <separator />
+ </dialog>
+</window>