Credentials Helper

Connect with Rust+

Detailed walkthrough of the Connect-with-Rust+ flow.

The Connect-with-Rust+ button does six things behind the scenes:

1. Register FCM

@liamcottle/push-receiver opens a connection to Google FCM with the Facepunch sender ID 976529667804 (the same value rustplusplus and rustplus.js use). FCM returns an FCM token.

2. Trade for an Expo push token

The helper POSTs the FCM token to https://exp.host/--/api/v2/push/getExpoPushToken with experienceId: @facepunch/RustCompanion and appId: com.facepunch.rust.companion. Expo returns an Expo push token (ExponentPushToken[…]).

3. Open Facepunch's login window

A new BrowserWindow opens to https://companion-rust.facepunch.com/login?token=<expoToken> in partition persist:rustplus so your Steam login cookies survive between sessions. If you've signed in before you skip Steam OpenID; otherwise you sign in to Steam.

4. Capture the redirect

After Steam OpenID confirms, Facepunch's site redirects with a SteamAuthToken + Steam64 in the URL. The helper intercepts via two mechanisms:

  • will-redirect / will-navigate URL parsing (primary).
  • DOM polling fallback (if Facepunch ever changes the redirect shape).

5. Bind at Facepunch

The helper POSTs { AuthToken, expoPushToken, SteamId } to https://companion-rust.facepunch.com/api/push/register. Facepunch records the Expo push token against your Steam account — from that moment, your Rust+ pairings will fire as FCM pushes through that token.

6. Upload to Rust Pulse

The helper PUTs the full credential bundle to rustplus-api /credentials/fcm with the device bearer token from pairing. The API:

  • Decodes the bundle.
  • Verifies the Steam ID inside matches the Steam ID on your session.
  • Encrypts the bundle with AES-256-GCM.
  • Stores ciphertext.

The FCM listener worker picks up the new credential on its next reconcile (~30s).

Brittle parts to know about

  • The Facepunch login page's exact redirect/success behavior isn't publicly documented. The helper uses both URL interception and DOM polling. If Facepunch changes their site you'll need to tweak the patterns in services/facepunch.ts tryExtractFromUrl.
  • The FCM sender ID is hard-coded as 976529667804. If Facepunch rotates their Firebase project, update config.FACEPUNCH_FCM_SENDER_ID.