mirror of
https://github.com/wahyd4/home-docker.git
synced 2026-08-08 20:15:03 +10:00
fix(demo-service): drafts accessible when authenticated
- New /site-content endpoint serves files with visibility+auth check - All paths proxied through API (not Caddy file_server) - Drafts: 401 canvas page (no auth) or 200 content (with auth) - Nonexistent: 404 canvas page - Preserves proper HTTP status codes
This commit is contained in:
@@ -33,16 +33,15 @@
|
||||
reverse_proxy localhost:3000
|
||||
}
|
||||
|
||||
# Root → redirect to admin
|
||||
handle / {
|
||||
reverse_proxy localhost:3000
|
||||
}
|
||||
|
||||
# Static demo sites — public, no auth
|
||||
handle_path /* {
|
||||
root * /data/demos
|
||||
file_server {
|
||||
index index.html
|
||||
# ── Site content: API handles visibility + auth ──
|
||||
# Public sites served without auth; drafts require login
|
||||
handle {
|
||||
rewrite * /site-content{uri}
|
||||
reverse_proxy localhost:3000 {
|
||||
header_up Host {host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto https
|
||||
header_up Cookie {http.request.header.Cookie}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import FastAPI, Request, HTTPException, UploadFile, File, Form
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse, FileResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
DEMO_ROOT = Path(os.environ.get("DEMO_ROOT", "/data/demos"))
|
||||
@@ -134,6 +134,38 @@ def error_page():
|
||||
"""Serve the canvas error page for any HTTP error."""
|
||||
return HTMLResponse(AUTH_REQUIRED_HTML)
|
||||
|
||||
@app.get("/site-content", response_class=FileResponse)
|
||||
@app.get("/site-content/{path:path}")
|
||||
async def site_content(path: str = "", request: Request = None):
|
||||
"""Serve site files. Drafts require auth."""
|
||||
if not path:
|
||||
raise HTTPException(404)
|
||||
parts = path.split("/", 1)
|
||||
site_name = parts[0]
|
||||
sub = parts[1] if len(parts) > 1 else ""
|
||||
if not site_name or not site_exists(site_name):
|
||||
return HTMLResponse(AUTH_REQUIRED_HTML, status_code=404)
|
||||
visible = is_site_visible(site_name)
|
||||
if not visible:
|
||||
if not check_auth(request):
|
||||
return HTMLResponse(AUTH_REQUIRED_HTML, status_code=401)
|
||||
site_dir = DEMO_ROOT / site_name
|
||||
target = (site_dir / sub) if sub else (site_dir / "index.html")
|
||||
if not target.exists():
|
||||
if not sub or sub == "index.html":
|
||||
for fb in [".index.html.draft", ".index.html.bak"]:
|
||||
p = site_dir / fb
|
||||
if p.exists():
|
||||
target = p
|
||||
break
|
||||
if not target.exists():
|
||||
return HTMLResponse(AUTH_REQUIRED_HTML, status_code=404)
|
||||
if target.is_dir():
|
||||
target = target / "index.html"
|
||||
if not target.exists():
|
||||
return HTMLResponse(AUTH_REQUIRED_HTML, status_code=404)
|
||||
return FileResponse(target)
|
||||
|
||||
@app.get("/api/sites")
|
||||
def list_sites(request: Request):
|
||||
user = require_auth(request)
|
||||
|
||||
Reference in New Issue
Block a user