Pier Angelo Vendrame pushed to branch tor-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
d5582e87
by Pier Angelo Vendrame at 2025-09-08T12:03:34+02:00
-
d4c6e7a4
by Pier Angelo Vendrame at 2025-09-08T12:03:35+02:00
-
8eccdc93
by Pier Angelo Vendrame at 2025-09-08T12:03:35+02:00
-
167c0116
by Pier Angelo Vendrame at 2025-09-08T12:03:36+02:00
-
b45bb7f1
by Pier Angelo Vendrame at 2025-09-08T12:03:37+02:00
-
ad267a06
by Pier Angelo Vendrame at 2025-09-08T12:03:37+02:00
-
a05bd724
by Pier Angelo Vendrame at 2025-09-08T12:03:38+02:00
-
a857af7e
by Pier Angelo Vendrame at 2025-09-08T12:03:38+02:00
-
51ca3bdf
by Pier Angelo Vendrame at 2025-09-08T12:03:39+02:00
12 changed files:
- browser/components/BrowserComponents.manifest
- browser/components/BrowserGlue.sys.mjs
- browser/components/ProfileDataUpgrader.sys.mjs
- browser/components/onionservices/OnionAliasStore.sys.mjs
- browser/components/onionservices/moz.build
- browser/components/rulesets/RulesetsParent.sys.mjs
- + browser/modules/ClipboardPrivacy.sys.mjs
- browser/modules/moz.build
- dom/base/ContentAreaDropListener.sys.mjs
- toolkit/components/places/PlacesUtils.sys.mjs
- toolkit/components/tor-launcher/tor-launcher.manifest
- toolkit/modules/moz.build
Changes:
... | ... | @@ -51,6 +51,11 @@ category browser-first-window-ready resource://gre/modules/CaptchaDetectionPingU |
51 | 51 | category browser-first-window-ready resource://gre/modules/SandboxUtils.sys.mjs SandboxUtils.maybeWarnAboutMissingUserNamespaces
|
52 | 52 | #endif
|
53 | 53 | #endif
|
54 | +category browser-first-window-ready moz-src:///browser/modules/ClipboardPrivacy.sys.mjs ClipboardPrivacy.init
|
|
55 | +category browser-first-window-ready moz-src:///browser/modules/SecurityLevelRestartNotification.sys.mjs SecurityLevelRestartNotification.ready
|
|
56 | +category browser-first-window-ready moz-src:///toolkit/modules/DragDropFilter.sys.mjs DragDropFilter.init
|
|
57 | +category browser-first-window-ready moz-src:///browser/modules/TorSettingsNotification.sys.mjs TorSettingsNotification.ready
|
|
58 | +category browser-first-window-ready moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.init
|
|
54 | 59 | |
55 | 60 | category browser-idle-startup resource:///modules/PlacesUIUtils.sys.mjs PlacesUIUtils.unblockToolbars
|
56 | 61 | category browser-idle-startup resource:///modules/BuiltInThemes.sys.mjs BuiltInThemes.ensureBuiltInThemes
|
... | ... | @@ -94,5 +99,6 @@ category browser-quit-application-granted moz-src:///browser/components/search/S |
94 | 99 | category browser-quit-application-granted resource://gre/modules/UpdateListener.sys.mjs UpdateListener.reset
|
95 | 100 | #endif
|
96 | 101 | category browser-quit-application-granted resource:///modules/UrlbarSearchTermsPersistence.sys.mjs UrlbarSearchTermsPersistence.uninit
|
102 | +category browser-quit-application-granted moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs OnionAliasStore.uninit
|
|
97 | 103 | |
98 | 104 | category search-service-notification moz-src:///browser/components/search/SearchUIUtils.sys.mjs SearchUIUtils.showSearchServiceNotification |
... | ... | @@ -12,7 +12,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
12 | 12 | AWToolbarButton: "resource:///modules/aboutwelcome/AWToolbarUtils.sys.mjs",
|
13 | 13 | ASRouter: "resource:///modules/asrouter/ASRouter.sys.mjs",
|
14 | 14 | AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
|
15 | - AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
|
|
16 | 15 | BackupService: "resource:///modules/backup/BackupService.sys.mjs",
|
17 | 16 | BrowserSearchTelemetry:
|
18 | 17 | "moz-src:///browser/components/search/BrowserSearchTelemetry.sys.mjs",
|
... | ... | @@ -31,7 +30,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
31 | 30 | DistributionManagement: "resource:///modules/distribution.sys.mjs",
|
32 | 31 | DownloadsViewableInternally:
|
33 | 32 | "resource:///modules/DownloadsViewableInternally.sys.mjs",
|
34 | - DragDropFilter: "resource://gre/modules/DragDropFilter.sys.mjs",
|
|
35 | 33 | ExtensionsUI: "resource:///modules/ExtensionsUI.sys.mjs",
|
36 | 34 | // FilePickerCrashed is used by the `listeners` object below.
|
37 | 35 | // eslint-disable-next-line mozilla/valid-lazy
|
... | ... | @@ -42,7 +40,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
42 | 40 | LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs",
|
43 | 41 | MigrationUtils: "resource:///modules/MigrationUtils.sys.mjs",
|
44 | 42 | NimbusFeatures: "resource://nimbus/ExperimentAPI.sys.mjs",
|
45 | - OnionAliasStore: "resource:///modules/OnionAliasStore.sys.mjs",
|
|
46 | 43 | OnboardingMessageProvider:
|
47 | 44 | "resource:///modules/asrouter/OnboardingMessageProvider.sys.mjs",
|
48 | 45 | PageDataService: "resource:///modules/pagedata/PageDataService.sys.mjs",
|
... | ... | @@ -63,8 +60,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
63 | 60 | ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs",
|
64 | 61 | SearchSERPTelemetry:
|
65 | 62 | "moz-src:///browser/components/search/SearchSERPTelemetry.sys.mjs",
|
66 | - SecurityLevelRestartNotification:
|
|
67 | - "resource:///modules/SecurityLevelRestartNotification.sys.mjs",
|
|
68 | 63 | SessionStartup: "resource:///modules/sessionstore/SessionStartup.sys.mjs",
|
69 | 64 | SessionStore: "resource:///modules/sessionstore/SessionStore.sys.mjs",
|
70 | 65 | ShortcutUtils: "resource://gre/modules/ShortcutUtils.sys.mjs",
|
... | ... | @@ -75,11 +70,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
75 | 70 | TelemetryReportingPolicy:
|
76 | 71 | "resource://gre/modules/TelemetryReportingPolicy.sys.mjs",
|
77 | 72 | TRRRacer: "resource:///modules/TRRPerformance.sys.mjs",
|
78 | - TorConnect: "resource://gre/modules/TorConnect.sys.mjs",
|
|
79 | - TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs",
|
|
80 | - TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
81 | - TorSettingsNotification:
|
|
82 | - "resource:///modules/TorSettingsNotification.sys.mjs",
|
|
83 | 73 | WebChannel: "resource://gre/modules/WebChannel.sys.mjs",
|
84 | 74 | WebProtocolHandlerRegistrar:
|
85 | 75 | "resource:///modules/WebProtocolHandlerRegistrar.sys.mjs",
|
... | ... | @@ -113,170 +103,6 @@ if (AppConstants.ENABLE_WEBDRIVER) { |
113 | 103 | |
114 | 104 | const PREF_PDFJS_ISDEFAULT_CACHE_STATE = "pdfjs.enabledCache.state";
|
115 | 105 | |
116 | -// Empty clipboard content from private windows on exit
|
|
117 | -// (tor-browser#42154)
|
|
118 | -const ClipboardPrivacy = {
|
|
119 | - _lastClipboardHash: null,
|
|
120 | - _globalActivation: false,
|
|
121 | - _isPrivateClipboard: false,
|
|
122 | - _hasher: null,
|
|
123 | - _shuttingDown: false,
|
|
124 | - _log: null,
|
|
125 | - |
|
126 | - _createTransferable() {
|
|
127 | - const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
|
128 | - Ci.nsITransferable
|
|
129 | - );
|
|
130 | - trans.init(null);
|
|
131 | - return trans;
|
|
132 | - },
|
|
133 | - _computeClipboardHash() {
|
|
134 | - const flavors = ["text/x-moz-url", "text/plain"];
|
|
135 | - if (
|
|
136 | - !Services.clipboard.hasDataMatchingFlavors(
|
|
137 | - flavors,
|
|
138 | - Ci.nsIClipboard.kGlobalClipboard
|
|
139 | - )
|
|
140 | - ) {
|
|
141 | - return null;
|
|
142 | - }
|
|
143 | - const trans = this._createTransferable();
|
|
144 | - flavors.forEach(trans.addDataFlavor);
|
|
145 | - try {
|
|
146 | - Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
|
|
147 | - const clipboardContent = {};
|
|
148 | - trans.getAnyTransferData({}, clipboardContent);
|
|
149 | - const { data } = clipboardContent.value.QueryInterface(
|
|
150 | - Ci.nsISupportsString
|
|
151 | - );
|
|
152 | - const bytes = new TextEncoder().encode(data);
|
|
153 | - const hasher = (this._hasher ||= Cc[
|
|
154 | - "@mozilla.org/security/hash;1"
|
|
155 | - ].createInstance(Ci.nsICryptoHash));
|
|
156 | - hasher.init(hasher.SHA256);
|
|
157 | - hasher.update(bytes, bytes.length);
|
|
158 | - return hasher.finish(true);
|
|
159 | - } catch (e) {}
|
|
160 | - return null;
|
|
161 | - },
|
|
162 | - |
|
163 | - startup() {
|
|
164 | - this._log = console.createInstance({
|
|
165 | - prefix: "ClipboardPrivacy",
|
|
166 | - });
|
|
167 | - this._lastClipboardHash = this._computeClipboardHash();
|
|
168 | - |
|
169 | - // Here we track changes in active window / application,
|
|
170 | - // by filtering focus events and window closures.
|
|
171 | - const handleActivation = (win, activation) => {
|
|
172 | - if (activation) {
|
|
173 | - if (!this._globalActivation) {
|
|
174 | - // focus changed within this window, bail out.
|
|
175 | - return;
|
|
176 | - }
|
|
177 | - this._globalActivation = false;
|
|
178 | - } else if (!Services.focus.activeWindow) {
|
|
179 | - // focus is leaving this window:
|
|
180 | - // let's track whether it remains within the browser.
|
|
181 | - lazy.setTimeout(() => {
|
|
182 | - this._globalActivation = !Services.focus.activeWindow;
|
|
183 | - }, 100);
|
|
184 | - }
|
|
185 | - |
|
186 | - const checkClipboardContent = () => {
|
|
187 | - const clipboardHash = this._computeClipboardHash();
|
|
188 | - if (clipboardHash !== this._lastClipboardHash) {
|
|
189 | - this._isPrivateClipboard =
|
|
190 | - !activation &&
|
|
191 | - (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing ||
|
|
192 | - lazy.PrivateBrowsingUtils.isWindowPrivate(win));
|
|
193 | - this._lastClipboardHash = clipboardHash;
|
|
194 | - this._log.debug(
|
|
195 | - `Clipboard changed: private ${this._isPrivateClipboard}, hash ${clipboardHash}.`
|
|
196 | - );
|
|
197 | - }
|
|
198 | - };
|
|
199 | - |
|
200 | - if (win.closed) {
|
|
201 | - checkClipboardContent();
|
|
202 | - } else {
|
|
203 | - // defer clipboard access on DOM events to work-around tor-browser#42306
|
|
204 | - lazy.setTimeout(checkClipboardContent, 0);
|
|
205 | - }
|
|
206 | - };
|
|
207 | - const focusListener = e =>
|
|
208 | - e.isTrusted && handleActivation(e.currentTarget, e.type === "focusin");
|
|
209 | - const initWindow = win => {
|
|
210 | - for (const e of ["focusin", "focusout"]) {
|
|
211 | - win.addEventListener(e, focusListener);
|
|
212 | - }
|
|
213 | - };
|
|
214 | - for (const w of Services.ww.getWindowEnumerator()) {
|
|
215 | - initWindow(w);
|
|
216 | - }
|
|
217 | - Services.ww.registerNotification((win, event) => {
|
|
218 | - switch (event) {
|
|
219 | - case "domwindowopened":
|
|
220 | - initWindow(win);
|
|
221 | - break;
|
|
222 | - case "domwindowclosed":
|
|
223 | - handleActivation(win, false);
|
|
224 | - if (
|
|
225 | - this._isPrivateClipboard &&
|
|
226 | - lazy.PrivateBrowsingUtils.isWindowPrivate(win) &&
|
|
227 | - (this._shuttingDown ||
|
|
228 | - !Array.from(Services.ww.getWindowEnumerator()).find(
|
|
229 | - w =>
|
|
230 | - lazy.PrivateBrowsingUtils.isWindowPrivate(w) &&
|
|
231 | - // We need to filter out the HIDDEN WebExtensions window,
|
|
232 | - // which might be private as well but is not UI-relevant.
|
|
233 | - !w.location.href.startsWith("chrome://extensions/")
|
|
234 | - ))
|
|
235 | - ) {
|
|
236 | - // no more private windows, empty private content if needed
|
|
237 | - this.emptyPrivate();
|
|
238 | - }
|
|
239 | - }
|
|
240 | - });
|
|
241 | - |
|
242 | - lazy.AsyncShutdown.quitApplicationGranted.addBlocker(
|
|
243 | - "ClipboardPrivacy: removing private data",
|
|
244 | - () => {
|
|
245 | - this._shuttingDown = true;
|
|
246 | - this.emptyPrivate();
|
|
247 | - }
|
|
248 | - );
|
|
249 | - },
|
|
250 | - emptyPrivate() {
|
|
251 | - if (
|
|
252 | - this._isPrivateClipboard &&
|
|
253 | - !Services.prefs.getBoolPref(
|
|
254 | - "browser.privatebrowsing.preserveClipboard",
|
|
255 | - false
|
|
256 | - ) &&
|
|
257 | - this._lastClipboardHash === this._computeClipboardHash()
|
|
258 | - ) {
|
|
259 | - // nsIClipboard.emptyClipboard() does nothing in Wayland:
|
|
260 | - // we'll set an empty string as a work-around.
|
|
261 | - const trans = this._createTransferable();
|
|
262 | - const flavor = "text/plain";
|
|
263 | - trans.addDataFlavor(flavor);
|
|
264 | - const emptyString = Cc["@mozilla.org/supports-string;1"].createInstance(
|
|
265 | - Ci.nsISupportsString
|
|
266 | - );
|
|
267 | - emptyString.data = "";
|
|
268 | - trans.setTransferData(flavor, emptyString);
|
|
269 | - const { clipboard } = Services,
|
|
270 | - { kGlobalClipboard } = clipboard;
|
|
271 | - clipboard.setData(trans, null, kGlobalClipboard);
|
|
272 | - clipboard.emptyClipboard(kGlobalClipboard);
|
|
273 | - this._lastClipboardHash = null;
|
|
274 | - this._isPrivateClipboard = false;
|
|
275 | - this._log.info("Private clipboard emptied.");
|
|
276 | - }
|
|
277 | - },
|
|
278 | -};
|
|
279 | - |
|
280 | 106 | ChromeUtils.defineLazyGetter(
|
281 | 107 | lazy,
|
282 | 108 | "WeaveService",
|
... | ... | @@ -603,13 +429,8 @@ BrowserGlue.prototype = { |
603 | 429 | |
604 | 430 | // handle any UI migration
|
605 | 431 | this._migrateUI();
|
606 | - |
|
607 | - // Base Browser-specific version of _migrateUI.
|
|
608 | - this._migrateUIBB();
|
|
609 | - |
|
610 | - // Handle any TBB-specific migration before showing the UI. Keep after
|
|
611 | - // _migrateUI to make sure this._isNewProfile has been defined.
|
|
612 | - this._migrateUITBB();
|
|
432 | + lazy.ProfileDataUpgrader.upgradeBB(this._isNewProfile);
|
|
433 | + lazy.ProfileDataUpgrader.upgradeTB(this._isNewProfile);
|
|
613 | 434 | |
614 | 435 | if (!Services.prefs.prefHasUserValue(PREF_PDFJS_ISDEFAULT_CACHE_STATE)) {
|
615 | 436 | lazy.PdfJs.checkIsDefault(this._isNewProfile);
|
... | ... | @@ -995,16 +816,6 @@ BrowserGlue.prototype = { |
995 | 816 | lazy.WeaveService.init();
|
996 | 817 | }
|
997 | 818 | |
998 | - lazy.SecurityLevelRestartNotification.ready();
|
|
999 | - |
|
1000 | - lazy.DragDropFilter.init();
|
|
1001 | - |
|
1002 | - lazy.TorProviderBuilder.firstWindowLoaded();
|
|
1003 | - |
|
1004 | - lazy.TorSettingsNotification.ready();
|
|
1005 | - |
|
1006 | - ClipboardPrivacy.startup();
|
|
1007 | - |
|
1008 | 819 | lazy.BrowserUtils.callModulesFromCategory(
|
1009 | 820 | {
|
1010 | 821 | categoryName: "browser-first-window-ready",
|
... | ... | @@ -1104,7 +915,6 @@ BrowserGlue.prototype = { |
1104 | 915 | // can perform at-shutdown tasks later in shutdown.
|
1105 | 916 | Services.fog;
|
1106 | 917 | },
|
1107 | - () => lazy.OnionAliasStore.uninit(),
|
|
1108 | 918 | ];
|
1109 | 919 | |
1110 | 920 | for (let task of tasks) {
|
... | ... | @@ -1375,30 +1185,6 @@ BrowserGlue.prototype = { |
1375 | 1185 | },
|
1376 | 1186 | },
|
1377 | 1187 | |
1378 | - {
|
|
1379 | - task: () => {
|
|
1380 | - if (!lazy.TorConnect.shouldShowTorConnect) {
|
|
1381 | - // we will take this path when the user is using the legacy tor launcher or
|
|
1382 | - // when Tor Browser didn't launch its own tor.
|
|
1383 | - lazy.OnionAliasStore.init();
|
|
1384 | - } else {
|
|
1385 | - // this path is taken when using about:torconnect, we wait to init
|
|
1386 | - // after we are bootstrapped and connected to tor
|
|
1387 | - const topic = lazy.TorConnectTopics.BootstrapComplete;
|
|
1388 | - let bootstrapObserver = {
|
|
1389 | - observe(aSubject, aTopic) {
|
|
1390 | - if (aTopic === topic) {
|
|
1391 | - lazy.OnionAliasStore.init();
|
|
1392 | - // we only need to init once, so remove ourselves as an obvserver
|
|
1393 | - Services.obs.removeObserver(this, topic);
|
|
1394 | - }
|
|
1395 | - },
|
|
1396 | - };
|
|
1397 | - Services.obs.addObserver(bootstrapObserver, topic);
|
|
1398 | - }
|
|
1399 | - },
|
|
1400 | - },
|
|
1401 | - |
|
1402 | 1188 | // Run TRR performance measurements for DoH.
|
1403 | 1189 | {
|
1404 | 1190 | name: "doh-rollout.trrRacer.run",
|
... | ... | @@ -1865,208 +1651,6 @@ BrowserGlue.prototype = { |
1865 | 1651 | }
|
1866 | 1652 | },
|
1867 | 1653 | |
1868 | - _migrateUIBB() {
|
|
1869 | - // Version 1: 13.0a3. Reset layout.css.prefers-color-scheme.content-override
|
|
1870 | - // for tor-browser#41739.
|
|
1871 | - // Version 2: 14.0a5: Reset the privacy tracking headers preferences since
|
|
1872 | - // the UI is hidden. tor-browser#42777.
|
|
1873 | - // Also, do not set
|
|
1874 | - // dom.security.https_only_mode_send_http_background_request in
|
|
1875 | - // the security level anymore (tor-browser#42149).
|
|
1876 | - // Also, reset security.xfocsp.errorReporting.automatic since we
|
|
1877 | - // hid its neterror checkbox. tor-browser#42653.
|
|
1878 | - // Version 3: 14.0a7: Reset general.smoothScroll. tor-browser#42070.
|
|
1879 | - // Version 4: 15.0a2: Drop ML components. tor-browser#44045.
|
|
1880 | - const MIGRATION_VERSION = 4;
|
|
1881 | - const MIGRATION_PREF = "basebrowser.migration.version";
|
|
1882 | - if (this._isNewProfile) {
|
|
1883 | - // Do not migrate fresh profiles
|
|
1884 | - Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION);
|
|
1885 | - return;
|
|
1886 | - } else if (this._isNewProfile === undefined) {
|
|
1887 | - // If this happens, check if upstream updated their function and do not
|
|
1888 | - // set this member anymore!
|
|
1889 | - console.error("_migrateUIBB: this._isNewProfile is undefined.");
|
|
1890 | - }
|
|
1891 | - // We do not care whether this is a new or old profile, since in version 1
|
|
1892 | - // we just quickly clear a user preference, which should not do anything to
|
|
1893 | - // new profiles.
|
|
1894 | - // Shall we ever raise the version number and have a watershed, we can add
|
|
1895 | - // a check easily (any version > 0 will be an old profile).
|
|
1896 | - const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
|
|
1897 | - if (currentVersion < 1) {
|
|
1898 | - Services.prefs.clearUserPref(
|
|
1899 | - "layout.css.prefers-color-scheme.content-override"
|
|
1900 | - );
|
|
1901 | - }
|
|
1902 | - if (currentVersion < 2) {
|
|
1903 | - for (const prefName of [
|
|
1904 | - "privacy.globalprivacycontrol.enabled",
|
|
1905 | - "privacy.donottrackheader.enabled",
|
|
1906 | - // Telemetry preference for if the user changed the value.
|
|
1907 | - "privacy.globalprivacycontrol.was_ever_enabled",
|
|
1908 | - // The next two preferences have no corresponding UI, but are related.
|
|
1909 | - "privacy.globalprivacycontrol.functionality.enabled",
|
|
1910 | - "privacy.globalprivacycontrol.pbmode.enabled",
|
|
1911 | - "dom.security.https_only_mode_send_http_background_request",
|
|
1912 | - "security.xfocsp.errorReporting.automatic",
|
|
1913 | - ]) {
|
|
1914 | - Services.prefs.clearUserPref(prefName);
|
|
1915 | - }
|
|
1916 | - }
|
|
1917 | - if (currentVersion < 3) {
|
|
1918 | - Services.prefs.clearUserPref("general.smoothScroll");
|
|
1919 | - }
|
|
1920 | - if (currentVersion < 4) {
|
|
1921 | - for (const prefName of [
|
|
1922 | - "browser.translations.enable",
|
|
1923 | - "browser.ml.enable",
|
|
1924 | - "browser.ml.chat.enabled",
|
|
1925 | - "browser.ml.linkPreview.enabled",
|
|
1926 | - "browser.tabs.groups.smart.enabled",
|
|
1927 | - "browser.tabs.groups.smart.userEnabled",
|
|
1928 | - "extensions.ml.enabled",
|
|
1929 | - "pdfjs.enableAltText",
|
|
1930 | - "pdfjs.enableAltTextForEnglish",
|
|
1931 | - "pdfjs.enableGuessAltText",
|
|
1932 | - "pdfjs.enableAltTextModelDownload",
|
|
1933 | - "browser.urlbar.quicksuggest.mlEnabled",
|
|
1934 | - "places.semanticHistory.featureGate",
|
|
1935 | - ]) {
|
|
1936 | - // Preferences are locked. Do not want user values to linger in the
|
|
1937 | - // user's profile and become active if these preferences become unlocked
|
|
1938 | - // in the future.
|
|
1939 | - Services.prefs.clearUserPref(prefName);
|
|
1940 | - }
|
|
1941 | - }
|
|
1942 | - Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION);
|
|
1943 | - },
|
|
1944 | - |
|
1945 | - // Use this method for any TBB migration that can be run just before showing
|
|
1946 | - // the UI.
|
|
1947 | - // Anything that critically needs to be migrated earlier should not use this.
|
|
1948 | - async _migrateUITBB() {
|
|
1949 | - // Version 1: Tor Browser 12.0. We use it to remove langpacks, after the
|
|
1950 | - // migration to packaged locales.
|
|
1951 | - // Version 2: Tor Browser 13.0/13.0a1: tor-browser#41845. Also, removed some
|
|
1952 | - // torbutton preferences that are not used anymore.
|
|
1953 | - // Version 3: Tor Browser 13.0.7/13.5a3: Remove blockchair
|
|
1954 | - // (tor-browser#42283).
|
|
1955 | - // Version 4: Tor Browser 14.0a4 (2024-09-02): Remove Twitter, Yahoo and
|
|
1956 | - // YouTube search engines (tor-browser#41835).
|
|
1957 | - // Version 5: Tor Browser 14.0a5: Clear user preference for CFR settings
|
|
1958 | - // since we hid the UI (tor-browser#43118).
|
|
1959 | - // Version 6: Tor Browser 14.5a3: Clear preference for TorSettings that is
|
|
1960 | - // no longer used (tor-browser#41921).
|
|
1961 | - // Drop unused TorConnect setting (tor-browser#43462).
|
|
1962 | - // Version 7: Tor Browser 14.5a6: Clear home page update url preference
|
|
1963 | - // (tor-browser#43567).
|
|
1964 | - // Version 8: Tor Browser 15.0a2: Remove legacy search addons
|
|
1965 | - // (tor-browser#43111).
|
|
1966 | - const TBB_MIGRATION_VERSION = 8;
|
|
1967 | - const MIGRATION_PREF = "torbrowser.migration.version";
|
|
1968 | - |
|
1969 | - // If we decide to force updating users to pass through any version
|
|
1970 | - // following 12.0, we can remove this check, and check only whether
|
|
1971 | - // MIGRATION_PREF has a user value, like Mozilla does.
|
|
1972 | - if (this._isNewProfile) {
|
|
1973 | - // Do not migrate fresh profiles
|
|
1974 | - Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION);
|
|
1975 | - return;
|
|
1976 | - } else if (this._isNewProfile === undefined) {
|
|
1977 | - // If this happens, check if upstream updated their function and do not
|
|
1978 | - // set this member anymore!
|
|
1979 | - console.error("_migrateUITBB: this._isNewProfile is undefined.");
|
|
1980 | - }
|
|
1981 | - |
|
1982 | - const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
|
|
1983 | - const removeLangpacks = async () => {
|
|
1984 | - for (const addon of await AddonManager.getAddonsByTypes(["locale"])) {
|
|
1985 | - await addon.uninstall();
|
|
1986 | - }
|
|
1987 | - };
|
|
1988 | - if (currentVersion < 1) {
|
|
1989 | - try {
|
|
1990 | - await removeLangpacks();
|
|
1991 | - } catch (err) {
|
|
1992 | - console.error("Could not remove langpacks", err);
|
|
1993 | - }
|
|
1994 | - }
|
|
1995 | - if (currentVersion < 2) {
|
|
1996 | - const prefToClear = [
|
|
1997 | - // tor-browser#41845: We were forcing these value by check the value of
|
|
1998 | - // automatic PBM. We decided not to change
|
|
1999 | - "browser.cache.disk.enable",
|
|
2000 | - "places.history.enabled",
|
|
2001 | - "security.nocertdb",
|
|
2002 | - "permissions.memory_only",
|
|
2003 | - // Old torbutton preferences not used anymore.
|
|
2004 | - "extensions.torbutton.loglevel",
|
|
2005 | - "extensions.torbutton.logmethod",
|
|
2006 | - "extensions.torbutton.pref_fixup_version",
|
|
2007 | - "extensions.torbutton.resize_new_windows",
|
|
2008 | - "extensions.torbutton.startup",
|
|
2009 | - "extensions.torlauncher.prompt_for_locale",
|
|
2010 | - "extensions.torlauncher.loglevel",
|
|
2011 | - "extensions.torlauncher.logmethod",
|
|
2012 | - "extensions.torlauncher.torrc_fixup_version",
|
|
2013 | - ];
|
|
2014 | - for (const pref of prefToClear) {
|
|
2015 | - if (Services.prefs.prefHasUserValue(pref)) {
|
|
2016 | - Services.prefs.clearUserPref(pref);
|
|
2017 | - }
|
|
2018 | - }
|
|
2019 | - }
|
|
2020 | - const dropAddons = async list => {
|
|
2021 | - for (const id of list) {
|
|
2022 | - try {
|
|
2023 | - const engine = await lazy.AddonManager.getAddonByID(id);
|
|
2024 | - await engine?.uninstall();
|
|
2025 | - } catch {}
|
|
2026 | - }
|
|
2027 | - };
|
|
2028 | - if (currentVersion < 3) {
|
|
2029 | - await dropAddons([
|
|
2030 | - "blockchair@search.mozilla.org",
|
|
2031 | - "blockchair-onion@search.mozilla.org",
|
|
2032 | - ]);
|
|
2033 | - }
|
|
2034 | - if (currentVersion < 4) {
|
|
2035 | - await dropAddons([
|
|
2036 | - "twitter@search.mozilla.org",
|
|
2037 | - "yahoo@search.mozilla.org",
|
|
2038 | - "youtube@search.mozilla.org",
|
|
2039 | - ]);
|
|
2040 | - }
|
|
2041 | - if (currentVersion < 5) {
|
|
2042 | - for (const pref of [
|
|
2043 | - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons",
|
|
2044 | - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features",
|
|
2045 | - ]) {
|
|
2046 | - Services.prefs.clearUserPref(pref);
|
|
2047 | - }
|
|
2048 | - }
|
|
2049 | - if (currentVersion < 6) {
|
|
2050 | - Services.prefs.clearUserPref("torbrowser.settings.enabled");
|
|
2051 | - Services.prefs.clearUserPref("torbrowser.bootstrap.allow_internet_test");
|
|
2052 | - }
|
|
2053 | - if (currentVersion < 7) {
|
|
2054 | - Services.prefs.clearUserPref("torbrowser.post_update.url");
|
|
2055 | - }
|
|
2056 | - if (currentVersion < 8) {
|
|
2057 | - await dropAddons([
|
|
2058 | - "ddg@search.mozilla.org",
|
|
2059 | - "ddg-onion@search.mozilla.org",
|
|
2060 | - "google@search.mozilla.org",
|
|
2061 | - "startpage@search.mozilla.org",
|
|
2062 | - "startpage-onion@search.mozilla.org",
|
|
2063 | - "wikipedia@search.mozilla.org",
|
|
2064 | - ]);
|
|
2065 | - }
|
|
2066 | - |
|
2067 | - Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION);
|
|
2068 | - },
|
|
2069 | - |
|
2070 | 1654 | async _showUpgradeDialog() {
|
2071 | 1655 | const data = await lazy.OnboardingMessageProvider.getUpgradeMessage();
|
2072 | 1656 | const { gBrowser } = lazy.BrowserWindowTracker.getTopWindow();
|
... | ... | @@ -900,4 +900,200 @@ export let ProfileDataUpgrader = { |
900 | 900 | // Update the migration version.
|
901 | 901 | Services.prefs.setIntPref("browser.migration.version", newVersion);
|
902 | 902 | },
|
903 | + |
|
904 | + upgradeBB(isNewProfile) {
|
|
905 | + // Version 1: 13.0a3. Reset layout.css.prefers-color-scheme.content-override
|
|
906 | + // for tor-browser#41739.
|
|
907 | + // Version 2: 14.0a5: Reset the privacy tracking headers preferences since
|
|
908 | + // the UI is hidden. tor-browser#42777.
|
|
909 | + // Also, do not set
|
|
910 | + // dom.security.https_only_mode_send_http_background_request in
|
|
911 | + // the security level anymore (tor-browser#42149).
|
|
912 | + // Also, reset security.xfocsp.errorReporting.automatic since we
|
|
913 | + // hid its neterror checkbox. tor-browser#42653.
|
|
914 | + // Version 3: 14.0a7: Reset general.smoothScroll. tor-browser#42070.
|
|
915 | + // Version 4: 15.0a2: Drop ML components. tor-browser#44045.
|
|
916 | + const MIGRATION_VERSION = 4;
|
|
917 | + const MIGRATION_PREF = "basebrowser.migration.version";
|
|
918 | + |
|
919 | + if (isNewProfile) {
|
|
920 | + // Do not migrate fresh profiles
|
|
921 | + Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION);
|
|
922 | + return;
|
|
923 | + } else if (isNewProfile === undefined) {
|
|
924 | + // If this happens, check if upstream updated their function and do not
|
|
925 | + // set this member anymore!
|
|
926 | + console.error("upgradeBB: isNewProfile is undefined.");
|
|
927 | + }
|
|
928 | + |
|
929 | + const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
|
|
930 | + if (currentVersion < 1) {
|
|
931 | + Services.prefs.clearUserPref(
|
|
932 | + "layout.css.prefers-color-scheme.content-override"
|
|
933 | + );
|
|
934 | + }
|
|
935 | + if (currentVersion < 2) {
|
|
936 | + for (const prefName of [
|
|
937 | + "privacy.globalprivacycontrol.enabled",
|
|
938 | + "privacy.donottrackheader.enabled",
|
|
939 | + // Telemetry preference for if the user changed the value.
|
|
940 | + "privacy.globalprivacycontrol.was_ever_enabled",
|
|
941 | + // The next two preferences have no corresponding UI, but are related.
|
|
942 | + "privacy.globalprivacycontrol.functionality.enabled",
|
|
943 | + "privacy.globalprivacycontrol.pbmode.enabled",
|
|
944 | + "dom.security.https_only_mode_send_http_background_request",
|
|
945 | + "security.xfocsp.errorReporting.automatic",
|
|
946 | + ]) {
|
|
947 | + Services.prefs.clearUserPref(prefName);
|
|
948 | + }
|
|
949 | + }
|
|
950 | + if (currentVersion < 3) {
|
|
951 | + Services.prefs.clearUserPref("general.smoothScroll");
|
|
952 | + }
|
|
953 | + if (currentVersion < 4) {
|
|
954 | + for (const prefName of [
|
|
955 | + "browser.translations.enable",
|
|
956 | + "browser.ml.enable",
|
|
957 | + "browser.ml.chat.enabled",
|
|
958 | + "browser.ml.linkPreview.enabled",
|
|
959 | + "browser.tabs.groups.smart.enabled",
|
|
960 | + "browser.tabs.groups.smart.userEnabled",
|
|
961 | + "extensions.ml.enabled",
|
|
962 | + "pdfjs.enableAltText",
|
|
963 | + "pdfjs.enableAltTextForEnglish",
|
|
964 | + "pdfjs.enableGuessAltText",
|
|
965 | + "pdfjs.enableAltTextModelDownload",
|
|
966 | + "browser.urlbar.quicksuggest.mlEnabled",
|
|
967 | + "places.semanticHistory.featureGate",
|
|
968 | + ]) {
|
|
969 | + // Preferences are locked. Do not want user values to linger in the
|
|
970 | + // user's profile and become active if these preferences become unlocked
|
|
971 | + // in the future.
|
|
972 | + Services.prefs.clearUserPref(prefName);
|
|
973 | + }
|
|
974 | + }
|
|
975 | + Services.prefs.setIntPref(MIGRATION_PREF, MIGRATION_VERSION);
|
|
976 | + },
|
|
977 | + |
|
978 | + async upgradeTB(isNewProfile) {
|
|
979 | + // Version 1: Tor Browser 12.0. We use it to remove langpacks, after the
|
|
980 | + // migration to packaged locales.
|
|
981 | + // Version 2: Tor Browser 13.0/13.0a1: tor-browser#41845. Also, removed some
|
|
982 | + // torbutton preferences that are not used anymore.
|
|
983 | + // Version 3: Tor Browser 13.0.7/13.5a3: Remove blockchair
|
|
984 | + // (tor-browser#42283).
|
|
985 | + // Version 4: Tor Browser 14.0a4 (2024-09-02): Remove Twitter, Yahoo and
|
|
986 | + // YouTube search engines (tor-browser#41835).
|
|
987 | + // Version 5: Tor Browser 14.0a5: Clear user preference for CFR settings
|
|
988 | + // since we hid the UI (tor-browser#43118).
|
|
989 | + // Version 6: Tor Browser 14.5a3: Clear preference for TorSettings that is
|
|
990 | + // no longer used (tor-browser#41921).
|
|
991 | + // Drop unused TorConnect setting (tor-browser#43462).
|
|
992 | + // Version 7: Tor Browser 14.5a6: Clear home page update url preference
|
|
993 | + // (tor-browser#43567).
|
|
994 | + // Version 8: Tor Browser 15.0a2: Remove legacy search addons
|
|
995 | + // (tor-browser#43111).
|
|
996 | + const TBB_MIGRATION_VERSION = 8;
|
|
997 | + const MIGRATION_PREF = "torbrowser.migration.version";
|
|
998 | + |
|
999 | + // If we decide to force updating users to pass through any version
|
|
1000 | + // following 12.0, we can remove this check, and check only whether
|
|
1001 | + // MIGRATION_PREF has a user value, like Mozilla does.
|
|
1002 | + if (isNewProfile) {
|
|
1003 | + // Do not migrate fresh profiles
|
|
1004 | + Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION);
|
|
1005 | + return;
|
|
1006 | + } else if (isNewProfile === undefined) {
|
|
1007 | + // If this happens, check if upstream updated their function and do not
|
|
1008 | + // set this member anymore!
|
|
1009 | + console.error("upgradeTB: isNewProfile is undefined.");
|
|
1010 | + }
|
|
1011 | + |
|
1012 | + const currentVersion = Services.prefs.getIntPref(MIGRATION_PREF, 0);
|
|
1013 | + const removeLangpacks = async () => {
|
|
1014 | + for (const addon of await AddonManager.getAddonsByTypes(["locale"])) {
|
|
1015 | + await addon.uninstall();
|
|
1016 | + }
|
|
1017 | + };
|
|
1018 | + if (currentVersion < 1) {
|
|
1019 | + try {
|
|
1020 | + await removeLangpacks();
|
|
1021 | + } catch (err) {
|
|
1022 | + console.error("Could not remove langpacks", err);
|
|
1023 | + }
|
|
1024 | + }
|
|
1025 | + if (currentVersion < 2) {
|
|
1026 | + const prefToClear = [
|
|
1027 | + // tor-browser#41845: We were forcing these value by check the value of
|
|
1028 | + // automatic PBM. We decided not to change
|
|
1029 | + "browser.cache.disk.enable",
|
|
1030 | + "places.history.enabled",
|
|
1031 | + "security.nocertdb",
|
|
1032 | + "permissions.memory_only",
|
|
1033 | + // Old torbutton preferences not used anymore.
|
|
1034 | + "extensions.torbutton.loglevel",
|
|
1035 | + "extensions.torbutton.logmethod",
|
|
1036 | + "extensions.torbutton.pref_fixup_version",
|
|
1037 | + "extensions.torbutton.resize_new_windows",
|
|
1038 | + "extensions.torbutton.startup",
|
|
1039 | + "extensions.torlauncher.prompt_for_locale",
|
|
1040 | + "extensions.torlauncher.loglevel",
|
|
1041 | + "extensions.torlauncher.logmethod",
|
|
1042 | + "extensions.torlauncher.torrc_fixup_version",
|
|
1043 | + ];
|
|
1044 | + for (const pref of prefToClear) {
|
|
1045 | + if (Services.prefs.prefHasUserValue(pref)) {
|
|
1046 | + Services.prefs.clearUserPref(pref);
|
|
1047 | + }
|
|
1048 | + }
|
|
1049 | + }
|
|
1050 | + const dropAddons = async list => {
|
|
1051 | + for (const id of list) {
|
|
1052 | + try {
|
|
1053 | + const engine = await lazy.AddonManager.getAddonByID(id);
|
|
1054 | + await engine?.uninstall();
|
|
1055 | + } catch {}
|
|
1056 | + }
|
|
1057 | + };
|
|
1058 | + if (currentVersion < 3) {
|
|
1059 | + await dropAddons([
|
|
1060 | + "blockchair@search.mozilla.org",
|
|
1061 | + "blockchair-onion@search.mozilla.org",
|
|
1062 | + ]);
|
|
1063 | + }
|
|
1064 | + if (currentVersion < 4) {
|
|
1065 | + await dropAddons([
|
|
1066 | + "twitter@search.mozilla.org",
|
|
1067 | + "yahoo@search.mozilla.org",
|
|
1068 | + "youtube@search.mozilla.org",
|
|
1069 | + ]);
|
|
1070 | + }
|
|
1071 | + if (currentVersion < 5) {
|
|
1072 | + for (const pref of [
|
|
1073 | + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons",
|
|
1074 | + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features",
|
|
1075 | + ]) {
|
|
1076 | + Services.prefs.clearUserPref(pref);
|
|
1077 | + }
|
|
1078 | + }
|
|
1079 | + if (currentVersion < 6) {
|
|
1080 | + Services.prefs.clearUserPref("torbrowser.settings.enabled");
|
|
1081 | + Services.prefs.clearUserPref("torbrowser.bootstrap.allow_internet_test");
|
|
1082 | + }
|
|
1083 | + if (currentVersion < 7) {
|
|
1084 | + Services.prefs.clearUserPref("torbrowser.post_update.url");
|
|
1085 | + }
|
|
1086 | + if (currentVersion < 8) {
|
|
1087 | + await dropAddons([
|
|
1088 | + "ddg@search.mozilla.org",
|
|
1089 | + "ddg-onion@search.mozilla.org",
|
|
1090 | + "google@search.mozilla.org",
|
|
1091 | + "startpage@search.mozilla.org",
|
|
1092 | + "startpage-onion@search.mozilla.org",
|
|
1093 | + "wikipedia@search.mozilla.org",
|
|
1094 | + ]);
|
|
1095 | + }
|
|
1096 | + |
|
1097 | + Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION);
|
|
1098 | + },
|
|
903 | 1099 | }; |
1 | -// Copyright (c) 2022, The Tor Project, Inc.
|
|
1 | +/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
2 | 4 | |
3 | 5 | import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs";
|
4 | 6 | |
... | ... | @@ -6,7 +8,10 @@ const lazy = {}; |
6 | 8 | |
7 | 9 | ChromeUtils.defineESModuleGetters(lazy, {
|
8 | 10 | JSONFile: "resource://gre/modules/JSONFile.sys.mjs",
|
9 | - TorRequestWatch: "resource:///modules/TorRequestWatch.sys.mjs",
|
|
11 | + TorConnect: "resource://gre/modules/TorConnect.sys.mjs",
|
|
12 | + TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs",
|
|
13 | + TorRequestWatch:
|
|
14 | + "moz-src:///browser/components/onionservices/TorRequestWatch.sys.mjs",
|
|
10 | 15 | });
|
11 | 16 | |
12 | 17 | /* OnionAliasStore observer topics */
|
... | ... | @@ -84,12 +89,14 @@ class Channel { |
84 | 89 | };
|
85 | 90 | }
|
86 | 91 | |
92 | + #enabled;
|
|
93 | + |
|
87 | 94 | constructor(name, pathPrefix, jwk, scope, enabled) {
|
88 | 95 | this.name = name;
|
89 | 96 | this.pathPrefix = pathPrefix;
|
90 | 97 | this.jwk = jwk;
|
91 | 98 | this.scope = scope;
|
92 | - this._enabled = enabled;
|
|
99 | + this.#enabled = enabled;
|
|
93 | 100 | |
94 | 101 | this.mappings = [];
|
95 | 102 | this.currentTimestamp = 0;
|
... | ... | @@ -158,10 +165,10 @@ class Channel { |
158 | 165 | log.debug(
|
159 | 166 | `Downloaded and verified rules for ${this.name}, now uncompressing`
|
160 | 167 | );
|
161 | - this._makeMappings(JSON.parse(await gunzip(rulesGz)));
|
|
168 | + this.#makeMappings(JSON.parse(await gunzip(rulesGz)));
|
|
162 | 169 | }
|
163 | 170 | |
164 | - _makeMappings(rules) {
|
|
171 | + #makeMappings(rules) {
|
|
165 | 172 | const toTest = /^https?:\/\/[a-zA-Z0-9\.]{56}\.onion$/;
|
166 | 173 | const mappings = [];
|
167 | 174 | rules.rulesets.forEach(rule => {
|
... | ... | @@ -210,7 +217,7 @@ class Channel { |
210 | 217 | |
211 | 218 | async updateMappings(force) {
|
212 | 219 | force = force === undefined ? false : !!force;
|
213 | - if (!this._enabled && !force) {
|
|
220 | + if (!this.#enabled && !force) {
|
|
214 | 221 | return;
|
215 | 222 | }
|
216 | 223 | await this.updateLatestTimestamp();
|
... | ... | @@ -224,10 +231,10 @@ class Channel { |
224 | 231 | }
|
225 | 232 | |
226 | 233 | get enabled() {
|
227 | - return this._enabled;
|
|
234 | + return this.#enabled;
|
|
228 | 235 | }
|
229 | 236 | set enabled(enabled) {
|
230 | - this._enabled = enabled;
|
|
237 | + this.#enabled = enabled;
|
|
231 | 238 | if (!enabled) {
|
232 | 239 | this.mappings = [];
|
233 | 240 | this.currentTimestamp = 0;
|
... | ... | @@ -243,7 +250,7 @@ class Channel { |
243 | 250 | pathPrefix: this.pathPrefix,
|
244 | 251 | jwk: this.jwk,
|
245 | 252 | scope,
|
246 | - enabled: this._enabled,
|
|
253 | + enabled: this.#enabled,
|
|
247 | 254 | mappings: this.mappings,
|
248 | 255 | currentTimestamp: this.currentTimestamp,
|
249 | 256 | };
|
... | ... | @@ -277,37 +284,40 @@ class _OnionAliasStore { |
277 | 284 | return 86400 * 1000; // 1 day, like HTTPS-Everywhere
|
278 | 285 | }
|
279 | 286 | |
280 | - constructor() {
|
|
281 | - this._channels = new Map();
|
|
282 | - this._rulesetTimeout = null;
|
|
283 | - this._lastCheck = 0;
|
|
284 | - this._storage = null;
|
|
285 | - }
|
|
287 | + #channels = new Map();
|
|
288 | + #rulesetTimeout = null;
|
|
289 | + #lastCheck = 0;
|
|
290 | + #storage = null;
|
|
286 | 291 | |
287 | 292 | async init() {
|
288 | 293 | lazy.TorRequestWatch.start();
|
289 | - await this._loadSettings();
|
|
290 | - if (this.enabled) {
|
|
291 | - await this._startUpdates();
|
|
294 | + await this.#loadSettings();
|
|
295 | + if (this.enabled && !lazy.TorConnect.shouldShowTorConnect) {
|
|
296 | + await this.#startUpdates();
|
|
297 | + } else {
|
|
298 | + Services.obs.addObserver(this, lazy.TorConnectTopics.BootstrapComplete);
|
|
292 | 299 | }
|
293 | 300 | Services.prefs.addObserver(kPrefOnionAliasEnabled, this);
|
294 | 301 | }
|
295 | 302 | |
296 | 303 | uninit() {
|
297 | - this._clear();
|
|
298 | - if (this._rulesetTimeout) {
|
|
299 | - clearTimeout(this._rulesetTimeout);
|
|
304 | + this.#clear();
|
|
305 | + if (this.#rulesetTimeout) {
|
|
306 | + clearTimeout(this.#rulesetTimeout);
|
|
300 | 307 | }
|
301 | - this._rulesetTimeout = null;
|
|
308 | + this.#rulesetTimeout = null;
|
|
309 | + |
|
310 | + Services.obs.removeObserver(this, lazy.TorConnectTopics.BootstrapComplete);
|
|
302 | 311 | Services.prefs.removeObserver(kPrefOnionAliasEnabled, this);
|
312 | + |
|
303 | 313 | lazy.TorRequestWatch.stop();
|
304 | 314 | }
|
305 | 315 | |
306 | 316 | async getChannels() {
|
307 | - if (this._storage === null) {
|
|
308 | - await this._loadSettings();
|
|
317 | + if (this.#storage === null) {
|
|
318 | + await this.#loadSettings();
|
|
309 | 319 | }
|
310 | - return Array.from(this._channels.values(), ch => ch.toJSON());
|
|
320 | + return Array.from(this.#channels.values(), ch => ch.toJSON());
|
|
311 | 321 | }
|
312 | 322 | |
313 | 323 | async setChannel(chanData) {
|
... | ... | @@ -328,20 +338,20 @@ class _OnionAliasStore { |
328 | 338 | );
|
329 | 339 | // Call makeKey to make it throw if the key is invalid
|
330 | 340 | await ch.makeKey();
|
331 | - this._channels.set(name, ch);
|
|
332 | - this._applyMappings();
|
|
333 | - this._saveSettings();
|
|
334 | - setTimeout(this._notifyChanges.bind(this), 1);
|
|
341 | + this.#channels.set(name, ch);
|
|
342 | + this.#applyMappings();
|
|
343 | + this.#saveSettings();
|
|
344 | + setTimeout(this.#notifyChanges.bind(this), 1);
|
|
335 | 345 | return ch;
|
336 | 346 | }
|
337 | 347 | |
338 | 348 | enableChannel(name, enabled) {
|
339 | - const channel = this._channels.get(name);
|
|
349 | + const channel = this.#channels.get(name);
|
|
340 | 350 | if (channel !== null) {
|
341 | 351 | channel.enabled = enabled;
|
342 | - this._applyMappings();
|
|
343 | - this._saveSettings();
|
|
344 | - this._notifyChanges();
|
|
352 | + this.#applyMappings();
|
|
353 | + this.#saveSettings();
|
|
354 | + this.#notifyChanges();
|
|
345 | 355 | if (this.enabled && enabled && !channel.currentTimestamp) {
|
346 | 356 | this.updateChannel(name);
|
347 | 357 | }
|
... | ... | @@ -352,46 +362,46 @@ class _OnionAliasStore { |
352 | 362 | if (!this.enabled) {
|
353 | 363 | throw Error("Onion Aliases are disabled");
|
354 | 364 | }
|
355 | - const channel = this._channels.get(name);
|
|
365 | + const channel = this.#channels.get(name);
|
|
356 | 366 | if (channel === null) {
|
357 | 367 | throw Error("Channel not found");
|
358 | 368 | }
|
359 | 369 | await channel.updateMappings(true);
|
360 | - this._saveSettings();
|
|
361 | - this._applyMappings();
|
|
362 | - setTimeout(this._notifyChanges.bind(this), 1);
|
|
370 | + this.#saveSettings();
|
|
371 | + this.#applyMappings();
|
|
372 | + setTimeout(this.#notifyChanges.bind(this), 1);
|
|
363 | 373 | return channel;
|
364 | 374 | }
|
365 | 375 | |
366 | 376 | deleteChannel(name) {
|
367 | - if (this._channels.delete(name)) {
|
|
368 | - this._saveSettings();
|
|
369 | - this._applyMappings();
|
|
370 | - this._notifyChanges();
|
|
377 | + if (this.#channels.delete(name)) {
|
|
378 | + this.#saveSettings();
|
|
379 | + this.#applyMappings();
|
|
380 | + this.#notifyChanges();
|
|
371 | 381 | }
|
372 | 382 | }
|
373 | 383 | |
374 | - async _loadSettings() {
|
|
375 | - if (this._storage !== null) {
|
|
384 | + async #loadSettings() {
|
|
385 | + if (this.#storage !== null) {
|
|
376 | 386 | return;
|
377 | 387 | }
|
378 | - this._channels = new Map();
|
|
379 | - this._storage = new lazy.JSONFile({
|
|
388 | + this.#channels = new Map();
|
|
389 | + this.#storage = new lazy.JSONFile({
|
|
380 | 390 | path: PathUtils.join(
|
381 | 391 | Services.dirsvc.get("ProfD", Ci.nsIFile).path,
|
382 | 392 | "onion-aliases.json"
|
383 | 393 | ),
|
384 | - dataPostProcessor: this._settingsProcessor.bind(this),
|
|
394 | + dataPostProcessor: this.#settingsProcessor.bind(this),
|
|
385 | 395 | });
|
386 | - await this._storage.load();
|
|
387 | - log.debug("Loaded settings", this._storage.data, this._storage.path);
|
|
388 | - this._applyMappings();
|
|
389 | - this._notifyChanges();
|
|
396 | + await this.#storage.load();
|
|
397 | + log.debug("Loaded settings", this.#storage.data, this.#storage.path);
|
|
398 | + this.#applyMappings();
|
|
399 | + this.#notifyChanges();
|
|
390 | 400 | }
|
391 | 401 | |
392 | - _settingsProcessor(data) {
|
|
402 | + #settingsProcessor(data) {
|
|
393 | 403 | if ("lastCheck" in data) {
|
394 | - this._lastCheck = data.lastCheck;
|
|
404 | + this.#lastCheck = data.lastCheck;
|
|
395 | 405 | } else {
|
396 | 406 | data.lastCheck = 0;
|
397 | 407 | }
|
... | ... | @@ -410,56 +420,56 @@ class _OnionAliasStore { |
410 | 420 | }
|
411 | 421 | return true;
|
412 | 422 | });
|
413 | - this._channels = channels;
|
|
423 | + this.#channels = channels;
|
|
414 | 424 | return data;
|
415 | 425 | }
|
416 | 426 | |
417 | - _saveSettings() {
|
|
418 | - if (this._storage === null) {
|
|
427 | + #saveSettings() {
|
|
428 | + if (this.#storage === null) {
|
|
419 | 429 | throw Error("Settings have not been loaded");
|
420 | 430 | }
|
421 | - this._storage.data.lastCheck = this._lastCheck;
|
|
422 | - this._storage.data.channels = Array.from(this._channels.values(), ch =>
|
|
431 | + this.#storage.data.lastCheck = this.#lastCheck;
|
|
432 | + this.#storage.data.channels = Array.from(this.#channels.values(), ch =>
|
|
423 | 433 | ch.toJSON()
|
424 | 434 | );
|
425 | - this._storage.saveSoon();
|
|
435 | + this.#storage.saveSoon();
|
|
426 | 436 | }
|
427 | 437 | |
428 | - _addMapping(shortOnionHost, longOnionHost) {
|
|
438 | + #addMapping(shortOnionHost, longOnionHost) {
|
|
429 | 439 | const service = Cc["@torproject.org/onion-alias-service;1"].getService(
|
430 | 440 | Ci.IOnionAliasService
|
431 | 441 | );
|
432 | 442 | service.addOnionAlias(shortOnionHost, longOnionHost);
|
433 | 443 | }
|
434 | 444 | |
435 | - _clear() {
|
|
445 | + #clear() {
|
|
436 | 446 | const service = Cc["@torproject.org/onion-alias-service;1"].getService(
|
437 | 447 | Ci.IOnionAliasService
|
438 | 448 | );
|
439 | 449 | service.clearOnionAliases();
|
440 | 450 | }
|
441 | 451 | |
442 | - _applyMappings() {
|
|
443 | - this._clear();
|
|
444 | - for (const ch of this._channels.values()) {
|
|
452 | + #applyMappings() {
|
|
453 | + this.#clear();
|
|
454 | + for (const ch of this.#channels.values()) {
|
|
445 | 455 | if (!ch.enabled) {
|
446 | 456 | continue;
|
447 | 457 | }
|
448 | 458 | for (const [short, long] of ch.mappings) {
|
449 | - this._addMapping(short, long);
|
|
459 | + this.#addMapping(short, long);
|
|
450 | 460 | }
|
451 | 461 | }
|
452 | 462 | }
|
453 | 463 | |
454 | - async _periodicRulesetCheck() {
|
|
464 | + async #periodicRulesetCheck() {
|
|
455 | 465 | if (!this.enabled) {
|
456 | 466 | log.debug("Onion Aliases are disabled, not updating rulesets.");
|
457 | 467 | return;
|
458 | 468 | }
|
459 | 469 | log.debug("Begin scheduled ruleset update");
|
460 | - this._lastCheck = Date.now();
|
|
470 | + this.#lastCheck = Date.now();
|
|
461 | 471 | let anyUpdated = false;
|
462 | - for (const ch of this._channels.values()) {
|
|
472 | + for (const ch of this.#channels.values()) {
|
|
463 | 473 | if (!ch.enabled) {
|
464 | 474 | log.debug(`Not updating ${ch.name} because not enabled`);
|
465 | 475 | continue;
|
... | ... | @@ -473,22 +483,22 @@ class _OnionAliasStore { |
473 | 483 | }
|
474 | 484 | }
|
475 | 485 | if (anyUpdated) {
|
476 | - this._saveSettings();
|
|
477 | - this._applyMappings();
|
|
478 | - this._notifyChanges();
|
|
486 | + this.#saveSettings();
|
|
487 | + this.#applyMappings();
|
|
488 | + this.#notifyChanges();
|
|
479 | 489 | } else {
|
480 | 490 | log.debug("No channel has been updated, avoid saving");
|
481 | 491 | }
|
482 | - this._scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL);
|
|
492 | + this.#scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL);
|
|
483 | 493 | }
|
484 | 494 | |
485 | - async _startUpdates() {
|
|
486 | - // This is a "private" function, so we expect the callers to verify wheter
|
|
495 | + async #startUpdates() {
|
|
496 | + // This is a private function, so we expect the callers to verify whether
|
|
487 | 497 | // onion aliases are enabled.
|
488 | 498 | // Callees will also do, so we avoid an additional check here.
|
489 | - const dt = Date.now() - this._lastCheck;
|
|
499 | + const dt = Date.now() - this.#lastCheck;
|
|
490 | 500 | let force = false;
|
491 | - for (const ch of this._channels.values()) {
|
|
501 | + for (const ch of this.#channels.values()) {
|
|
492 | 502 | if (ch.enabled && !ch.currentTimestamp) {
|
493 | 503 | // Edited while being offline or some other error happened
|
494 | 504 | force = true;
|
... | ... | @@ -499,34 +509,34 @@ class _OnionAliasStore { |
499 | 509 | log.debug(
|
500 | 510 | `Mappings are stale (${dt}), or force check requested (${force}), checking them immediately`
|
501 | 511 | );
|
502 | - await this._periodicRulesetCheck();
|
|
512 | + await this.#periodicRulesetCheck();
|
|
503 | 513 | } else {
|
504 | - this._scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL - dt);
|
|
514 | + this.#scheduleCheck(_OnionAliasStore.RULESET_CHECK_INTERVAL - dt);
|
|
505 | 515 | }
|
506 | 516 | }
|
507 | 517 | |
508 | - _scheduleCheck(dt) {
|
|
509 | - if (this._rulesetTimeout) {
|
|
518 | + #scheduleCheck(dt) {
|
|
519 | + if (this.#rulesetTimeout) {
|
|
510 | 520 | log.warn("The previous update timeout was not null");
|
511 | - clearTimeout(this._rulesetTimeout);
|
|
521 | + clearTimeout(this.#rulesetTimeout);
|
|
512 | 522 | }
|
513 | 523 | if (!this.enabled) {
|
514 | 524 | log.warn(
|
515 | 525 | "Ignoring the scheduling of a new check because the Onion Alias feature is currently disabled."
|
516 | 526 | );
|
517 | - this._rulesetTimeout = null;
|
|
527 | + this.#rulesetTimeout = null;
|
|
518 | 528 | return;
|
519 | 529 | }
|
520 | 530 | log.debug(`Scheduling ruleset update in ${dt}`);
|
521 | - this._rulesetTimeout = setTimeout(() => {
|
|
522 | - this._rulesetTimeout = null;
|
|
523 | - this._periodicRulesetCheck();
|
|
531 | + this.#rulesetTimeout = setTimeout(() => {
|
|
532 | + this.#rulesetTimeout = null;
|
|
533 | + this.#periodicRulesetCheck();
|
|
524 | 534 | }, dt);
|
525 | 535 | }
|
526 | 536 | |
527 | - _notifyChanges() {
|
|
537 | + #notifyChanges() {
|
|
528 | 538 | Services.obs.notifyObservers(
|
529 | - Array.from(this._channels.values(), ch => ch.toJSON()),
|
|
539 | + Array.from(this.#channels.values(), ch => ch.toJSON()),
|
|
530 | 540 | OnionAliasStoreTopics.ChannelsChanged
|
531 | 541 | );
|
532 | 542 | }
|
... | ... | @@ -538,11 +548,16 @@ class _OnionAliasStore { |
538 | 548 | observe(aSubject, aTopic) {
|
539 | 549 | if (aTopic === "nsPref:changed") {
|
540 | 550 | if (this.enabled) {
|
541 | - this._startUpdates();
|
|
542 | - } else if (this._rulesetTimeout) {
|
|
543 | - clearTimeout(this._rulesetTimeout);
|
|
544 | - this._rulesetTimeout = null;
|
|
551 | + this.#startUpdates();
|
|
552 | + } else if (this.#rulesetTimeout) {
|
|
553 | + clearTimeout(this.#rulesetTimeout);
|
|
554 | + this.#rulesetTimeout = null;
|
|
545 | 555 | }
|
556 | + } else if (
|
|
557 | + aTopic === lazy.TorConnectTopics.BootstrapComplete &&
|
|
558 | + this.enabled
|
|
559 | + ) {
|
|
560 | + this.#startUpdates();
|
|
546 | 561 | }
|
547 | 562 | }
|
548 | 563 | }
|
1 | 1 | JAR_MANIFESTS += ["jar.mn"]
|
2 | 2 | |
3 | 3 | EXTRA_JS_MODULES += [
|
4 | - "OnionAliasStore.sys.mjs",
|
|
5 | 4 | "OnionLocationChild.sys.mjs",
|
6 | 5 | "OnionLocationParent.sys.mjs",
|
6 | +]
|
|
7 | + |
|
8 | +MOZ_SRC_FILES += [
|
|
9 | + "OnionAliasStore.sys.mjs",
|
|
7 | 10 | "TorRequestWatch.sys.mjs",
|
8 | 11 | ] |
1 | -// Copyright (c) 2022, The Tor Project, Inc.
|
|
1 | +/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
2 | 4 | |
3 | 5 | import {
|
4 | 6 | OnionAliasStore,
|
5 | 7 | OnionAliasStoreTopics,
|
6 | -} from "resource:///modules/OnionAliasStore.sys.mjs";
|
|
8 | +} from "moz-src:///browser/components/onionservices/OnionAliasStore.sys.mjs";
|
|
7 | 9 | |
8 | 10 | const kShowWarningPref = "torbrowser.rulesets.show_warning";
|
9 | 11 | |
... | ... | @@ -56,9 +58,10 @@ export class RulesetsParent extends JSWindowActorParent { |
56 | 58 | return {
|
57 | 59 | showWarning: Services.prefs.getBoolPref(kShowWarningPref, true),
|
58 | 60 | };
|
59 | - case "rulesets:set-channel":
|
|
61 | + case "rulesets:set-channel": {
|
|
60 | 62 | const ch = await OnionAliasStore.setChannel(message.data);
|
61 | 63 | return ch;
|
64 | + }
|
|
62 | 65 | case "rulesets:update-channel":
|
63 | 66 | // We need to catch any error in this way, because in case of an
|
64 | 67 | // exception, RPMSendQuery does not return on the other side
|
1 | +/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
4 | + |
|
5 | +const lazy = {};
|
|
6 | + |
|
7 | +ChromeUtils.defineESModuleGetters(lazy, {
|
|
8 | + AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
|
|
9 | + PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
|
|
10 | + setTimeout: "resource://gre/modules/Timer.sys.mjs",
|
|
11 | +});
|
|
12 | + |
|
13 | +/**
|
|
14 | + * Empty clipboard content from private windows on exit.
|
|
15 | + *
|
|
16 | + * See tor-browser#42154.
|
|
17 | + */
|
|
18 | +export const ClipboardPrivacy = {
|
|
19 | + _lastClipboardHash: null,
|
|
20 | + _globalActivation: false,
|
|
21 | + _isPrivateClipboard: false,
|
|
22 | + _hasher: null,
|
|
23 | + _shuttingDown: false,
|
|
24 | + _log: null,
|
|
25 | + |
|
26 | + _createTransferable() {
|
|
27 | + const trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
|
28 | + Ci.nsITransferable
|
|
29 | + );
|
|
30 | + trans.init(null);
|
|
31 | + return trans;
|
|
32 | + },
|
|
33 | + _computeClipboardHash() {
|
|
34 | + const flavors = ["text/x-moz-url", "text/plain"];
|
|
35 | + if (
|
|
36 | + !Services.clipboard.hasDataMatchingFlavors(
|
|
37 | + flavors,
|
|
38 | + Ci.nsIClipboard.kGlobalClipboard
|
|
39 | + )
|
|
40 | + ) {
|
|
41 | + return null;
|
|
42 | + }
|
|
43 | + const trans = this._createTransferable();
|
|
44 | + flavors.forEach(trans.addDataFlavor);
|
|
45 | + try {
|
|
46 | + Services.clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
|
|
47 | + const clipboardContent = {};
|
|
48 | + trans.getAnyTransferData({}, clipboardContent);
|
|
49 | + const { data } = clipboardContent.value.QueryInterface(
|
|
50 | + Ci.nsISupportsString
|
|
51 | + );
|
|
52 | + const bytes = new TextEncoder().encode(data);
|
|
53 | + const hasher = (this._hasher ||= Cc[
|
|
54 | + "@mozilla.org/security/hash;1"
|
|
55 | + ].createInstance(Ci.nsICryptoHash));
|
|
56 | + hasher.init(hasher.SHA256);
|
|
57 | + hasher.update(bytes, bytes.length);
|
|
58 | + return hasher.finish(true);
|
|
59 | + } catch (e) {}
|
|
60 | + return null;
|
|
61 | + },
|
|
62 | + |
|
63 | + init() {
|
|
64 | + this._log = console.createInstance({
|
|
65 | + prefix: "ClipboardPrivacy",
|
|
66 | + });
|
|
67 | + this._lastClipboardHash = this._computeClipboardHash();
|
|
68 | + |
|
69 | + // Here we track changes in active window / application,
|
|
70 | + // by filtering focus events and window closures.
|
|
71 | + const handleActivation = (win, activation) => {
|
|
72 | + if (activation) {
|
|
73 | + if (!this._globalActivation) {
|
|
74 | + // focus changed within this window, bail out.
|
|
75 | + return;
|
|
76 | + }
|
|
77 | + this._globalActivation = false;
|
|
78 | + } else if (!Services.focus.activeWindow) {
|
|
79 | + // focus is leaving this window:
|
|
80 | + // let's track whether it remains within the browser.
|
|
81 | + lazy.setTimeout(() => {
|
|
82 | + this._globalActivation = !Services.focus.activeWindow;
|
|
83 | + }, 100);
|
|
84 | + }
|
|
85 | + |
|
86 | + const checkClipboardContent = () => {
|
|
87 | + const clipboardHash = this._computeClipboardHash();
|
|
88 | + if (clipboardHash !== this._lastClipboardHash) {
|
|
89 | + this._isPrivateClipboard =
|
|
90 | + !activation &&
|
|
91 | + (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing ||
|
|
92 | + lazy.PrivateBrowsingUtils.isWindowPrivate(win));
|
|
93 | + this._lastClipboardHash = clipboardHash;
|
|
94 | + this._log.debug(
|
|
95 | + `Clipboard changed: private ${this._isPrivateClipboard}, hash ${clipboardHash}.`
|
|
96 | + );
|
|
97 | + }
|
|
98 | + };
|
|
99 | + |
|
100 | + if (win.closed) {
|
|
101 | + checkClipboardContent();
|
|
102 | + } else {
|
|
103 | + // defer clipboard access on DOM events to work-around tor-browser#42306
|
|
104 | + lazy.setTimeout(checkClipboardContent, 0);
|
|
105 | + }
|
|
106 | + };
|
|
107 | + const focusListener = e =>
|
|
108 | + e.isTrusted && handleActivation(e.currentTarget, e.type === "focusin");
|
|
109 | + const initWindow = win => {
|
|
110 | + for (const e of ["focusin", "focusout"]) {
|
|
111 | + win.addEventListener(e, focusListener);
|
|
112 | + }
|
|
113 | + };
|
|
114 | + for (const w of Services.ww.getWindowEnumerator()) {
|
|
115 | + initWindow(w);
|
|
116 | + }
|
|
117 | + Services.ww.registerNotification((win, event) => {
|
|
118 | + switch (event) {
|
|
119 | + case "domwindowopened":
|
|
120 | + initWindow(win);
|
|
121 | + break;
|
|
122 | + case "domwindowclosed":
|
|
123 | + handleActivation(win, false);
|
|
124 | + if (
|
|
125 | + this._isPrivateClipboard &&
|
|
126 | + lazy.PrivateBrowsingUtils.isWindowPrivate(win) &&
|
|
127 | + (this._shuttingDown ||
|
|
128 | + !Array.from(Services.ww.getWindowEnumerator()).find(
|
|
129 | + w =>
|
|
130 | + lazy.PrivateBrowsingUtils.isWindowPrivate(w) &&
|
|
131 | + // We need to filter out the HIDDEN WebExtensions window,
|
|
132 | + // which might be private as well but is not UI-relevant.
|
|
133 | + !w.location.href.startsWith("chrome://extensions/")
|
|
134 | + ))
|
|
135 | + ) {
|
|
136 | + // no more private windows, empty private content if needed
|
|
137 | + this.emptyPrivate();
|
|
138 | + }
|
|
139 | + }
|
|
140 | + });
|
|
141 | + |
|
142 | + lazy.AsyncShutdown.quitApplicationGranted.addBlocker(
|
|
143 | + "ClipboardPrivacy: removing private data",
|
|
144 | + () => {
|
|
145 | + this._shuttingDown = true;
|
|
146 | + this.emptyPrivate();
|
|
147 | + }
|
|
148 | + );
|
|
149 | + },
|
|
150 | + emptyPrivate() {
|
|
151 | + if (
|
|
152 | + this._isPrivateClipboard &&
|
|
153 | + !Services.prefs.getBoolPref(
|
|
154 | + "browser.privatebrowsing.preserveClipboard",
|
|
155 | + false
|
|
156 | + ) &&
|
|
157 | + this._lastClipboardHash === this._computeClipboardHash()
|
|
158 | + ) {
|
|
159 | + // nsIClipboard.emptyClipboard() does nothing in Wayland:
|
|
160 | + // we'll set an empty string as a work-around.
|
|
161 | + const trans = this._createTransferable();
|
|
162 | + const flavor = "text/plain";
|
|
163 | + trans.addDataFlavor(flavor);
|
|
164 | + const emptyString = Cc["@mozilla.org/supports-string;1"].createInstance(
|
|
165 | + Ci.nsISupportsString
|
|
166 | + );
|
|
167 | + emptyString.data = "";
|
|
168 | + trans.setTransferData(flavor, emptyString);
|
|
169 | + const { clipboard } = Services,
|
|
170 | + { kGlobalClipboard } = clipboard;
|
|
171 | + clipboard.setData(trans, null, kGlobalClipboard);
|
|
172 | + clipboard.emptyClipboard(kGlobalClipboard);
|
|
173 | + this._lastClipboardHash = null;
|
|
174 | + this._isPrivateClipboard = false;
|
|
175 | + this._log.info("Private clipboard emptied.");
|
|
176 | + }
|
|
177 | + },
|
|
178 | +}; |
... | ... | @@ -136,12 +136,10 @@ EXTRA_JS_MODULES += [ |
136 | 136 | "PopupBlockerObserver.sys.mjs",
|
137 | 137 | "ProcessHangMonitor.sys.mjs",
|
138 | 138 | "Sanitizer.sys.mjs",
|
139 | - "SecurityLevelRestartNotification.sys.mjs",
|
|
140 | 139 | "SelectionChangedMenulist.sys.mjs",
|
141 | 140 | "SharingUtils.sys.mjs",
|
142 | 141 | "SiteDataManager.sys.mjs",
|
143 | 142 | "SitePermissions.sys.mjs",
|
144 | - "TorSettingsNotification.sys.mjs",
|
|
145 | 143 | "TorUIUtils.sys.mjs",
|
146 | 144 | "TransientPrefs.sys.mjs",
|
147 | 145 | "URILoadingHelper.sys.mjs",
|
... | ... | @@ -151,6 +149,9 @@ EXTRA_JS_MODULES += [ |
151 | 149 | |
152 | 150 | MOZ_SRC_FILES += [
|
153 | 151 | "ContextId.sys.mjs",
|
152 | + "ClipboardPrivacy.sys.mjs",
|
|
153 | + "SecurityLevelRestartNotification.sys.mjs",
|
|
154 | + "TorSettingsNotification.sys.mjs",
|
|
154 | 155 | ]
|
155 | 156 | |
156 | 157 | if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
|
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | const lazy = {};
|
6 | 6 | |
7 | 7 | ChromeUtils.defineESModuleGetters(lazy, {
|
8 | - OpaqueDrag: "resource://gre/modules/DragDropFilter.sys.mjs",
|
|
8 | + OpaqueDrag: "moz-src:///toolkit/modules/DragDropFilter.sys.mjs",
|
|
9 | 9 | });
|
10 | 10 | |
11 | 11 | // This component is used for handling dragover and drop of urls.
|
... | ... | @@ -12,7 +12,7 @@ const lazy = {}; |
12 | 12 | ChromeUtils.defineESModuleGetters(lazy, {
|
13 | 13 | Bookmarks: "resource://gre/modules/Bookmarks.sys.mjs",
|
14 | 14 | History: "resource://gre/modules/History.sys.mjs",
|
15 | - OpaqueDrag: "resource://gre/modules/DragDropFilter.sys.mjs",
|
|
15 | + OpaqueDrag: "moz-src:///toolkit/modules/DragDropFilter.sys.mjs",
|
|
16 | 16 | PlacesSyncUtils: "resource://gre/modules/PlacesSyncUtils.sys.mjs",
|
17 | 17 | Sqlite: "resource://gre/modules/Sqlite.sys.mjs",
|
18 | 18 | });
|
1 | 1 | category profile-after-change TorStartupService @torproject.org/tor-startup-service;1
|
2 | +category browser-first-window-ready resource://gre/modules/TorProviderBuilder.sys.mjs TorProviderBuilder.firstWindowLoaded |
... | ... | @@ -164,7 +164,6 @@ EXTRA_JS_MODULES += [ |
164 | 164 | "DateTimePickerPanel.sys.mjs",
|
165 | 165 | "DeferredTask.sys.mjs",
|
166 | 166 | "DomainFrontedRequests.sys.mjs",
|
167 | - "DragDropFilter.sys.mjs",
|
|
168 | 167 | "E10SUtils.sys.mjs",
|
169 | 168 | "EventEmitter.sys.mjs",
|
170 | 169 | "FileUtils.sys.mjs",
|
... | ... | @@ -220,6 +219,10 @@ EXTRA_JS_MODULES += [ |
220 | 219 | "WebChannel.sys.mjs",
|
221 | 220 | ]
|
222 | 221 | |
222 | +MOZ_SRC_FILES += [
|
|
223 | + "DragDropFilter.sys.mjs",
|
|
224 | +]
|
|
225 | + |
|
223 | 226 | if CONFIG["MOZ_ASAN_REPORTER"]:
|
224 | 227 | EXTRA_JS_MODULES += [
|
225 | 228 | "AsanReporter.sys.mjs",
|