Commit 47afbf56 authored by henry's avatar henry
Browse files

fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in...

fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection

Bug 42036: Replace replace/add bridges section with new design, ready
for Lox.
parent 6211ed8f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
<svg width="40" height="44" viewBox="0 0 40 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M37.1877 22.7584C38.7409 25.1504 38.9178 27.7923 37.5828 28.6591C36.2478 29.5259 33.9065 28.2895 32.3533 25.8975C30.8001 23.5055 30.6232 20.8637 31.9582 19.9969C33.2932 19.13 35.6345 20.3664 37.1877 22.7584Z" fill="#C069FF"/>
<path d="M2.81234 22.7584C1.25915 25.1504 1.08224 27.7923 2.41721 28.6591C3.75217 29.5259 6.09349 28.2895 7.64668 25.8975C9.19987 23.5055 9.37678 20.8637 8.04181 19.9969C6.70685 19.13 4.36553 20.3664 2.81234 22.7584Z" fill="#C069FF"/>
<path d="M32.2002 19.4754C33.9149 19.4754 35.3181 20.8678 35.1823 22.5772C34.7579 27.9186 33.2458 32.9181 30.8541 36.7668C28.0043 41.3527 24.1391 43.9291 20.1088 43.9291C16.0785 43.9291 12.2133 41.3527 9.36344 36.7668C6.97177 32.9181 5.45965 27.9186 5.03525 22.5772C4.89944 20.8678 6.30265 19.4754 8.0174 19.4754L32.2002 19.4754Z" fill="#C069FF"/>
<path d="M28.4375 32.1121C28.4375 27.4522 24.6599 23.6746 20 23.6746C15.3401 23.6746 11.5625 27.4522 11.5625 32.1121V33.5139H12.8809V32.1121C12.8809 28.1803 16.0682 24.9929 20 24.9929C23.9318 24.9929 27.1191 28.1803 27.1191 32.1121V33.5139H28.4375V32.1121Z" fill="#15141A"/>
<path d="M25.9062 32.1121C25.9062 28.8501 23.2619 26.2058 20 26.2058C16.7381 26.2058 14.0937 28.8501 14.0937 32.1121L14.0936 33.5139H15.412L15.4121 32.1121C15.4121 29.5782 17.4662 27.5242 20 27.5242C22.5338 27.5242 24.5879 29.5782 24.5879 32.1121L24.588 33.5139H25.9064L25.9062 32.1121Z" fill="#15141A"/>
<path d="M20 28.7371C21.864 28.7371 23.375 30.2481 23.375 32.1121L23.3753 33.5139H22.0569L22.0566 32.1121C22.0566 30.9762 21.1359 30.0554 20 30.0554C18.8642 30.0554 17.9434 30.9762 17.9434 32.1121L17.9431 33.5139H16.6247V32.1121C16.6247 30.2481 18.136 28.7371 20 28.7371Z" fill="#15141A"/>
<path d="M8.9145 17.8162C7.19975 17.8162 5.78665 16.4193 6.02668 14.7215C6.53221 11.1456 7.9061 7.82078 9.99195 5.21826C12.6698 1.87706 16.3018 -1.07451e-07 20.0889 0C23.8759 1.07451e-07 27.5079 1.87706 30.1858 5.21826C32.2716 7.82078 33.6455 11.1456 34.151 14.7215C34.3911 16.4193 32.978 17.8162 31.2632 17.8162H8.9145Z" fill="#C069FF"/>
<path d="M13.1064 15.1091C11.3916 15.1091 9.96814 13.7048 10.3139 12.0252C10.7578 9.86855 11.6634 7.87853 12.956 6.27814C14.8477 3.93602 17.4134 2.62024 20.0887 2.62024C22.7639 2.62024 25.3296 3.93602 27.2213 6.27814C28.514 7.87853 29.4195 9.86855 29.8635 12.0252C30.2092 13.7048 28.7857 15.1091 27.071 15.1091H13.1064Z" fill="#EBD0FF"/>
<path d="M17.5125 6.81215C17.5125 7.58388 16.9065 8.2095 16.1589 8.2095C15.4112 8.2095 14.8052 7.58388 14.8052 6.81215C14.8052 6.04041 15.4112 5.41479 16.1589 5.41479C16.9065 5.41479 17.5125 6.04041 17.5125 6.81215Z" fill="#15141A"/>
<path d="M25.1981 6.81215C25.1981 7.58388 24.592 8.2095 23.8444 8.2095C23.0968 8.2095 22.4907 7.58388 22.4907 6.81215C22.4907 6.04041 23.0968 5.41479 23.8444 5.41479C24.592 5.41479 25.1981 6.04041 25.1981 6.81215Z" fill="#15141A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.4395 9.01993L22.4044 9.11353C21.5971 11.2673 18.526 11.1951 17.8208 9.0058L18.427 8.81052C18.9472 10.4254 21.2125 10.4787 21.808 8.88998L21.8431 8.79639L22.4395 9.01993Z" fill="#15141A"/>
</svg>
+197 −159
Original line number Diff line number Diff line
@@ -1316,6 +1316,18 @@ const gBridgeSettings = {
   * @type {Element?}
   */
  _noBridgesEl: null,
  /**
   * The heading element for changing bridges.
   *
   * @type {Element?}
   */
  _changeHeadingEl: null,
  /**
   * The button for user to provide a bridge address or share code.
   *
   * @type {Element?}
   */
  _userProvideButton: null,

  /**
   * Initialize the bridge settings.
@@ -1345,6 +1357,47 @@ const gBridgeSettings = {
      });
    });

    this._changeHeadingEl = document.getElementById(
      "tor-bridges-change-heading"
    );
    this._userProvideButton = document.getElementById(
      "tor-bridges-open-user-provide-dialog-button"
    );

    document.l10n.setAttributes(
      document.getElementById("tor-bridges-user-provide-description"),
      // TODO: Set a different string if we have Lox enabled.
      "tor-bridges-add-addresses-description"
    );

    // TODO: Change to GetLoxBridges if Lox enabled, and the account is set up.
    const telegramUserName = "GetBridgesBot";
    const telegramInstruction = document.getElementById(
      "tor-bridges-provider-instruction-telegram"
    );
    telegramInstruction.querySelector(
      "a"
    ).href = `https://t.me/${telegramUserName}`;
    document.l10n.setAttributes(
      telegramInstruction,
      "tor-bridges-provider-telegram-instruction",
      { telegramUserName }
    );

    document
      .getElementById("tor-bridges-open-built-in-dialog-button")
      .addEventListener("click", () => {
        this._openBuiltinDialog();
      });
    this._userProvideButton.addEventListener("click", () => {
      this._openUserProvideDialog(this._haveBridges ? "replace" : "add");
    });
    document
      .getElementById("tor-bridges-open-request-dialog-button")
      .addEventListener("click", () => {
        this._openRequestDialog();
      });

    Services.obs.addObserver(this, TorSettingsTopics.SettingsChanged);

    gBridgeGrid.init();
@@ -1488,6 +1541,17 @@ const gBridgeSettings = {
    // and hidden.
    this._groupEl.classList.toggle("no-bridges", !haveBridges);
    this._groupEl.classList.toggle("have-bridges", haveBridges);

    document.l10n.setAttributes(
      this._changeHeadingEl,
      haveBridges
        ? "tor-bridges-replace-bridges-heading"
        : "tor-bridges-add-bridges-heading"
    );
    document.l10n.setAttributes(
      this._userProvideButton,
      haveBridges ? "tor-bridges-replace-button" : "tor-bridges-add-new-button"
    );
  },

  /**
@@ -1615,9 +1679,7 @@ const gBridgeSettings = {
      "tor-bridges-options-edit-all-menu-item"
    );
    editItem.addEventListener("click", () => {
      // TODO: move to gBridgeSettings.
      // TODO: Change dialog title. Do not allow Lox invite.
      gConnectionPane.onAddBridgeManually();
      this._openUserProvideDialog("edit");
    });

    // TODO: Do we want a different item for built-in bridges, rather than
@@ -1687,6 +1749,138 @@ const gBridgeSettings = {
  _forceCloseBridgesMenu() {
    this._bridgesMenu.hide(null, { force: true });
  },

  /**
   * Open a bridge dialog that will change the users bridges.
   *
   * @param {string} url - The url of the dialog to open.
   * @param {object?} inputData - The input data to send to the dialog window.
   * @param {Function} onAccept - The method to call if the bridge dialog was
   *   accepted by the user. This will be passed a "result" object containing
   *   data set by the dialog. This should return a promise that resolves once
   *   the bridge settings have been set, or null if the settings have not
   *   been applied.
   */
  _openDialog(url, inputData, onAccept) {
    const result = { accepted: false, connect: false };
    let savedSettings = null;
    gSubDialog.open(
      url,
      {
        features: "resizable=yes",
        closingCallback: () => {
          if (!result.accepted) {
            return;
          }
          savedSettings = onAccept(result);
          if (!savedSettings) {
            // No change in settings.
            return;
          }
          if (!result.connect) {
            // Do not open about:torconnect.
            return;
          }

          // Wait until the settings are applied before bootstrapping.
          savedSettings.then(() => {
            // The bridge dialog button is "connect" when Tor is not
            // bootstrapped, so do the connect.

            // Start Bootstrapping, which should use the configured bridges.
            // NOTE: We do this regardless of any previous TorConnect Error.
            if (TorConnect.canBeginBootstrap) {
              TorConnect.beginBootstrap();
            }
            // Open "about:torconnect".
            // FIXME: If there has been a previous bootstrapping error then
            // "about:torconnect" will be trying to get the user to use
            // AutoBootstrapping. It is not set up to handle a forced direct
            // entry to plain Bootstrapping from this dialog so the UI will
            // not be aligned. In particular the
            // AboutTorConnect.uiState.bootstrapCause will be aligned to
            // whatever was shown previously in "about:torconnect" instead.
            TorConnect.openTorConnect();
          });
        },
        // closedCallback should be called after gSubDialog has already
        // re-assigned focus back to the document.
        closedCallback: () => {
          if (!savedSettings) {
            return;
          }
          // Wait until the settings have changed, so that the UI could
          // respond, then move focus.
          savedSettings.then(() => gBridgeSettings.takeFocus());
        },
      },
      result,
      inputData
    );
  },

  /**
   * Open the built-in bridge dialog.
   */
  _openBuiltinDialog() {
    this._openDialog(
      "chrome://browser/content/torpreferences/builtinBridgeDialog.xhtml",
      null,
      result => {
        if (!result.type) {
          return null;
        }
        return setTorSettings(() => {
          TorSettings.bridges.enabled = true;
          TorSettings.bridges.source = TorBridgeSource.BuiltIn;
          TorSettings.bridges.builtin_type = result.type;
        });
      }
    );
  },

  /*
   * Open the request bridge dialog.
   */
  _openRequestDialog() {
    this._openDialog(
      "chrome://browser/content/torpreferences/requestBridgeDialog.xhtml",
      null,
      result => {
        if (!result.bridges?.length) {
          return null;
        }
        return setTorSettings(() => {
          TorSettings.bridges.enabled = true;
          TorSettings.bridges.source = TorBridgeSource.BridgeDB;
          TorSettings.bridges.bridge_strings = result.bridges.join("\n");
        });
      }
    );
  },

  /**
   * Open the user provide dialog.
   *
   * @param {string} mode - The mode to open the dialog in: "add", "replace" or
   *   "edit".
   */
  _openUserProvideDialog(mode) {
    this._openDialog(
      "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
      { mode },
      result => {
        if (!result.bridgeStrings) {
          return null;
        }
        return setTorSettings(() => {
          TorSettings.bridges.enabled = true;
          TorSettings.bridges.source = TorBridgeSource.UserProvided;
          TorSettings.bridges.bridge_strings = result.bridgeStrings;
        });
      }
    );
  },
};

