mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-29 11:19:44 +02:00
[eric] auth: dev-only /api/dev/token so the split-port frontend can authenticate (404s when packaged)
This commit is contained in:
@@ -186,6 +186,9 @@ _AUTH_EXEMPT_EXACT = {
|
||||
# public api.openswarm.com/api/oauth/google/refresh doesn't already
|
||||
# do for any internet caller, so no new attack surface.
|
||||
"/api/tools/google-oauth-token",
|
||||
# Dev-only token handoff for the split-port frontend (no Electron preload
|
||||
# to read the token from). The route itself 404s in packaged builds.
|
||||
"/api/dev/token",
|
||||
}
|
||||
|
||||
_AUTH_EXEMPT_PREFIX = (
|
||||
|
||||
@@ -386,6 +386,17 @@ async def websocket_dashboard(websocket: WebSocket):
|
||||
ws_manager.disconnect_global(websocket)
|
||||
|
||||
|
||||
@app.get("/api/dev/token")
|
||||
async def dev_token():
|
||||
"""Hand the per-install token to the dev frontend, which has no Electron
|
||||
preload to read it from. Disabled in packaged builds (the preload exists
|
||||
there); localhost binding is the only thing gating it in dev."""
|
||||
if os.environ.get("OPENSWARM_PACKAGED") == "1":
|
||||
return JSONResponse({"error": "not available"}, status_code=404)
|
||||
from backend.auth import get_auth_token
|
||||
return JSONResponse({"token": get_auth_token()})
|
||||
|
||||
|
||||
@app.post("/api/browser/command")
|
||||
async def browser_command(request: Request):
|
||||
"""HTTP endpoint called by the browser MCP server subprocess.
|
||||
|
||||
@@ -268,3 +268,26 @@ def test_signout_succeeds_even_when_cloud_unreachable(client, reset_settings):
|
||||
s2 = load_settings()
|
||||
assert s2.user_id is None
|
||||
assert s2.openswarm_bearer_token is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# The dev-token handoff must be dev-only so it can't widen prod surface (#49).
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_dev_token_is_dev_only():
|
||||
"""/api/dev/token hands the install token to the split-port dev frontend
|
||||
without auth, but 404s in packaged builds where the preload supplies it."""
|
||||
import os
|
||||
import backend.auth as auth_mod
|
||||
noauth = TestClient(app) # deliberately no bearer header
|
||||
|
||||
os.environ.pop("OPENSWARM_PACKAGED", None)
|
||||
r = noauth.get("/api/dev/token")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["token"] == auth_mod._TOKEN
|
||||
|
||||
os.environ["OPENSWARM_PACKAGED"] = "1"
|
||||
try:
|
||||
assert noauth.get("/api/dev/token").status_code == 404
|
||||
finally:
|
||||
os.environ.pop("OPENSWARM_PACKAGED", None)
|
||||
|
||||
@@ -23,6 +23,18 @@ export async function refreshAuthToken(): Promise<string> {
|
||||
} catch {
|
||||
_authTokenCache = '';
|
||||
}
|
||||
return _authTokenCache;
|
||||
}
|
||||
// Dev (split-port, no Electron preload): the backend hands us the token over
|
||||
// localhost. The route 404s in packaged builds, so this only fires under run.sh.
|
||||
try {
|
||||
const r = await fetch(`http://${host}:${port}/api/dev/token`);
|
||||
if (r.ok) {
|
||||
const data = await r.json();
|
||||
_authTokenCache = typeof data?.token === 'string' ? data.token : '';
|
||||
}
|
||||
} catch {
|
||||
_authTokenCache = '';
|
||||
}
|
||||
return _authTokenCache;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user