feat: add Datenschutzerklärung and Konto löschen pages
- Created datenschutz.vue for the privacy policy with sections on data protection, responsible entity, data processing, rights, and contact information. - Created konto-loeschen.vue for account deletion requests, detailing the process, affected data, and processing time. - Added anonymize-playstore-screenshot.sh script for image anonymization using ImageMagick. - Introduced playstore-assets.mjs for generating Play Store assets, including icons and feature graphics, using sharp. - Added playstore-assets.sh script to execute the asset generation script.
This commit is contained in:
@@ -145,6 +145,8 @@ Kurz: Ziel ist eine native Android-App mit Kotlin + Jetpack Compose, die die Web
|
||||
- [x] Production-Release-Flavor auf Produktiv-Backend parametrisierbar gemacht (`PRODUCTION_API_BASE_URL`, Default `https://harheimertc.de/`).
|
||||
- [x] Release-Signing per sicheren Gradle-Properties vorbereitet (`RELEASE_STORE_FILE`, `RELEASE_STORE_PASSWORD`, `RELEASE_KEY_ALIAS`, `RELEASE_KEY_PASSWORD`) statt Hardcoding.
|
||||
- [x] `:app:assembleProductionRelease` erfolgreich gebaut (Stand 2026-05-29).
|
||||
- [x] Play-Store-Listing-Basis ergänzt: Datenschutzseite unter `/datenschutz` sowie Skripte für Icon/Feature-Graphic-Export und Screenshot-Anonymisierung inklusive Anleitung (`android-app/PLAYSTORE_ASSETS.md`).
|
||||
- [x] Konto-Lösch-URL für Play Store ergänzt: öffentliche Seite unter `/konto-loeschen` inklusive Prozessbeschreibung.
|
||||
- [ ] Offen: Finales Upload-Keystore + Credentials in CI/Build-Host hinterlegen, Play-Store-Release-Notes und Store-Metadaten pflegen.
|
||||
[ ] 25. Dokumentation: `README-android.md` mit Setup, Architektur und Release-Anleitung
|
||||
|
||||
@@ -197,6 +199,7 @@ Kurz: Ziel ist eine native Android-App mit Kotlin + Jetpack Compose, die die Web
|
||||
- 2026-05-28: Caching-Teil von Punkt 17 und MVP-D umgesetzt: OkHttp cached öffentliche GET-Antworten und nutzt gecachte Antworten offline, Coil nutzt denselben authentifizierten Client plus Memory-/Diskcache. Geschützte Daten werden bewusst nicht unverschlüsselt im HTTP-Diskcache persistiert.
|
||||
- 2026-05-28: Testbasis für Punkt 20 begonnen: JVM-Unit-Tests für E-Mail- und ISO-Datum-Validierung ergänzt; `:app:testLocalDebugUnitTest` läuft mit `compileSdk 35` grün.
|
||||
- 2026-05-28: Punkte 17, 19, 21 und 23 weiter umgesetzt: geschützte Mitglieder-/CMS-Daten werden verschlüsselt in Keystore-gestützten Preferences gecacht und bei Ladefehlern genutzt; Galerie-Accessibility und Thumbnail-Decoding verbessert; Sentry-Android 8.42.0 über optionalen `SENTRY_DSN`-Gradle-Parameter integriert.
|
||||
- 2026-05-29: Play-Store-Listing-Vorbereitung ergänzt: eigenständige Web-Datenschutzseite (`/datenschutz`) sowie Asset-/Anonymisierungs-Skripte und Anleitung in `android-app/PLAYSTORE_ASSETS.md` hinzugefügt.
|
||||
|
||||
8) Android-Testumgebungen
|
||||
- Lokal im Emulator: `./gradlew :app:installLocalDebug` verwendet `http://10.0.2.2:3100/` und die App-ID `de.harheimertc.local`.
|
||||
|
||||
70
android-app/PLAYSTORE_ASSETS.md
Normal file
70
android-app/PLAYSTORE_ASSETS.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Play Store Assets - Harheimer TC Android
|
||||
|
||||
## 1) Datenschutzerklaerung (Web-URL)
|
||||
|
||||
Empfohlene URL fuer Play Console:
|
||||
- https://harheimertc.de/datenschutz
|
||||
|
||||
Die Seite ist in der Web-App als eigene Route vorhanden.
|
||||
|
||||
## 1b) Konto-Loeschung (Web-URL)
|
||||
|
||||
Empfohlene URL fuer Play Console:
|
||||
- https://harheimertc.de/konto-loeschen
|
||||
|
||||
Die Seite beschreibt den Loeschprozess und Kontaktweg fuer App- und Webkonto.
|
||||
|
||||
## 2) Logo / Grafiken
|
||||
|
||||
### Pflicht
|
||||
- App-Icon (Play): 512 x 512 PNG
|
||||
|
||||
### Optional, aber empfohlen
|
||||
- Feature Graphic: 1024 x 500 PNG
|
||||
|
||||
### Generierung
|
||||
|
||||
Im Repo ist ein Script vorhanden, das aus dem Vereinslogo fertige Dateien erzeugt:
|
||||
|
||||
```bash
|
||||
./scripts/playstore-assets.sh
|
||||
```
|
||||
|
||||
Ausgabe in:
|
||||
- android-app/playstore-assets/generated/playstore-icon-512.png
|
||||
- android-app/playstore-assets/generated/playstore-feature-graphic-1024x500.png
|
||||
|
||||
## 3) Screenshots (anonymisiert)
|
||||
|
||||
### Grobe Anforderungen (Telefon)
|
||||
- Mindestens 2 Screenshots
|
||||
- PNG oder JPEG
|
||||
- Seitenlaenge je Seite zwischen 320 px und 3840 px
|
||||
|
||||
Empfehlung fuer Android-Phone:
|
||||
- 1080 x 1920 (Portrait)
|
||||
|
||||
### Anonymisierung
|
||||
|
||||
Script fuer schwarze halbtransparente Balken ueber sensible Bereiche:
|
||||
|
||||
```bash
|
||||
./scripts/anonymize-playstore-screenshot.sh <input.png> <output.png> 'x,y,w,h;x,y,w,h'
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
./scripts/anonymize-playstore-screenshot.sh \
|
||||
android-app/playstore-assets/raw/screen1.png \
|
||||
android-app/playstore-assets/anon/screen1-anon.png \
|
||||
'68,118,520,72;70,706,560,98'
|
||||
```
|
||||
|
||||
## 4) Upload in Play Console
|
||||
|
||||
- Datenschutzerklaerung: URL eintragen
|
||||
- Konto-Loeschung: URL eintragen
|
||||
- App-Icon: playstore-icon-512.png
|
||||
- Feature Graphic: playstore-feature-graphic-1024x500.png
|
||||
- Screenshots: anonymisierte PNG/JPEG hochladen
|
||||
@@ -8,7 +8,7 @@ LOCAL_API_BASE_URL=https://harheimertc.tsschulz.de/
|
||||
PRODUCTION_API_BASE_URL=https://harheimertc.de/
|
||||
|
||||
# Android app versioning for Play Store uploads
|
||||
ANDROID_VERSION_CODE=3
|
||||
ANDROID_VERSION_CODE=4
|
||||
ANDROID_VERSION_NAME=1.0.0
|
||||
|
||||
# Enable R8 for release by default so mapping.txt is generated for Play Console.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
BIN
android-app/playstore-assets/generated/playstore-icon-512.png
Normal file
BIN
android-app/playstore-assets/generated/playstore-icon-512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -19,6 +19,18 @@
|
||||
>
|
||||
Impressum
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/datenschutz"
|
||||
class="text-gray-400 hover:text-primary-400 transition-colors"
|
||||
>
|
||||
Datenschutz
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/konto-loeschen"
|
||||
class="text-gray-400 hover:text-primary-400 transition-colors"
|
||||
>
|
||||
Konto loeschen
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/kontakt"
|
||||
class="text-gray-400 hover:text-primary-400 transition-colors"
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
"sync-public-data": "node scripts/sync-public-data.js",
|
||||
"import-spielplan": "node scripts/import-spielplan.js",
|
||||
"publish-spielplan": "node scripts/publish-imported-spielplan.js",
|
||||
"playstore:assets": "./scripts/playstore-assets.sh",
|
||||
"playstore:anonymize": "./scripts/anonymize-playstore-screenshot.sh",
|
||||
"test:watch": "vitest watch",
|
||||
"lint": "eslint . --fix"
|
||||
},
|
||||
|
||||
110
pages/datenschutz.vue
Normal file
110
pages/datenschutz.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="min-h-full py-16 px-4 sm:px-6 lg:px-8 bg-gray-50">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<h1 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-6">
|
||||
Datenschutzerklärung
|
||||
</h1>
|
||||
<div class="w-24 h-1 bg-primary-600 mb-8" />
|
||||
|
||||
<div class="bg-white p-8 rounded-xl shadow-lg space-y-6 text-gray-700">
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
1. Datenschutz auf einen Blick
|
||||
</h2>
|
||||
<p>
|
||||
Der Schutz Ihrer personenbezogenen Daten hat für den Harheimer TC 1954 e.V. einen hohen Stellenwert.
|
||||
Wir verarbeiten personenbezogene Daten vertraulich und entsprechend den gesetzlichen Datenschutzvorschriften.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
2. Verantwortliche Stelle
|
||||
</h2>
|
||||
<p>
|
||||
Harheimer TC 1954 e.V.<br>
|
||||
Kontakt über die Angaben im
|
||||
<NuxtLink
|
||||
to="/impressum"
|
||||
class="text-primary-600 hover:underline"
|
||||
>
|
||||
Impressum
|
||||
</NuxtLink>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
3. Verarbeitung personenbezogener Daten
|
||||
</h2>
|
||||
<p class="mb-3">
|
||||
Wir verarbeiten personenbezogene Daten insbesondere in folgenden Fällen:
|
||||
</p>
|
||||
<ul class="list-disc pl-6 space-y-1">
|
||||
<li>Kontaktanfragen über Formulare oder E-Mail</li>
|
||||
<li>Mitgliedschaftsanträge</li>
|
||||
<li>Nutzung des Mitgliederbereichs (Login, Profilfunktionen)</li>
|
||||
<li>Newsletter-Anmeldung und -Abmeldung</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
4. Technische und organisatorische Maßnahmen
|
||||
</h2>
|
||||
<p>
|
||||
Für besonders schützenswerte Daten setzen wir technische Schutzmaßnahmen ein,
|
||||
darunter Verschlüsselung, rollenbasierte Zugriffssteuerung und abgesicherte
|
||||
Authentifizierungsverfahren.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
5. Ihre Rechte
|
||||
</h2>
|
||||
<p class="mb-3">
|
||||
Sie haben im Rahmen der gesetzlichen Vorgaben insbesondere folgende Rechte:
|
||||
</p>
|
||||
<ul class="list-disc pl-6 space-y-1">
|
||||
<li>Auskunft über gespeicherte Daten</li>
|
||||
<li>Berichtigung unrichtiger Daten</li>
|
||||
<li>Löschung oder Einschränkung der Verarbeitung</li>
|
||||
<li>Widerspruch gegen die Verarbeitung</li>
|
||||
<li>Datenübertragbarkeit</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
6. Kontakt zum Datenschutz
|
||||
</h2>
|
||||
<p>
|
||||
Bei Fragen zum Datenschutz nutzen Sie bitte die Kontaktangaben im
|
||||
<NuxtLink
|
||||
to="/impressum"
|
||||
class="text-primary-600 hover:underline"
|
||||
>
|
||||
Impressum
|
||||
</NuxtLink>
|
||||
oder unser
|
||||
<NuxtLink
|
||||
to="/kontakt"
|
||||
class="text-primary-600 hover:underline"
|
||||
>
|
||||
Kontaktformular
|
||||
</NuxtLink>
|
||||
.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
useHead({
|
||||
title: 'Datenschutzerklärung - Harheimer TC',
|
||||
})
|
||||
</script>
|
||||
75
pages/konto-loeschen.vue
Normal file
75
pages/konto-loeschen.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div class="min-h-full py-16 px-4 sm:px-6 lg:px-8 bg-gray-50">
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<h1 class="text-4xl sm:text-5xl font-display font-bold text-gray-900 mb-6">
|
||||
Konto loeschen
|
||||
</h1>
|
||||
<div class="w-24 h-1 bg-primary-600 mb-8" />
|
||||
|
||||
<div class="bg-white p-8 rounded-xl shadow-lg space-y-6 text-gray-700">
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
Kontoloeschung fuer App- und Webkonto
|
||||
</h2>
|
||||
<p>
|
||||
Sie koennen die Loeschung Ihres Harheimer-TC-Kontos jederzeit beantragen.
|
||||
Nach erfolgreicher Pruefung wird Ihr Zugang deaktiviert und Ihre personenbezogenen Daten
|
||||
gemaess den gesetzlichen Aufbewahrungspflichten geloescht oder anonymisiert.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
So stellen Sie den Antrag
|
||||
</h2>
|
||||
<ol class="list-decimal pl-6 space-y-2">
|
||||
<li>Melden Sie sich mit Ihrem Konto im Mitgliederbereich an.</li>
|
||||
<li>Nutzen Sie das Kontaktformular oder schreiben Sie eine E-Mail mit dem Betreff "Konto loeschen".</li>
|
||||
<li>Nennen Sie dabei die E-Mail-Adresse Ihres Kontos zur Zuordnung.</li>
|
||||
</ol>
|
||||
<div class="mt-4 flex flex-wrap gap-3">
|
||||
<NuxtLink
|
||||
to="/kontakt"
|
||||
class="inline-flex items-center px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg transition-colors"
|
||||
>
|
||||
Kontaktformular
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/impressum"
|
||||
class="inline-flex items-center px-4 py-2 bg-gray-100 hover:bg-gray-200 text-gray-900 font-medium rounded-lg transition-colors"
|
||||
>
|
||||
Kontakt per E-Mail im Impressum
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
Welche Daten sind betroffen?
|
||||
</h2>
|
||||
<ul class="list-disc pl-6 space-y-1">
|
||||
<li>Login-Daten und Zugangsdaten werden entfernt oder ungueltig gemacht.</li>
|
||||
<li>Persoenliche Profildaten im Mitgliederbereich werden geloescht oder anonymisiert.</li>
|
||||
<li>Rechtlich erforderliche Restdaten (z. B. vereins- oder steuerrechtlich) koennen befristet gespeichert bleiben.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="text-xl font-display font-bold text-gray-900 mb-2">
|
||||
Bearbeitungszeit
|
||||
</h2>
|
||||
<p>
|
||||
Wir bearbeiten Loeschanfragen in der Regel innerhalb von 30 Tagen.
|
||||
Bei Rueckfragen kontaktieren wir Sie ueber die hinterlegte E-Mail-Adresse.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
useHead({
|
||||
title: 'Konto loeschen - Harheimer TC',
|
||||
})
|
||||
</script>
|
||||
32
scripts/anonymize-playstore-screenshot.sh
Executable file
32
scripts/anonymize-playstore-screenshot.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 3 ]]; then
|
||||
echo "Nutzung: $0 <input.png> <output.png> <rects>"
|
||||
echo "rects Format: x,y,w,h;x,y,w,h"
|
||||
echo "Beispiel: $0 shot.png shot-anon.png '80,120,420,70;72,720,540,90'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT="$1"
|
||||
OUTPUT="$2"
|
||||
RECTS="$3"
|
||||
|
||||
if ! command -v magick >/dev/null 2>&1; then
|
||||
echo "Fehler: 'magick' (ImageMagick) ist nicht installiert."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP="$OUTPUT.tmp.png"
|
||||
cp "$INPUT" "$TMP"
|
||||
|
||||
IFS=';' read -r -a BOXES <<< "$RECTS"
|
||||
for box in "${BOXES[@]}"; do
|
||||
IFS=',' read -r x y w h <<< "$box"
|
||||
magick "$TMP" \
|
||||
\( -size "${w}x${h}" xc:black -alpha set -channel a -evaluate set 70% +channel \) \
|
||||
-geometry "+${x}+${y}" -composite "$TMP"
|
||||
done
|
||||
|
||||
mv "$TMP" "$OUTPUT"
|
||||
echo "Anonymisierte Datei geschrieben: $OUTPUT"
|
||||
69
scripts/playstore-assets.mjs
Normal file
69
scripts/playstore-assets.mjs
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env node
|
||||
import { mkdir, readFile } from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import sharp from 'sharp'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
const rootDir = path.resolve(__dirname, '..')
|
||||
const logoSrc = path.join(rootDir, 'public', 'images', 'logos', 'Harheimer TC.svg')
|
||||
const outDir = path.join(rootDir, 'android-app', 'playstore-assets', 'generated')
|
||||
|
||||
const iconOut = path.join(outDir, 'playstore-icon-512.png')
|
||||
const featureOut = path.join(outDir, 'playstore-feature-graphic-1024x500.png')
|
||||
|
||||
const featureOverlaySvg = `
|
||||
<svg width="1024" height="500" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#0f172a"/>
|
||||
<stop offset="100%" stop-color="#1e293b"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="1024" height="500" fill="url(#bg)"/>
|
||||
<text x="430" y="185" font-size="66" font-family="DejaVu Sans, Arial, sans-serif" font-weight="700" fill="#e5e7eb">Harheimer TC</text>
|
||||
<text x="430" y="250" font-size="30" font-family="DejaVu Sans, Arial, sans-serif" fill="#cbd5e1">Tischtennis in Frankfurt-Harheim</text>
|
||||
</svg>
|
||||
`
|
||||
|
||||
async function generateAssets() {
|
||||
await mkdir(outDir, { recursive: true })
|
||||
|
||||
const logoBuffer = await readFile(logoSrc)
|
||||
const resizedLogoForIcon = await sharp(logoBuffer)
|
||||
.resize(440, 440, { fit: 'contain' })
|
||||
.png()
|
||||
.toBuffer()
|
||||
|
||||
await sharp({
|
||||
create: {
|
||||
width: 512,
|
||||
height: 512,
|
||||
channels: 4,
|
||||
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
||||
},
|
||||
})
|
||||
.composite([{ input: resizedLogoForIcon, gravity: 'center' }])
|
||||
.png()
|
||||
.toFile(iconOut)
|
||||
|
||||
const resizedLogoForFeature = await sharp(logoBuffer)
|
||||
.resize(320, 320, { fit: 'contain' })
|
||||
.png()
|
||||
.toBuffer()
|
||||
|
||||
await sharp(Buffer.from(featureOverlaySvg))
|
||||
.composite([{ input: resizedLogoForFeature, left: 72, top: 90 }])
|
||||
.png()
|
||||
.toFile(featureOut)
|
||||
|
||||
console.log(`Fertig. Assets erzeugt in: ${outDir}`)
|
||||
console.log(`- ${path.basename(iconOut)}`)
|
||||
console.log(`- ${path.basename(featureOut)}`)
|
||||
}
|
||||
|
||||
generateAssets().catch((error) => {
|
||||
console.error('Fehler bei der Asset-Generierung:', error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
6
scripts/playstore-assets.sh
Executable file
6
scripts/playstore-assets.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
node "$ROOT_DIR/scripts/playstore-assets.mjs"
|
||||
Reference in New Issue
Block a user