From ba7101292ce381717498d1531bc055165bfaad8e Mon Sep 17 00:00:00 2001 From: Brian Krabach Date: Sat, 28 Mar 2026 21:53:00 -0700 Subject: [PATCH] feat: add /login stub and /auth/mode endpoint --- muxplex/main.py | 29 +++++++++++++++++++++++++++++ muxplex/tests/test_api.py | 22 ++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/muxplex/main.py b/muxplex/main.py index 5791bc3..ddcbbf7 100644 --- a/muxplex/main.py +++ b/muxplex/main.py @@ -22,6 +22,7 @@ import websockets.exceptions from websockets.typing import Subprotocol from fastapi import FastAPI, HTTPException, WebSocket +from fastapi.responses import HTMLResponse, JSONResponse as FastJSONResponse from fastapi.staticfiles import StaticFiles from pydantic import BaseModel @@ -465,6 +466,34 @@ async def terminal_ws_proxy(websocket: WebSocket) -> None: pass +# --------------------------------------------------------------------------- +# Auth routes +# --------------------------------------------------------------------------- + + +@app.get("/login", response_class=HTMLResponse) +async def login_page(): + """Stub login page — replaced in Phase 2 with branded login.html.""" + return HTMLResponse( + "" + "

muxplex login

" + "
" + "" + "" + "
" + "" + ) + + +@app.get("/auth/mode") +async def auth_mode_endpoint(): + """Return the current auth mode and running username.""" + username = "" + if _auth_mode == "pam": + username = pwd.getpwuid(os.getuid()).pw_name + return {"mode": _auth_mode, "user": username} + + # --------------------------------------------------------------------------- # Static file serving — MUST come after all API routes (first-match-wins) # --------------------------------------------------------------------------- diff --git a/muxplex/tests/test_api.py b/muxplex/tests/test_api.py index b53850b..45cafc0 100644 --- a/muxplex/tests/test_api.py +++ b/muxplex/tests/test_api.py @@ -683,3 +683,25 @@ def test_non_localhost_without_auth_gets_redirected(monkeypatch): response = c.get("/health", follow_redirects=False) # Should be redirected to /login or get 307/401 assert response.status_code in (307, 401) + + +# --------------------------------------------------------------------------- +# Login stub and auth mode endpoint +# --------------------------------------------------------------------------- + + +def test_get_login_returns_200_html(client): + """GET /login returns 200 with HTML content.""" + response = client.get("/login") + assert response.status_code == 200 + assert "text/html" in response.headers["content-type"] + assert "