Session 2026-04-20: Medien-Konvertierung, Umami Analytics, Username/Privacy

- HEIC→JPEG, MOV/AVI→MP4 Konvertierung bei allen Upload-Endpoints (media_utils.py)
- ffmpeg im Docker-Image, Video-Thumbnails (extract_video_thumb, poster-Attribut)
- Google Analytics entfernt, Umami self-hosted eingebunden (index.html, datenschutz.js)
- Admin-Panel Analytics-Tab: Stat-Cards, Sparkline 7 Tage, Top-Seiten (Umami-API-Proxy)
- Admin-Panel Tab-Icons korrigiert (aus vorhandenem Phosphor-Sprite)
- users.real_name Spalte: Username öffentlich, echter Name privat und optional
- Registrierung: Label "Benutzername", Leerzeichen verboten, Profanity-Blockliste
- Datenschutzerklärung: GA-Abschnitt durch Umami-Text ersetzt
This commit is contained in:
rene 2026-04-20 18:36:58 +02:00
parent 9a78121a3e
commit 5141ba9969
20 changed files with 524 additions and 143 deletions

View file

@ -5,36 +5,19 @@
window.Page_datenschutz = (() => {
function init(container) {
const optOut = localStorage.getItem('gaOptOut') === 'yes';
const gaSection = `
const umamiSection = `
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
color:var(--c-text);margin:0 0 var(--space-2)">Google Analytics</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0 0 var(--space-3)">
Wir nutzen Google Analytics 4 (Google LLC, USA) zur anonymisierten Analyse der App-Nutzung.
Deine IP-Adresse wird gekürzt, es werden keine Cookies gesetzt und keine
personenbezogenen Daten gespeichert. Die Verarbeitung erfolgt auf Basis von
Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an anonymer Nutzungsanalyse).
Du kannst der Erhebung jederzeit widersprechen.
color:var(--c-text);margin:0 0 var(--space-2)">Nutzungsanalyse (Umami)</h2>
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Wir verwenden Umami, ein datenschutzfreundliches Analysetool, das ausschließlich auf
unserem eigenen Server betrieben wird. Es werden keine Cookies gesetzt, keine
personenbezogenen Daten erhoben und keine Daten an Dritte weitergegeben.
Erfasst werden lediglich anonyme Seitenaufrufe zur Verbesserung der App.
Eine Rechtsgrundlage nach Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse) ist
gegeben; ein Widerspruch oder Opt-out ist nicht erforderlich, da keine
personenbezogenen Daten verarbeitet werden.
</p>
${optOut ? `
<p style="font-size:var(--text-sm);color:var(--c-success,#16a34a);margin:0 0 var(--space-3)">
Analytics ist für dich <strong>deaktiviert</strong>.
</p>
<button id="ga-optin-btn"
style="padding:var(--space-2) var(--space-4);border:1px solid var(--c-border,#e5e7eb);
border-radius:var(--radius-md);background:transparent;cursor:pointer;
font-size:var(--text-sm);color:var(--c-text-secondary)">
Analytics wieder aktivieren
</button>
` : `
<button id="ga-optout-btn"
style="padding:var(--space-2) var(--space-4);border:1px solid var(--c-border,#e5e7eb);
border-radius:var(--radius-md);background:transparent;cursor:pointer;
font-size:var(--text-sm);color:var(--c-text-secondary)">
Analytics deaktivieren (Opt-out)
</button>
`}
</section>
`;
@ -78,7 +61,7 @@ window.Page_datenschutz = (() => {
<p style="font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0">
Die Verarbeitung erfolgt auf Basis von Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
für alle zur Bereitstellung des Dienstes notwendigen Daten, sowie Art. 6 Abs. 1 lit. a
DSGVO (Einwilligung) für optionale Funktionen wie Standortfreigabe und Analytics.
DSGVO (Einwilligung) für optionale Funktionen wie Standortfreigabe.
</p>
</section>
@ -92,7 +75,7 @@ window.Page_datenschutz = (() => {
</p>
</section>
${gaSection}
${umamiSection}
<section style="margin-bottom:var(--space-6)">
<h2 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
@ -123,16 +106,6 @@ window.Page_datenschutz = (() => {
</div>
`;
container.querySelector('#ga-optout-btn')?.addEventListener('click', () => {
localStorage.setItem('gaOptOut', 'yes');
UI.toast.success('Analytics deaktiviert. Wirksam nach nächstem App-Neustart.');
init(container);
});
container.querySelector('#ga-optin-btn')?.addEventListener('click', () => {
localStorage.removeItem('gaOptOut');
UI.toast.success('Analytics wieder aktiviert. Wirksam nach nächstem App-Neustart.');
init(container);
});
}
function refresh() {}