From 79e9ebd4d78cf921884e4b49ce88c74a4f8e3322 Mon Sep 17 00:00:00 2001 From: Alex Catarineu Date: Thu, 5 Mar 2020 22:16:39 +0100 Subject: [PATCH] Bug 21952: Implement Onion-Location Whenever a valid Onion-Location HTTP header (or corresponding HTML http-equiv attribute) is found in a document load, we either redirect to it (if the user opted-in via preference) or notify the presence of an onionsite alternative with a badge in the urlbar. --- browser/base/content/browser.js | 12 ++ browser/base/content/browser.xul | 3 + browser/components/BrowserGlue.jsm | 10 ++ .../onionservices/OnionLocationChild.jsm | 43 +++++ .../onionservices/OnionLocationParent.jsm | 161 ++++++++++++++++++ .../onionlocation-notification-icons.css | 5 + .../content/onionlocation-urlbar.css | 27 +++ .../content/onionlocation-urlbar.inc.xul | 10 ++ .../onionservices/content/onionlocation.svg | 3 + .../content/onionlocationPreferences.inc.xul | 11 ++ .../content/onionlocationPreferences.js | 31 ++++ browser/components/onionservices/jar.mn | 2 + browser/components/onionservices/moz.build | 5 + .../preferences/in-content/privacy.js | 17 ++ .../preferences/in-content/privacy.xul | 2 + browser/modules/TorStrings.jsm | 39 +++++ .../themes/shared/notification-icons.inc.css | 2 + .../themes/shared/urlbar-searchbar.inc.css | 2 + dom/base/Document.cpp | 32 +++- dom/base/Document.h | 2 + dom/webidl/Document.webidl | 9 + modules/libpref/init/StaticPrefList.h | 7 + xpcom/ds/StaticAtoms.py | 1 + 23 files changed, 435 insertions(+), 1 deletion(-) create mode 100644 browser/components/onionservices/OnionLocationChild.jsm create mode 100644 browser/components/onionservices/OnionLocationParent.jsm create mode 100644 browser/components/onionservices/content/onionlocation-notification-icons.css create mode 100644 browser/components/onionservices/content/onionlocation-urlbar.css create mode 100644 browser/components/onionservices/content/onionlocation-urlbar.inc.xul create mode 100644 browser/components/onionservices/content/onionlocation.svg create mode 100644 browser/components/onionservices/content/onionlocationPreferences.inc.xul create mode 100644 browser/components/onionservices/content/onionlocationPreferences.js diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 3f9bf006f5626..410c8f62d0efd 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -43,6 +43,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { NetUtil: "resource://gre/modules/NetUtil.jsm", NewTabUtils: "resource://gre/modules/NewTabUtils.jsm", OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm", + OnionLocationParent: "resource:///modules/OnionLocationParent.jsm", PageActions: "resource:///modules/PageActions.jsm", PageThumbs: "resource://gre/modules/PageThumbs.jsm", PanelMultiView: "resource:///modules/PanelMultiView.jsm", @@ -5934,6 +5935,7 @@ var XULBrowserWindow = { Services.obs.notifyObservers(null, "touchbar-location-change", location); UpdateBackForwardCommands(gBrowser.webNavigation); ReaderParent.updateReaderButton(gBrowser.selectedBrowser); + OnionLocationParent.updateOnionLocationBadge(gBrowser.selectedBrowser); if (!gMultiProcessBrowser) { // Bug 1108553 - Cannot rotate images with e10s @@ -6581,6 +6583,16 @@ var TabsProgressListener = { }, onStateChange(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) { + // Clear OnionLocation UI + if ( + aStateFlags & Ci.nsIWebProgressListener.STATE_START && + aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK && + aRequest && + aWebProgress.isTopLevel + ) { + OnionLocationParent.onStateChange(aBrowser); + } + // Collect telemetry data about tab load times. if ( aWebProgress.isTopLevel && diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index d2f72eea8edb9..4309a0b712283 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -992,6 +992,9 @@ onclick="FullZoom.reset();" tooltip="dynamic-shortcut-tooltip" hidden="true"/> + +#include ../../components/onionservices/content/onionlocation-urlbar.inc.xul + {}, + }; + + const options = { + autofocus: true, + persistent: true, + removeOnDismissal: false, + eventCallback(aTopic) { + if (aTopic === "removed") { + delete browser._onionLocationPrompt; + delete browser.onionpopupnotificationanchor; + } + }, + learnMoreURL: NOTIFICATION_LEARN_MORE_URL, + displayURI: { + hostPort: NOTIFICATION_TITLE, // This is hacky, but allows us to have a title without extra markup/css. + }, + hideClose: true, + popupIconClass: "onionlocation-notification-icon", + }; + + // A hacky way of setting the popup anchor outside the usual url bar icon box + // onionlocationpopupnotificationanchor comes from `${ANCHOR_ID}popupnotificationanchor` + // From https://searchfox.org/mozilla-esr68/rev/080f9ed47742644d2ff84f7aa0b10aea5c44301a/browser/components/newtab/lib/CFRPageActions.jsm#488 + browser.onionlocationpopupnotificationanchor = win.document.getElementById( + ONIONLOCATION_BUTTON_ID + ); + + browser._onionLocationPrompt = win.PopupNotifications.show( + browser, + NOTIFICATION_ID, + NOTIFICATION_DESCRIPTION, + NOTIFICATION_ANCHOR_ID, + mainAction, + [cancelAction], + options + ); + }, + + setEnabled(browser) { + const win = browser.ownerGlobal; + const label = win.document.getElementById(ONIONLOCATION_LABEL_ID); + label.textContent = STRING_ONION_AVAILABLE; + const elem = win.document.getElementById(ONIONLOCATION_BOX_ID); + elem.removeAttribute("hidden"); + }, + + setDisabled(browser) { + const win = browser.ownerGlobal; + const elem = win.document.getElementById(ONIONLOCATION_BOX_ID); + elem.setAttribute("hidden", true); + }, + + updateOnionLocationBadge(browser) { + if (browser._onionLocation) { + this.setEnabled(browser); + this.showNotification(browser); + } else { + this.setDisabled(browser); + } + }, +}; diff --git a/browser/components/onionservices/content/onionlocation-notification-icons.css b/browser/components/onionservices/content/onionlocation-notification-icons.css new file mode 100644 index 0000000000000..7c8a6d892c6ff --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-notification-icons.css @@ -0,0 +1,5 @@ +/* Copyright (c) 2020, The Tor Project, Inc. */ + +.onionlocation-notification-icon { + display: none; +} \ No newline at end of file diff --git a/browser/components/onionservices/content/onionlocation-urlbar.css b/browser/components/onionservices/content/onionlocation-urlbar.css new file mode 100644 index 0000000000000..91cad5f178d14 --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-urlbar.css @@ -0,0 +1,27 @@ +/* Copyright (c) 2020, The Tor Project, Inc. */ + +#onion-location-button { + list-style-image: url(chrome://browser/content/onionservices/onionlocation.svg); +} + +#onion-location-box { + border-radius: 3px; + background-color: #6200A4; + padding-left: 5px; + padding-right: 5px; + color: white; + -moz-context-properties: fill; + fill: white; +} + +#onion-location-box:hover { + background-color: #0060DF !important; +} + +toolbar[brighttext] #onion-location-box { + background-color: #9400ff; +} + +toolbar[brighttext] #onion-location-box:hover { + background-color: #0060DF !important; +} diff --git a/browser/components/onionservices/content/onionlocation-urlbar.inc.xul b/browser/components/onionservices/content/onionlocation-urlbar.inc.xul new file mode 100644 index 0000000000000..b612a4236f3cf --- /dev/null +++ b/browser/components/onionservices/content/onionlocation-urlbar.inc.xul @@ -0,0 +1,10 @@ +# Copyright (c) 2020, The Tor Project, Inc. + + diff --git a/browser/components/onionservices/content/onionlocation.svg b/browser/components/onionservices/content/onionlocation.svg new file mode 100644 index 0000000000000..37f40ac1812f8 --- /dev/null +++ b/browser/components/onionservices/content/onionlocation.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/browser/components/onionservices/content/onionlocationPreferences.inc.xul b/browser/components/onionservices/content/onionlocationPreferences.inc.xul new file mode 100644 index 0000000000000..c386316c98dca --- /dev/null +++ b/browser/components/onionservices/content/onionlocationPreferences.inc.xul @@ -0,0 +1,11 @@ +# Copyright (c) 2020, The Tor Project, Inc. + + + + + + + + + diff --git a/browser/components/onionservices/content/onionlocationPreferences.js b/browser/components/onionservices/content/onionlocationPreferences.js new file mode 100644 index 0000000000000..aa569b54721cd --- /dev/null +++ b/browser/components/onionservices/content/onionlocationPreferences.js @@ -0,0 +1,31 @@ +// Copyright (c) 2020, The Tor Project, Inc. + +"use strict"; + +ChromeUtils.defineModuleGetter( + this, + "TorStrings", + "resource:///modules/TorStrings.jsm" +); + +const OnionLocationPreferences = { + init() { + document.getElementById("onionServicesTitle").textContent = + TorStrings.onionLocation.onionServicesTitle; + document.getElementById("prioritizeOnionsDesc").textContent = + TorStrings.onionLocation.prioritizeOnionsDescription; + const learnMore = document.getElementById("onionServicesLearnMore"); + learnMore.textContent = TorStrings.onionLocation.learnMore; + learnMore.href = TorStrings.onionLocation.learnMoreURL; + document.getElementById("onionServicesRadioAlways").label = + TorStrings.onionLocation.always; + document.getElementById("onionServicesRadioAsk").label = + TorStrings.onionLocation.askEverytime; + }, +}; + +Object.defineProperty(this, "OnionLocationPreferences", { + value: OnionLocationPreferences, + enumerable: true, + writable: false, +}); diff --git a/browser/components/onionservices/jar.mn b/browser/components/onionservices/jar.mn index 1272d5dc9b6a3..654e05e894a3d 100644 --- a/browser/components/onionservices/jar.mn +++ b/browser/components/onionservices/jar.mn @@ -7,3 +7,5 @@ browser.jar: content/browser/onionservices/onionservices.css (content/onionservices.css) content/browser/onionservices/savedKeysDialog.js (content/savedKeysDialog.js) content/browser/onionservices/savedKeysDialog.xul (content/savedKeysDialog.xul) + content/browser/onionservices/onionlocationPreferences.js (content/onionlocationPreferences.js) + content/browser/onionservices/onionlocation.svg (content/onionlocation.svg) diff --git a/browser/components/onionservices/moz.build b/browser/components/onionservices/moz.build index 7e103239c8d67..bf276c4a3c4cc 100644 --- a/browser/components/onionservices/moz.build +++ b/browser/components/onionservices/moz.build @@ -1 +1,6 @@ JAR_MANIFESTS += ['jar.mn'] + +EXTRA_JS_MODULES += [ + 'OnionLocationChild.jsm', + 'OnionLocationParent.jsm', +] diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js index ee86b4158d7ce..015ee77932b7f 100644 --- a/browser/components/preferences/in-content/privacy.js +++ b/browser/components/preferences/in-content/privacy.js @@ -75,6 +75,12 @@ XPCOMUtils.defineLazyScriptGetter( "chrome://browser/content/securitylevel/securityLevel.js" ); +XPCOMUtils.defineLazyScriptGetter( + this, + ["OnionLocationPreferences"], + "chrome://browser/content/onionservices/onionlocationPreferences.js" +); + XPCOMUtils.defineLazyServiceGetter( this, "listManager", @@ -124,6 +130,9 @@ Preferences.addAll([ // Do not track { id: "privacy.donottrackheader.enabled", type: "bool" }, + // Onion Location + { id: "privacy.prioritizeonions.enabled", type: "bool" }, + // Media { id: "media.autoplay.default", type: "int" }, @@ -250,6 +259,13 @@ var gPrivacyPane = { window.addEventListener("unload", unload); }, + /** + * Show the OnionLocation preferences UI + */ + _initOnionLocation() { + OnionLocationPreferences.init(); + }, + /** * Whether the prompt to restart Firefox should appear when changing the autostart pref. */ @@ -377,6 +393,7 @@ var gPrivacyPane = { this._initTrackingProtectionExtensionControl(); OnionServicesAuthPreferences.init(); this._initSecurityLevel(); + this._initOnionLocation(); Services.telemetry.setEventRecordingEnabled("pwmgr", true); diff --git a/browser/components/preferences/in-content/privacy.xul b/browser/components/preferences/in-content/privacy.xul index e807ac69f1f17..05c4966a1e595 100644 --- a/browser/components/preferences/in-content/privacy.xul +++ b/browser/components/preferences/in-content/privacy.xul @@ -15,6 +15,8 @@ +#include ../../onionservices/content/onionlocationPreferences.inc.xul +