Die Anmeldung galt fest 7 Tage - und die Frist lief ab dem *Anmelden*, nicht
ab der letzten Nutzung. Wer die App taeglich benutzte, flog trotzdem
punktgenau nach einer Woche hinaus.
Beides ist jetzt geregelt:
- Einstellungen -> Anmeldung: 7 Tage bis 1 Jahr oder unbegrenzt. Gilt fuer
Website und App gemeinsam, weil beide dasselbe Token bekommen - auch nach
Single Sign-on.
- POST /auth/refresh schiebt die Frist beim Start nach vorn. Damit zaehlt die
eingestellte Dauer ab dem letzten Besuch, und eine geaenderte Einstellung
greift ohne Neuanmeldung.
"Unbegrenzt" heisst ein Token ganz ohne exp. Das ist bewusst folgenreich: Es
gibt keine Sperrliste, eine erteilte Anmeldung laesst sich nicht einzeln
zurueckziehen. Die Oberflaeche sagt das dazu und nennt den einzigen Ausweg
(JWT_SECRET aendern).
/auth/refresh nimmt bewusst nur JWTs an, keine langlebigen API-Token: aus
einem jederzeit widerrufbaren Zugang (Home Assistant) waere sonst ein
unwiderruflicher geworden.
Der Rueckfallwert aus der Umgebung steigt von 7 auf 30 Tage - er gilt nur noch,
solange nichts eingestellt ist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bisher hiess JEDER fehlgeschlagene git pull "lokale Änderungen?" - samt dem Rat,
"git checkout -- ." auszufuehren. Bei einem DNS- oder Netzausfall behebt das
nichts und wirft im schlimmsten Fall Aenderungen weg, die voellig in Ordnung
waren.
Die Ausgabe von git wird jetzt ausgewertet und die Ursache benannt: nicht
aufloesbarer Name, nicht erreichbarer Server oder tatsaechlich abweichender
lokaler Stand. Nur im letzten Fall erscheint der checkout-Hinweis. Dazu der
betroffene Rechnername und die passenden Pruefbefehle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
In Authentik hat jede Anwendung standardmaessig ihren eigenen Issuer, abgeleitet
aus dem Application-Slug. Web- und App-Client brauchen dort aber zwei getrennte
Anwendungen, weil ein Provider entweder vertraulich ODER oeffentlich ist.
Bisher wurde das App-Token gegen den Issuer und den Schluesselsatz der
Web-Anwendung geprueft - die App-Anmeldung waere damit an der iss-Pruefung
gescheitert. Discovery und JWKS werden jetzt je Adresse gepuffert statt je
Anbieter, und OIDC_<KUERZEL>_NATIVE_DISCOVERY_URL benennt die Anwendung des
App-Clients. Ohne die Variable bleibt es bei einer gemeinsamen Adresse.
Ausserdem im README: der Signing Key muss gesetzt sein, sonst signiert Authentik
mit HS256 und das Token wird abgelehnt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neben dem Passwort-Login gibt es jetzt einen zweiten, gleichberechtigten Weg:
OpenID Connect gegen einen selbst gehosteten Anmeldedienst. Ohne Konfiguration
aendert sich nichts - keine SSO-Knoepfe, Passwort-Login wie bisher.
Der Anmeldedienst ist NUR fuer die Anmeldung zustaendig. Danach stellt Vorrania
sein eigenes Token aus wie beim Passwort-Login, deshalb bleiben deps.py, die
Rollenpruefung und die langlebigen API-Tokens unveraendert.
Backend
- Anbieter kommen aus der Umgebung (OIDC_PROVIDERS + OIDC_<KUERZEL>_*). Ein
zweiter Anbieter ist damit reine Konfiguration, ohne Codeaenderung.
- Browser-Weg (vertraulicher Client) und App-Weg (oeffentlicher Client, PKCE)
enden beide im selben Token-Schema.
- state/nonce/PKCE-Verifier liegen in einer kurzlebigen Tabelle statt in einem
Cookie: Starlettes CORS-Schicht spiegelt bei allow_origins=["*"] zusammen mit
allow_credentials die Herkunft zurueck, sobald ein Request ein Cookie traegt.
Ohne Cookie entsteht diese Wechselwirkung erst gar nicht - und der Ablauf
bleibt mit der db-Fixture pruefbar.
- Zuordnung ueber die sub des Anbieters; die Erstverknuepfung laeuft ueber die
BESTAETIGTE E-Mail-Adresse. Rollen kommen nie aus dem Anbieter, und ein
gleichlautender preferred_username uebernimmt nie ein bestehendes Konto.
- users.password_hash darf jetzt leer sein (reine SSO-Konten). verify_password
faengt das ab, sonst antwortete der Login mit 500 statt 401.
Verknuepfen bestehender Konten
- Neue Seite "Mein Konto" (fuer alle Benutzer, nicht nur Admins): verknuepfen
und wieder loesen. Die Berechtigung stammt aus der laufenden Sitzung, es
braucht also weder eine hinterlegte Adresse noch Admin-Rechte.
- Der Start laeuft ueber POST, weil eine Seitennavigation das Bearer-Token
nicht mitschicken kann.
- Die letzte Anmeldemoeglichkeit eines Kontos laesst sich nicht loesen.
iOS
- AppAuth (erste Paketabhaengigkeit) mit PKCE im System-Browser, nie in einem
eingebetteten WebView, und ohne Client-Secret.
- offline_access nur im App-Weg: der Browser-Weg braucht kein Refresh-Token und
bekaeme sonst einen ueberfluessigen Zustimmungsdialog.
- Anmeldezustand je Serverprofil im Keychain; abgelaufene Token erneuert die App
still im Hintergrund. Gleichzeitige 401er teilen sich eine Erneuerung.
Deployment
- docker-compose reicht die ganze .env durch. Einzeln aufzuzaehlen ginge nur mit
fest verdrahteten Kuerzeln - genau das soll ein weiterer Anbieter nicht
erfordern.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Auf ausdruecklichen Wunsch jetzt auch die internen Bezeichner, weil die
Installation noch keine echten Daten enthaelt: POSTGRES_USER/PASSWORD/DB, der
Volume-Name, die Standard-DATABASE_URL, der localStorage-Schluessel und die
iOS-Zeichenketten inklusive Keychain-Konto.
Das setzt eine leere Datenbank voraus: Der neue Volume-Name legt eine neue,
leere Datenbank an. Die alte bleibt als verwaistes Volume liegen und muss von
Hand entfernt werden.
Die Warnung in docker-compose.yml bleibt stehen, damit eine spaetere
Umbenennung nicht versehentlich mit Daten im Volume passiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sichtbarer Name ueberall: Kopfzeichen der Oberflaeche, Seitentitel, Favicon,
API-Titel, User-Agent zu Open Food Facts, Dateinamen der Sicherungen, README,
Roadmap, Installer- und Update-Skript, npm-Paketname.
Bewusst NICHT umbenannt, jeweils mit Begruendung im Code:
- POSTGRES_USER/DB und der Volume-Name bleiben "project_good". Ein neuer
Volume-Name legt eine leere Datenbank an, ein neuer Benutzername scheitert am
bestehenden Volume - vorhandene Bestaende waeren verloren.
- Der localStorage-Schluessel bleibt, sonst waeren alle Browser einmal
ausgesperrt.
- ios/ bleibt unangetastet (wird getrennt bearbeitet).
Die Klon-Adresse im README zeigt jetzt auf .../vorrania.git; das Repo in Gitea
muss dafuer umbenannt werden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Holt den neuesten Stand aus Git und baut die Container neu. Findet seinen
eigenen Pfad (von ueberall aufrufbar), nutzt die vorhandene deploy/.env,
erkennt docker compose v1/v2 und prueft am Ende /api/health.
Optionen: --prune (alte Images aufraeumen), --no-pull (nur neu bauen).
Bei fehlgeschlagenem git pull gibt es einen Hinweis auf lokale Aenderungen.
Im Repo direkt als ausfuehrbar markiert; README ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verhindert, dass 'chmod +x install.sh' lokal als Aenderung erscheint und
kuenftige 'git pull' mit "local changes would be overwritten" blockiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- install.sh: ensure_example legt .env.example an falls fehlend; env_hint weist
klar auf die anpassbare .env hin; wait_for_backend pollt /api/health und meldet
502-Ursachen mit Log-Hinweis.
- web/api.js: HTML-Fehlerseiten (z.B. nginx 502) nicht mehr roh anzeigen,
stattdessen verständliche Meldung.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neue Helfer ensure_curl + pkg_install (apt/dnf/yum/apk/pacman/zypper) mit
sudo-Erkennung; wird vor der Docker-Installation aufgerufen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Anzeigename, Paketname, Token-Key, DB-/Volume-Namen auf project_good
- README Clone-Abschnitt mit git.scarriffle.com/Scarriffle/project-good
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>