Skip to content

Set up another device: QR code and link with server, coordinator or settings - #243

Merged
ingoau merged 3 commits into
mainfrom
t3/profile-setup-device-qr
Nov 13, 2026
Merged

ingoau merged 3 commits into
mainfrom
t3/profile-setup-device-qr

Conversation

@ingoau

@ingoau ingoau commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Adds Set up another device to the account sheet on Android and to the account card in Settings on desktop. It shows a QR code of a hocket://setup link that hands the sign-in details to a new device.

What the link holds

hocket://setup?server=…&user=…[&password=…][&coordinator=…][&settings=…]

  • The Navidrome server and the username.
  • The password, only if you switch "Include password" on (off by default).
  • The coordinator URL, if this device has one.
  • Without a coordinator, the account settings you've changed from their defaults. These are the same ones a coordinator would sync. They're compressed (zlib, then unpadded base64url) to keep the code small.
    • The QR code leaves the settings out if they'd make it too dense to scan. Share link and Copy link always include them.
    • Device settings stay behind: theme, EQ and audio output, storage, battery.

Using it on the new device

  • Android:
    • The first screen has a "Scan a setup code" button, which uses Google's code scanner and needs no camera permission.
    • The FOSS build has no in-app scanner, but the phone's camera opens the link through an intent filter.
  • Desktop: paste the link into the server address field.
  • Opened from outside: a hocket://setup link opened from another app only fills in the form. Any web page can open such a link, so it waits for you to press Connect. It also drops the link's coordinator and settings, because neither shows in the form and a coordinator receives the account's credential. Only a scanned or pasted link brings them, and typing your own server or user drops them.
  • Already signed in: the link is turned away with a message.

Core

  • Query::SetupSettings returns the account settings that differ from their defaults, as a JSON object.
  • Command::ApplySetupSettings applies them. It takes account-level settings only and ignores device settings, unknown keys and invalid values.

Tests

  • Core: actor_library::setup_settings_carry_changed_synced_settings_to_a_new_device.
  • Android:
    • SetupLinkTest, including reading a link the desktop packed.
    • SetupDeviceTest: the sheet, opening and pasting links, applying settings, and turning a link away.
  • Desktop:
    • Unit tests: setup-settings (including reading what Android packs), deep-link and ipc.
    • e2e: e2e/setup-device.spec.ts.

🤖 Generated with Claude Code

ingoau and others added 3 commits November 13, 2026 21:02
…dinator or settings

The account sheet (Android) and the Settings account card (desktop) gain
"Set up another device": a QR code of a hocket://setup link carrying the
Navidrome server and user, the password only when switched on, and the
coordinator, or without one the account settings changed from their
defaults (packed: zlib + base64url). A new device scans it (Google code
scanner, non-FOSS builds), opens it from the camera, or takes it pasted
into the server field. Links opened from outside only fill the form;
a signed-in device turns them away.

Core: Query::SetupSettings and Command::ApplySetupSettings (account-synced
keys only).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A hocket:// link any web page can open showed only the server and user,
while its coordinator (which receives the account's credential when the
device joins it) and settings were kept hidden and applied on Connect.
Now only a scanned or pasted link brings them, and typing a server or
user of one's own drops them.

Also: Android never replays a setup link from Recents and reads the
keystore off the main thread; both apps find a link pasted into a field
that already holds an address; the desktop dialog offers no link until
its settings are known, and turns away a link that arrived before a
cold start's servers loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ingoau
ingoau merged commit 7a28ab5 into main Nov 13, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant