From 322270ee4450849249ec277fa6c5f7edf65b0692 Mon Sep 17 00:00:00 2001 From: ARIA Date: Tue, 21 Jul 2026 09:52:19 +0000 Subject: [PATCH] Add Starface Chat-Loesch-Script mit README --- README.md | 86 ++++++++++++++++++++++++++++++++++++ delete_starface_chat.sh | 98 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 README.md create mode 100755 delete_starface_chat.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1369ee --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# Starface Chat löschen + +Kleines Bash-Script, das den kompletten UCC-Chatverlauf eines einzelnen +Starface-Users aus der internen Openfire-Chat-DB löscht. Nötig, weil Starface +in der App/Admin-UI selbst keine Möglichkeit bietet, den Chatverlauf eines +Users zu löschen — z.B. wenn ein Mitarbeiter das Unternehmen verlässt. + +## Hintergrund + +Starface nutzt für den UCC-Chat einen eingebetteten **Openfire-XMPP-Server**, +der dieselbe Postgres-Datenbank (`asterisk`) wie die restliche PBX verwendet. +Relevant sind zwei Tabellen (Openfire Monitoring-Plugin): + +- `ofmessagearchive` — die eigentlichen Chat-Nachrichten (`fromjid`, `tojid`, `body`, `sentdate`, ...) +- `ofconversation` — Konversations-Header (Zeitraum, Nachrichtenanzahl je `conversationid`) + +Es gibt **keine offizielle API** dafür — die Löschung passiert direkt per SQL +auf dem Starface-Server. + +## Voraussetzungen + +- SSH-Zugriff auf den Starface-Server (root oder ein User mit `sudo -u postgres`-Rechten) +- `psql` muss installiert sein (bei Starface Standard) +- Script liegt/läuft direkt **auf** dem Starface-Server (nicht remote per SQL-Tunnel) + +## Nutzung + +```bash +./delete_starface_chat.sh +``` + +Beispiel — Mitarbeiter mit der Starface-Benutzer-ID `0022` verlässt das Unternehmen: + +```bash +./delete_starface_chat.sh 0022 +``` + +`` ist die Starface-Benutzernummer/-ID wie sie intern als JID genutzt +wird (JID-Format `@`) — einfach die Nummer/den +Login-Namen des Users angeben. + +## Was das Script macht + +1. Sucht alle Nachrichten in `ofmessagearchive`, bei denen der angegebene + User Absender **oder** Empfänger ist (`fromjid`/`tojid LIKE '@%'`). +2. **Erstellt zuerst ein Backup** — CSV-Dump aller betroffenen Nachrichten und + Konversationen nach `/var/backups/starface_chat_backups/`, bevor irgendwas + gelöscht wird. +3. Löscht die betroffenen Zeilen aus `ofmessagearchive`. +4. Löscht die zugehörigen `ofconversation`-Einträge — aber **nur**, wenn nach + dem Löschen wirklich keine Nachricht mehr auf diese `conversationid` + verweist (Konversations-Header bleibt sonst stehen). +5. Gibt am Ende die verbleibende Nachrichtenanzahl für den User aus (sollte `0` sein). + +Alles läuft in **einer Transaktion** (`BEGIN` / `COMMIT`) — entweder alles +oder nichts. + +## Wichtige Einschränkung: gemeinsame Konversation + +Openfire speichert eine Konversation zwischen zwei Usern als **eine +gemeinsame** Nachrichten-Historie — es gibt **keine getrennten Kopien** pro +Teilnehmer (kein "Postfach pro User"). + +Das heißt konkret: Löscht man z.B. User `0022`, der einen Chat mit User `0005` +hatte, verschwindet dieser Chat **für beide Seiten** — nicht nur bei `0022`. +Andere Chats von `0005` mit anderen Kollegen (ohne `0022`) bleiben davon +unberührt. + +Es gibt technisch keinen Weg, "nur die Hälfte" eines Chats zu löschen, ohne +die Nachrichten zu duplizieren oder zu anonymisieren (Body/Name ersetzen statt +Zeile zu löschen) — das macht dieses Script bewusst nicht, da vollständige +Löschung (z.B. aus DSGVO-Gründen beim Austritt eines Mitarbeiters) hier das +Ziel war. + +## Sicherheit + +- Backup **vor** jeder Löschung, automatisch, ungefragt. +- Input-Validierung: `user_id` darf nur `A-Za-z0-9._-` enthalten (keine SQL-Injection über das Argument). +- `set -euo pipefail` — Script bricht bei jedem Fehler sofort ab. +- Bei `0` gefundenen Nachrichten: Script beendet sich ohne jede Aktion. + +## Wiederherstellung aus dem Backup + +Die CSV-Backups liegen unter `/var/backups/starface_chat_backups/` und lassen +sich bei Bedarf mit `\copy ... FROM ... WITH CSV HEADER` wieder in die +jeweilige Tabelle zurückspielen. diff --git a/delete_starface_chat.sh b/delete_starface_chat.sh new file mode 100755 index 0000000..241b60e --- /dev/null +++ b/delete_starface_chat.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# delete_starface_chat.sh — loescht den kompletten Chat-Verlauf eines Starface-Users +# aus der Openfire-Chat-DB (Postgres, Datenbank "asterisk"). +# +# Aufruf: +# ./delete_starface_chat.sh +# +# ist die Starface-Benutzer-ID wie sie im JID-Format verwendet wird, +# z.B. "0001" (JID dann 0001@). Einfach die Nummer/den Login-Namen +# des Users angeben, wie er in Starface als Benutzer-ID gefuehrt wird. +# +# Was das Script macht: +# 1. Findet alle Konversationen (ofconversation) in denen der User als +# Absender oder Empfaenger vorkommt (fromjid/tojid LIKE '@%'). +# 2. Sichert ALLE betroffenen Zeilen aus ofmessagearchive + ofconversation +# als CSV-Backup nach /var/backups/starface_chat_backups/ BEVOR irgendwas +# geloescht wird. +# 3. Loescht die Nachrichten aus ofmessagearchive. +# 4. Loescht die zugehoerigen ofconversation-Eintraege, aber NUR wenn nach +# dem Loeschen keine Nachricht mehr auf diese conversationid verweist +# (falls doch noch andere Nutzer/Nachrichten dranhaengen, bleibt der +# Konversations-Header stehen, nur ohne die geloeschten Nachrichten). +# +# Muss LOKAL auf dem Starface-Server laufen (braucht sudo-Zugriff auf den +# postgres-User, psql muss installiert sein — ist bei Starface Standard). +# +# WICHTIG: Loescht die GEMEINSAME Konversation. Openfire speichert eine +# Konversation zwischen zwei Usern als EINE gemeinsame History (keine +# getrennten Kopien pro Teilnehmer). D.h. loescht man z.B. User 0022, dann +# verschwindet auch bei dessen Chatpartnern (z.B. 0005) genau dieser eine +# Chat mit 0022 — alle anderen Chats von 0005 mit anderen Usern bleiben +# unberuehrt. Das ist technisch bedingt und so gewollt (siehe README). + +set -euo pipefail + +USER_ID="${1:-}" + +if [[ -z "$USER_ID" ]]; then + echo "Usage: $0 " >&2 + echo "Beispiel: $0 0001" >&2 + exit 1 +fi + +# Nur alphanumerisch + . _ - erlauben (keine SQL-Injection ueber das Argument) +if [[ ! "$USER_ID" =~ ^[A-Za-z0-9._-]+$ ]]; then + echo "Fehler: user_id enthaelt ungueltige Zeichen: '$USER_ID'" >&2 + exit 1 +fi + +JID_PATTERN="${USER_ID}@%" +TS="$(date +%Y%m%d_%H%M%S)" +BACKUP_DIR="/var/backups/starface_chat_backups" +MSG_BACKUP="${BACKUP_DIR}/chat_backup_${USER_ID}_${TS}_messages.csv" +CONV_BACKUP="${BACKUP_DIR}/chat_backup_${USER_ID}_${TS}_conversations.csv" + +mkdir -p "$BACKUP_DIR" +chmod 777 "$BACKUP_DIR" # postgres-OS-User braucht Schreibzugriff fuer \copy + +PSQL="sudo -u postgres psql -d asterisk -v ON_ERROR_STOP=1" + +echo "== Starface Chat-Loeschung fuer User '${USER_ID}' ==" + +MSG_COUNT=$($PSQL -t -A -c "SELECT count(*) FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}';") +echo "Gefundene Nachrichten: ${MSG_COUNT}" + +if [[ "$MSG_COUNT" -eq 0 ]]; then + echo "Keine Nachrichten fuer diesen User gefunden — nichts zu tun." + exit 0 +fi + +echo "Erstelle Backup..." +$PSQL -c "\copy (SELECT * FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}') TO '${MSG_BACKUP}' WITH CSV HEADER" +$PSQL -c "\copy (SELECT * FROM ofconversation WHERE conversationid IN (SELECT DISTINCT conversationid FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}')) TO '${CONV_BACKUP}' WITH CSV HEADER" +echo "Backup gespeichert:" +echo " ${MSG_BACKUP}" +echo " ${CONV_BACKUP}" + +echo "Loesche Nachrichten + verwaiste Konversationen..." +$PSQL <