Repository navigation
Mobile: persistent mobile token + revoke control for hands-free PWA reconnect #191
Description
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 (
autoStartRemoteAccesssetting). - 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
- 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. - Add a "Regenerate / disconnect devices" control in
ConnectPhoneModalthat rotates the stored mobile token, immediately invalidating any previously paired phone. This is the revoke path. - 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/subscribeover WS, noresize/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
autoStartRemoteAccessis 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 intostartRemoteServer; 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 dedicateduserDatafile 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