ma1 pushed to branch tor-browser-102.12.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
- 
338b3317
by Henry Wilkes at 2023-06-07T19:58:06+00:00
4 changed files:
- browser/components/torpreferences/content/builtinBridgeDialog.jsm
- browser/components/torpreferences/content/connectionPane.js
- browser/components/torpreferences/content/provideBridgeDialog.jsm
- browser/components/torpreferences/content/requestBridgeDialog.jsm
Changes:
| ... | ... | @@ -36,9 +36,6 @@ class BuiltinBridgeDialog { | 
| 36 | 36 |        "#torPreferences-builtinBridge-description"
 | 
| 37 | 37 |      ).textContent = TorStrings.settings.builtinBridgeDescription2;
 | 
| 38 | 38 | |
| 39 | -    this._acceptButton = dialog.getButton("accept");
 | |
| 40 | -    this.onTorStateChange();
 | |
| 41 | - | |
| 42 | 39 |      const radioGroup = dialog.querySelector(
 | 
| 43 | 40 |        "#torPreferences-builtinBridge-typeSelection"
 | 
| 44 | 41 |      );
 | 
| ... | ... | @@ -102,20 +99,26 @@ class BuiltinBridgeDialog { | 
| 102 | 99 |      dialog.style.minWidth = "0";
 | 
| 103 | 100 |      dialog.style.minHeight = "0";
 | 
| 104 | 101 | |
| 102 | +    this._acceptButton = dialog.getButton("accept");
 | |
| 103 | + | |
| 105 | 104 |      Services.obs.addObserver(this, TorConnectTopics.StateChange);
 | 
| 105 | +    this.onAcceptStateChange();
 | |
| 106 | 106 |    }
 | 
| 107 | 107 | |
| 108 | -  onTorStateChange() {
 | |
| 109 | -    if (TorConnect.canBeginBootstrap) {
 | |
| 110 | -      this._acceptButton.setAttribute(
 | |
| 111 | -        "label",
 | |
| 112 | -        TorStrings.settings.bridgeButtonConnect
 | |
| 113 | -      );
 | |
| 114 | -    } else {
 | |
| 115 | -      this._acceptButton.setAttribute(
 | |
| 116 | -        "label",
 | |
| 117 | -        TorStrings.settings.bridgeButtonAccept
 | |
| 118 | -      );
 | |
| 108 | +  onAcceptStateChange() {
 | |
| 109 | +    this._acceptButton.setAttribute(
 | |
| 110 | +      "label",
 | |
| 111 | +      TorConnect.canBeginBootstrap
 | |
| 112 | +        ? TorStrings.settings.bridgeButtonConnect
 | |
| 113 | +        : TorStrings.settings.bridgeButtonAccept
 | |
| 114 | +    );
 | |
| 115 | +  }
 | |
| 116 | + | |
| 117 | +  observe(subject, topic, data) {
 | |
| 118 | +    switch (topic) {
 | |
| 119 | +      case TorConnectTopics.StateChange:
 | |
| 120 | +        this.onAcceptStateChange();
 | |
| 121 | +        break;
 | |
| 119 | 122 |      }
 | 
| 120 | 123 |    }
 | 
| 121 | 124 | |
| ... | ... | @@ -126,16 +129,8 @@ class BuiltinBridgeDialog { | 
| 126 | 129 |      }, 0);
 | 
| 127 | 130 |    }
 | 
| 128 | 131 | |
| 129 | -  observe(subject, topic, data) {
 | |
| 130 | -    switch (topic) {
 | |
| 131 | -      case TorConnectTopics.StateChange:
 | |
| 132 | -        this.onTorStateChange();
 | |
| 133 | -        break;
 | |
| 134 | -    }
 | |
| 135 | -  }
 | |
