tor-browser

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

commit 623dcff6d873596b7f7ce483738be031e85241d0
parent 0ac2f426113b56cea6794274afaec8483c707956
Author: Andrea Marchesini <amarchesini@mozilla.com>
Date:   Mon, 13 Oct 2025 21:56:18 +0000

Bug 1991982 - Documentation for the IPProtection feature, r=ip-protection-reviewers,fchasen

Differential Revision: https://phabricator.services.mozilla.com/D268437

Diffstat:
Mbrowser/components/ipprotection/IPProtectionHelpers.sys.mjs | 5+++++
Mbrowser/components/ipprotection/IPProtectionService.sys.mjs | 3+++
Abrowser/components/ipprotection/docs/Components.rst | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abrowser/components/ipprotection/docs/Preferences.rst | 36++++++++++++++++++++++++++++++++++++
Abrowser/components/ipprotection/docs/StateMachine.rst | 39+++++++++++++++++++++++++++++++++++++++
Abrowser/components/ipprotection/docs/index.rst | 18++++++++++++++++++
Mbrowser/components/ipprotection/moz.build | 2++
Mbrowser/docs/index.rst | 1+
8 files changed, 258 insertions(+), 0 deletions(-)

diff --git a/browser/components/ipprotection/IPProtectionHelpers.sys.mjs b/browser/components/ipprotection/IPProtectionHelpers.sys.mjs @@ -2,6 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/** + * Note: If you add or modify the list of helpers, make sure to update the + * corresponding documentation in the `docs` folder as well. + */ + const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { diff --git a/browser/components/ipprotection/IPProtectionService.sys.mjs b/browser/components/ipprotection/IPProtectionService.sys.mjs @@ -51,6 +51,9 @@ ChromeUtils.defineLazyGetter(lazy, "logConsole", function () { * Proxy is active. * @property {string} ERROR * Error + * + * Note: If you update this list of states, make sure to update the + * corresponding documentation in the `docs` folder as well. */ export const IPProtectionStates = Object.freeze({ UNINITIALIZED: "uninitialized", diff --git a/browser/components/ipprotection/docs/Components.rst b/browser/components/ipprotection/docs/Components.rst @@ -0,0 +1,154 @@ +Components +========== + +This page summarizes the main components and how to extend the system safely. + +Component Diagram +----------------- + +A diagram of all the main components is the following: + +.. mermaid:: + :align: center + :caption: IP Protection architecture + + flowchart TD + + IPProtectionService + + Helpers["IPProtectionHelpers"] + + %% UI + subgraph UI + IPProtection + IPProtectionPanel + IPPExceptionsManager + end + + %% Helpers + subgraph Helpers + IPPStartupCache["Startup Cache Helper"] + IPPSignInWatcher["Sign-in Observer"] + UIHelper["UI Helper"] + AccountResetHelper["Account Reset Helper"] + VPNAddonHelper["VPN Add-on Helper"] + EligibilityHelper["Nimbus Eligibility Helper"] + IPPAutoStart["Auto-Start Helper"] + IPPEarlyStartupFilter["Early Startup Filter Helper"] + end + + %% Proxy stack + subgraph Proxy + IPPProxyManager + IPPChannelFilter + IPProtectionUsage + IPPNetworkErrorObserver + IPProtectionServerlist + GuardianClient + end + + %% Service wiring + IPProtectionService --> IPPProxyManager + IPProtectionService --> GuardianClient + IPProtectionService --> Helpers + + %% UI wiring + IPProtection --> IPProtectionPanel + IPProtection --> IPProtectionService + + %% Proxy wiring + IPPProxyManager --> GuardianClient + IPPProxyManager --> IPPChannelFilter + IPPProxyManager --> IPProtectionUsage + IPPProxyManager --> IPPNetworkErrorObserver + IPPProxyManager --> IPProtectionServerlist + IPPNetworkErrorObserver -- "error events (401)" --> IPPProxyManager + + +GuardianClient + Manages communication between Firefox and the Guardian backend. It retrieves + account information, obtains the token for the proxy, and exposes the server list. + +IPPChannelFilter + Main network component. It processes network requests and decides which ones + should go through the proxy. + +IPPProxyManager + Implements the proxy activation/deactivation and exposes the current status. + +IPProtectionPanel + Controls the feature’s panel UI. + +IPPExceptionsManager + Manages the exceptions UI and logic (for example, domain exclusions and + exceptions mode) in coordination with the panel and preferences. + +IPProtectionService + The main service. It is initialized during browser startup, initializes helpers + and other components, and implements the state machine that drives the feature. + +IPProtection + Manages the UI integration and interactions with the panel. + +Additional proxy/telemetry components +------------------------------------- + +IPProtectionServerlist + Provides the available proxy endpoints (server list) to the proxy manager. + +IPProtectionUsage + Gathers usage information and telemetry related to proxy activity. + +IPPNetworkErrorObserver + Observes network errors related to the proxy and notifies the proxy manager + (for example, authentication or connectivity failures). + +Helper objects +-------------- + +The list of helpers lives in ``IPProtectionHelpers.sys.mjs`` and is exported +as the ``IPPHelpers`` array. Helpers implement small, self‑contained behaviors +and listen to service events when needed. + +IPPAutoStart + Activates the proxy at startup time when auto‑start is enabled. + +IPPSignInWatcher + Observes user authentication state. It informs the state machine when the user + signs in or out. + +IPPStartupCache + Exposes cached information to keep the state machine responsive during startup + (last known state and entitlement JSON object). + +UIHelper + Shows and hides the UI based on the current state machine state. + +AccountResetHelper + Resets stored account information and stops the proxy when the account becomes + unavailable. + +VPNAddonHelper + Monitors the installation of the Mozilla VPN add‑on and removes the UI when + appropriate. + +EligibilityHelper + Monitors the Nimbus experiment flag and triggers state updates when it changes. + +How to implement new components +------------------------------- + +Do not modify the state machine. New functionality should be added via helper +classes to keep the core simple and robust. + +Recommended steps: + +1. Create a helper class with the methods ``init()``, ``initOnStartupCompleted()`` + and ``uninit()`` as appropriate for lifecycle needs. +2. If your helper reacts to state changes, listen to the + ``IPProtectionService:StateChanged`` event. +3. Add your helper to the ``IPPHelpers`` array in ``IPProtectionHelpers.sys.mjs``. + Be mindful of ordering if your helper depends on others (e.g. Nimbus + eligibility is registered last to avoid premature updates). +4. If your component needs to trigger a recomputation, call + ``IPProtectionService.updateState``. diff --git a/browser/components/ipprotection/docs/Preferences.rst b/browser/components/ipprotection/docs/Preferences.rst @@ -0,0 +1,36 @@ +Preferences +=========== + +This document describes preferences affecting Firefox's IP Protection. +These preferences are normally hidden and should not be used unless you really +know what you are doing. + +``browser.ipProtection.enabled`` (boolean, default: ``false``) + Controls the entire feature. + +``browser.ipProtection.autoStartEnabled`` (boolean, default: ``false``) + Enables the auto‑start feature. + +``browser.ipProtection.log`` (boolean, default: ``false``) + Enable/disable logging. + +``browser.ipProtection.stateCache`` (string, default: ``""``) + Caches the latest ``IPProtectionStates`` value for use during startup. + +``browser.ipProtection.entitlementCache`` (string, default: ``""``) + Cached entitlement JSON string used during startup to avoid network requests. + +``browser.ipProtection.cacheDisabled`` (boolean, default: ``false``) + For testing; disables caching of the entitlement and the state. + +``browser.ipProtection.guardian.endpoint`` (string, default: ``"https://vpn.mozilla.org/"``) + Endpoint for the server‑side infrastructure. + +``browser.ipProtection.exceptionsMode`` (string, default: ``"all"``) + Defines which network requests are processed. Default: all. + +``browser.ipProtection.domainExclusions`` (string) + Comma‑separated list of domains to exclude from the proxy. + +``browser.ipProtection.userEnabled`` (boolean, default: ``false``) + For testing; simulates user‑enabled state. diff --git a/browser/components/ipprotection/docs/StateMachine.rst b/browser/components/ipprotection/docs/StateMachine.rst @@ -0,0 +1,39 @@ +State Machine +============= + +The finite state machine is implemented in the ``IPProtectionService`` class +and the states are defined in the ``IPProtectionStates`` object. + +States +------ + +The service transitions across the following states: + +- ``UNINITIALIZED``: Service not initialized or feature disabled. +- ``UNAVAILABLE``: User not eligible (Nimbus) or signed out with no eligibility; UI hidden. +- ``UNAUTHENTICATED``: User signed out but eligible; UI shows login. +- ``ENROLLING``: User signed in and eligible; enrollment in progress. +- ``READY``: Ready to activate the proxy. +- ``ACTIVE``: Proxy is active. +- ``ERROR``: An error occurred (see ``IPProtectionService.errors``). + +High‑level transitions +---------------------- + +- Feature disabled → ``UNINITIALIZED``. +- During startup, if initialization isn’t complete, use cached state from ``IPPStartupCache``. +- Not signed in → ``UNAVAILABLE`` if not eligible, otherwise ``UNAUTHENTICATED``. +- Proxy already active → ``ACTIVE``. +- If an entitlement is cached/valid → ``READY``. +- Otherwise, check enrollment with Guardian: + - Not enrolled → ``UNAVAILABLE`` (not eligible) or ``ENROLLING`` (eligible). + - Enrolled → fetch entitlement; if successful → ``READY``, else ``UNAVAILABLE`` when not eligible. + +Events and integration points +----------------------------- + +- ``IPProtectionService:StateChanged`` is dispatched on state changes with + ``detail.state`` and ``detail.prevState``. +- Helpers can call ``IPProtectionService.updateState()`` to request a recomputation. +- Public actions: ``start(userAction)``, ``stop(userAction)``, ``maybeEnroll()``, + ``resetAccount()``, and ``startLoginFlow(browser)``. diff --git a/browser/components/ipprotection/docs/index.rst b/browser/components/ipprotection/docs/index.rst @@ -0,0 +1,18 @@ +IP Protection +============= + +This document describes the implementation of the IP Protection feature in Firefox. + +The code lives in `browser/components/ipprotection` and is composed of three major areas: + + * A finite-state machine managed by the main component: `IPProtectionService`. + * The UI, controlled by `IPProtection` and `IPProtectionPanel`. + * The proxy/network controller: `IPPProxyManager` and helper classes. + +See the following pages for details on components, preferences, and the state machine. + +.. toctree:: + + Components + Preferences + StateMachine diff --git a/browser/components/ipprotection/moz.build b/browser/components/ipprotection/moz.build @@ -30,3 +30,5 @@ BROWSER_CHROME_MANIFESTS += [ "tests/browser/browser.toml", ] XPCSHELL_TESTS_MANIFESTS += ["tests/xpcshell/xpcshell.toml"] + +SPHINX_TREES["/browser/ipprotection"] = "docs" diff --git a/browser/docs/index.rst b/browser/docs/index.rst @@ -27,6 +27,7 @@ This is the nascent documentation of the Firefox front-end code. places/index components/asrouter/docs/index search/index + ipprotection/index base/tabbrowser/index touchbar/index components/uitour/docs/index