diff --git a/mobile/.gradle/8.7/checksums/checksums.lock b/mobile/.gradle/8.7/checksums/checksums.lock index 65f65998..401f2b1b 100644 Binary files a/mobile/.gradle/8.7/checksums/checksums.lock and b/mobile/.gradle/8.7/checksums/checksums.lock differ diff --git a/mobile/.gradle/8.7/checksums/md5-checksums.bin b/mobile/.gradle/8.7/checksums/md5-checksums.bin index 52912c50..b50fd68b 100644 Binary files a/mobile/.gradle/8.7/checksums/md5-checksums.bin and b/mobile/.gradle/8.7/checksums/md5-checksums.bin differ diff --git a/mobile/.gradle/8.7/checksums/sha1-checksums.bin b/mobile/.gradle/8.7/checksums/sha1-checksums.bin index 5811f033..f237467e 100644 Binary files a/mobile/.gradle/8.7/checksums/sha1-checksums.bin and b/mobile/.gradle/8.7/checksums/sha1-checksums.bin differ diff --git a/mobile/README.md b/mobile/README.md index 870d5027..aab201dc 100644 --- a/mobile/README.md +++ b/mobile/README.md @@ -57,3 +57,5 @@ $env:DESKHUB_RELEASE_KEY_PASSWORD = '' Das Skript erzeugt eine minifizierte, produktiv signierte APK unter `artifacts\deskhub-employee-release.apk`. Schlüssel und Passwörter werden nicht eingecheckt. + +**Play Store:** Schritt-für-Schritt-Anleitung (Keystore mit `new-keystore.ps1`, AAB mit `build-release.ps1`, Play Console) in `VEROEFFENTLICHEN.md`. diff --git a/mobile/STORE-EINTRAG.md b/mobile/STORE-EINTRAG.md new file mode 100644 index 00000000..e77d0d3f --- /dev/null +++ b/mobile/STORE-EINTRAG.md @@ -0,0 +1,63 @@ +# Texte für den Play-Store-Eintrag (Entwurf) + +Alles hier sind Entwürfe. Bitte Platzhalter in `<…>` ersetzen und die Datenschutzerklärung von einer fachkundigen Person prüfen lassen. + +## Titel und Beschreibungen + +**Titel (max. 30 Zeichen):** DeskHub Mitarbeiter + +**Kurzbeschreibung (max. 80 Zeichen):** Tickets Ihres DeskHub-Helpdesks unterwegs bearbeiten, mit Push-Popups. + +**Langbeschreibung:** +DeskHub Mitarbeiter ist die mobile Ergänzung zu eurem selbst gehosteten DeskHub-Helpdesk. Ihr bearbeitet Tickets, antwortet Kunden, weist Tickets zu und chattet mit Kollegen, auch unterwegs. + +• Tickets ansehen, filtern, beantworten, Status und Bearbeiter ändern +• Push-Benachrichtigungen bei neuen Tickets, Kundenantworten und Zuweisungen +• Interne Notizen, Zeiterfassung, Live-Chat und Team-Chat +• Datenschutzfreundlich: Im Popup steht standardmäßig nur die Ticketnummer +• Eure Daten bleiben auf eurem eigenen Server + +Wichtig: Die App benötigt einen DeskHub-Server (Adresse und Mitarbeiter-Zugang vom Administrator). Ohne eigenen Server ist keine Anmeldung möglich. + +## Datenschutzerklärung (Vorlage, unter einer öffentlichen URL veröffentlichen) + +**Verantwortlicher:** + +**Wofür die App Daten verarbeitet.** Die App ist ein Werkzeug für Mitarbeiter eines Unternehmens, das DeskHub auf einem eigenen Server betreibt. Die Ticket- und Kundendaten werden ausschließlich zwischen der App und dem Server dieses Unternehmens übertragen (verschlüsselt per HTTPS). Der Herausgeber der App erhält diese Inhalte nicht. Für sie ist das jeweilige Unternehmen verantwortlich. + +**Anmeldedaten.** Das Anmelde-Token wird verschlüsselt (Android Keystore) auf dem Gerät gespeichert und beim Abmelden gelöscht. + +**Push-Benachrichtigungen.** Für Popups wird ein Geräte-Token von Google Firebase Cloud Messaging vergeben. Dieses Token und die Ticketnummer (nur bei ausdrücklicher Aktivierung durch den Administrator zusätzlich Betreff und Kundenname) werden vom DeskHub-Server über den Push-Dienst des Herausgebers () an Google übermittelt, um die Benachrichtigung zuzustellen. Der Push-Dienst speichert pro DeskHub-Server eine Installations-ID und die Anzahl der gesendeten Nachrichten, nicht die Nachrichteninhalte. Anbieter: Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Irland. Rechtsgrundlage: Art. 6 Abs. 1 lit. b/f DSGVO. Push kann in Android-Einstellungen oder durch Abmelden beendet werden. + +**Keine Werbung, kein Tracking.** Die App enthält keine Werbung und keine Analyse-Dienste Dritter. + +**Berechtigungen.** Internet (Verbindung zum Server), Benachrichtigungen (Popups). + +**Löschung und Rechte.** Beim Abmelden wird das Gerät beim Server abgemeldet und das Token gelöscht. Auskunft, Berichtigung und Löschung: . + +## Formular „Datensicherheit“ (Play Console) + +| Frage | Antwort | +|---|---| +| Werden Daten erhoben/geteilt? | Ja, erhoben; Weitergabe nur an Dienstleister (Firebase) | +| Gerätekennungen (Geräte-Token) | Erhoben, App-Funktionalität, nicht für Werbung, im Zusammenhang mit der Zustellung an Dienstleister | +| App-Aktivität / Nachrichten (Ticketinhalte) | Erhoben, App-Funktionalität; liegen auf dem Server der Organisation | +| Personenbezogene Daten (Name, E-Mail der Mitarbeiter) | Erhoben, Kontoverwaltung | +| Verschlüsselt bei der Übertragung | Ja | +| Löschung beantragen möglich | Ja (über den Administrator des Servers bzw. ) | + +## Weitere Angaben + +- **Kategorie:** Unternehmensorganisation / Produktivität +- **Zielgruppe:** Erwachsene (nicht für Kinder) +- **Inhaltseinstufung:** Fragebogen ehrlich beantworten (keine nutzergenerierten öffentlichen Inhalte) +- **Grafiken:** App-Symbol 512×512, Feature-Grafik 1024×500, mindestens 2 Handy-Screenshots + +## Zugang für die Play-Prüfer („App-Zugriff“) + +Google lehnt Apps mit Anmeldung ohne Zugangsdaten oft ab. Richte dafür einen **Demo-Server** ein: + +1. Eigene DeskHub-Installation unter einer Demo-Adresse (z. B. `https://demo-deskhub.`), ohne echte Kundendaten. +2. Darin einen Mitarbeiter „Prüfer“ (Rolle Mitarbeiter, nicht Admin) und ein paar Beispieltickets anlegen. +3. In der Play Console unter „App-Zugriff“ eintragen: Serveradresse, E-Mail und Passwort des Prüfer-Kontos, mit dem Hinweis, dass die Serveradresse beim Start eingegeben wird. +4. Das Konto nach der Prüfung deaktivieren oder das Passwort ändern. diff --git a/mobile/VEROEFFENTLICHEN.md b/mobile/VEROEFFENTLICHEN.md new file mode 100644 index 00000000..622f52ac --- /dev/null +++ b/mobile/VEROEFFENTLICHEN.md @@ -0,0 +1,35 @@ +# DeskHub-App im Google Play Store veröffentlichen + +## 1. Einmalig: Upload-Schlüssel erzeugen + +```powershell +cd mobile +.\new-keystore.ps1 +``` + +Legt `%USERPROFILE%\deskhub-keys\deskhub-release.jks` an (Passwort wird abgefragt, nie angezeigt). **Datei und Passwort an mindestens zwei Orten sichern und nie weitergeben.** Beim Play-Upload nutzt ihr „Play App Signing“ (Standard): Google verwaltet den eigentlichen App-Schlüssel, euer Keystore ist nur der Upload-Schlüssel und ließe sich bei Verlust über den Play-Support zurücksetzen. + +## 2. Jede Version bauen + +1. In `build.gradle.kts` `versionCode` um 1 erhöhen (Play lehnt gleiche oder kleinere Nummern ab) und `versionName` anpassen. +2. `.\build-release.ps1` (fragt das Keystore-Passwort ab). Ergebnis in `artifacts\`: + - `deskhub-release.aab` → **das lädt ihr in den Play Store hoch** + - `deskhub-employee-release.apk` → zum direkten Installieren/Testen + +Voraussetzung: `google-services.json` (Firebase, Paketname `de.deskhub.staff`) liegt in `mobile\`, Internet für Gradle. + +## 3. Play Console (einmalig) + +- Entwicklerkonto (einmalig 25 US-$, Identitätsprüfung). +- App anlegen → Produktionsfreigabe bzw. zuerst **geschlossener Test** (für neue private Entwicklerkonten verlangt Google meist 12 Tester über 14 Tage, bevor die Produktion freigeschaltet wird; Anforderung in der Console prüfen). +- Store-Eintrag: Name, Kurz- und Langbeschreibung, Symbol 512×512, Feature-Grafik 1024×500, mindestens 2 Screenshots. +- **Datenschutzerklärung (URL, Pflicht):** nennt, dass der Server der jeweiligen Firma die Daten verarbeitet; bei Push: Geräte-Token und Ticketnummern laufen über den DeskHub-Push-Dienst und Google (Firebase Cloud Messaging). +- **Data-Safety-Formular:** Geräte-ID/Token (Push), Kontoinformationen (Anmeldung am Firmenserver), Ticketinhalte (App-Funktion); Übertragung verschlüsselt. +- Inhaltseinstufung, Zielgruppe (nicht für Kinder), Berechtigung `POST_NOTIFICATIONS` (Android 13+, wird zur Laufzeit erfragt). +- **Zielversion prüfen:** Play verlangt für neue Apps ein aktuelles `targetSdk`. Die App steht auf 34. Die aktuelle Mindestvorgabe steht in der Play Console unter „Richtlinien → API-Level“; falls höher, `targetSdk`/`compileSdk` anheben und neu testen. + +## 4. Vor dem Upload prüfen + +- Push-Dienst (Plugin-Webseite) mit `schluessel\firebase-dienstkonto.json` gebaut und erreichbar, `access_key` in `includes/catalog_defaults.php` gesetzt, Release neu gebaut. +- Release-AAB auf einem echten Handy: anmelden, Benachrichtigungen erlauben, **Testnachricht** im Adminportal, neues Ticket anlegen, auf Popup tippen. +- Die App fragt beim Start die Adresse des Servers ab; im Store-Eintrag erwähnen, dass ein eigener DeskHub-Server nötig ist (sonst Ablehnung wegen nicht nutzbarer App möglich; Play-Prüfer brauchen Demo-Zugangsdaten unter „App-Zugriff“). diff --git a/mobile/new-keystore.ps1 b/mobile/new-keystore.ps1 new file mode 100644 index 00000000..1c1354e9 --- /dev/null +++ b/mobile/new-keystore.ps1 @@ -0,0 +1,28 @@ +<# +.SYNOPSIS + Erzeugt den Upload-Schlüssel (Keystore) für die Veröffentlichung im Play Store. + +.DESCRIPTION + Der Keystore wird außerhalb des Projekts abgelegt (Standard: %USERPROFILE%\deskhub-keys\deskhub-release.jks). + Passwort wird abgefragt und nie angezeigt oder gespeichert. DIESE DATEI UND DAS PASSWORT SICHERN (mindestens zwei Orte): + Ohne sie kann die App später nicht mehr aktualisiert werden. Niemals einchecken oder weitergeben. +#> +param([string]$StoreFile = (Join-Path $env:USERPROFILE 'deskhub-keys\deskhub-release.jks'), [string]$Alias = 'deskhub') +$ErrorActionPreference = 'Stop' +if (Test-Path -LiteralPath $StoreFile) { throw "Keystore existiert bereits: $StoreFile (nicht überschrieben)." } +New-Item -ItemType Directory -Force (Split-Path $StoreFile) | Out-Null +$s1 = Read-Host 'Neues Keystore-Passwort (mindestens 12 Zeichen)' -AsSecureString +$s2 = Read-Host 'Passwort wiederholen' -AsSecureString +$p1 = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($s1)) +$p2 = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($s2)) +if ($p1 -ne $p2) { throw 'Die Passwörter stimmen nicht überein.' } +if ($p1.Length -lt 12) { throw 'Das Passwort ist zu kurz (mindestens 12 Zeichen).' } +$dname = Read-Host 'Name für das Zertifikat (z. B. CN=M_Viper, O=DeskHub, C=DE)' +if ([string]::IsNullOrWhiteSpace($dname)) { $dname = 'CN=DeskHub, O=DeskHub, C=DE' } +$env:DH_KS_PW = $p1 +try { + keytool -genkeypair -v -keystore $StoreFile -alias $Alias -keyalg RSA -keysize 4096 -validity 10000 ` + -storepass:env DH_KS_PW -keypass:env DH_KS_PW -dname $dname + if ($LASTEXITCODE -ne 0) { throw 'keytool ist fehlgeschlagen.' } +} finally { Remove-Item Env:\DH_KS_PW -ErrorAction SilentlyContinue } +Write-Host "`nFertig: $StoreFile (Alias $Alias). SICHERN: Datei + Passwort. Danach: .\build-release.ps1" diff --git a/mobile/settings.gradle.kts b/mobile/settings.gradle.kts index be9c85a8..6af31b05 100644 --- a/mobile/settings.gradle.kts +++ b/mobile/settings.gradle.kts @@ -4,6 +4,12 @@ pluginManagement { mavenCentral() gradlePluginPortal() } + resolutionStrategy { + eachPlugin { + // Google-Services-Plugin (liest google-services.json für Firebase) direkt aus dem Google-Repository + if (requested.id.id == "com.google.gms.google-services") useModule("com.google.gms:google-services:4.4.4") + } + } } dependencyResolutionManagement {