| 136 | - | |
| 137 | 132 |    close() {
 | 
| 138 | -    // unregister our observer topics
 | |
| 133 | +    // Unregister our observer topics.
 | |
| 139 | 134 |      Services.obs.removeObserver(this, TorConnectTopics.StateChange);
 | 
| 140 | 135 |    }
 | 
| 141 | 136 | 
| ... | ... | @@ -1047,9 +1047,47 @@ const gConnectionPane = (function() { | 
| 1047 | 1047 |        });
 | 
| 1048 | 1048 |      },
 | 
| 1049 | 1049 | |
| 1050 | +    /**
 | |
| 1051 | +     * Save and apply settings, then optionally open about:torconnect and start
 | |
| 1052 | +     * bootstrapping.
 | |
| 1053 | +     *
 | |
| 1054 | +     * @param {boolean} connect - Whether to open about:torconnect and start
 | |
| 1055 | +     *   bootstrapping if possible.
 | |
| 1056 | +     */
 | |
| 1057 | +    async saveBridgeSettings(connect) {
 | |
| 1058 | +      TorSettings.saveToPrefs();
 | |
| 1059 | +      // FIXME: This can throw if the user adds a bridge manually with invalid
 | |
| 1060 | +      // content. Should be addressed by tor-browser#40552.
 | |
| 1061 | +      await TorSettings.applySettings();
 | |
| 1062 | + | |
| 1063 | +      this._populateBridgeCards();
 | |
| 1064 | + | |
| 1065 | +      if (!connect) {
 | |
| 1066 | +        return;
 | |
| 1067 | +      }
 | |
| 1068 | + | |
| 1069 | +      // The bridge dialog button is "connect" when Tor is not bootstrapped,
 | |
| 1070 | +      // so do the connect.
 | |
| 1071 | + | |
| 1072 | +      // Start Bootstrapping, which should use the configured bridges.
 | |
| 1073 | +      // NOTE: We do this regardless of any previous TorConnect Error.
 | |
| 1074 | +      if (TorConnect.canBeginBootstrap) {
 | |
| 1075 | +        TorConnect.beginBootstrap();
 | |
| 1076 | +      }
 | |
| 1077 | +      // Open "about:torconnect".
 | |
| 1078 | +      // FIXME: If there has been a previous bootstrapping error then
 | |
| 1079 | +      // "about:torconnect" will be trying to get the user to use
 | |
| 1080 | +      // AutoBootstrapping. It is not set up to handle a forced direct
 | |
| 1081 | +      // entry to plain Bootstrapping from this dialog so the UI will not
 | |
| 1082 | +      // be aligned. In particular the
 | |
| 1083 | +      // AboutTorConnect.uiState.bootstrapCause will be aligned to
 | |
| 1084 | +      // whatever was shown previously in "about:torconnect" instead.
 | |
| 1085 | +      TorConnect.openTorConnect();
 | |
| 1086 | +    },
 | |