/*
@@ -1719,13 +1913,6 @@ const gConnectionPane = (function () {
      location: "#torPreferences-bridges-location",
      locationEntries: "#torPreferences-bridges-locationEntries",
      chooseForMe: "#torPreferences-bridges-buttonChooseBridgeForMe",
      addHeader: "#torPreferences-addBridge-header",
      addBuiltinLabel: "#torPreferences-addBridge-labelBuiltinBridge",
      addBuiltinButton: "#torPreferences-addBridge-buttonBuiltinBridge",
      requestLabel: "#torPreferences-addBridge-labelRequestBridge",
      requestButton: "#torPreferences-addBridge-buttonRequestBridge",
      enterLabel: "#torPreferences-addBridge-labelEnterBridge",
      enterButton: "#torPreferences-addBridge-buttonEnterBridge",
    },
    advanced: {
      header: "h1#torPreferences-advanced-header",
@@ -1985,39 +2172,6 @@ const gConnectionPane = (function () {
        this._showAutoconfiguration();
      }

      // Add a new bridge
      prefpane.querySelector(selectors.bridges.addHeader).textContent =
        TorStrings.settings.bridgeAdd;
      prefpane.querySelector(selectors.bridges.addBuiltinLabel).textContent =
        TorStrings.settings.bridgeSelectBrowserBuiltin;
      {
        const button = prefpane.querySelector(
          selectors.bridges.addBuiltinButton
        );
        button.setAttribute("label", TorStrings.settings.bridgeSelectBuiltin);
        button.addEventListener("command", e => {
          this.onAddBuiltinBridge();
        });
      }
      prefpane.querySelector(selectors.bridges.requestLabel).textContent =
        TorStrings.settings.bridgeRequestFromTorProject;
      {
        const button = prefpane.querySelector(selectors.bridges.requestButton);
        button.setAttribute("label", TorStrings.settings.bridgeRequest);
        button.addEventListener("command", e => {
          this.onRequestBridge();
        });
      }
      prefpane.querySelector(selectors.bridges.enterLabel).textContent =
        TorStrings.settings.bridgeEnterKnown;
      {
        const button = prefpane.querySelector(selectors.bridges.enterButton);
        button.setAttribute("label", TorStrings.settings.bridgeAddManually);
        button.addEventListener("command", e => {
          this.onAddBridgeManually();
        });
      }

      // Advanced setup
      prefpane.querySelector(selectors.advanced.header).innerText =
        TorStrings.settings.advancedHeading;
@@ -2122,122 +2276,6 @@ const gConnectionPane = (function () {
      this._showAutoconfiguration();
    },

    /**
     * Open a bridge dialog that will change the users bridges.
     *
     * @param {string} url - The url of the dialog to open.
     * @param {Function} onAccept - The method to call if the bridge dialog was
     *   accepted by the user. This will be passed a "result" object containing
     *   data set by the dialog. This should return a promise that resolves once
     *   the bridge settings have been set, or null if the settings have not
     *   been applied.
     */
    openBridgeDialog(url, onAccept) {
      const result = { accepted: false, connect: false };
      let savedSettings = null;
      gSubDialog.open(
        url,
        {
          features: "resizable=yes",
          closingCallback: () => {
            if (!result.accepted) {
              return;
            }
            savedSettings = onAccept(result);
            if (!savedSettings) {
              // No change in settings.
              return;
            }
            if (!result.connect) {
              // Do not open about:torconnect.
              return;
            }

            // Wait until the settings are applied before bootstrapping.
            savedSettings.then(() => {
              // The bridge dialog button is "connect" when Tor is not
              // bootstrapped, so do the connect.

              // Start Bootstrapping, which should use the configured bridges.
              // NOTE: We do this regardless of any previous TorConnect Error.
              if (TorConnect.canBeginBootstrap) {
                TorConnect.beginBootstrap();
              }
              // Open "about:torconnect".
              // FIXME: If there has been a previous bootstrapping error then
              // "about:torconnect" will be trying to get the user to use
              // AutoBootstrapping. It is not set up to handle a forced direct
              // entry to plain Bootstrapping from this dialog so the UI will
              // not be aligned. In particular the
              // AboutTorConnect.uiState.bootstrapCause will be aligned to
              // whatever was shown previously in "about:torconnect" instead.
              TorConnect.openTorConnect();
            });
          },
          // closedCallback should be called after gSubDialog has already
          // re-assigned focus back to the document.
          closedCallback: () => {
            if (!savedSettings) {
              return;
            }
            // Wait until the settings have changed, so that the UI could
            // respond, then move focus.
            savedSettings.then(() => gCurrentBridgesArea.takeFocus());
          },
        },
        result
      );
    },

    onAddBuiltinBridge() {
      this.openBridgeDialog(
        "chrome://browser/content/torpreferences/builtinBridgeDialog.xhtml",
        result => {
          if (!result.type) {
            return null;
          }
          return setTorSettings(() => {
            TorSettings.bridges.enabled = true;
            TorSettings.bridges.source = TorBridgeSource.BuiltIn;
            TorSettings.bridges.builtin_type = result.type;
          });
        }
      );
    },

    // called when the request bridge button is activated
    onRequestBridge() {
      this.openBridgeDialog(
        "chrome://browser/content/torpreferences/requestBridgeDialog.xhtml",
        result => {
          if (!result.bridges?.length) {
            return null;
          }
          return setTorSettings(() => {
            TorSettings.bridges.enabled = true;
            TorSettings.bridges.source = TorBridgeSource.BridgeDB;
            TorSettings.bridges.bridge_strings = result.bridges.join("\n");
          });
        }
      );
    },

    onAddBridgeManually() {
      this.openBridgeDialog(
        "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
        result => {
          if (!result.bridgeStrings) {
            return null;
          }
          return setTorSettings(() => {
            TorSettings.bridges.enabled = true;
            TorSettings.bridges.source = TorBridgeSource.UserProvided;
            TorSettings.bridges.bridge_strings = result.bridgeStrings;
          });
        }
      );
    },

    onAdvancedSettings() {
      gSubDialog.open(
        "chrome://browser/content/torpreferences/connectionSettingsDialog.xhtml",
+89 −15
Original line number Diff line number Diff line
@@ -293,28 +293,102 @@
        ></html:button>
      </html:div>
    </html:div>
    <html:h2 id="torPreferences-addBridge-header"></html:h2>
    <html:h2 id="tor-bridges-change-heading"></html:h2>
    <hbox align="center">
      <label id="torPreferences-addBridge-labelBuiltinBridge" flex="1" />
      <button
        id="torPreferences-addBridge-buttonBuiltinBridge"
        class="accessory-button"
      <description
        flex="1"
        data-l10n-id="tor-bridges-select-built-in-description"
      />
    </hbox>
    <hbox align="center">
      <label id="torPreferences-addBridge-labelRequestBridge" flex="1" />
      <button
        id="torPreferences-addBridge-buttonRequestBridge"
      <html:button
        id="tor-bridges-open-built-in-dialog-button"
        class="accessory-button"
      />
        data-l10n-id="tor-bridges-select-built-in-button"
      ></html:button>
    </hbox>
    <hbox align="center">
      <label id="torPreferences-addBridge-labelEnterBridge" flex="1" />
      <button
        id="torPreferences-addBridge-buttonEnterBridge"
      <description id="tor-bridges-user-provide-description" flex="1" />
      <html:button
        id="tor-bridges-open-user-provide-dialog-button"
        class="accessory-button"
      />
      ></html:button>
    </hbox>
    <html:h3
      id="tor-bridges-provider-heading"
      data-l10n-id="tor-bridges-find-more-heading"
    ></html:h3>
    <description data-l10n-id="tor-bridges-find-more-description" />
    <html:div id="tor-bridges-provider-area">
      <html:ul id="tor-bridges-provider-list">
        <html:li class="tor-bridges-provider-item">
          <html:img
            id="tor-bridges-provider-icon-telegram"
            class="tor-bridges-provider-icon"
            alt=""
          />
          <html:div
            class="tor-bridges-provider-name"
            data-l10n-id="tor-bridges-provider-telegram-name"
          ></html:div>
          <html:div
            id="tor-bridges-provider-instruction-telegram"
            class="tor-bridges-provider-instruction"
          >
            <html:a data-l10n-name="user"></html:a>
          </html:div>
        </html:li>
        <html:li class="tor-bridges-provider-item">
          <html:img
            id="tor-bridges-provider-icon-web"
            class="tor-bridges-provider-icon"
            alt=""
          />
          <html:div
            class="tor-bridges-provider-name"
            data-l10n-id="tor-bridges-provider-web-name"
          ></html:div>
          <html:div
            class="tor-bridges-provider-instruction"
            data-l10n-id="tor-bridges-provider-web-instruction"
            data-l10n-args='{ "url": "bridges.torproject.org" }'
          >
            <html:a
              href="https://bridges.torproject.org"
              data-l10n-name="url"
            ></html:a>
          </html:div>
        </html:li>
        <html:li class="tor-bridges-provider-item">
          <html:img
            id="tor-bridges-provider-icon-email"
            class="tor-bridges-provider-icon"
            alt=""
          />
          <html:div
            class="tor-bridges-provider-name"
            data-l10n-id="tor-bridges-provider-email-name"
          ></html:div>
          <html:div
            class="tor-bridges-provider-instruction"
            data-l10n-id="tor-bridges-provider-email-instruction"
            data-l10n-args='{ "address": "bridges@torproject.org" }'
          ></html:div>
        </html:li>
      </html:ul>
      <html:div id="tor-bridges-request-box">
        <html:img
          alt=""
          src="chrome://browser/content/torpreferences/bridge-bot.svg"
        ></html:img>
        <html:div
          id="tor-bridges-request-description"
          data-l10n-id="tor-bridges-request-from-browser"
        ></html:div>
        <html:button
          id="tor-bridges-open-request-dialog-button"
          data-l10n-id="tor-bridges-request-button"
        ></html:button>
      </html:div>
    </html:div>
  </groupbox>

  <!-- Advanced -->
+17 −4
Original line number Diff line number Diff line
@@ -15,11 +15,24 @@ const { TorConnect, TorConnectTopics } = ChromeUtils.importESModule(
const gProvideBridgeDialog = {
  init() {
    this._result = window.arguments[0];
    const mode = window.arguments[1].mode;

    let titleId;
    switch (mode) {
      case "edit":
        titleId = "user-provide-bridge-dialog-edit-title";
        break;
      case "add":
        titleId = "user-provide-bridge-dialog-add-title";
        break;
      case "replace":
      default:
        titleId = "user-provide-bridge-dialog-replace-title";
        break;
    }

    document.l10n.setAttributes(document.documentElement, titleId);

    document.documentElement.setAttribute(
      "title",
      TorStrings.settings.provideBridgeTitleAdd
    );
    const learnMore = document.createXULElement("label");
    learnMore.className = "learnMore text-link";
    learnMore.setAttribute("is", "text-link");
+4 −0
Original line number Diff line number Diff line
@@ -9,6 +9,10 @@
  xmlns:html="http://www.w3.org/1999/xhtml"
>
  <dialog id="torPreferences-provideBridge-dialog" buttons="accept,cancel">
    <linkset>
      <html:link rel="localization" href="browser/tor-browser.ftl" />
    </linkset>

    <script src="chrome://browser/content/torpreferences/provideBridgeDialog.js" />

    <description>
Loading