Revision control

Copy as Markdown

// # Firefox Accounts Client
//
// The fxa-client component lets applications integrate with the
// identity service. The shape of a typical integration would look
// something like:
//
// * Out-of-band, register your application with the Firefox Accounts service,
// providing an OAuth `redirect_uri` controlled by your application and
// obtaining an OAuth `client_id`.
//
// * On application startup, create a [`FirefoxAccount`] object to represent the
// signed-in state of the application.
// * On first startup, a new [`FirefoxAccount`] can be created by calling
// [`FirefoxAccount::new`] and passing the application's `client_id`.
// * For subsequent startups the object can be persisted using the
// [`to_json`](FirefoxAccount::to_json) method and re-created by
// calling [`FirefoxAccount::from_json`].
//
// * When the user wants to sign in to your application, direct them through
// a web-based OAuth flow using [`begin_oauth_flow`](FirefoxAccount::begin_oauth_flow)
// or [`begin_pairing_flow`](FirefoxAccount::begin_pairing_flow); when they return
// to your registered `redirect_uri`, pass the resulting authorization state back to
// [`complete_oauth_flow`](FirefoxAccount::complete_oauth_flow) to sign them in.
//
// * Display information about the signed-in user by using the data from
// [`get_profile`](FirefoxAccount::get_profile).
//
// * Access account-related services on behalf of the user by obtaining OAuth
// access tokens via [`get_access_token`](FirefoxAccount::get_access_token).
//
// * If the user opts to sign out of the application, calling [`disconnect`](FirefoxAccount::disconnect)
// and then discarding any persisted account data.
[External="sync15"]
typedef extern DeviceType;
namespace fxa_client {
};
// Generic error type thrown by many [`FirefoxAccount`] operations.
//
// Precise details of the error are hidden from consumers, mostly due to limitations of
// how we expose this API to other languages. The type of the error indicates how the
// calling code should respond.
//
[Error]
enum FxaError {
// Thrown when there was a problem with the authentication status of the account,
// such as an expired token. The application should [check its authorization status](
// FirefoxAccount::check_authorization_status) to see whether it has been disconnected,
// or retry the operation with a freshly-generated token.
"Authentication",
// Thrown if an operation fails due to network access problems.
// The application may retry at a later time once connectivity is restored.
"Network",
// Thrown if the application attempts to complete an OAuth flow when no OAuth flow has been initiated for that state.
// This may indicate a user who navigated directly to the OAuth `redirect_uri` for the application.
"NoExistingAuthFlow",
// Thrown if the application attempts to complete an OAuth flow, but the state
// tokens returned from the Firefox Account server do not match with the ones
// expected by the client.
// This may indicate a stale OAuth flow, or potentially an attempted hijacking
// of the flow by an attacker. The signin attempt cannot be completed.
//
// **Note:** This error is currently only thrown in the Swift language bindings.
"WrongAuthFlow",
// Origin mismatch when handling a pairing flow
//
// The most likely cause of this is that a user tried to pair together two firefox instances
// that are configured to use different servers.
"OriginMismatch",
// The sync scoped key was missing in the server response
"SyncScopedKeyMissingInServerResponse",
// Thrown if there is a panic in the underlying Rust code.
//
// **Note:** This error is currently only thrown in the Kotlin language bindings.
"Panic",
// A catch-all for other unspecified errors.
"Other",
};
// Object representing the signed-in state of an application.
//
// The `FirefoxAccount` object is the main interface provided by this crate.
// It represents the signed-in state of an application that may be connected to
// user's Firefox Account, and provides methods for inspecting the state of the
// account and accessing other services on behalf of the user.
//
interface FirefoxAccount {
// Create a new [`FirefoxAccount`] instance, not connected to any account.
//
// **💾 This method alters the persisted account state.**
//
// This method constructs as new [`FirefoxAccount`] instance configured to connect
// the application to a user's account.
constructor(FxaConfig config);
// Restore a [`FirefoxAccount`] instance from serialized state.
//
// Given a JSON string previously obtained from [`FirefoxAccount::to_json`], this
// method will deserialize it and return a live [`FirefoxAccount`] instance.
//
// **⚠️ Warning:** since the serialized state contains access tokens, you should
// not call `from_json` multiple times on the same data. This would result
// in multiple live objects sharing the same access tokens and is likely to
// produce unexpected behaviour.
//
[Throws=FxaError,Name=from_json]
constructor([ByRef] string data);
// Save current state to a JSON string.
//
// This method serializes the current account state into a JSON string, which
// the application can use to persist the user's signed-in state across restarts.
// The application should call this method and update its persisted state after
// any potentially-state-changing operation.
//
// **⚠️ Warning:** the serialized state may contain encryption keys and access
// tokens that let anyone holding them access the user's data in Firefox Sync
// and/or other FxA services. Applications should take care to store the resulting
// data in a secure fashion, as appropriate for their target platform.
//
[Throws=FxaError]
string to_json();
// Sets the users information based on the web content's login information
// This is intended to only be used by user agents (eg: Firefox) to set the users
// session token and tie it to the refresh token that will be issued at the end of the
// oauth flow.
void set_user_data(UserData user_data);
// Initiate a web-based OAuth sign-in flow.
//
// This method initializes some internal state and then returns a URL at which the
// user may perform a web-based authorization flow to connect the application to
// their account. The application should direct the user to the provided URL.
//
// When the resulting OAuth flow redirects back to the configured `redirect_uri`,
// the query parameters should be extracting from the URL and passed to the
// [`complete_oauth_flow`](FirefoxAccount::complete_oauth_flow) method to finalize
// the signin.
//
// # Arguments
//
// - `scopes` - list of OAuth scopes to request.
// - The requested scopes will determine what account-related data
// the application is able to access.
// - `entrypoint` - metrics identifier for UX entrypoint.
// - This parameter is used for metrics purposes, to identify the
// UX entrypoint from which the user triggered the signin request.
// For example, the application toolbar, on the onboarding flow.
// - `metrics` - optionally, additional metrics tracking paramters.
// - These will be included as query parameters in the resulting URL.
//
[Throws=FxaError]
string begin_oauth_flow([ByRef] sequence<string> scopes, [ByRef] string entrypoint);
// Get the URL at which to begin a device-pairing signin flow.
//
// If the user wants to sign in using device pairing, call this method and then
// direct them to visit the resulting URL on an already-signed-in device. Doing
// so will trigger the other device to show a QR code to be scanned, and the result
// from said QR code can be passed to [`begin_pairing_flow`](FirefoxAccount::begin_pairing_flow).
//
[Throws=FxaError]
string get_pairing_authority_url();
// Initiate a device-pairing sign-in flow.
//
// Once the user has scanned a pairing QR code, pass the scanned value to this
// method. It will return a URL to which the application should redirect the user
// in order to continue the sign-in flow.
//
// When the resulting flow redirects back to the configured `redirect_uri`,
// the resulting OAuth parameters should be extracting from the URL and passed
// to [`complete_oauth_flow`](FirefoxAccount::complete_oauth_flow) to finalize
// the signin.
//
// # Arguments
//
// - `pairing_url` - the URL scanned from a QR code on another device.
// - `scopes` - list of OAuth scopes to request.
// - The requested scopes will determine what account-related data
// the application is able to access.
// - `entrypoint` - metrics identifier for UX entrypoint.
// - This parameter is used for metrics purposes, to identify the
// UX entrypoint from which the user triggered the signin request.
// For example, the application toolbar, on the onboarding flow.
// - `metrics` - optionally, additional metrics tracking paramters.
// - These will be included as query parameters in the resulting URL.
//
[Throws=FxaError]
string begin_pairing_flow([ByRef] string pairing_url, [ByRef] sequence<string> scopes, [ByRef] string entrypoint);
// Complete an OAuth flow.
//
// **💾 This method alters the persisted account state.**
//
// At the conclusion of an OAuth flow, the user will be redirect to the
// application's registered `redirect_uri`. It should extract the `code`
// and `state` parameters from the resulting URL and pass them to this
// method in order to complete the sign-in.
//
// # Arguments
//
// - `code` - the OAuth authorization code obtained from the redirect URI.
// - `state` - the OAuth state parameter obtained from the redirect URI.
//
[Throws=FxaError]
void complete_oauth_flow([ByRef] string code, [ByRef] string state );
// Check authorization status for this application.
//
// **💾 This method alters the persisted account state.**
//
// Applications may call this method to check with the FxA server about the status
// of their authentication tokens. It returns an [`AuthorizationInfo`] struct
// with details about whether the tokens are still active.
//
[Throws=FxaError]
AuthorizationInfo check_authorization_status();
// Disconnect from the user's account.
//
// **💾 This method alters the persisted account state.**
//
// This method destroys any tokens held by the client, effectively disconnecting
// from the user's account. Applications should call this when the user opts to
// sign out.
//
// The persisted account state after calling this method will contain only the
// user's last-seen profile information, if any. This may be useful in helping
// the user to reconnnect to their account. If reconnecting to the same account
// is not desired then the application should discard the persisted account state.
//
void disconnect();
// Update the state based on authentication issues.
//
// **💾 This method alters the persisted account state.**
//
// Call this if you know there's an authentication / authorization issue that requires the
// user to re-authenticated. It transitions the user to the [FxaRustAuthState.AuthIssues] state.
void on_auth_issues();
// Get the high-level authentication state of the client
//
// Deprecated: Use get_state() instead
FxaRustAuthState get_auth_state();
// Get the current state
FxaState get_state();
// Process an event (login, logout, etc).
//
// On success, update the current state and return it.
// On error, the current state will remain the same.
[Throws=FxaError]
FxaState process_event(FxaEvent event);
// Get profile information for the signed-in user, if any.
//
// **💾 This method alters the persisted account state.**
//
// This method fetches a [`Profile`] struct with information about the currently-signed-in
// user, either by using locally-cached profile information or by fetching fresh data from
// the server.
//
// # Arguments
//
// - `ignore_cache` - if true, always hit the server for fresh profile information.
//
// # Notes
//
// - Profile information is only available to applications that have been
// granted the `profile` scope.
// - There is currently no API for fetching cached profile information without
// potentially hitting the server.
// - If there is no signed-in user, this method will throw an
// [`Authentication`](FxaError::Authentication) error.
//
[Throws=FxaError]
Profile get_profile( boolean ignore_cache );
// Create a new device record for this application.
//
// **💾 This method alters the persisted account state.**
//
// This method registed a device record for the application, providing basic metadata for
// the device along with a list of supported [Device Capabilities](DeviceCapability) for
// participating in the "device commands" ecosystem.
//
// Applications should call this method soon after a successful sign-in, to ensure
// they they appear correctly in the user's account-management pages and when discovered
// by other devices connected to the account.
//
// # Arguments
//
// - `name` - human-readable display name to use for this application
// - `device_type` - the [type](DeviceType) of device the application is installed on
// - `supported_capabilities` - the set of [capabilities](DeviceCapability) to register
// for this device in the "device commands" ecosystem.
//
// # Notes
//
// - Device registration is only available to applications that have been
//
[Throws=FxaError]
LocalDevice initialize_device([ByRef] string name, DeviceType device_type, sequence<DeviceCapability> supported_capabilities );
// Get the device id registered for this application.
//
// # Notes
//
// - If the application has not registered a device record, this method will
// throw an [`Other`](FxaError::Other) error.
// - (Yeah...sorry. This should be changed to do something better.)
// - Device metadata is only visible to applications that have been
//
[Throws=FxaError]
string get_current_device_id();
// Get the list of devices registered on the user's account.
//
// **💾 This method alters the persisted account state.**
//
// This method returns a list of [`Device`] structs representing all the devices
// currently attached to the user's account (including the current device).
// The application might use this information to e.g. display a list of appropriate
// send-tab targets.
//
// # Arguments
//
// - `ignore_cache` - if true, always hit the server for fresh profile information.
//
// # Notes
//
// - Device metadata is only visible to applications that have been
//
[Throws=FxaError]
sequence<Device> get_devices( boolean ignore_cache );
// Get the list of all client applications attached to the user's account.
//
// This method returns a list of [`AttachedClient`] structs representing all the applications
// connected to the user's acount. This includes applications that are registered as a device
// as well as server-side services that the user has connected.
//
// This information is really only useful for targetted messaging or marketing purposes,
// e.g. if the application wants to advertize a related product, but first wants to check
// whether the user is already using that product.
//
// # Notes
//
// - Attached client metadata is only visible to applications that have been
//
[Throws=FxaError]
sequence<AttachedClient> get_attached_clients();
// Update the display name used for this application instance.
//
// **💾 This method alters the persisted account state.**
//
// This method modifies the name of the current application's device record, as seen by
// other applications and in the user's account management pages.
//
// # Arguments
//
// - `display_name` - the new name for the current device.
//
// # Notes
//
// - Device registration is only available to applications that have been
//
[Throws=FxaError]
LocalDevice set_device_name([ByRef] string display_name );
// Clear any custom display name used for this application instance.
//
// **💾 This method alters the persisted account state.**
//
// This method clears the name of the current application's device record, causing other
// applications or the user's account management pages to have to fill in some sort of
// default name when displaying this device.
//
// # Notes
//
// - Device registration is only available to applications that have been
//
[Throws=FxaError]
void clear_device_name();
// Ensure that the device record has a specific set of capabilities.
//
// **💾 This method alters the persisted account state.**
//
// This method checks that the currently-registred device record is advertising the
// given set of capabilities in the FxA "device commands" ecosystem. If not, then it
// updates the device record to do so.
//
// Applications should call this method on each startup as a way to ensure that their
// expected set of capabilities is being accurately reflected on the FxA server, and
// to handle the rollout of new capabilities over time.
//
// # Arguments
//
// - `supported_capabilities` - the set of [capabilities](DeviceCapability) to register
// for this device in the "device commands" ecosystem.
//
// # Notes
//
// - Device registration is only available to applications that have been
//
[Throws=FxaError]
LocalDevice ensure_capabilities( sequence<DeviceCapability> supported_capabilities );
// Set or update a push subscription endpoint for this device.
//
// **💾 This method alters the persisted account state.**
//
// This method registers the given webpush subscription with the FxA server, requesting
// that is send notifications in the event of any significant changes to the user's
// account. When the application receives a push message at the registered subscription
// endpoint, it should decrypt the payload and pass it to the [`handle_push_message`](
// FirefoxAccount::handle_push_message) method for processing.
//
// # Arguments
//
// - `subscription` - the [`DevicePushSubscription`] details to register with the server.
//
// # Notes
//
// - Device registration is only available to applications that have been
//
[Throws=FxaError]
LocalDevice set_push_subscription( DevicePushSubscription subscription );
// Process and respond to a server-delivered account update message
//
// **💾 This method alters the persisted account state.**
//
// Applications should call this method whenever they receive a push notification from the Firefox Accounts server.
// Such messages typically indicate a noteworthy change of state on the user's account, such as an update to their profile information
// or the disconnection of a client. The [`FirefoxAccount`] struct will update its internal state
// accordingly and return an individual [`AccountEvent`] struct describing the event, which the application
// may use for further processing.
//
// It's important to note if the event is [`AccountEvent::CommandReceived`], the caller should call
// [`FirefoxAccount::poll_device_commands`]
//
[Throws=FxaError]
AccountEvent handle_push_message([ByRef] string payload );
// Poll the server for any pending device commands.
//
// **💾 This method alters the persisted account state.**
//
// Applications that have registered one or more [`DeviceCapability`]s with the server can use
// this method to check whether other devices on the account have sent them any commands.
// It will return a list of [`IncomingDeviceCommand`] structs for the application to process.
//
// # Notes
//
// - Device commands are typically delivered via push message and the [`CommandReceived`](
// AccountEvent::CommandReceived) event. Polling should only be used as a backup delivery
// mechanism, f the application has reason to believe that push messages may have been missed.
// - Device commands functionality is only available to applications that have been
//
[Throws=FxaError]
sequence<IncomingDeviceCommand> poll_device_commands();
// Use device commands to send a single tab to another device.
//
// **💾 This method alters the persisted account state.**
//
// If a device on the account has registered the [`SendTab`](DeviceCapability::SendTab)
// capability, this method can be used to send it a tab.
//
// # Notes
//
// - If the given device id does not existing or is not capable of receiving tabs,
// this method will throw an [`Other`](FxaError::Other) error.
// - (Yeah...sorry. This should be changed to do something better.)
// - It is not currently possible to send a full [`SendTabPayload`] to another device,
// but that's purely an API limitation that should go away in future.
// - Device commands functionality is only available to applications that have been
//
[Throws=FxaError]
void send_single_tab([ByRef] string target_device_id, [ByRef] string title, [ByRef] string url );
/// Use device commands to close one or more tabs on another device.
///
/// **💾 This method alters the persisted account state.**
///
/// If a device on the account has registered the [`CloseTabs`](DeviceCapability::CloseTabs)
/// capability, this method can be used to close its tabs.
[Throws=FxaError]
void close_tabs([ByRef] string target_device_id, sequence<string> urls);
// Get the URL at which to access the user's sync data.
//
// **💾 This method alters the persisted account state.**
//
[Throws=FxaError]
string get_token_server_endpoint_url();
// Get a URL which shows a "successfully connceted!" message.
//
// **💾 This method alters the persisted account state.**
//
// Applications can use this method after a successful signin, to redirect the
// user to a success message displayed in web content rather than having to
// implement their own native success UI.
//
[Throws=FxaError]
string get_connection_success_url();
// Get a URL at which the user can manage their account and profile data.
//
// **💾 This method alters the persisted account state.**
//
// Applications should link the user out to this URL from an appropriate place
// in their signed-in settings UI.
//
// # Arguments
//
// - `entrypoint` - metrics identifier for UX entrypoint.
// - This parameter is used for metrics purposes, to identify the
// UX entrypoint from which the user followed the link.
//
[Throws=FxaError]
string get_manage_account_url([ByRef] string entrypoint );
// Get a URL at which the user can manage the devices connected to their account.
//
// **💾 This method alters the persisted account state.**
//
// Applications should link the user out to this URL from an appropriate place
// in their signed-in settings UI. For example, "Manage your devices..." may be
// a useful link to place somewhere near the device list in the send-tab UI.
//
// # Arguments
//
// - `entrypoint` - metrics identifier for UX entrypoint.
// - This parameter is used for metrics purposes, to identify the
// UX entrypoint from which the user followed the link.
//
[Throws=FxaError]
string get_manage_devices_url([ByRef] string entrypoint );
// Get a short-lived OAuth access token for the user's account.
//
// **💾 This method alters the persisted account state.**
//
// Applications that need to access resources on behalf of the user must obtain an
// `access_token` in order to do so. For example, an access token is required when
// fetching the user's profile data, or when accessing their data stored in Firefox Sync.
//
// This method will obtain and return an access token bearing the requested scopes, either
// from a local cache of previously-issued tokens, or by creating a new one from the server.
//
// # Arguments
//
// - `scope` - the OAuth scope to be granted by the token.
// - This must be one of the scopes requested during the signin flow.
// - Only a single scope is supported; for multiple scopes request multiple tokens.
// - `ttl` - optionally, the time for which the token should be valid, in seconds.
//
// # Notes
//
// - If the application receives an authorization error when trying to use the resulting
// token, it should call [`clear_access_token_cache`](FirefoxAccount::clear_access_token_cache)
// before requesting a fresh token.
//
[Throws=FxaError]
AccessTokenInfo get_access_token([ByRef] string scope, optional i64? ttl = null);
// Get the session token for the user's account, if one is available.
//
// **💾 This method alters the persisted account state.**
//
// Applications that function as a web browser may need to hold on to a session token
// on behalf of Firefox Accounts web content. This method exists so that they can retreive
// it an pass it back to said web content when required.
//
// # Notes
//
// - Please do not attempt to use the resulting token to directly make calls to the
// Firefox Accounts servers! All account management functionality should be performed
// in web content.
// - A session token is only available to applications that have requested the
//
[Throws=FxaError]
string get_session_token();
// Update the stored session token for the user's account.
//
// **💾 This method alters the persisted account state.**
//
// Applications that function as a web browser may need to hold on to a session token
// on behalf of Firefox Accounts web content. This method exists so that said web content
// signals that it has generated a new session token, the stored value can be updated
// to match.
//
// # Arguments
//
// - `session_token` - the new session token value provided from web content.
//
[Throws=FxaError]
void handle_session_token_change([ByRef] string session_token );
// Create a new OAuth authorization code using the stored session token.
//
// When a signed-in application receives an incoming device pairing request, it can
// use this method to grant the request and generate a corresponding OAuth authorization
// code. This code would then be passed back to the connecting device over the
// pairing channel (a process which is not currently supported by any code in this
// component).
//
// # Arguments
//
// - `params` - the OAuth parameters from the incoming authorization request
//
[Throws=FxaError]
string authorize_code_using_session_token( AuthorizationParameters params );
// Clear the access token cache in response to an auth failure.
//
// **💾 This method alters the persisted account state.**
//
// Applications that receive an authentication error when trying to use an access token,
// should call this method before creating a new token and retrying the failed operation.
// It ensures that the expired token is removed and a fresh one generated.
//
void clear_access_token_cache();
// Collect and return telemetry about incoming and outgoing device commands.
//
// Applications that have registered one or more [`DeviceCapability`]s
// should also arrange to submit "sync ping" telemetry. Calling this method will
// return a JSON string of telemetry data that can be incorporated into that ping.
//
// Sorry, this is not particularly carefully documented because it is intended
// as a stop-gap until we get native Glean support. If you know how to submit
// a sync ping, you'll know what to do with the contents of the JSON string.
//
[Throws=FxaError]
string gather_telemetry();
// Used by the application to test auth token issues
void simulate_network_error();
// Used by the application to test auth token issues
void simulate_temporary_auth_token_issue();
// Used by the application to test auth token issues
void simulate_permanent_auth_token_issue();
};
dictionary FxaConfig {
// FxaServer to connect with
FxaServer server;
// Registered OAuth client id of the application.
string client_id;
// `redirect_uri` - the registered OAuth redirect URI of the application.
string redirect_uri;
// URL for the user's Sync Tokenserver. This can be used to support users who self-host their
// sync data. If `None` then it will default to the Mozilla-hosted Sync server.
string? token_server_url_override = null;
};
// FxA server to connect to
[Enum]
interface FxaServer {
Release();
Stable();
Stage();
China();
LocalDev();
Custom(string url);
};
// Information about the authorization state of the application.
//
// This struct represents metadata about whether the application is currently
// connected to the user's account.
//
dictionary AuthorizationInfo {
boolean active;
};
// An OAuth access token, with its associated keys and metadata.
//
// This struct represents an FxA OAuth access token, which can be used to access a resource
// or service on behalf of the user. For example, accessing the user's data in Firefox Sync
// an access token for the scope `https://identity.mozilla.com/apps/sync` along with the
// associated encryption key.
//
dictionary AccessTokenInfo {
// The scope of access granted by token.
string scope;
// The access token itself.
//
// This is the value that should be included in the `Authorization` header when
// accessing an OAuth protected resource on behalf of the user.
string token;
// The client-side encryption key associated with this scope.
//
// **⚠️ Warning:** the value of this field should never be revealed outside of the
// application. For example, it should never to sent to a server or logged in a log file.
ScopedKey? key;
// The expiry time of the token, in seconds.
//
// This is the timestamp at which the token is set to expire, in seconds since
// unix epoch. Note that it is a signed integer, for compatibility with languages
// that do not have an unsigned integer type.
//
// This timestamp is for guidance only. Access tokens are not guaranteed to remain
// value for any particular lengthof time, and consumers should be prepared to handle
// auth failures even if the token has not yet expired.
i64 expires_at;
};
// A cryptograpic key associated with an OAuth scope.
//
// Some OAuth scopes have a corresponding client-side encryption key that is required
// in order to access protected data. This struct represents such key material in a
// format compatible with the common "JWK" standard.
//
dictionary ScopedKey {
// The type of key.
//
// In practice for FxA, this will always be string string "oct" (short for "octal")
// to represent a raw symmetric key.
string kty;
// The OAuth scope with which this key is associated.
string scope;
// The key material, as base64-url-encoded bytes.
//
// **⚠️ Warning:** the value of this field should never be revealed outside of the
// application. For example, it should never to sent to a server or logged in a log file.
string k;
// An opaque unique identifier for this key.
//
// Unlike the `k` field, this value is not secret and may be revealed to the server.
string kid;
};
// Parameters provided in an incoming OAuth request.
//
// This struct represents parameters obtained from an incoming OAuth request - that is,
// the values that an OAuth client would append to the authorization URL when initiating
// an OAuth sign-in flow.
//
dictionary AuthorizationParameters {
string client_id;
sequence<string> scope;
string state;
string access_type;
string? code_challenge;
string? code_challenge_method;
string? keys_jwk;
};
// A device connected to the user's account.
//
// This struct provides metadata about a device connected to the user's account.
// This data would typically be used to display e.g. the list of candidate devices
// in a "send tab" menu.
//
dictionary Device {
string id;
string display_name;
DeviceType device_type;
sequence<DeviceCapability> capabilities;
DevicePushSubscription? push_subscription;
boolean push_endpoint_expired;
boolean is_current_device;
i64? last_access_time;
};
// Device configuration
dictionary DeviceConfig {
string name;
DeviceType device_type;
sequence<DeviceCapability> capabilities;
};
// Local device that's connecting to FxA
//
// This is returned by the device update methods and represents the server's view of the local
// device.
dictionary LocalDevice {
string id;
string display_name;
DeviceType device_type;
sequence<DeviceCapability> capabilities;
DevicePushSubscription? push_subscription;
boolean push_endpoint_expired;
};
// Details of a web-push subscription endpoint.
//
// This struct encapsulates the details of a web-push subscription endpoint,
// including all the information necessary to send a notification to its owner.
// Devices attached to the user's account may register one of these in order
// to receive timely updates about account-related events.
//
// Managing a web-push subscription is outside of the scope of this component.
//
dictionary DevicePushSubscription {
string endpoint;
string public_key;
string auth_key;
};
// The payload sent when invoking a "send tab" command.
//
dictionary SendTabPayload {
// The navigation history of the sent tab.
//
// The last item in this list represents the page to be displayed,
// while earlier items may be included in the navigation history
// as a convenience to the user.
sequence<TabHistoryEntry> entries;
// A unique identifier to be included in send-tab metrics.
//
// The application should treat this as opaque.
string flow_id = "";
// A unique identifier to be included in send-tab metrics.
//
// The application should treat this as opaque.
string stream_id = "";
};
/// The payload sent when invoking a "close tabs" command.
//
dictionary CloseTabsPayload {
/// The URLs of the tabs to close.
sequence<string> urls;
};
// An individual entry in the navigation history of a sent tab.
//
dictionary TabHistoryEntry {
string title;
string url;
};
// A client connected to the user's account.
//
// This struct provides metadata about a client connected to the user's account.
// Unlike the [`Device`] struct, "clients" encompasses both client-side and server-side
// applications - basically anything where the user is able to sign in with their
// Firefox Account.
//
//
// This data would typically be used for targetted messaging purposes, catering the
// contents of the message to what other applications the user has on their account.
//
dictionary AttachedClient {
string? client_id;
string? device_id;
DeviceType device_type;
boolean is_current_session;
string? name;
i64? created_time;
i64? last_access_time;
sequence<string>? scope;
};
// Information about the user that controls a Firefox Account.
//
// This struct represents details about the user themselves, and would typically be
// used to customize account-related UI in the browser so that it is personalize
// for the current user.
//
dictionary Profile {
// The user's account uid
//
// This is an opaque immutable unique identifier for their account.
string uid;
// The user's current primary email address.
//
// Note that unlike the `uid` field, the email address may change over time.
string email;
// The user's preferred textual display name.
string? display_name;
// The URL of a profile picture representing the user.
//
// All accounts have a corresponding profile picture. If the user has not
// provided one then a default image is used.
string avatar;
// Whether the `avatar` URL represents the default avatar image.
boolean is_default_avatar;
};
[Enum]
interface FxaState {
Uninitialized();
Disconnected();
Authenticating(string oauth_url);
Connected();
AuthIssues();
};
[Enum]
interface FxaEvent {
Initialize(DeviceConfig device_config);
BeginOAuthFlow(sequence<string> scopes, string entrypoint);
BeginPairingFlow(string pairing_url, sequence<string> scopes, string entrypoint);
CompleteOAuthFlow(string code, string state);
CancelOAuthFlow();
CheckAuthorizationStatus();
Disconnect();
CallGetProfile();
};
enum FxaRustAuthState {
"Disconnected",
"Connected",
"AuthIssues",
};
// A "capability" offered by a device.
//
// In the FxA ecosystem, connected devices may advertize their ability to respond
// to various "commands" that can be invoked by other devices. The details of
// executing these commands are encapsulated as part of the FxA Client component,
// so consumers simply need to select which ones they want to support, and can
// use the variants of this enum to do so.
//
enum DeviceCapability {
"SendTab",
"CloseTabs",
};
// An event that happened on the user's account.
//
// If the application has registered a [`DevicePushSubscription`] as part of its
// device record, then the Firefox Accounts server can send push notifications
// about important events that happen on the user's account. This enum represents
// the different kinds of event that can occur.
//
[Enum]
interface AccountEvent {
// Sent when another device has invoked a command for this device to execute.
//
// When receiving this event, the application should inspect the contained
// command and react appropriately.
CommandReceived(IncomingDeviceCommand command );
// Sent when the user has modified their account profile information.
//
// When receiving this event, the application should request fresh profile
// information by calling [`get_profile`](FirefoxAccount::get_profile) with
// `ignore_cache` set to true, and update any profile information displayed
// in its UI.
//
ProfileUpdated();
// Sent when when there has been a change in authorization status.
//
// When receiving this event, the application should check whether it is
// still connected to the user's account by calling [`check_authorization_status`](
// FirefoxAccount::check_authorization_status), and updating its UI as appropriate.
//
AccountAuthStateChanged();
// Sent when the user deletes their Firefox Account.
//
// When receiving this event, the application should act as though the user had
// signed out, discarding any persisted account state.
AccountDestroyed();
// Sent when a new device connects to the user's account.
//
// When receiving this event, the application may use it to trigger an update
// of any UI that shows the list of connected devices. It may also show the
// user an informational notice about the new device, as a security measure.
DeviceConnected(string device_name );
// Sent when a device disconnects from the user's account.
//
// When receiving this event, the application may use it to trigger an update
// of any UI that shows the list of connected devices.
DeviceDisconnected(string device_id, boolean is_local_device );
// An unknown event, most likely an event the client doesn't support yet.
//
// When receiving this event, the application should gracefully ignore it.
Unknown();
};
// A command invoked by another device.
//
// This enum represents all possible commands that can be invoked on
// the device. It is the responsibility of the application to interpret
// each command.
//
[Enum]
interface IncomingDeviceCommand {
// Indicates that a tab has been sent to this device.
TabReceived(Device? sender, SendTabPayload payload );
/// Indicates that the sender wants to close one or more tabs on this device.
TabsClosed(Device? sender, CloseTabsPayload payload);
};
// Machinery for dry-run testing of FxaAuthStateMachine
//
// Remove this once we've migrated the firefox-android and firefox-ios code to using FxaAuthStateMachine
interface FxaStateMachineChecker {
constructor();
void handle_public_event(FxaEvent event);
void handle_internal_event(FxaStateCheckerEvent event);
void check_public_state(FxaState state);
void check_internal_state(FxaStateCheckerState state);
};
[Enum]
interface FxaStateCheckerEvent {
GetAuthStateSuccess(FxaRustAuthState auth_state);
BeginOAuthFlowSuccess(string oauth_url);
BeginPairingFlowSuccess(string oauth_url);
CompleteOAuthFlowSuccess();
InitializeDeviceSuccess();
EnsureDeviceCapabilitiesSuccess();
CheckAuthorizationStatusSuccess(boolean active);
DisconnectSuccess();
GetProfileSuccess();
CallError();
EnsureCapabilitiesAuthError();
};
[Enum]
interface FxaStateCheckerState {
GetAuthState();
BeginOAuthFlow(sequence<string> scopes, string entrypoint);
BeginPairingFlow(string pairing_url, sequence<string> scopes, string entrypoint);
CompleteOAuthFlow(string code, string state);
InitializeDevice();
EnsureDeviceCapabilities();
CheckAuthorizationStatus();
Disconnect();
GetProfile();
Complete(FxaState new_state);
Cancel();
};
dictionary UserData {
string session_token;
string uid;
string email;
boolean verified;
};