Feature+Security: DSGVO-Datenexport, auth-geschützte Media, Datenschutzerklärung v2 (SW by-v880)
This commit is contained in:
parent
465dc2e4d3
commit
bf1087c5e1
7 changed files with 264 additions and 27 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '879'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '880'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VERSION = '1.5.1'; // ← semantische Version, wird bei make release gesetzt
|
||||
const IS_STAGING = location.hostname === 'staging.banyaro.app';
|
||||
// Cache-Bust-Parameter nach Update-Reload sofort entfernen
|
||||
|
|
|
|||
|
|
@ -102,13 +102,20 @@ window.Page_datenschutz = (() => {
|
|||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Als Ausweichlösung bei Nichtverfügbarkeit des lokalen Modells wird
|
||||
<strong>Claude Sonnet 4.6</strong> von Anthropic, PBC (San Francisco, USA) genutzt.
|
||||
In diesem Fall wird ausschließlich der Inhalt deiner Anfrage (Prompt-Text) übermittelt —
|
||||
keine Account- oder Profildaten. Die Übermittlung in die USA erfolgt auf Basis der
|
||||
EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
|
||||
In diesem Fall wird der Inhalt deiner Anfrage übermittelt. Bei Gesundheits- und
|
||||
Ernährungsberichten kann dies Hundedaten (Name, Rasse, Gewicht, Impfhistorie,
|
||||
Medikamente, Allergien) als Teil des Anfragetextes umfassen. Die Übermittlung
|
||||
in die USA erfolgt auf Basis der EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
|
||||
Datenschutzerklärung von Anthropic:
|
||||
<a href="https://www.anthropic.com/privacy" target="_blank" rel="noopener"
|
||||
style="${S.a}">anthropic.com/privacy</a>.
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Die <strong>Rassenerkennung per Foto</strong> sendet das hochgeladene Bild direkt an
|
||||
Claude von Anthropic (USA) zur Analyse — es gibt hierfür keinen lokalen Fallback.
|
||||
Das Foto wird nicht dauerhaft bei Anthropic gespeichert. Rechtsgrundlage: Einwilligung
|
||||
gem. Art. 6 Abs. 1 lit. a DSGVO durch aktive Nutzung der Funktion.
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Der <strong>KI-Trainer</strong> analysiert deinen bisherigen Trainingsfortschritt
|
||||
(Übungshistorie, Erfolgsquoten, Streaks) und gibt personalisierte Empfehlungen.
|
||||
|
|
@ -122,19 +129,31 @@ window.Page_datenschutz = (() => {
|
|||
findet nicht statt.
|
||||
</p>`)}
|
||||
|
||||
${sec('Wetterdaten (Open-Meteo)', `
|
||||
${sec('Wetterdaten & Kartendienste', `
|
||||
<p style="${S.p}">
|
||||
Die Wetter-Funktion übermittelt auf Wunsch deine GPS-Koordinaten einmalig an
|
||||
<strong>Open-Meteo</strong> (Österreich, DSGVO-konform), um die lokale
|
||||
Wettervorhersage abzurufen. Es werden ausschließlich anonyme Koordinaten übertragen —
|
||||
keine Account- oder Profildaten. Open-Meteo protokolliert keine personenbezogenen
|
||||
Daten. Die Funktion wird nur aktiv, wenn du deinen Standort im Browser freigibst.
|
||||
Die Wetter-Funktion übermittelt auf Wunsch deine GPS-Koordinaten serverseitig an
|
||||
<strong>Open-Meteo</strong> (Österreich, DSGVO-konform) für die Wettervorhersage.
|
||||
Für Wetter-Kartenlayer (Regenradar, Temperaturen) werden Kacheln von
|
||||
<strong>OpenWeatherMap</strong> (OpenWeather Ltd., UK/USA) geladen — dabei wird
|
||||
dein Browser direkt kontaktiert. Es werden keine Account-Daten übermittelt.
|
||||
Rechtsgrundlage: Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO.
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Datenschutzerklärung von Open-Meteo:
|
||||
Für die automatische Ortsnamens-Ermittlung (z. B. im Wetter-Detail) werden deine
|
||||
GPS-Koordinaten serverseitig an <strong>Nominatim</strong> der OpenStreetMap Foundation
|
||||
(UK) übermittelt. Es werden ausschließlich Koordinaten weitergegeben — keine
|
||||
personenbezogenen Daten.
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Datenschutzerklärung Open-Meteo:
|
||||
<a href="https://open-meteo.com/en/terms" target="_blank" rel="noopener"
|
||||
style="${S.a}">open-meteo.com/en/terms</a>
|
||||
style="${S.a}">open-meteo.com/en/terms</a> ·
|
||||
OpenWeatherMap:
|
||||
<a href="https://openweathermap.org/privacy-policy" target="_blank" rel="noopener"
|
||||
style="${S.a}">openweathermap.org/privacy-policy</a> ·
|
||||
OpenStreetMap/Nominatim:
|
||||
<a href="https://osmfoundation.org/wiki/Privacy_Policy" target="_blank" rel="noopener"
|
||||
style="${S.a}">osmfoundation.org</a>
|
||||
</p>`)}
|
||||
|
||||
${sec('Routenvorschläge (OpenRouteService)', `
|
||||
|
|
@ -200,7 +219,16 @@ window.Page_datenschutz = (() => {
|
|||
(Art. 16), <strong>Löschung</strong> (Art. 17), <strong>Einschränkung der Verarbeitung</strong>
|
||||
(Art. 18) sowie <strong>Datenportabilität</strong> (Art. 20). Erteilte Einwilligungen
|
||||
kannst du jederzeit mit Wirkung für die Zukunft widerrufen (Art. 7 Abs. 3 DSGVO).
|
||||
Zur Ausübung deiner Rechte wende dich per E-Mail an
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
<strong>Datenexport (Art. 20 DSGVO):</strong> Du kannst jederzeit unter
|
||||
Einstellungen → „Meine Daten exportieren" eine vollständige Kopie deiner
|
||||
gespeicherten Daten als JSON-Datei herunterladen. Der Export enthält Profildaten,
|
||||
Hundedaten, Tagebuch, Gesundheitseinträge, Trainingsfortschritt, Ausgaben,
|
||||
Verhaltensprotokoll, Forum-Beiträge und Gassi-Teilnahmen.
|
||||
</p>
|
||||
<p style="${S.p};margin-top:var(--space-3)">
|
||||
Zur Ausübung weiterer Rechte wende dich per E-Mail an
|
||||
<a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>.<br><br>
|
||||
Du hast außerdem das Recht, bei der zuständigen Datenschutz-Aufsichtsbehörde
|
||||
Beschwerde einzulegen:<br>
|
||||
|
|
@ -212,14 +240,14 @@ window.Page_datenschutz = (() => {
|
|||
|
||||
${sec('Speicherdauer', `
|
||||
<p style="${S.p}">
|
||||
Deine Daten werden gelöscht, sobald du deinen Account löschst. Server-Logs
|
||||
werden nach 30 Tagen automatisch gelöscht. Öffentlich gepostete Inhalte
|
||||
(Forenbeiträge, Giftköder-Meldungen) bleiben nach Account-Löschung anonymisiert
|
||||
erhalten, sofern sie für die Community relevant sind.
|
||||
Deine Daten werden vollständig gelöscht, sobald du deinen Account löschst —
|
||||
einschließlich Tagebuch, Gesundheitseinträge, Fotos, Forenbeiträge und Hundeprofil.
|
||||
Es gibt keine anonymisierte Weiterverarbeitung deiner Inhalte nach Account-Löschung.
|
||||
Server-Logs werden nach 30 Tagen rotiert.
|
||||
</p>`)}
|
||||
|
||||
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
|
||||
Stand: Mai 2026
|
||||
Stand: Mai 2026 · Version 2
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -294,6 +294,15 @@ window.Page_settings = (() => {
|
|||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#sign-out"></use></svg>
|
||||
Abmelden
|
||||
</button>
|
||||
<button id="settings-export-btn"
|
||||
style="width:100%;margin-top:var(--space-2);display:flex;align-items:center;justify-content:center;
|
||||
gap:var(--space-2);padding:var(--space-2) var(--space-4);
|
||||
border-radius:var(--radius-md);border:none;
|
||||
background:none;color:var(--c-text-secondary);
|
||||
font-size:var(--text-xs);cursor:pointer">
|
||||
<svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
||||
Meine Daten exportieren (DSGVO Art. 20)
|
||||
</button>
|
||||
<button id="settings-delete-account-btn"
|
||||
style="width:100%;margin-top:var(--space-2);display:flex;align-items:center;justify-content:center;
|
||||
gap:var(--space-2);padding:var(--space-2) var(--space-4);
|
||||
|
|
@ -892,6 +901,32 @@ window.Page_settings = (() => {
|
|||
_render();
|
||||
});
|
||||
|
||||
document.getElementById('settings-export-btn')?.addEventListener('click', async () => {
|
||||
const btn = document.getElementById('settings-export-btn');
|
||||
await UI.asyncButton(btn, async () => {
|
||||
try {
|
||||
const resp = await fetch('/api/profile/export', {
|
||||
credentials: 'include',
|
||||
headers: { 'Authorization': `Bearer ${localStorage.getItem('by_token') || ''}` },
|
||||
});
|
||||
if (!resp.ok) throw new Error('Export fehlgeschlagen.');
|
||||
const data = await resp.json();
|
||||
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `banyaro-export-${new Date().toISOString().slice(0,10)}.json`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
UI.toast.success('Export heruntergeladen.');
|
||||
} catch (err) {
|
||||
UI.toast.error(err.message || 'Fehler beim Export.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('settings-delete-account-btn')?.addEventListener('click', async () => {
|
||||
const ok = await UI.modal.confirm({
|
||||
title: 'Konto unwiderruflich löschen?',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue