Uni-Verein 1.9.1 – Mitgliedsstatus, bessere Beitragsverwaltung und mehr Sicherheit 🧾🛡️
Veröffentlicht am 23. Oktober 2026
Uni-Verein 1.9.1 bringt einen Mitgliedsstatus (Mitglied oder Fördermitglied), eine verbesserte Beitragsverwaltung mit Löschen offener Beiträge und ein deutlich erweitertes Audit Log. Dazu kommen mehrere Sicherheitsverbesserungen. Wer einen eigenen Reverse Proxy vor Uni-Verein betreibt, muss beim Update einmalig etwas einrichten, siehe die Hinweise zum Update unten.
Highlights
- ⭐ Mitgliedsstatus (UV-58): Jedes Mitglied ist Mitglied oder Fördermitglied, mit Spalte und Filter in der Mitgliederliste und der Beitragsverwaltung
- 🗑️ Offene Beiträge löschen (UV-57): Admins und Finanzverwalter können offene Beiträge löschen, z. B. bei zurückgebuchten Lastschriften. Admins können sie wiederherstellen
- 🚫 Keine Abrechnung mehr nach dem Austritt (UV-63): Gelöschte Mitglieder und Mitglieder mit verstrichenem Austrittsdatum werden nicht mehr abgerechnet
- 📜 Erweitertes Audit Log: Benutzer, Gläubigerdaten, Beitragstarife, Beiträge, Mail-Einstellungen, Backup-Wiederherstellung und CSV-Import werden protokolliert
- 🛡️ Sicherere Anmeldung: Die Login-Sperre trifft nicht mehr alle Nutzer eines Kontos, und gelöschte oder geänderte Benutzer verlieren sofort den Zugriff
Neue Funktionen
- ⭐ Mitgliedsstatus (UV-58): Mitglieder haben jetzt einen Mitgliedsstatus, im Formular einstellbar und im CSV-Import als Spalte "Membership status" (
MEMBERoderSUPPORTING_MEMBER, leer = Mitglied). Die Mitgliederliste und die Beitragsverwaltung bekommen dazu eine Spalte und einen Filter. Die Beitragsverwaltung zeigt zusätzlich die Mitgliedsnummer - 🗑️ Offene Beiträge löschen (UV-57): Neben "Zahlung erhalten" gibt es ein Mülleimer-Symbol, das nach einer Bestätigung einen offenen Beitrag entfernt. Die Beiträge werden soft-gelöscht und im Audit Log protokolliert, Admins können sie über "Gelöschte anzeigen" einsehen und wiederherstellen
- 📜 Audit Log für alle wichtigen Vorgänge: Zusätzlich zu den Mitgliedern werden Änderungen an Benutzern, Gläubigerdaten, Beitragstarifen, bezahlten/offenen Beiträgen, SMTP-/Mail-Einstellungen, das Einspielen eines Backups und der CSV-Import von Mitgliedern protokolliert. Passwörter, IBAN/BIC und importierte Mitgliederdaten werden nicht gespeichert
Fehlerbehebungen
- 🚫 Abrechnung (UV-63): Gelöschte Mitglieder und Mitglieder, deren Austrittsdatum verstrichen ist, werden bei der Beitragserzeugung und im SEPA-Export nicht mehr berücksichtigt. Liegt das Austrittsdatum in der Zukunft, wird noch bis zu diesem Datum abgerechnet
- 👥 Mitgliederkategorie-Filter (UV-61): Wird der Filter der Mitgliederkategorie wieder auf "Alle" gestellt, zeigt die Liste wieder alle Mitglieder
- 🕵️ Audit Log (UV-10): Einträge gelöschter Benutzer werden als "Deleted user" angezeigt, statt ausgeblendet zu werden
- 📱 App-Icon unter Android (UV-55): Das Web-Manifest hat den richtigen Content-Type, und für die thematischen Symbole von Android 16 ist ein einfarbiges Icon enthalten. Die App-Icons sind RGBA-PNGs, das iOS-Icon ist deckend
- 🌐 Englische Texte der Beitragsverwaltung: Wegen eines falschen Übersetzungsschlüssels wurden die englischen Texte nicht angezeigt
- 📧 Update-Hinweis per E-Mail: Die Mail "Neue Version verfügbar" ging stündlich an die Admins, wenn einer von ihnen keine E-Mail-Adresse hatte. Solche Admins werden jetzt übersprungen
- 💶 SEPA-Export: Die Prüfungen von IBAN und Gläubiger-ID akzeptieren nur noch die Ziffern 0-9, damit ungültige IBANs die
pain.008-Datei nicht mehr beschädigen können
Sicherheit
- 🔐 Login-Sperre pro Benutzername und Adresse: Die Sperre wird nicht mehr pro Konto, sondern pro Benutzername und Adresse des Besuchers gezählt. Ein Angreifer kann so bekannte Konten wie
Adminnicht mehr dauerhaft für alle sperren. IPv6 zählt pro /64-Netz, unbekannte Benutzernamen werden wie bekannte gesperrt. Der Zustand liegt im Arbeitsspeicher und wird durch einen Neustart des Backends zurückgesetzt. Mehr dazu unter Benutzerkonto & Sicherheit - 🎫 Tokens werden bei jeder Anfrage geprüft: Die Anmeldung wird bei jeder Anfrage gegen den aktuellen Benutzer und seine Rolle geprüft, gelöschte oder geänderte Benutzer verlieren sofort den Zugriff und nicht erst nach bis zu 8 Stunden
- 🗃️ Gelöschte Mitglieder: Nur Admins können gelöschte Mitglieder noch lesen oder ändern, ein zweites Löschen überschreibt nicht mehr den ursprünglichen Löschzeitpunkt
- 📝 Selbstregistrierung: Das Datum der SEPA-Zustimmung setzt der Server,
sepaConsentwird vonPOST /self-enrollmentnicht mehr akzeptiert. HTML in Namen wird in System-Mails und Rundmail-Platzhaltern kodiert, Namensfelder sind auf 100 Zeichen begrenzt - 🧱 Proxy-Vertrauen (nginx):
X-Forwarded-Forwird nicht mehr von dem gesamten Bereich172.16.0.0/12akzeptiert, wodurch sich Rate-Limit und Login-Sperre umgehen und die IP bei Selbstregistrierungen fälschen ließen. Vertraut wird nur noch dem Caddy ausdocker-compose-tls.yml(feste Adresse172.31.250.2im Netzwerkedge)
Logging
- 🪵 Wichtige Aktionen werden protokolliert: Anmeldungen, Benutzer- und Mitgliederverwaltung, Selbstregistrierung, CSV-Import/-Export, Beiträge, SEPA-Exporte, Belege, Mail, Kalender, Backups, Einstellungen und Hintergrundjobs landen mit IDs und der ID des handelnden Benutzers im Backend-Log, dazu fehlgeschlagene Token-Prüfungen, verbotene Zugriffe und Rate-Limit-Treffer. Personenbezogene Daten werden nicht mehr geloggt
- 📊 Jede Anfrage einmal mit Status und Dauer:
/healthund die doppelteREQUEST:-Zeile, die den Kalender-Feed-Token preisgab, entfallen. Fehlgeschlagene Backups und Wiederherstellungen, unbehandelte Ausnahmen (mit Stacktrace), Startinformationen und die stündliche Update-Prüfung werden sauber protokolliert
⚠️ Hinweise zum Update
- Immer mit
docker-compose-update.ymlaktualisieren, wie in der README beschrieben - Es ist eine neue Datenbank-Migration enthalten (
AddMembershipStatusToMembers), sie läuft beim Start automatisch. Bestehende Mitglieder erhalten den Status "Mitglied" - Nur Variante B (eigener Reverse Proxy): Lege neben der Compose-Datei den Ordner
trusted-proxiesan und trage die Adresse deines Proxys in eine.conf-Datei darin ein, z. B.set_real_ip_from 192.168.1.20;. Dein Proxy mussX-Forwarded-Formit der Besucher-Adresse überschreiben (nginx:proxy_set_header X-Forwarded-For $remote_addr;). Ohne diesen Schritt teilen sich alle Besucher ein Rate-Limit und eine Login-Sperre. Die Anleitung steht unter Get Started, der Ordner bleibt bei Updates unangetastet. Variante A (Caddy) braucht nichts
Warum diese Updates wichtig sind
Der Mitgliedsstatus macht Fördermitglieder in Liste und Beitragsverwaltung auf einen Blick erkennbar, und das Löschen offener Beiträge nimmt den Druck, falsche oder zurückgebuchte Forderungen mühsam umgehen zu müssen. Dass ausgetretene Mitglieder nicht mehr abgerechnet werden, verhindert Fehlbuchungen. Das erweiterte Audit Log zeigt nachvollziehbar, wer was geändert hat, ohne sensible Daten zu speichern, und die Sicherheitsverbesserungen stellen sicher, dass Login-Sperre und Rate-Limits wirklich nur Angreifer treffen und nicht den eigenen Vorstand.
Wie geht es weiter?
Weiteres Feedback aus der Praxis ist wie immer herzlich willkommen, gerne über GitHub Issues. Schaut auch weiterhin gerne hier vorbei!