Fix iris setup: embed generated token in the pairing URL/QR
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:
1 parent
6f339330c5
commit
f3f1b37221
2 files changed
+41
-3
No files matched your search
@@ -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).")
|
||||||
|
|||||||
@@ -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) ──
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user