Unter Einstellungen gibt es jetzt eine Karte "Mealie (Rezepte)": Adresse, Benutzername, Passwort. Vorrania meldet sich damit EINMAL an (POST /api/auth/token), laesst sich von Mealie ueber POST /api/users/api-tokens ein Dauertoken ausstellen und verwirft das Passwort sofort - es steht in keiner Zeile der Datenbank, in keiner Antwort und in keinem Fehlertext. Wer sein Passwort gar nicht erst eintippen will, haekelt "Ich gebe lieber selbst ein Token ein" an. Das Token liegt NICHT in den Einstellungen: GET /settings liefert jedem angemeldeten Nutzer alle Zeilen im Klartext. Eine Ausschlussliste dort waere beim naechsten Geheimnis vergessen, deshalb eine eigene Tabelle ohne jeden Leseweg - setzen, loeschen, und die Auskunft "ist gesetzt". Was keinen Ausgang hat, kann nicht durchrutschen. Ein Test prueft genau das. Der Dienst folgt services/oidc.py, nicht off.py: Bei Open Food Facts ist "kein Treffer" der Normalfall und wird still zu None, hier ist "Mealie antwortet nicht" ein Fehler, den der Nutzer sehen muss. Die Kennungen trennen auch, was verschieden ist - ein falsches Passwort (400) ist etwas anderes als ein weggetretener Server (502). Mealie 1.x legt die Haushalts-Routen unter /api/groups/, 2.x unter /api/households/. Erkannt wird das zur Laufzeit mit einer Anfrage und dann eine Stunde gepuffert; ueber die Versionsnummer waere es unzuverlaessig, die melden Installationen uneinheitlich. Rezeptliste und -abgleich kommen als Naechstes; dies ist der Teil, mit dem sich der Server ueberhaupt erst verbinden laesst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
53 lines
2.0 KiB
Python
53 lines
2.0 KiB
Python
from functools import lru_cache
|
||
|
||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||
|
||
|
||
class Settings(BaseSettings):
|
||
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
|
||
|
||
# Database
|
||
database_url: str = "postgresql+psycopg2://vorrania:vorrania@localhost:5432/vorrania"
|
||
|
||
# Auth / JWT
|
||
jwt_secret: str = "change-me-in-production"
|
||
jwt_algorithm: str = "HS256"
|
||
# Rueckfallwert fuer die Sitzungsdauer. Im Betrieb entscheidet die
|
||
# Einstellung "session_days" (Verwaltung -> Einstellungen); dieser Wert gilt
|
||
# nur, solange dort nichts gesetzt ist.
|
||
jwt_expire_minutes: int = 60 * 24 * 30 # 30 Tage
|
||
|
||
# First admin, created on startup if no users exist
|
||
admin_username: str = "admin"
|
||
admin_password: str = "changeme"
|
||
|
||
# Oeffentliche Adresse der Instanz, z.B. "https://vorrania.example.com".
|
||
# Wird fuer die OIDC-Rueckleit-Adresse gebraucht und laesst sich NICHT aus dem
|
||
# Request ableiten: das /api-Praefix entsteht erst in nginx, und es gibt weder
|
||
# root_path noch ProxyHeadersMiddleware.
|
||
public_base_url: str = ""
|
||
|
||
# Open Food Facts (Lebensmittel)
|
||
off_base_url: str = "https://world.openfoodfacts.org"
|
||
# Open Products Facts (allgemeine Produkte / Gegenstände) – gleiche API-Struktur.
|
||
opf_base_url: str = "https://world.openproductsfacts.org"
|
||
off_timeout_seconds: float = 8.0
|
||
|
||
# Behaviour
|
||
expiry_warning_days_default: int = 7
|
||
# Wie lange eine angebrochene Packung haelt, wenn weder Artikel noch
|
||
# Kategorie etwas sagen. Im Betrieb entscheidet die Einstellung
|
||
# "open_days"; dieser Wert gilt nur, solange dort nichts gesetzt ist.
|
||
open_days_default: int = 3
|
||
# Mealie: Adresse und Token stehen in der Datenbank (Admin traegt sie in der
|
||
# Oberflaeche ein), hier nur die Geduld fuer eine Antwort.
|
||
mealie_timeout_seconds: float = 10.0
|
||
|
||
# CORS (comma separated); "*" allows all
|
||
cors_origins: str = "*"
|
||
|
||
|
||
@lru_cache
|
||
def get_settings() -> Settings:
|
||
return Settings()
|