From 311049379ded0438d002484d37e13068e33c127a Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Fri, 28 Aug 2026 22:45:29 -0400 Subject: [PATCH] docs(android): add QR pairing sign-in to roadmap, update auth design Document the authentication decision reached for the Android client: username/password login is primary (the app needs the user-JWT API surface that device tokens cannot reach), with the app self-approving its own device registration post-login so it still shows up on the Devices page with sync attribution. Add the Netflix-style QR pairing flow to the post-v1 roadmap with its constraints: the QR grants a full login with zero typing; a typed-code fallback covers phones with broken cameras; KOReader keeps its existing flow (no typed codes there); and pairing must encode the configured BASE_URL rather than a detected LAN IP so remote instances (https://public.domain) work identically. --- docs/developer/android-app.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/developer/android-app.md b/docs/developer/android-app.md index b10ccd2..56d94a6 100644 --- a/docs/developer/android-app.md +++ b/docs/developer/android-app.md @@ -68,10 +68,11 @@ Keeping `:core:domain` free of Android dependencies preserves optionality: a fut 4. While online, a WebSocket connection receives realtime updates pushed by other devices (web reader, KOReader) 5. Books are downloaded to app storage for fully offline reading, with storage management UI -### Device registration & auth +### Authentication & device identity -- The app registers as a Bookhoard **device** using the existing QR-approval flow (`POST /api/devices/register` + web-based approval) — no passwords stored on the device -- JWT access/refresh handled by the existing auth endpoints +- **Primary auth: username/password login** via the existing endpoints (`POST /api/auth/login` + refresh). The app is a full user client — browse, collections, ratings, and annotation management all live behind the user JWT, which device tokens cannot reach +- After login, the app registers itself as a **device** (`device_type: mobile`) and **self-approves** its registration using its own JWT — approval only requires a logged-in user. The phone then appears on the Devices page with sync attribution, per-device settings, and individually revocable access, with no QR ceremony +- Netflix-style QR pairing as a zero-typing sign-in option: post-v1 (see below) --- @@ -125,6 +126,18 @@ iOS is a real roadmap item but not near-term. The strategy is **not** to pre-pay ## 🔭 Post-v1 Ideas +### QR pairing sign-in (Netflix-style) + +"Add device" on the web (while logged in) displays a QR code; a fresh app install scans it and is **fully signed in** — no server URL, no password, nothing typed on the phone. + +- **QR is a full login**: the claim endpoint returns JWT + refresh token (plus the device token for sync identity) +- **Typed-code fallback** (GitHub/Netflix device-flow style: app displays a short code, user enters it on the web) for phones with broken cameras or no camera +- **KOReader keeps its existing flow unchanged** — no typed-code pairing there; it is already as convenient as it can be +- **Use the configured `BASE_URL`, never a detected LAN IP** — if the server is published at `https://public.domain`, pairing must work identically from outside the LAN +- Requires small server additions: `pair`/`claim` endpoints backed by single-use pairing sessions with a short TTL (in-memory like `pendingRegistrations`) + +### Other ideas + - Webtoon / continuous vertical reading mode - Home-screen widgets and app shortcuts ("continue reading") - Text-to-speech