Add remote browser pages and website sync

Enable managed remote browser custom pages with login autofill and add website sync workflows so external admin surfaces can be handled inside SmartUp.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
liumangmang
2026-05-15 15:43:58 +08:00
parent a13a0070a5
commit 7adc7c00ab
43 changed files with 6615 additions and 641 deletions
+13 -2
View File
@@ -3,7 +3,7 @@ import logging
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import FastAPI
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
@@ -14,7 +14,8 @@ from app.models.admin_user import AdminUser
from app.database import SessionLocal
from app.utils.auth import hash_password
from app.services.scheduler import start_scheduler, stop_scheduler
from app.routers import auth, upstreams, webhooks, logs, custom_pages
from app.routers import auth, upstreams, webhooks, logs, custom_pages, browser_sessions, websites
from app.services.browser_session_service import browser_sessions as browser_session_service
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s %(message)s")
logger = logging.getLogger(__name__)
@@ -48,6 +49,7 @@ async def lifespan(app: FastAPI):
_init_admin()
start_scheduler()
yield
await browser_session_service.shutdown()
stop_scheduler()
@@ -75,6 +77,8 @@ app.include_router(upstreams.router)
app.include_router(webhooks.router)
app.include_router(logs.router)
app.include_router(custom_pages.router)
app.include_router(browser_sessions.router)
app.include_router(websites.router)
@app.get("/healthz")
@@ -87,6 +91,13 @@ STATIC_DIR = Path(__file__).parent.parent / "static"
if STATIC_DIR.exists():
app.mount("/assets", StaticFiles(directory=str(STATIC_DIR / "assets")), name="assets")
@app.api_route("/favicon.svg", methods=["GET", "HEAD"])
def serve_favicon():
favicon = STATIC_DIR / "favicon.svg"
if not favicon.exists():
raise HTTPException(status_code=404, detail="favicon not found")
return FileResponse(str(favicon), media_type="image/svg+xml")
@app.get("/{full_path:path}")
def serve_spa(full_path: str):
index = STATIC_DIR / "index.html"