tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_exportP12_passwordUI.js (5479B)


      1 // Any copyright is dedicated to the Public Domain.
      2 // http://creativecommons.org/publicdomain/zero/1.0/
      3 "use strict";
      4 
      5 // Tests that the UI for setting the password on a to be exported PKCS #12 file:
      6 //   1. Correctly requires the password to be typed in twice as confirmation.
      7 //   2. Calculates and displays the strength of said password.
      8 
      9 /**
     10 * @typedef TestCase
     11 * @type {object}
     12 * @property {string} name
     13 *           The name of the test case for display purposes.
     14 * @property {string} password1
     15 *           The password to enter into the first password textbox.
     16 * @property {string} password2
     17 *           The password to enter into the second password textbox.
     18 * @property {string} strength
     19 *           The expected strength of the password in the range [0, 100].
     20 */
     21 
     22 /**
     23 * A list of test cases representing various inputs to the password textboxes.
     24 *
     25 * @type {TestCase[]}
     26 */
     27 const TEST_CASES = [
     28  { name: "empty", password1: "", password2: "", strength: "0" },
     29  { name: "match-weak", password1: "foo", password2: "foo", strength: "10" },
     30  {
     31    name: "match-medium",
     32    password1: "foo123",
     33    password2: "foo123",
     34    strength: "60",
     35  },
     36  {
     37    name: "match-strong",
     38    password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
     39    password2: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
     40    strength: "100",
     41  },
     42  { name: "mismatch-weak", password1: "foo", password2: "bar", strength: "10" },
     43  {
     44    name: "mismatch-medium",
     45    password1: "foo123",
     46    password2: "bar",
     47    strength: "60",
     48  },
     49  {
     50    name: "mismatch-strong",
     51    password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
     52    password2: "bar",
     53    strength: "100",
     54  },
     55 ];
     56 
     57 /**
     58 * Opens the dialog shown to set the password on a PKCS #12 file being exported.
     59 *
     60 * @returns {Promise}
     61 *          A promise that resolves when the dialog has finished loading, with
     62 *          an array consisting of:
     63 *            1. The window of the opened dialog.
     64 *            2. The return value nsIWritablePropertyBag2 passed to the dialog.
     65 */
     66 function openSetP12PasswordDialog() {
     67  let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
     68    Ci.nsIWritablePropertyBag2
     69  );
     70  let win = window.openDialog(
     71    "chrome://pippki/content/setp12password.xhtml",
     72    "",
     73    "",
     74    returnVals
     75  );
     76  return new Promise(resolve => {
     77    win.addEventListener(
     78      "load",
     79      function () {
     80        executeSoon(() => resolve([win, returnVals]));
     81      },
     82      { once: true }
     83    );
     84  });
     85 }
     86 
     87 // Tests that the first password textbox is the element that is initially
     88 // focused.
     89 add_task(async function testFocus() {
     90  let [win] = await openSetP12PasswordDialog();
     91  Assert.equal(
     92    win.document.activeElement,
     93    win.document.getElementById("pw1"),
     94    "First password textbox should have focus"
     95  );
     96  await BrowserTestUtils.closeWindow(win);
     97 });
     98 
     99 // Tests that the password strength algorithm used is reasonable, and that the
    100 // Accept button is only enabled if the two passwords match.
    101 add_task(async function testPasswordStrengthAndEquality() {
    102  let [win] = await openSetP12PasswordDialog();
    103  let password1Textbox = win.document.getElementById("pw1");
    104  let password2Textbox = win.document.getElementById("pw2");
    105  let strengthProgressBar = win.document.getElementById("pwmeter");
    106 
    107  for (let testCase of TEST_CASES) {
    108    password1Textbox.value = testCase.password1;
    109    password2Textbox.value = testCase.password2;
    110    // Setting the value of the password textboxes via |.value| apparently
    111    // doesn't cause the oninput handlers to be called, so we do it here.
    112    password1Textbox.dispatchEvent(new Event("input", { bubbles: true }));
    113    password2Textbox.dispatchEvent(new Event("input", { bubbles: true }));
    114 
    115    Assert.equal(
    116      win.document.getElementById("setp12password").getButton("accept")
    117        .disabled,
    118      password1Textbox.value != password2Textbox.value,
    119      "Actual and expected accept button disable state should " +
    120        `match for ${testCase.name}`
    121    );
    122    Assert.equal(
    123      strengthProgressBar.value,
    124      testCase.strength,
    125      `Actual and expected strength value should match for ${testCase.name}`
    126    );
    127  }
    128 
    129  await BrowserTestUtils.closeWindow(win);
    130 });
    131 
    132 // Test that the right values are returned when the dialog is accepted.
    133 add_task(async function testAcceptDialogReturnValues() {
    134  let [win, retVals] = await openSetP12PasswordDialog();
    135  const password = "fooBAR 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三";
    136  win.document.getElementById("pw1").value = password;
    137  win.document.getElementById("pw2").value = password;
    138  info("Accepting dialog");
    139  win.document.getElementById("setp12password").acceptDialog();
    140  await BrowserTestUtils.windowClosed(win);
    141 
    142  Assert.ok(
    143    retVals.get("confirmedPassword"),
    144    "Return value should signal user confirmed a password"
    145  );
    146  Assert.equal(
    147    retVals.get("password"),
    148    password,
    149    "Actual and expected password should match"
    150  );
    151 });
    152 
    153 // Test that the right values are returned when the dialog is canceled.
    154 add_task(async function testCancelDialogReturnValues() {
    155  let [win, retVals] = await openSetP12PasswordDialog();
    156  info("Canceling dialog");
    157  win.document.getElementById("setp12password").cancelDialog();
    158  await BrowserTestUtils.windowClosed(win);
    159 
    160  Assert.ok(
    161    !retVals.get("confirmedPassword"),
    162    "Return value should signal user didn't confirm a password"
    163  );
    164 });