feat: TLS nudge in doctor and service install output
When host is set to network access (not 127.0.0.1) and TLS is not configured, doctor shows 'Run: muxplex setup-tls' and service install shows a tip line. Hidden on localhost-only setups since clipboard works without HTTPS there.
This commit is contained in:
+8
-3
@@ -369,9 +369,14 @@ def doctor() -> None:
|
||||
else:
|
||||
print(f" {warn_mark} TLS: configured but cert not readable ({tls_cert})")
|
||||
else:
|
||||
print(
|
||||
f" {warn_mark} TLS: disabled (clipboard requires HTTPS on non-localhost)"
|
||||
)
|
||||
# Only show TLS warning if host is not localhost
|
||||
host = cfg.get("host", "127.0.0.1")
|
||||
if host != "127.0.0.1":
|
||||
# Network host without TLS: show nudge
|
||||
print(
|
||||
f" {warn_mark} TLS: disabled — clipboard won't work on remote devices"
|
||||
)
|
||||
print(" Run: muxplex setup-tls")
|
||||
|
||||
# Auth status
|
||||
pw_path = get_password_path()
|
||||
|
||||
@@ -116,6 +116,18 @@ def _prompt_host_if_localhost() -> None:
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
def _show_tls_nudge_if_needed() -> None:
|
||||
"""Show TLS setup nudge if host is network and TLS is not configured."""
|
||||
from muxplex.settings import load_settings
|
||||
|
||||
settings = load_settings()
|
||||
host = settings.get("host", "127.0.0.1")
|
||||
tls_cert = settings.get("tls_cert", "")
|
||||
|
||||
if host != "127.0.0.1" and not tls_cert:
|
||||
print(" Tip: Enable HTTPS for clipboard support: muxplex setup-tls")
|
||||
def _systemd_install() -> None:
|
||||
muxplex_bin = _resolve_muxplex_bin()
|
||||
safe_path = os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin")
|
||||
@@ -128,6 +140,7 @@ def _systemd_install() -> None:
|
||||
subprocess.run(["systemctl", "--user", "daemon-reload"], check=True)
|
||||
subprocess.run(["systemctl", "--user", "enable", "--now", "muxplex"], check=True)
|
||||
_prompt_host_if_localhost()
|
||||
_show_tls_nudge_if_needed()
|
||||
|
||||
|
||||
def _systemd_uninstall() -> None:
|
||||
@@ -179,6 +192,7 @@ def _launchd_install() -> None:
|
||||
["launchctl", "bootstrap", f"gui/{uid}", str(_LAUNCHD_PLIST_PATH)], check=True
|
||||
)
|
||||
_prompt_host_if_localhost()
|
||||
_show_tls_nudge_if_needed()
|
||||
|
||||
|
||||
def _launchd_uninstall() -> None:
|
||||
|
||||
@@ -1618,11 +1618,14 @@ def test_doctor_shows_tls_enabled(tmp_path, monkeypatch, capsys):
|
||||
|
||||
|
||||
def test_doctor_shows_tls_clipboard_warning(tmp_path, monkeypatch, capsys):
|
||||
"""doctor() mentions clipboard or https when TLS is disabled."""
|
||||
"""doctor() mentions clipboard or https when TLS is disabled on network host."""
|
||||
import json
|
||||
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
settings_file = tmp_path / "settings.json"
|
||||
settings_file.write_text("{}")
|
||||
# Set host to network to trigger the TLS warning (not localhost)
|
||||
settings_file.write_text(json.dumps({"host": "0.0.0.0"}))
|
||||
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_file)
|
||||
|
||||
from muxplex.cli import doctor
|
||||
@@ -1632,7 +1635,7 @@ def test_doctor_shows_tls_clipboard_warning(tmp_path, monkeypatch, capsys):
|
||||
out = capsys.readouterr().out
|
||||
out_lower = out.lower()
|
||||
assert "clipboard" in out_lower or "https" in out_lower, (
|
||||
f"Expected 'clipboard' or 'https' in doctor TLS-disabled output, got: {out!r}"
|
||||
f"Expected 'clipboard' or 'https' in doctor TLS-disabled output for network host, got: {out!r}"
|
||||
)
|
||||
|
||||
|
||||
@@ -2005,3 +2008,48 @@ def test_setup_tls_regenerates_on_eof(tmp_path, monkeypatch, capsys):
|
||||
assert "keeping" in out_lower, (
|
||||
f"Expected 'keeping' in output after EOFError (default 'n'), got: {out!r}"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# task: TLS nudge hints in doctor and service install
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_doctor_tls_nudge_shows_run_command_on_network_host(capsys, tmp_path, monkeypatch):
|
||||
"""doctor must show 'Run: muxplex setup-tls' when host is network and TLS disabled."""
|
||||
import json
|
||||
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
settings_file = tmp_path / "settings.json"
|
||||
settings_file.write_text(json.dumps({"host": "0.0.0.0", "tls_cert": "", "tls_key": ""}))
|
||||
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_file)
|
||||
|
||||
from muxplex.cli import doctor
|
||||
|
||||
doctor()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "muxplex setup-tls" in out, (
|
||||
f"Expected 'muxplex setup-tls' in doctor output when host is 0.0.0.0 and TLS disabled, got: {out!r}"
|
||||
)
|
||||
|
||||
|
||||
def test_doctor_tls_nudge_hidden_on_localhost(capsys, tmp_path, monkeypatch):
|
||||
"""doctor must NOT show TLS nudge when host is 127.0.0.1."""
|
||||
import json
|
||||
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
settings_file = tmp_path / "settings.json"
|
||||
settings_file.write_text(json.dumps({"host": "127.0.0.1", "tls_cert": "", "tls_key": ""}))
|
||||
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_file)
|
||||
|
||||
from muxplex.cli import doctor
|
||||
|
||||
doctor()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "muxplex setup-tls" not in out, (
|
||||
f"TLS nudge must NOT appear in doctor output when host is 127.0.0.1, got: {out!r}"
|
||||
)
|
||||
|
||||
@@ -586,3 +586,80 @@ def test_launchd_logs_handles_keyboard_interrupt(monkeypatch):
|
||||
monkeypatch.setattr(subprocess, "run", mock_run)
|
||||
# Should not raise
|
||||
svc._launchd_logs()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# task: TLS nudge hints in service install
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_service_install_shows_tls_tip_on_network_host(capsys, tmp_path, monkeypatch):
|
||||
"""service install must show TLS tip when host is network and TLS disabled."""
|
||||
import json
|
||||
|
||||
import muxplex.service as svc
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
# Setup paths
|
||||
unit_dir = tmp_path / "systemd" / "user"
|
||||
unit_path = unit_dir / "muxplex.service"
|
||||
settings_file = tmp_path / "settings.json"
|
||||
|
||||
monkeypatch.setattr(svc, "_SYSTEMD_UNIT_DIR", unit_dir)
|
||||
monkeypatch.setattr(svc, "_SYSTEMD_UNIT_PATH", unit_path)
|
||||
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_file)
|
||||
|
||||
# Setup settings with network host and no TLS
|
||||
settings_file.write_text(json.dumps({"host": "0.0.0.0", "tls_cert": "", "tls_key": ""}))
|
||||
|
||||
# Mock subprocess to avoid actual systemctl calls
|
||||
calls = []
|
||||
monkeypatch.setattr(subprocess, "run", lambda cmd, **kw: calls.append(list(cmd)))
|
||||
|
||||
# Mock the prompt function
|
||||
monkeypatch.setattr(svc, "_prompt_host_if_localhost", lambda: None)
|
||||
|
||||
from muxplex.service import service_install
|
||||
|
||||
service_install()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "muxplex setup-tls" in out, (
|
||||
f"Expected 'muxplex setup-tls' in service install output when host is 0.0.0.0 and TLS disabled, got: {out!r}"
|
||||
)
|
||||
|
||||
|
||||
def test_service_install_hides_tls_tip_on_localhost(capsys, tmp_path, monkeypatch):
|
||||
"""service install must NOT show TLS tip when host is 127.0.0.1."""
|
||||
import json
|
||||
|
||||
import muxplex.service as svc
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
# Setup paths
|
||||
unit_dir = tmp_path / "systemd" / "user"
|
||||
unit_path = unit_dir / "muxplex.service"
|
||||
settings_file = tmp_path / "settings.json"
|
||||
|
||||
monkeypatch.setattr(svc, "_SYSTEMD_UNIT_DIR", unit_dir)
|
||||
monkeypatch.setattr(svc, "_SYSTEMD_UNIT_PATH", unit_path)
|
||||
monkeypatch.setattr(settings_mod, "SETTINGS_PATH", settings_file)
|
||||
|
||||
# Setup settings with localhost
|
||||
settings_file.write_text(json.dumps({"host": "127.0.0.1", "tls_cert": "", "tls_key": ""}))
|
||||
|
||||
# Mock subprocess
|
||||
calls = []
|
||||
monkeypatch.setattr(subprocess, "run", lambda cmd, **kw: calls.append(list(cmd)))
|
||||
|
||||
# Mock the prompt function
|
||||
monkeypatch.setattr(svc, "_prompt_host_if_localhost", lambda: None)
|
||||
|
||||
from muxplex.service import service_install
|
||||
|
||||
service_install()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
assert "muxplex setup-tls" not in out, (
|
||||
f"TLS tip must NOT appear in service install output when host is 127.0.0.1, got: {out!r}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user