From d9c77e0b463811f66d339ab2ce5805034cc29685 Mon Sep 17 00:00:00 2001 From: Patrick Date: Wed, 3 Jun 2026 09:29:13 +0200 Subject: [PATCH] Konfigurierbares CORS per ZMB_CORS_ORIGINS + dynamische Frontend-URL - main.py: CORS-Origins aus ZMB_CORS_ORIGINS (kommagetrennt), Default "*" - allow_credentials automatisch aktiv bei konkreten Origins, aus bei "*" - Root-Endpoint liefert Frontend-URL dynamisch via request.base_url - keine hartkodierten IPs mehr im Anwendungscode - Doku in CLAUDE.md und systemd-Unit ergaenzt Co-Authored-By: Claude Opus 4.8 --- backend/main.py | 24 +++++++++++++++++++----- deploy/zfs-manager-backend.service | 4 ++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/backend/main.py b/backend/main.py index 402eb68..520b8a8 100644 --- a/backend/main.py +++ b/backend/main.py @@ -6,6 +6,7 @@ FastAPI backend for ZFS pool management import asyncio import json import logging +import os import sys from pathlib import Path from typing import Set @@ -35,11 +36,24 @@ app = FastAPI( version="1.0.0" ) -# CORS middleware (adjust origins for production!) +# CORS middleware — configurable via environment variable. +# Set ZMB_CORS_ORIGINS to a comma-separated list of allowed origins +# (e.g. "https://:8090,http://:3000"). +# Defaults to "*" for development if unset. +_cors_origins_env = os.getenv("ZMB_CORS_ORIGINS", "*").strip() +cors_origins = ( + ["*"] + if _cors_origins_env == "*" + else [origin.strip() for origin in _cors_origins_env.split(",") if origin.strip()] +) +# allow_credentials cannot be combined with the "*" wildcard per the CORS spec +allow_credentials = cors_origins != ["*"] +logger.info("CORS allowed origins: %s", cors_origins) + app.add_middleware( CORSMiddleware, - allow_origins=["*"], # Change to specific origins in production - allow_credentials=True, + allow_origins=cors_origins, + allow_credentials=allow_credentials, allow_methods=["*"], allow_headers=["*"], ) @@ -144,13 +158,13 @@ async def status_check(): # Root endpoint - API info only @app.get("/") -async def root(): +async def root(request: Request): """API info""" return { "name": "ZMB Webui API", "version": "1.0.0", "docs": "/docs", - "frontend": "http://192.168.1.179:3000" + "frontend": str(request.base_url) } diff --git a/deploy/zfs-manager-backend.service b/deploy/zfs-manager-backend.service index 9d05951..1166468 100644 --- a/deploy/zfs-manager-backend.service +++ b/deploy/zfs-manager-backend.service @@ -9,6 +9,10 @@ WorkingDirectory=/opt/zmb-webui/backend Environment="PATH=/opt/zmb-webui/venv/bin" Environment="PYTHONUNBUFFERED=1" Environment="PYTHONDONTWRITEBYTECODE=1" +# CORS: comma-separated list of allowed frontend origins. +# Leave unset (or "*") for development. Set to specific origins in production, +# e.g. Environment="ZMB_CORS_ORIGINS=https://:8090" +#Environment="ZMB_CORS_ORIGINS=*" ExecStart=/opt/zmb-webui/venv/bin/python -m uvicorn main:app \ --host 0.0.0.0 \