feat(admin): log Claude ind igen fra telefonen
Claude Codes login på værten holder 28 dage, og et langtidstoken kan ikke bruges til Remote Control, så der skal logges ind igen hver 4. uge. Hidtil krævede det en terminal for at kopiere en adresse ud og en kode ind igen. /admin/claude-login viser hvornår login udløber og har en "Start login"-knap. Værten (claude-login-agent, som spørger portalen, ikke omvendt) starter `claude auth login`, og siden viser login-adressen; koden fra Claudes side indsættes på samme side og hentes af værten et par sekunder senere. Portalen gemmer kun den korte kode, indtil den er hentet; den virker kun sammen med login-processen på værten (PKCE). Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -21,6 +21,7 @@ import mcpkeys
|
||||
import mcp_server
|
||||
import mcp_gateway
|
||||
import secretdrop
|
||||
import claudelogin
|
||||
|
||||
# Portalens egen MCP (FastMCP), monteret in-process på /mcp. json_response=True
|
||||
# => almindelig JSON (ingen SSE), så det passerer edge'en utunet. Bearer-gated.
|
||||
@@ -353,6 +354,34 @@ async def admin_secrets_delete(request: Request, navn: str):
|
||||
return RedirectResponse(f"/admin/secrets?saved={'Slettet' if ok else 'Fandtes ikke'}", status_code=303)
|
||||
|
||||
|
||||
@app.get("/admin/claude-login", response_class=HTMLResponse)
|
||||
async def admin_claude_login(request: Request):
|
||||
user = require_admin(request)
|
||||
return templates.TemplateResponse(request, "admin_claude_login.html", {
|
||||
"request": request, "user": user, "is_admin": True, "st": claudelogin.state()})
|
||||
|
||||
|
||||
@app.get("/admin/claude-login/status")
|
||||
async def admin_claude_login_status(request: Request):
|
||||
require_admin(request)
|
||||
return JSONResponse(claudelogin.state(), headers={"Cache-Control": "no-store"})
|
||||
|
||||
|
||||
@app.post("/admin/claude-login/start")
|
||||
async def admin_claude_login_start(request: Request):
|
||||
user = require_admin(request)
|
||||
claudelogin.request((user or {}).get("preferred_username") or "?")
|
||||
return JSONResponse(claudelogin.state())
|
||||
|
||||
|
||||
@app.post("/admin/claude-login/kode")
|
||||
async def admin_claude_login_code(request: Request):
|
||||
require_admin(request)
|
||||
f = await request.form()
|
||||
fejl = claudelogin.submit_code(f.get("kode") or "")
|
||||
return JSONResponse({"error": fejl, **claudelogin.state()}, status_code=400 if fejl else 200)
|
||||
|
||||
|
||||
@app.get("/admin/groups", response_class=HTMLResponse)
|
||||
async def admin_groups(request: Request, saved: str = ""):
|
||||
user = require_admin(request)
|
||||
|
||||
Reference in New Issue
Block a user