Fix iris setup: embed generated token in the pairing URL/QR
CI / Gateway plugin tests (push) Successful in 5m23s
CI / Kotlin tests (android host + desktop) (push) Successful in 6m53s

interactive_setup() generated a fresh IRIS_TOKEN and saved it to .env,
but the local `token` variable was never updated, so the pairing URL and
QR payload were built with an empty token (token=). The gateway accepted
the saved token, but the app never received it, so pairing was impossible.

Assign the generated value back to `token` so the pairing URL/QR carry it.
Add a regression test (test_interactive_setup_generates_token_in_pairing_url).
This commit is contained in:
ARIA committed 2026-08-25 13:42:46 +02:00
1 parent 6f339330c5
commit f3f1b37221
2 files changed
+41 -3

No files matched your search

+3 -3
View File
@@ -481,9 +481,9 @@ def interactive_setup() -> None:
print_info("📱 Android / Desktop (Iris x Hermes)") print_info("📱 Android / Desktop (Iris x Hermes)")
token = get_env_value("IRIS_TOKEN") or "" token = get_env_value("IRIS_TOKEN") or ""
if not token: if not token:
generated = generate_token() token = generate_token()
save_env_value("IRIS_TOKEN", generated) save_env_value("IRIS_TOKEN", token)
print_success(f"Generated pairing token: {generated}") print_success(f"Generated pairing token: {token}")
print_warning("Keep this secret -- the app presents it on connect.") print_warning("Keep this secret -- the app presents it on connect.")
else: else:
print_info("Existing IRIS_TOKEN found (not shown).") print_info("Existing IRIS_TOKEN found (not shown).")
+38
View File
@@ -3024,6 +3024,44 @@ def test_offer_device_removal_setup_flow(tmp_path, monkeypatch):
_run([]) # any input() call would raise StopIteration → test fails _run([]) # any input() call would raise StopIteration → test fails
def test_interactive_setup_generates_token_in_pairing_url(tmp_path, monkeypatch, capsys):
"""interactive_setup: when no IRIS_TOKEN is set, the generated token is
saved AND embedded in the printed pairing URL (regression: the token was
generated but the local ``token`` stayed empty, so the pairing URL carried
``token=`` and pairing was impossible)."""
plugin = _load_plugin()
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
saved: dict[str, str] = {}
monkeypatch.setattr(
"hermes_cli.config.get_env_value",
lambda name: saved.get(name, ""),
)
monkeypatch.setattr(
"hermes_cli.config.save_env_value",
lambda name, value: saved.__setitem__(name, value),
)
# prompt returns the default (no interactive input needed).
monkeypatch.setattr(
"hermes_cli.cli_output.prompt",
lambda question, default="": default,
)
# Skip the device-removal / TLS sub-flows, LAN-IP discovery, and the
# terminal QR block.
monkeypatch.setattr(plugin.setup, "_offer_device_removal", lambda: None)
monkeypatch.setattr(plugin.setup, "_offer_tls_setup", lambda *a, **k: None)
monkeypatch.setattr(plugin.setup, "advertise_host", lambda host: "10.0.0.111")
monkeypatch.setattr(plugin.qr, "render_qr", lambda *a, **k: "")
plugin.setup.interactive_setup()
out = capsys.readouterr().out
token = saved.get("IRIS_TOKEN", "")
assert token, "IRIS_TOKEN was not saved"
# The pairing URL must carry the generated token (not an empty token=).
assert f"token={token}" in out, f"pairing URL missing the generated token:\n{out}"
# ── TLS setup: self-signed cert generation (install.md Part 4, Option B) ── # ── TLS setup: self-signed cert generation (install.md Part 4, Option B) ──