feat: device-auth backend for codeless sign-in (app #12) #3
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/device-auth"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Backend half of codeless device sign-in (amber-app issue #12). Pairs with amber-app PR
feature/codeless-signin.What's here
device_authcollection (migration) —code(unique short),deviceName,status,user→users,expiresAt, + hiddenauthToken/keyCiphertext/pollSecret/devicePubKey. Collection REST rules are owner-scoped list/view/delete (= the device list + revoke); create/update are locked to the hooks.pb_hooks/device_auth.pb.js— the handshake:POST /api/device-auth/request(public) →{id, code, pollSecret, expiresAt, ttl}(5-min TTL).GET /api/device-auth/info?code=(public, non-secret) → deviceName + the TV's ephemeral pubkey + status (what the approve page needs).GET /api/device-auth/poll?id=&secret=(pollSecret-gated) → status; on approved, delivers{token, keyCiphertext, record}— the only place secrets leave the server, and only to thepollSecretholder (the TV). 120s pickup window.POST /api/device-auth/approve(auth required) → mintse.auth.newAuthToken()for the caller, stores the E2E-sealed vault key.POST /api/device-auth/decline(auth) → denies + scrubs.pb_hooks/device_page.pb.js— self-containedGET /device?code=approve page: signs the user in, shows "Approve ?", and seals the addon-config vault key to the TV's pubkey.docs/device-auth-contract.md— full contract + crypto spec.Crypto (the load-bearing part)
The approve page (where the user does type their password) derives the #20 vault key — PBKDF2-HMAC-SHA256, 210000 iters, 256-bit, account salt — and transfers it to the TV end-to-end so the server only ever sees opaque ciphertext: X25519 → HKDF-SHA256 → AES-256-GCM. Proven to match the app byte-for-byte with committed interop fixtures (a Node run of the page's exact inlined crypto seals vectors the Dart tests open).
Deploy
Merge + redeploy on Coolify (Dockerfile now ships
pb_hooksvia--hooksDir; the migration auto-applies on boot).python scripts/verify.pyagainst the live URL includes new device_auth checks;https://pb.petruzalekr.cz/device?code=TESTshould render the approve page. On-device E2E happens with the app build after this deploys.Known limitation
PocketBase JWTs are stateless — revoking a device drops it from the list + stops polling but can't invalidate an already-minted token before expiry. Documented as a follow-up.
🤖 Generated with Claude Code