Go to file
Val 1ac834dd94
Merge pull request #5 from jschauma/master
tyop: colections -> collections
2023-05-16 15:51:43 -04:00
.gitignore Initial commit 2021-10-16 09:13:19 -04:00
README.md tyop: colections -> collections 2023-05-16 14:25:25 -04:00
cli.js Initial commit 2021-10-16 09:13:19 -04:00
ffs CLI error handling 2022-01-23 09:56:19 -05:00
oauth.js Initial commit 2021-10-16 09:13:19 -04:00
package.json 1.0.2 2022-01-23 09:56:25 -05:00
password.js Initial commit 2021-10-16 09:13:19 -04:00
prompt.js Initial commit 2021-10-16 09:13:19 -04:00


Firefox Sync CLI npm version

Manage Firefox Sync from the CLI!


Firefox Sync is a great tool, but up to now, there was no easy way to interact with it programmatically, or a command line interface to access the data it holds (like bookmarks, history, or Lockwise passwords).

Using Node Firefox Sync, this CLI gives you access to all the endpoints and objects exposed by the Firefox Sync API.

It features two ways to authenticate, one using a Firefox Accounts email and password to open a session, and one using OAuth. See more about them below.


npm install -g firefox-sync-cli

The command will be available as ffs. 😏


Usage: ffs [options] [command]

  --version                           Show version.
  -c, --creds <file>                  File to get Firefox Sync creds from (or
                                      write to during authentication and
  -v, --verbose                       Output more details.
  -h, --help                          Show this screen.

  auth [email] [password]             Sign in using email and password.
  oauth                               Sign in using OAuth.
  collections                         List available collections.
  get [options] <collection> [id...]  Get some or all items from a collection.
                                      When getting all items, pass '--full' to
                                      get the full objects.
  set <collection>                    Store one or multiple payloads from
                                      'stdin' in the given collection.
  delete <collection> <id...>         Delete the given items by ID.
  quota                               Get the current usage and storage quota.
  collection-usage                    Get the usage in kB of all collections.
  collection-counts                   Get the number of items in each
  configuration                       Get the storage server configuration.
  help [command]                      Display help for command.

A typical flow will look like this:

ffs -c ~/.ffs-creds.json oauth
ffs -c ~/.ffs-creds.json collections
ffs -c ~/.ffs-creds.json get bookmarks --full

During authentication, this will create ~/.ffs-creds.json to store the credentials necessary to access Firefox Sync.

Further commands read credentials from this file to use that session to query the API.


Email and password

This opens a session with full access to the given Firefox Account in order to get the credentials to access Firefox Sync.

By design, this means this program will have to access to your plaintext password. It doesn't store it, and just forwards it to fxa-js-client which handles the actual authentication.


You're given a OAuth URL to open in your browser, where you can input your password in Mozilla's own website, which will in turn grant access to this program by redirecting to a URL that includes an authentication code.

With this method, the program never gets access to the plaintext password, on top of being granted a token with restricted permissions.

That said there's currently no way to request access to specific Firefox Sync collections meaning that this grant will have access to all the native Firefox Sync collections.

Because this program doesn't have its own OAuth client ID, it uses the public client ID from the Lockwise Android app.

This means that we don't control the OAuth redirect URL, and can't set it to a temporary server on some random localhost port, which would allow seamless authentication of this CLI. To work around that, the CLI will kindly ask you to open the OAuth URL in Firefox, which it knows how to poll for "visited places" by querying places.sqlite in the profile directory. It will be able to detect the Android app redirect URL to extract the OAuth code and complete the authentication process.

In case this doesn't work (it's clearly a hack, let's face it), consider falling back to password authentication!

See also

Node Firefox Sync, the underlying client library that powers the CLI.

The story on how this all started when I tried to access my Lockwise passwords from the CLI:

  1. A journey to scripting Firefox Sync / Lockwise: existing clients
  2. A journey to scripting Firefox Sync / Lockwise: figuring the protocol
  3. A journey to scripting Firefox Sync / Lockwise: understanding BrowserID
  4. A journey to scripting Firefox Sync / Lockwise: hybrid OAuth
  5. A journey to scripting Firefox Sync / Lockwise: complete OAuth