Pairing: scan a QR off the terminal once; the cookie lasts a year

The key already persisted across restarts, but the cookie was a
session cookie — Safari eventually drops those and the paste ritual
returned. The pairing cookie now lasts a year, and startup prints a QR
code of the pairing URL (qrcode dep, ASCII render) so a phone pairs by
pointing its camera at the terminal. Revoke every paired device by
deleting data/.lan_key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
Eric Wagoner
2026-08-03 16:50:36 -04:00
co-authored by Claude Fable 5
parent 78debdd62f
commit 44dd03d06a
6 changed files with 45 additions and 3 deletions
+3
View File
@@ -926,6 +926,8 @@ def test_lan_token_gates_every_request(tmp_path):
assert first.status_code == 303 # cookie commits BEFORE the document
assert first.headers["location"] == "/titles" # key scrubbed from URL
assert "bggpipe_key" in first.cookies
# pairing is one-time per device: a durable cookie, not a session one
assert "Max-Age=31536000" in first.headers["set-cookie"]
assert phone.get("/titles").status_code == 200 # cookie carries it now
# cookie carries the session: mutations work from ANY host the phone
# used (no allowlist dependence — DHCP/multi-interface safe), with a
@@ -1029,6 +1031,7 @@ def test_run_web_review_lan_branch_binds_and_warns(tmp_path, monkeypatch, capsys
assert f"?k={key}" in capsys.readouterr().out # same key after restart
# the default-route address leads; other interfaces are fallbacks
assert "on your phone, open: http://192.168.1.5:9999/?k=" in out
assert "" in out or "" in out # the pairing QR rendered
fallback = next(line for line in out.splitlines() if "try:" in line)
assert "192.168.64.1" in fallback and "erics-mac.local" in fallback
# no phone can reach loopback: only the desktop line mentions it