Impressum, Datenschutzerklärung und DSGVO-Löschfunktion

- /impressum (§ 5 DDG) und /datenschutz als öffentliche Seiten im
  Brand-Look; Betreiber-Angaben (Name, Anschrift, E-Mail, Zusatz)
  liegen als Settings und sind bewusst Owner-only — Team-Mitglieder
  mit settings-Scope kommen an die private Anschrift nicht heran
- Die Datenschutzerklärung beschreibt die tatsächliche Verarbeitung
  dieser Instanz: Server-Logs, Session-Cookies (einwilligungsfrei nach
  § 25 Abs. 2 TDDDG, kein Tracking), Discord-Login, Level, Wünsche,
  Geburtstage, Playtester/Alpha-Keys, Bewerbungen, Tickets/Modmail,
  Erinnerungen, Moderation und Audit-Log
- DSGVO Art. 17: DELETE /api/profile löscht XP, Geburtstag,
  Playtester-Eintrag, Abstimmungen, Erinnerungen, Rollen-Sicherung,
  Giveaway-Teilnahmen und gibt den Alpha-Key wieder frei; Button im
  Profil unter „Meine Daten", Löschung landet im Audit-Log
- Footer verlinkt beide Rechtstexte, neues GET /api/legal (öffentlich)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 13:19:33 +02:00
co-authored by Claude Fable 5
parent 676fc45bb1
commit 8853bce2ec
10 changed files with 464 additions and 4 deletions
+36 -1
View File
@@ -1,7 +1,8 @@
// Member-Profil: Rang & XP, Discord-Rollen, Alpha-Key, Playtester-Status
// + Rollen-Selfservice (Rollen-Menüs direkt im Browser togglen).
import { useEffect, useState } from 'react';
import { apiGet, apiPost } from '../api.js';
import { Link } from 'react-router-dom';
import { apiGet, apiPost, apiDelete } from '../api.js';
function fmtDate(iso) {
if (!iso) return '—';
@@ -15,6 +16,7 @@ export default function Profil({ me }) {
const [error, setError] = useState(null);
const [busy, setBusy] = useState('');
const [copied, setCopied] = useState(false);
const [wipeMsg, setWipeMsg] = useState('');
useEffect(() => {
apiGet('/api/profile').then(setProfile).catch((e) => setError(e?.message ?? 'Fehler'));
@@ -40,6 +42,23 @@ export default function Profil({ me }) {
setBusy('');
}
async function wipeData() {
if (!window.confirm(
'Wirklich alle gespeicherten Daten löschen?\n\n' +
'Betrifft: XP/Level, Geburtstag, Playtester-Eintrag, Abstimmungen, ' +
'Erinnerungen, Rollen-Sicherung und deinen Alpha-Key.\n\n' +
'Das lässt sich nicht rückgängig machen.'
)) return;
try {
const res = await apiDelete('/api/profile');
const total = Object.values(res.deleted).reduce((a, b) => a + b, 0);
setWipeMsg(`${total} Einträge gelöscht.`);
apiGet('/api/profile').then(setProfile).catch(() => {});
} catch {
setWipeMsg('⚠️ Löschen fehlgeschlagen — melde dich bitte beim Team.');
}
}
async function copyKey() {
try {
await navigator.clipboard.writeText(profile.alphaKey);
@@ -156,6 +175,22 @@ export default function Profil({ me }) {
))}
</div>
)}
{/* DSGVO Art. 17: eigene Daten löschen */}
<div className="roadmap-group danger-zone">
<h2 className="settings-title">// Meine Daten</h2>
<p className="field-hint">
Du kannst jederzeit alle Daten löschen, die hier zu dir gespeichert
sind: XP/Level, Geburtstag, Playtester-Eintrag, Abstimmungen,
Erinnerungen, Rollen-Sicherung und einen zugeteilten Alpha-Key.
Was du im Discord gepostet hast, löschst du bitte dort. Details im{' '}
<Link to="/datenschutz" style={{ textDecoration: 'underline' }}>Datenschutz</Link>.
</p>
<div className="field-row" style={{ marginTop: '.8rem' }}>
<button className="btn btn-danger" onClick={wipeData}>Meine Daten löschen</button>
</div>
{wipeMsg && <p className="notice" style={{ padding: '.6rem 0 0' }}>{wipeMsg}</p>}
</div>
</>
)}
</section>