326 lines
10 KiB
Markdown
326 lines
10 KiB
Markdown
# Components
|
|
|
|
This page summarizes the main components and how to extend the system safely.
|
|
|
|
The implementation is split across three layers:
|
|
|
|
- `toolkit/components/ipprotection` — platform-independent core (state machine,
|
|
proxy/network stack, core helpers).
|
|
- `browser/components/ipprotection` — desktop-specific UI layer (panel, toolbar
|
|
button, alert/infobar managers, and onboarding helpers).
|
|
- `mobile/shared/modules/geckoview/` — Android GeckoView entry point.
|
|
|
|
## Component Diagram
|
|
|
|
A diagram of all the main components is the following:
|
|
|
|
```{mermaid}
|
|
:align: center
|
|
:caption: IP Protection architecture
|
|
|
|
---
|
|
config:
|
|
flowchart:
|
|
defaultRenderer: "elk"
|
|
---
|
|
flowchart LR
|
|
|
|
%% browser/components/ipprotection
|
|
subgraph Browser["browser/components/ipprotection (UI layer)"]
|
|
IPProtection
|
|
IPProtectionPanel
|
|
|
|
subgraph BrowserHelpers["Browser Helpers"]
|
|
UIHelper["UI Helper"]
|
|
IPPOnboardingMessage["Onboarding Message"]
|
|
IPPOptOutHelper["Opt-Out Helper"]
|
|
IPPUsageHelper["Usage Helper"]
|
|
IPProtectionAlertManager["Alert Manager"]
|
|
IPProtectionInfobarManager["Infobar Manager"]
|
|
end
|
|
end
|
|
|
|
%% toolkit/components/ipprotection
|
|
subgraph Toolkit["toolkit/components/ipprotection (core)"]
|
|
IPProtectionService
|
|
IPProtectionActivator
|
|
|
|
subgraph CoreHelpers["Core Helpers"]
|
|
IPPStartupCache["Startup Cache Helper"]
|
|
IPProtectionServerlist
|
|
IPPProxyManager
|
|
IPPAutoStart["Auto-Start Helper"]
|
|
IPPAutoRestoreHelper["Auto-Restore Helper"]
|
|
IPPNimbusHelper["Nimbus Eligibility Helper"]
|
|
IPPSessionPrefManager["Session Pref Manager"]
|
|
IPPExceptionsManager
|
|
end
|
|
|
|
subgraph FxaAuth["FxA Authentication (fxa/)"]
|
|
IPPAuthProvider
|
|
IPPFxaActivateAuthProvider["Activate Auth Provider"]
|
|
IPPSignInWatcher["Sign-in Observer"]
|
|
GuardianClient
|
|
end
|
|
|
|
subgraph Proxy["Proxy stack"]
|
|
IPPChannelFilter
|
|
IPPNetworkErrorObserver
|
|
end
|
|
end
|
|
|
|
%% Android layer
|
|
subgraph Android["Android Glue"]
|
|
GeckoViewIPProtection
|
|
|
|
subgraph AndroidAuth["Android Authentication"]
|
|
IPPAndroidAuthProvider["Android FxA Auth Provider"]
|
|
IPPGpiAuthProvider["GPI Auth Provider"]
|
|
IPPAndroidSignInWatcher["Android Sign-in Observer"]
|
|
end
|
|
end
|
|
|
|
%% Activator wiring
|
|
BrowserHelpers -- "addHelpers()" --> IPProtectionActivator
|
|
IPProtectionActivator --> IPProtectionService
|
|
IPProtectionActivator --> CoreHelpers
|
|
IPProtectionActivator -- "setAuthProvider()" --> IPPFxaActivateAuthProvider
|
|
GeckoViewIPProtection -- "setAuthProvider()" --> IPProtectionActivator
|
|
|
|
%% Service wiring
|
|
IPProtectionService --> CoreHelpers
|
|
IPProtectionService -- "authProvider" --> IPPAuthProvider
|
|
|
|
%% FxA auth wiring
|
|
IPPFxaActivateAuthProvider -->|extends| IPPAuthProvider
|
|
IPPFxaActivateAuthProvider --> IPPSignInWatcher
|
|
IPPFxaActivateAuthProvider --> GuardianClient
|
|
|
|
%% Android auth wiring
|
|
IPPAndroidAuthProvider -->|extends| IPPFxaActivateAuthProvider
|
|
IPPAndroidAuthProvider --> IPPAndroidSignInWatcher
|
|
IPPGpiAuthProvider -->|extends| IPPAuthProvider
|
|
|
|
%% UI wiring
|
|
IPProtection --> IPProtectionPanel
|
|
IPProtection --> IPProtectionService
|
|
|
|
%% Proxy wiring
|
|
IPPProxyManager --> IPPChannelFilter
|
|
IPPProxyManager --> IPPNetworkErrorObserver
|
|
IPPNetworkErrorObserver -- "error events (401)" --> IPPProxyManager
|
|
```
|
|
|
|
## Toolkit components (`toolkit/components/ipprotection`)
|
|
|
|
GuardianClient
|
|
|
|
: HTTP client for the Guardian backend. Manages communication with Guardian to
|
|
retrieve account information, obtain proxy tokens, and run the FxA enrollment
|
|
flow.
|
|
|
|
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.
|
|
|
|
IPProtectionService
|
|
|
|
: The main service. It is initialized during browser startup, initializes helpers
|
|
and other components, and implements the state machine that drives the feature.
|
|
|
|
IPProtectionActivator
|
|
|
|
: Entry point that assembles the full helper list and initialises
|
|
`IPProtectionService`. It owns the ordered list of core helpers and exposes
|
|
`addHelpers()` so that the browser layer can register additional,
|
|
browser-specific helpers before `init()` is called. It also exposes
|
|
`setAuthProvider()` to set the active authentication provider.
|
|
|
|
IPPExceptionsManager
|
|
|
|
: Manages the exceptions logic (for example, domain exclusions) in coordination
|
|
with the panel and preferences.
|
|
|
|
### Additional proxy/telemetry components
|
|
|
|
IPProtectionServerlist
|
|
|
|
: Provides the available proxy endpoints (server list) to the proxy manager.
|
|
|
|
IPPNetworkErrorObserver
|
|
|
|
: Observes network errors related to the proxy and notifies the proxy manager
|
|
(for example, authentication or connectivity failures).
|
|
|
|
### Core helpers
|
|
|
|
The core helper list is defined in `IPProtectionActivator.sys.mjs` (toolkit).
|
|
|
|
IPPAutoStart
|
|
|
|
: Activates the proxy at startup time when auto-start is enabled.
|
|
|
|
IPPAutoRestoreHelper
|
|
|
|
: Restores the proxy state after a crash or restart when auto-restore is enabled.
|
|
|
|
IPPStartupCache
|
|
|
|
: Exposes cached information to keep the state machine responsive during startup
|
|
(last known state and entitlement JSON object).
|
|
|
|
IPPNimbusHelper
|
|
|
|
: Monitors the Nimbus feature (`NimbusFeatures.ipProtection`) and triggers a
|
|
state recomputation on updates.
|
|
|
|
### FxA authentication (`toolkit/components/ipprotection/fxa`)
|
|
|
|
Authentication is abstracted behind `IPPAuthProvider`, which lives in the
|
|
toolkit root. `IPProtectionService` always interacts with the provider through
|
|
this interface, so all FxA dependencies are fully contained in the `fxa/`
|
|
sub-directory. On desktop, the concrete provider and its helpers are registered
|
|
from `IPProtectionHelpers.sys.mjs` in the browser layer. On Android, the
|
|
selection is done by `GeckoViewIPProtection` at initialisation time (see below).
|
|
|
|
IPPAuthProvider
|
|
|
|
: Base class that defines the authentication interface used by
|
|
`IPProtectionService`. The default implementation is a no-op that keeps
|
|
the service in an unauthenticated/inactive state.
|
|
|
|
IPPFxaActivateAuthProvider
|
|
|
|
: Concrete FxA implementation of `IPPAuthProvider`. It obtains short-lived
|
|
OAuth tokens from `fxAccounts` via `getToken()`, passes them to
|
|
`GuardianClient` for all Guardian HTTP calls, and enrolls the user by sending
|
|
the FxA Bearer token directly to Guardian's activate endpoint, without using a
|
|
hidden tab or window.
|
|
|
|
IPPSignInWatcher
|
|
|
|
: Observes user authentication state. It informs the state machine when the
|
|
user signs in or out.
|
|
|
|
IPPSessionPrefManager
|
|
|
|
: Sets session-scoped preferences while the
|
|
proxy is active and resets them when it deactivates, preserving any
|
|
user-set values.
|
|
|
|
### Android authentication
|
|
|
|
On Android, two concrete `IPPAuthProvider` implementations are available and
|
|
selected at initialisation time by `GeckoViewIPProtection` based on the FxA
|
|
sign-in state stored in `toolkit.ipProtection.android.authProvider`.
|
|
|
|
IPPAndroidAuthProvider
|
|
|
|
: Android variant of the FxA provider. Extends `IPPFxaActivateAuthProvider`
|
|
and uses `IPPAndroidSignInWatcher` to track the FxA sign-in state.
|
|
|
|
IPPGpiAuthProvider
|
|
|
|
: Google Play Integrity implementation of `IPPAuthProvider`. Used when the
|
|
user is not signed into FxA. Obtains a short-lived GPI token from the Android
|
|
layer via `EventDispatcher` and exchanges it for an Auth JWT with Guardian.
|
|
The JWT is cached in `browser.ipProtection.gpi.authJwt` so that subsequent
|
|
proxy starts require no network requests.
|
|
|
|
IPPAndroidSignInWatcher
|
|
|
|
: Monitors the FxA sign-in state on Android by listening to
|
|
`IPP:AuthStateChanged` events from the Android layer. Exposes `isSignedIn`
|
|
and dispatches `IPPSignInWatcher:StateChanged` when the state changes.
|
|
|
|
## Android GeckoView entry point
|
|
|
|
GeckoViewIPProtection
|
|
|
|
: GeckoView module that owns the IP Protection lifecycle on Android. On
|
|
`GeckoView:IPProtection:Init` it reads the `toolkit.ipProtection.android.authProvider`
|
|
preference to determine which auth provider to activate: `IPPAndroidAuthProvider`
|
|
(with its FxA helpers) when the user is signed in, or `IPPGpiAuthProvider`
|
|
otherwise. When the FxA sign-in state changes the Android layer clears the
|
|
preference and calls `Uninit` followed by `Init` so that the correct
|
|
provider is selected again.
|
|
|
|
## Browser components (`browser/components/ipprotection`)
|
|
|
|
IPProtection
|
|
|
|
: Manages the UI integration and interactions with the panel.
|
|
|
|
IPProtectionPanel
|
|
|
|
: Controls the feature's panel UI.
|
|
|
|
IPProtectionHelpers
|
|
|
|
: Registers browser-specific helpers with `IPProtectionActivator` via
|
|
`addHelpers()`: `UIHelper`, `IPPOnboardingMessage`, `IPPOptOutHelper`,
|
|
`IPPUsageHelper`, `IPProtectionAlertManager`, and `IPProtectionInfobarManager`.
|
|
It also registers `IPPFxaActivateAuthProvider` (and its FxA helpers) via
|
|
`setAuthProvider()` and `addHelpers()`.
|
|
|
|
UIHelper
|
|
|
|
: Shows and hides the UI based on the current state machine state.
|
|
|
|
IPPOptOutHelper
|
|
|
|
: Handles the user opt-out flow and clears stored state accordingly.
|
|
|
|
IPPOnboardingMessage
|
|
|
|
: Handles the onboarding message flow for new users.
|
|
|
|
IPPUsageHelper
|
|
|
|
: Tracks bandwidth usage warning state and fires state-change events when
|
|
usage crosses the 75% or 90% thresholds.
|
|
|
|
IPProtectionAlertManager
|
|
|
|
: Manages alert notifications related to IP Protection.
|
|
|
|
IPProtectionInfobarManager
|
|
|
|
: Manages infobar notifications displayed to the user.
|
|
|
|
## 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. Decide whether the helper belongs in the **toolkit** layer (no UI, no chrome
|
|
dependency) or the **browser** layer (UI or chrome integration required).
|
|
|
|
2. Create a helper class with the methods `init()`, `initOnStartupCompleted()`
|
|
and `uninit()` as appropriate for lifecycle needs.
|
|
|
|
3. If your helper reacts to state changes, listen to the
|
|
`IPProtectionService:StateChanged` event.
|
|
|
|
4. Register your helper:
|
|
|
|
- **Toolkit helpers**: add it to the `coreHelpers` array in
|
|
`toolkit/components/ipprotection/IPProtectionActivator.sys.mjs`.
|
|
- **Browser helpers**: call `IPProtectionActivator.addHelpers([...])` in
|
|
`browser/components/ipprotection/IPProtectionHelpers.sys.mjs`.
|
|
|
|
Be mindful of ordering if your helper depends on others. For example,
|
|
`IPPNimbusHelper` is registered last to avoid premature state updates
|
|
triggered by Nimbus' immediate callback.
|
|
|
|
5. If your component needs to recompute the service state, call
|
|
`IPProtectionService.updateState()` after updating the helper data it
|
|
relies on; the recomputation is synchronous.
|