Uh oh!
There was an error while loading. Please reload this page.
Add QR device-handoff login ("scan to sign in") - #630
Merged
Conversation
Integrate the keyfob library as PhoenixKit's QR sign-in flow: a signed-out browser shows a QR code, an already-signed-in phone scans it (native camera works), reviews the requesting device, and taps Approve — the desktop signs in with no password. Approval always happens on the trusted phone; the desktop receives nothing until the phone approves. - PhoenixKit.Users.QrLogin context wraps keyfob on the internal PubSub, reads the qr_login_enabled setting, extracts device metadata, and logs a user.qr_login_approved activity on approval. - Desktop QR page (public LV), phone confirm page (authenticated LV), and completion controller (consume -> log_in_user). Panel expires with the request TTL and offers a fresh code. - Routes (localized + non-localized), Keyfob.Store.ETS in the supervisor, qr_login_enabled setting default (off), Authorization-settings toggle, a "Sign in with QR code" button on the login page, and an icon_qr_code. - Extract new gettext strings across all locales. Requires keyfob ~> 0.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MsjUy1HnuJnCSrqdbnANYL
# Conflicts: # priv/gettext/de/LC_MESSAGES/default.po # priv/gettext/default.pot # priv/gettext/en/LC_MESSAGES/default.po # priv/gettext/es/LC_MESSAGES/default.po # priv/gettext/et/LC_MESSAGES/default.po # priv/gettext/fr/LC_MESSAGES/default.po # priv/gettext/it/LC_MESSAGES/default.po # priv/gettext/pl/LC_MESSAGES/default.po # priv/gettext/ru/LC_MESSAGES/default.po
# Conflicts: # mix.lock
ddon pushed a commit
that referenced
this pull request
Jul 12, 2026
Review of the QR device-handoff login (#630) and prefix-hardening (#631) PRs surfaced real gaps: the qr_login_enabled setting wasn't an immediate kill switch on the phone-approval/completion paths, the public QR mint endpoint had no rate limiting, and V26's pgcrypto digest() backfill and the new Oban prefix-detection regex both had the same class of bugs the prefix-hardening PR was written to fix elsewhere. See CLAUDE_REVIEW.md in each PR's dev_docs directory for full findings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a QR "scan to sign in" flow to the login page, integrating the new
keyfoblibrary (0.1.0).A signed-out browser shows a QR code; an already-signed-in phone scans it (the native camera works — no app needed), reviews the requesting device (browser / OS / IP), and taps Approve — the desktop signs in with no password. Approval always happens on the trusted phone; the desktop receives nothing until the phone approves (defense against QR-jacking is keyfob's confirm-screen + secret split).
How
PhoenixKit.Users.QrLogincontext — wraps keyfob on the internal PubSub (:phoenix_kit_internal_pubsub), reads theqr_login_enabledsetting, extracts device metadata for the confirm screen, and logs auser.qr_login_approvedactivity on approval./users/qr-login) — mints the request on connect, renders keyfob's panel, redirects to completion on approval, and flips to "show a new code" when the 2-min TTL lapses (token-keyed timer so refresh/approve races can't clobber state)./users/qr-login/scan/:token) — device review + Approve/Deny; approves on behalf of the signed-in user. Unauthenticated hits are redirected to login withreturn_topreserved, then bounced back./users/qr-login/finish/:token) —Keyfob.consume/1→log_in_user.Keyfob.Store.ETSin the supervisor,qr_login_enabledsetting (default off), a toggle in Authorization settings, a "Sign in with QR code" button on the login page (gated on the setting), and a newicon_qr_code.Enabling / testing
Off by default. Enable at Admin → Settings → Authorization → QR Code → "Enable QR code sign-in"; the login-page button then appears. The QR encodes an absolute
Routes.urllink, so the phone must be able to reach the host (real domain in prod; a LAN IP / tunnel for local dev).Notes
keyfob ~> 0.1(published to Hex).mix compile --warnings-as-errors,mix credo --strict,mix format --check-formattedclean; routes confirmed viamix phx.routes.🤖 Generated with Claude Code