From 5fb92fd58229e4985f059f0d4b39aed6b4173f1f Mon Sep 17 00:00:00 2001 From: Tronax Date: Thu, 27 Aug 2026 20:44:39 +0200 Subject: [PATCH] fix(config): make FRONTEND_URL optional and default to APP_URL --- Dockerfile | 5 +++-- backend/.env.example | 10 +++++++--- backend/internal/config/config.go | 10 ++++++++-- docker-compose.yml | 4 +++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index d132cd9..6cfd7eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,8 +36,9 @@ USER app ENV PORT=8080 \ DB_PATH=/data/wannpassts.db \ STATIC_DIR=/app/dist \ - APP_URL=http://localhost:8080 \ - FRONTEND_URL=http://localhost:8080 + APP_URL=http://localhost:8080 +# FRONTEND_URL ist bewusst nicht gesetzt: Ohne Wert leiten Callbacks auf APP_URL. +# Bei getrenntem Frontend-Host einfach -e FRONTEND_URL=https://… setzen. VOLUME /data EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ diff --git a/backend/.env.example b/backend/.env.example index 54f1eeb..a9be5c8 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -7,11 +7,15 @@ PORT=8080 # SQLite-Datenbankdatei (relativ zum backend-Verzeichnis) DB_PATH=wannpassts.db -# Öffentliche URL des Backends (wichtig für den Google-OAuth-Redirect!) +# Öffentliche URL des Backends. Wichtig für: +# - Google-OAuth-Redirect: {APP_URL}/api/calendars/google/callback +# - Umleitung nach erfolgreichem Google-Login (sofern FRONTEND_URL leer) APP_URL=http://localhost:8080 -# URL des Frontends (dev: Vite, prod: gleiche Origin wie StaticDir) -FRONTEND_URL=http://localhost:5173 +# URL des Frontends – optional! Leer/unset = es wird APP_URL verwendet +# (Single-Origin, z. B. Docker). Nur setzen, wenn das Frontend getrennt läuft +# (Dev: Vite auf http://localhost:5173). +FRONTEND_URL= # Statische Secrets – in Produktion zwingend setzen (z. B. `openssl rand -hex 32`) # JWT_SECRET sichert Logins, ENCRYPTION_KEY verschlüsselt gespeicherte Kalender-Tokens. diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 1f8f7e0..8555b37 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "log" "os" + "strings" "github.com/joho/godotenv" ) @@ -29,14 +30,19 @@ func Load() Config { cfg := Config{ Port: env("PORT", "8080"), DBPath: env("DB_PATH", "wannpassts.db"), - AppURL: env("APP_URL", "http://localhost:8080"), - FrontendURL: env("FRONTEND_URL", "http://localhost:5173"), + AppURL: strings.TrimSuffix(env("APP_URL", "http://localhost:8080"), "/"), + FrontendURL: strings.TrimSuffix(os.Getenv("FRONTEND_URL"), "/"), JWTSecret: os.Getenv("JWT_SECRET"), EncryptionKey: os.Getenv("ENCRYPTION_KEY"), GoogleClientID: os.Getenv("GOOGLE_CLIENT_ID"), GoogleClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"), StaticDir: env("STATIC_DIR", ""), } + // FRONTEND_URL ist optional: Ohne eigenen Wert leiten Google-Callbacks etc. + // auf die öffentliche App-URL (APP_URL) – wichtig für Single-Origin-Deployments. + if cfg.FrontendURL == "" { + cfg.FrontendURL = cfg.AppURL + } if cfg.JWTSecret == "" { cfg.JWTSecret = randomHex(32) log.Println("WARNUNG: JWT_SECRET nicht gesetzt – temporäres Secret erzeugt (Sessions verfallen bei Neustart).") diff --git a/docker-compose.yml b/docker-compose.yml index 9e95fba..a6f3ecf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,8 +10,10 @@ services: # (cp backend/.env.example backend/.env) und Kommentar entfernen: # env_file: backend/.env environment: + # APP_URL = öffentliche URL; Frontend-Callbacks leiten standardmäßig dorthin. APP_URL: ${APP_URL:-http://localhost:8080} - FRONTEND_URL: ${FRONTEND_URL:-http://localhost:8080} + # Optional bei getrenntem Frontend-Host: + FRONTEND_URL: ${FRONTEND_URL:-} JWT_SECRET: ${JWT_SECRET:-} ENCRYPTION_KEY: ${ENCRYPTION_KEY:-} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}