| 1087 | + | |
| 1050 | 1088 |      onAddBuiltinBridge() {
 | 
| 1051 | 1089 |        const builtinBridgeDialog = new BuiltinBridgeDialog(
 | 
| 1052 | -        async (bridgeType, connect) => {
 | |
| 1090 | +        (bridgeType, connect) => {
 | |
| 1053 | 1091 |            if (!bridgeType) {
 | 
| 1054 | 1092 |              TorSettings.bridges.enabled = false;
 | 
| 1055 | 1093 |              TorSettings.bridges.builtin_type = "";
 | 
| ... | ... | @@ -1058,29 +1096,8 @@ const gConnectionPane = (function() { | 
| 1058 | 1096 |              TorSettings.bridges.source = TorBridgeSource.BuiltIn;
 | 
| 1059 | 1097 |              TorSettings.bridges.builtin_type = bridgeType;
 | 
| 1060 | 1098 |            }
 | 
| 1061 | -          TorSettings.saveToPrefs();
 | |
| 1062 | -          await TorSettings.applySettings();
 | |
| 1063 | - | |
| 1064 | -          this._populateBridgeCards();
 | |
| 1065 | 1099 | |
| 1066 | -          // The bridge dialog button is "connect" when Tor is not bootstrapped,
 | |
| 1067 | -          // so do the connect.
 | |
| 1068 | -          if (connect) {
 | |
| 1069 | -            // Start Bootstrapping, which should use the configured bridges.
 | |
| 1070 | -            // NOTE: We do this regardless of any previous TorConnect Error.
 | |
| 1071 | -            if (TorConnect.canBeginBootstrap) {
 | |
| 1072 | -              TorConnect.beginBootstrap();
 | |
| 1073 | -            }
 | |
| 1074 | -            // Open "about:torconnect".
 | |
| 1075 | -            // FIXME: If there has been a previous bootstrapping error then
 | |
| 1076 | -            // "about:torconnect" will be trying to get the user to use
 | |
| 1077 | -            // AutoBootstrapping. It is not set up to handle a forced direct
 | |
| 1078 | -            // entry to plain Bootstrapping from this dialog so the UI will not
 | |
| 1079 | -            // be aligned. In particular the
 | |
| 1080 | -            // AboutTorConnect.uiState.bootstrapCause will be aligned to
 | |
| 1081 | -            // whatever was shown previously in "about:torconnect" instead.
 | |
| 1082 | -            TorConnect.openTorConnect();
 | |
| 1083 | -          }
 | |
| 1100 | +          this.saveBridgeSettings(connect);
 | |
| 1084 | 1101 |          }
 | 
| 1085 | 1102 |        );
 | 
| 1086 | 1103 |        builtinBridgeDialog.openDialog(gSubDialog);
 | 
| ... | ... | @@ -1088,37 +1105,38 @@ const gConnectionPane = (function() { | 
| 1088 | 1105 | |
| 1089 | 1106 |      // called when the request bridge button is activated
 | 
| 1090 | 1107 |      onRequestBridge() {
 | 
| 1091 | -      const requestBridgeDialog = new RequestBridgeDialog(aBridges => {
 | |
| 1092 | -        if (aBridges.length) {
 | |
| 1108 | +      const requestBridgeDialog = new RequestBridgeDialog(
 | |
| 1109 | +        (aBridges, connect) => {
 | |
| 1110 | +          if (!aBridges.length) {
 | |
| 1111 | +            return;
 | |
| 1112 | +          }
 | |
| 1093 | 1113 |            const bridgeStrings = aBridges.join("\n");
 | 
| 1094 | 1114 |            TorSettings.bridges.enabled = true;
 | 
| 1095 | 1115 |            TorSettings.bridges.source = TorBridgeSource.BridgeDB;
 | 
| 1096 | 1116 |            TorSettings.bridges.bridge_strings = bridgeStrings;
 | 
| 1097 | -          TorSettings.saveToPrefs();
 | |
| 1098 | -          TorSettings.applySettings().then(result => {
 | |
| 1099 | -            this._populateBridgeCards();
 | |
| 1100 | -          });
 | |
| 1117 | + | |
| 1118 | +          this.saveBridgeSettings(connect);
 | |
| 1101 | 1119 |          }
 | 
| 1102 | -      });
 | |
| 1120 | +      );
 | |
| 1103 | 1121 |        requestBridgeDialog.openDialog(gSubDialog);
 | 
| 1104 | 1122 |      },
 | 
| 1105 | 1123 | |
| 1106 | 1124 |      onAddBridgeManually() {
 | 
| 1107 | -      const provideBridgeDialog = new ProvideBridgeDialog(aBridgeString => {
 | |
| 1108 | -        if (aBridgeString.length) {
 | |
| 1109 | -          TorSettings.bridges.enabled = true;
 | |
| 1110 | -          TorSettings.bridges.source = TorBridgeSource.UserProvided;
 | |
| 1111 | -          TorSettings.bridges.bridge_strings = aBridgeString;
 | |
| 1112 | -        } else {
 | |
| 1113 | -          TorSettings.bridges.enabled = false;
 | |
| 1114 | -          TorSettings.bridges.source = TorBridgeSource.Invalid;
 | |
| 1115 | -          TorSettings.bridges.bridge_strings = "";
 | |
| 1125 | +      const provideBridgeDialog = new ProvideBridgeDialog(
 | |
| 1126 | +        (aBridgeString, connect) => {
 | |
| 1127 | +          if (aBridgeString) {
 | |
| 1128 | +            TorSettings.bridges.enabled = true;
 | |
| 1129 | +            TorSettings.bridges.source = TorBridgeSource.UserProvided;
 | |
| 1130 | +            TorSettings.bridges.bridge_strings = aBridgeString;
 | |
| 1131 | +          } else {
 | |
| 1132 | +            TorSettings.bridges.enabled = false;
 | |
| 1133 | +            TorSettings.bridges.source = TorBridgeSource.Invalid;
 | |
| 1134 | +            TorSettings.bridges.bridge_strings = "";
 | |
| 1135 | +          }
 | |
| 1136 | + | |
| 1137 | +          this.saveBridgeSettings(connect);
 | |
| 1116 | 1138 |          }
 | 
| 1117 | -        TorSettings.saveToPrefs();
 | |
| 1118 | -        TorSettings.applySettings().then(result => {
 | |
| 1119 | -          this._populateBridgeCards();
 | |
| 1120 | -        });
 | |
| 1121 | -      });
 | |
| 1139 | +      );
 | |
| 1122 | 1140 |        provideBridgeDialog.openDialog(gSubDialog);
 | 
| 1123 | 1141 |      },
 | 
| 1124 | 1142 | 
| ... | ... | @@ -2,17 +2,24 @@ | 
| 2 | 2 | |
| 3 | 3 |  var EXPORTED_SYMBOLS = ["ProvideBridgeDialog"];
 | 
| 4 | 4 | |
| 5 | +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 | |
| 6 | + | |
| 5 | 7 |  const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
 | 
| 6 | 8 | |
| 7 | 9 |  const { TorSettings, TorBridgeSource } = ChromeUtils.import(
 | 
| 8 | 10 |    "resource:///modules/TorSettings.jsm"
 | 
| 9 | 11 |  );
 | 
| 10 | 12 | |
| 13 | +const { TorConnect, TorConnectTopics } = ChromeUtils.import(
 | |
| 14 | +  "resource:///modules/TorConnect.jsm"
 | |
| 15 | +);
 | |
| 16 | + | |
| 11 | 17 |  class ProvideBridgeDialog {
 | 
| 12 | 18 |    constructor(onSubmit) {
 | 
| 13 | 19 |      this._onSubmit_ = onSubmit;
 | 
| 14 | 20 |      this._dialog = null;
 | 
| 15 | 21 |      this._textarea = null;
 | 
| 22 | +    this._acceptButton = null;
 | |
| 16 | 23 |    }
 | 
| 17 | 24 | |
| 18 | 25 |    static get selectors() {
 | 
| ... | ... | @@ -49,14 +56,43 @@ class ProvideBridgeDialog { | 
| 49 | 56 |        "placeholder",
 | 
| 50 | 57 |        TorStrings.settings.provideBridgePlaceholder
 | 
| 51 | 58 |      );
 | 
| 59 | +    this._textarea.addEventListener("input", () => {
 | |
| 60 | +      this.onAcceptStateChange();
 | |
| 61 | +    });
 | |
| 52 | 62 |      if (TorSettings.bridges.source == TorBridgeSource.UserProvided) {
 | 
| 53 | 63 |        this._textarea.value = TorSettings.bridges.bridge_strings.join("\n");
 | 
| 54 | 64 |      }
 | 
| 55 | 65 | |
| 56 | 66 |      this._dialog.addEventListener("dialogaccept", e => {
 | 
| 57 | -      this.onSubmit(this._textarea.value);
 | |
| 67 | +      let value = this._textarea.value;
 | |
| 68 | +      if (!value.trim()) {
 | |
| 69 | +        value = null;
 | |
| 70 | +      }
 | |
| 71 | +      this.onSubmit(value, value && TorConnect.canBeginBootstrap);
 | |
| 58 | 72 |      });
 | 
| 59 | 73 |      this._dialog.addEventListener("dialoghelp", openHelp);
 | 
| 74 | + | |
| 75 | +    this._acceptButton = this._dialog.getButton("accept");
 | |
| 76 | + | |
| 77 | +    Services.obs.addObserver(this, TorConnectTopics.StateChange);
 | |
| 78 | +    this.onAcceptStateChange();
 | |
| 79 | +  }
 | |
| 80 | + | |
| 81 | +  onAcceptStateChange() {
 | |
| 82 | +    this._acceptButton.setAttribute(
 | |
| 83 | +      "label",
 | |
| 84 | +      this._textarea.value.trim() && TorConnect.canBeginBootstrap
 | |
| 85 | +        ? TorStrings.settings.bridgeButtonConnect
 | |
| 86 | +        : TorStrings.settings.bridgeButtonAccept
 | |
| 87 | +    );
 | |
| 88 | +  }
 | |
| 89 | + | |
| 90 | +  observe(subject, topic, data) {
 | |
| 91 | +    switch (topic) {
 | |
| 92 | +      case TorConnectTopics.StateChange:
 | |
| 93 | +        this.onAcceptStateChange();
 | |
| 94 | +        break;
 | |
| 95 | +    }
 | |
| 60 | 96 |    }
 | 
| 61 | 97 | |
| 62 | 98 |    init(window, aDialog) {
 | 
| ... | ... | @@ -66,10 +102,20 @@ class ProvideBridgeDialog { | 
| 66 | 102 |      }, 0);
 | 
| 67 | 103 |    }
 | 
| 68 | 104 | |
| 105 | +  close() {
 | |
| 106 | +    // Unregister our observer topics.
 | |
| 107 | +    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
 | |
| 108 | +  }
 | |
| 109 | + | |
| 69 | 110 |    openDialog(gSubDialog) {
 | 
| 70 | 111 |      gSubDialog.open(
 | 
| 71 | 112 |        "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
 | 
| 72 | -      { features: "resizable=yes" },
 | |
| 113 | +      {
 | |
| 114 | +        features: "resizable=yes",
 | |
| 115 | +        closingCallback: () => {
 | |
| 116 | +          this.close();
 | |
| 117 | +        },
 | |
| 118 | +      },
 | |
| 73 | 119 |        this
 | 
| 74 | 120 |      );
 | 
| 75 | 121 |    }
 | 
| ... | ... | @@ -2,9 +2,15 @@ | 
| 2 | 2 | |
| 3 | 3 |  var EXPORTED_SYMBOLS = ["RequestBridgeDialog"];
 | 
| 4 | 4 | |
| 5 | +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 | |
| 6 | + | |
| 5 | 7 |  const { BridgeDB } = ChromeUtils.import("resource:///modules/BridgeDB.jsm");
 | 
| 6 | 8 |  const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
 | 
| 7 | 9 | |
| 10 | +const { TorConnect, TorConnectTopics } = ChromeUtils.import(
 | |
| 11 | +  "resource:///modules/TorConnect.jsm"
 | |
| 12 | +);
 | |
| 13 | + | |
| 8 | 14 |  class RequestBridgeDialog {
 | 
| 9 | 15 |    constructor(onSubmit) {
 | 
| 10 | 16 |      this._onSubmit_ = onSubmit;
 | 
| ... | ... | @@ -20,8 +26,6 @@ class RequestBridgeDialog { | 
| 20 | 26 | |
| 21 | 27 |    static get selectors() {
 | 
| 22 | 28 |      return {
 | 
| 23 | -      submitButton:
 | |
| 24 | -        "accept" /* not really a selector but a key for dialog's getButton */,
 | |
| 25 | 29 |        dialogHeader: "h3#torPreferences-requestBridge-header",
 | 
| 26 | 30 |        captchaImage: "image#torPreferences-requestBridge-captchaImage",
 | 
| 27 | 31 |        captchaEntryTextbox: "input#torPreferences-requestBridge-captchaTextbox",
 | 
| ... | ... | @@ -57,8 +61,7 @@ class RequestBridgeDialog { | 
| 57 | 61 |        }
 | 
| 58 | 62 |      });
 | 
| 59 | 63 | |
| 60 | -    this._submitButton = this._dialog.getButton(selectors.submitButton);
 | |
| 61 | -    this._submitButton.setAttribute("label", TorStrings.settings.submitCaptcha);
 | |
| 64 | +    this._submitButton = this._dialog.getButton("accept");
 | |
| 62 | 65 |      this._submitButton.disabled = true;
 | 
| 63 | 66 |      this._dialog.addEventListener("dialogaccept", e => {
 | 
| 64 | 67 |        e.preventDefault();
 | 
| ... | ... | @@ -110,7 +113,25 @@ class RequestBridgeDialog { | 
| 110 | 113 |        TorStrings.settings.incorrectCaptcha
 | 
| 111 | 114 |      );
 | 
| 112 | 115 | |
| 113 | -    return true;
 | |
| 116 | +    Services.obs.addObserver(this, TorConnectTopics.StateChange);
 | |
| 117 | +    this.onAcceptStateChange();
 | |
| 118 | +  }
 | |
| 119 | + | |
| 120 | +  onAcceptStateChange() {
 | |
| 121 | +    this._submitButton.setAttribute(
 | |
| 122 | +      "label",
 | |
| 123 | +      TorConnect.canBeginBootstrap
 | |
| 124 | +        ? TorStrings.settings.bridgeButtonConnect
 | |
| 125 | +        : TorStrings.settings.submitCaptcha
 | |
| 126 | +    );
 | |
| 127 | +  }
 | |
| 128 | + | |
| 129 | +  observe(subject, topic, data) {
 | |
| 130 | +    switch (topic) {
 | |
| 131 | +      case TorConnectTopics.StateChange:
 | |
| 132 | +        this.onAcceptStateChange();
 | |
| 133 | +        break;
 | |
| 134 | +    }
 | |
| 114 | 135 |    }
 | 
| 115 | 136 | |
| 116 | 137 |    _setcaptchaImage(uri) {
 | 
| ... | ... | @@ -142,6 +163,8 @@ class RequestBridgeDialog { | 
| 142 | 163 | |
| 143 | 164 |    close() {
 | 
| 144 | 165 |      BridgeDB.close();
 | 
| 166 | +    // Unregister our observer topics.
 | |
| 167 | +    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
 | |
| 145 | 168 |    }
 | 
| 146 | 169 | |
| 147 | 170 |    /*
 | 
| ... | ... | @@ -161,7 +184,7 @@ class RequestBridgeDialog { | 
| 161 | 184 |      BridgeDB.submitCaptchaGuess(captchaText)
 | 
| 162 | 185 |        .then(aBridges => {
 | 
| 163 | 186 |          if (aBridges) {
 | 
| 164 | -          this.onSubmit(aBridges);
 | |
| 187 | +          this.onSubmit(aBridges, TorConnect.canBeginBootstrap);
 | |
| 165 | 188 |            this._submitButton.disabled = false;
 | 
| 166 | 189 |            // This was successful, but use cancelDialog() to close, since
 | 
| 167 | 190 |            // we intercept the `dialogaccept` event.
 |