Skip to content

Mobile: persistent mobile token + revoke control for hands-free PWA reconnect #191

Open

Description

@johannesjo

Summary

Make the mobile token survive desktop restarts and add a way to revoke it, so an installed PWA reconnects hands-free instead of forcing a re-scan after every restart.

This is follow-up step 4 of 5 from the "autoconnect to mobile + installable PWA" work. Steps 1–3 have landed:

  • Desktop auto-starts the remote server on launch (autoStartRemoteAccess setting).
  • The mobile app ships a PWA manifest + icons (iOS add-to-home-screen works).
  • The mobile app has a "Not connected" reconnect screen (paste connection URL / re-pair).

Problem

The mobile token is minted fresh on every server start:

// electron/remote/server.ts
const mobileToken = randomBytes(24).toString('base64url');

So after the desktop restarts, an installed PWA's stored token is invalid. The phone's WebSocket gets rejected (4001), the token is cleared, and the user must re-pair via the reconnect screen. That undermines the whole point of an installed PWA + autoconnect: it should "just work" on relaunch.

Proposed solution

  1. Persist the mobile token on the desktop (e.g. in userData, or the persisted app state) and reuse it on each server start instead of always minting a new one. The coordinator/subtask tokens can stay per-session — only the mobile token needs to be stable.
  2. Add a "Regenerate / disconnect devices" control in ConnectPhoneModal that rotates the stored mobile token, immediately invalidating any previously paired phone. This is the revoke path.
  3. Optionally rotate automatically if the user explicitly "Disconnects".

Security considerations

A persistent token is a longer-lived bearer credential. This is judged acceptable but should be bounded:

  • The remote server is LAN / Tailscale only — never internet-exposed.
  • The mobile token is least-privilege: read agents + input/subscribe over WS, no resize/kill (server.ts).
  • It must be revocable in one click (the regenerate control above).

Document the tradeoff in the UI ("Experimental") and/or PRIVACY.md.

Acceptance criteria

  • Mobile token persists across desktop restarts when autoStartRemoteAccess is on.
  • An installed PWA reconnects after a desktop restart with no re-scan (same origin reachable).
  • A "Regenerate / disconnect devices" action rotates the token and drops existing mobile WS clients.
  • Coordinator/subtask tokens remain per-session.
  • Round-trip + revoke covered by tests.

Touch points

  • electron/remote/server.ts — token minting / accept a supplied mobile token.
  • electron/ipc/register.ts — pass the persisted token into startRemoteServer; IPC for regenerate.
  • src/store/remote.ts, src/components/ConnectPhoneModal.tsx — revoke UI + store glue.
  • Persisted state (src/store/types.ts, persistence.ts) or a dedicated userData file for the token.

Note on origin stability

A persistent token only helps when the PWA's origin is reachable. The desktop LAN IP can change (DHCP) and the port should stay fixed (7777). Tailscale gives a stable IP across networks/restarts and is the most reliable transport for an installed PWA — see step 5.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions