899 lines
60 KiB
Markdown
899 lines
60 KiB
Markdown
# DeskHub
|
||
|
||
**DeskHub** ist ein vollständiges, selbst gehostetes Helpdesk-System. Kunden erstellen und verfolgen Supportanfragen über ein individuell gestaltbares Kundenportal. Das Support-Team bearbeitet Tickets, E-Mails, Aufgaben und Wissensartikel zentral über die Weboberfläche, die Windows-App oder die Android-App.
|
||
|
||

|
||
|
||
> Diese Anleitung ist auch für Einsteiger geeignet. Über das Inhaltsverzeichnis kommt ihr direkt zum gewünschten Thema. Die Abschnitte [Plugins entwickeln](#plugins-entwickeln) und [API und Webhooks](#api-und-webhooks-für-entwickler) richten sich an Entwickler.
|
||
|
||
## Funktionen
|
||
|
||
- **Kundenportal** mit Ticket-Erstellung, Ticketstatus, Wissensdatenbank und frei gestaltbaren Seiten
|
||
- **Mitarbeiterbereich** mit Ticketlisten, Filtern, gespeicherten Ansichten, Zuweisungen und internen Notizen
|
||
- **E-Mail**: Versand über SMTP (auch pro Absenderadresse), automatischer Ticketimport über IMAP
|
||
- **Abteilungen, Teams und Rollen** mit Berechtigungen, die pro Abteilung unterschiedlich sein können
|
||
- **SLA-Pläne**, Eskalations- und Ticketregeln, Geschäftszeiten und Feiertage
|
||
- **Berichte** mit frei zusammenstellbarem Bericht-Baukasten und CSV-Export
|
||
- **Integrationen**: API-Schlüssel, Webhooks und eine Schnittstelle zum Anlegen von Tickets aus anderen Systemen
|
||
- **Überwachung**: Warnung bei Störungen des E-Mail-Abrufs, Verbindungsanzeige in den Apps
|
||
- **Plugins** zum Nachrüsten eigener Funktionen
|
||
- **Update-Funktion** für Programmdateien und Datenbank, Backups und Datenschutz-Funktionen
|
||
- **Import aus osTicket** inklusive Abteilungen, Nachrichten und Anhängen
|
||
- **Windows-App und Android-App** mit hellem und dunklem Design, direkt aus dem Mitarbeiterbereich herunterladbar
|
||
|
||
## Einblicke
|
||
|
||
### Neues Ticket erstellen
|
||
|
||
[](DeskHub-Webseite/docs/images/new-ticket.png)
|
||
|
||
### Kunden-Login
|
||
|
||
[](DeskHub-Webseite/docs/images/customer-login.png)
|
||
|
||
### Mitarbeiter-Login
|
||
|
||
[](DeskHub-Webseite/docs/images/staff-login.png)
|
||
|
||
---
|
||
|
||
## Inhaltsverzeichnis
|
||
|
||
- [Was ist was?](#was-ist-was)
|
||
- [Erstinstallation](#erstinstallation)
|
||
- [Schnellstart](#schnellstart)
|
||
- [Anmelden](#anmelden)
|
||
- [Für Kunden: Ein Ticket erstellen](#für-kunden-ein-ticket-erstellen)
|
||
- [Für Mitarbeiter: Tickets bearbeiten](#für-mitarbeiter-tickets-bearbeiten)
|
||
- [Für Admins: Das Adminportal](#für-admins-das-adminportal)
|
||
- [E-Mails versenden (SMTP)](#e-mails-versenden-smtp)
|
||
- [E-Mails automatisch abrufen (Postfächer)](#e-mails-automatisch-abrufen-postfächer)
|
||
- [Automatisierung (Cronjobs)](#automatisierung-cronjobs)
|
||
- [SLA-Pläne](#sla-pläne)
|
||
- [Gespeicherte Ansichten](#gespeicherte-ansichten)
|
||
- [Berichte und Bericht-Baukasten](#berichte-und-bericht-baukasten)
|
||
- [Integrationen: API-Schlüssel und Webhooks](#integrationen-api-schlüssel-und-webhooks)
|
||
- [Rechte und Rollen](#rechte-und-rollen)
|
||
- [Überwachung und Störungsmeldungen](#überwachung-und-störungsmeldungen)
|
||
- [Windows-App und Android-App](#windows-app-und-android-app)
|
||
- [System-Update und Datenbank-Update](#system-update-und-datenbank-update)
|
||
- [Import aus osTicket](#import-aus-osticket)
|
||
- [Plugins verwenden](#plugins-verwenden)
|
||
- [Plugins entwickeln](#plugins-entwickeln)
|
||
- [Plugin- und Theme-Webseite](#plugin--und-theme-webseite)
|
||
- [API und Webhooks (für Entwickler)](#api-und-webhooks-für-entwickler)
|
||
- [Sicherheit und Datenschutz](#sicherheit-und-datenschutz)
|
||
- [Backup](#backup)
|
||
- [Hilfe, etwas funktioniert nicht](#hilfe-etwas-funktioniert-nicht)
|
||
|
||
---
|
||
|
||
## Was ist was?
|
||
|
||
DeskHub hat drei Bereiche:
|
||
|
||
| Bereich | Für wen? | Adresse |
|
||
|---|---|---|
|
||
| **Kundenportal** | Eure Kunden | `eure-domain.de/` |
|
||
| **Mitarbeiterbereich** | Support-Team und Admins | `eure-domain.de/staff/` |
|
||
| **Apps** | Support-Team und Admins am PC und unterwegs | Windows-App, Android-App |
|
||
|
||
Ein Admin-Konto ist ein Mitarbeiter-Konto mit der Rolle „Admin“. Beim Anmelden gibt es keinen Unterschied, nur bei dem, was man danach sieht.
|
||
|
||
---
|
||
|
||
## Erstinstallation
|
||
|
||
**Voraussetzungen** (im Zweifel euren Hosting-Anbieter fragen):
|
||
|
||
- PHP 8.2 oder neuer
|
||
- Eine MySQL-Datenbank (für kleine Installationen und Tests geht auch SQLite)
|
||
- PHP-Erweiterung `imap`, wenn E-Mails automatisch abgerufen werden sollen
|
||
- PHP-Erweiterung `zip` für Theme-Upload, Plugin-Installation und System-Update per ZIP
|
||
|
||
**So geht’s:**
|
||
|
||
1. Alle DeskHub-Dateien auf den Server hochladen (zum Beispiel per FTP).
|
||
2. Im Browser `eure-domain.de/install/` aufrufen.
|
||
3. Dem Assistenten folgen: Datenbank-Zugangsdaten, Website-Name, erstes Admin-Konto.
|
||
4. Danach unter `eure-domain.de/staff/login.php` mit dem neuen Konto anmelden.
|
||
|
||
**Ganz wichtig:** Löscht anschließend den Ordner `install` vom Server (oder sperrt ihn). Sonst könnte jemand die Installation ein zweites Mal starten und eure Daten überschreiben.
|
||
|
||
---
|
||
|
||
## Schnellstart
|
||
|
||
Direkt nach der Installation läuft DeskHub, kann aber noch keine E-Mails verschicken oder abrufen. Arbeitet diese Liste einmal von oben nach unten ab:
|
||
|
||
| # | Was | Wo | Warum |
|
||
|---|---|---|---|
|
||
| 1 | **Abteilungen anlegen** (z. B. „Technik“, „Vertrieb“) | Adminportal → Abteilungen | Jedes Ticket gehört zu genau einer Abteilung |
|
||
| 2 | **SMTP einrichten** (E-Mail-Versand) | Adminportal → Einstellungen → E-Mail | Damit Kunden Bestätigungen bekommen |
|
||
| 3 | **Postfach einrichten** (E-Mail-Abruf, optional) | Adminportal → Postfächer (Abruf) | Damit eingehende Mails zu Tickets werden |
|
||
| 4 | **Automatisierung prüfen** | Adminportal → Einstellungen → Cron-Jobs | Damit Versand, Abruf und Prüfungen von selbst laufen |
|
||
| 5 | **Mitarbeiter anlegen** | Adminportal → Mitarbeiter | Damit nicht nur ihr allein Tickets bearbeitet |
|
||
|
||
---
|
||
|
||
## Anmelden
|
||
|
||
Es gibt zwei getrennte Logins:
|
||
|
||
- **Kunden** melden sich unter `/login.php` an (oder erstellen ohne Konto ein Ticket).
|
||
- **Mitarbeiter und Admins** melden sich unter `/staff/login.php` an.
|
||
|
||
Ein Kunden-Konto hat keinen Zugang zum Mitarbeiterbereich und umgekehrt.
|
||
|
||
---
|
||
|
||
## Für Kunden: Ein Ticket erstellen
|
||
|
||
1. Auf der Startseite **„Neues Ticket eröffnen“** wählen.
|
||
2. Name, E-Mail-Adresse und Anliegen eintragen.
|
||
3. Nach dem Absenden gibt es eine **Ticketnummer** auf der Seite und per E-Mail.
|
||
4. Mit dieser Nummer lässt sich jederzeit unter **„Ticketstatus überprüfen“** nachsehen, ob es eine Antwort gibt, auch ohne Konto.
|
||
|
||
---
|
||
|
||
## Für Mitarbeiter: Tickets bearbeiten
|
||
|
||
Im Mitarbeiterbereich gibt es links im Menü:
|
||
|
||
- **Übersicht**: wie viele Tickets offen, euch zugewiesen oder überfällig sind
|
||
- **Tickets**: die komplette Liste mit Suche, Filtern und gespeicherten Ansichten
|
||
- **Aufgaben**: eigene To-dos, unabhängig von Tickets
|
||
- **Berichte**: Auswertungen zu Antwortzeiten und Ticketaufkommen
|
||
- **Sperrliste**: einzelne E-Mail-Adressen oder ganze Mail-Anbieter blockieren
|
||
- **Verzeichnis**: Kontaktliste aller Kollegen
|
||
|
||
In einem Ticket könnt ihr dem Kunden antworten, eine **interne Notiz** hinterlassen (nur das Team sieht sie), den Status ändern, das Ticket zuweisen, lösen oder schließen. Welche dieser Aktionen möglich sind, hängt von eurer Rolle in der Abteilung des Tickets ab.
|
||
|
||
---
|
||
|
||
## Für Admins: Das Adminportal
|
||
|
||
Im Menü gibt es den Punkt **„Adminportal“**. Er ist für echte Admins immer sichtbar und für Co-Admins mit passenden Einzelrechten (siehe [Rechte und Rollen](#rechte-und-rollen)). Sieht ein Admin den Punkt nicht: einmal ab- und wieder anmelden und prüfen, ob der Bereich eingeklappt ist (Pfeil daneben).
|
||
|
||
**Verwalten**
|
||
|
||
| Punkt | Wofür |
|
||
|---|---|
|
||
| Abteilungen | Themenbereiche, denen Tickets zugeordnet werden; mit Status, Abteilungsleiter, Mitgliedern und SLA-Plan |
|
||
| Prioritäten / SLA | Dringlichkeitsstufen mit Reaktions- und Lösungszeiten |
|
||
| SLA-Pläne | Eigene Zeiten pro Abteilung oder Hilfethema |
|
||
| Hilfethemen | Auswahl, die Kunden beim Ticket-Erstellen sehen, mit Zuordnung zu Abteilung, Priorität und Team |
|
||
| Ticket-Felder, Benutzerdefinierte Listen | Eigene Zusatzfelder für Tickets |
|
||
| Vorlagen | Textbausteine für schnelle Antworten |
|
||
| Seiten | Frei gestaltbare Inhaltsseiten im Kundenportal (z. B. AGB, Impressum) |
|
||
| E-Mail-Adressen | Absender- und Eingangsadressen, jeweils mit Abteilung, Hilfethema, optional eigenem SMTP und Test-Knopf |
|
||
| Postfächer (Abruf) | Von wo E-Mails abgerufen werden |
|
||
| E-Mail-Vorlagen | Texte der automatisch verschickten Mails |
|
||
| Wissensdatenbank | Öffentliche Hilfe-Artikel für Kunden |
|
||
| API-Schlüssel, Webhooks | Anbindung anderer Systeme |
|
||
| Plugins | Zusatzfunktionen installieren und verwalten |
|
||
|
||
**Kunden**
|
||
|
||
| Punkt | Wofür |
|
||
|---|---|
|
||
| Kundenverzeichnis | Alle Kunden-Konten im Überblick |
|
||
| Organisationen | Mehrere Kunden zu einer Firma bündeln |
|
||
|
||
**Agenten**
|
||
|
||
| Punkt | Wofür |
|
||
|---|---|
|
||
| Mitarbeiter | Konten anlegen, Abteilungen, Rolle je Abteilung vergeben |
|
||
| Teams | Mitarbeiter-Gruppen, z. B. für Zuweisungen |
|
||
| Rollen | Berechtigungssets |
|
||
|
||
**System**
|
||
|
||
| Punkt | Wofür |
|
||
|---|---|
|
||
| Admin-Protokoll | Alle wichtigen Änderungen und fehlgeschlagene automatische E-Mails |
|
||
| Ticket-Regeln | Automatische Aktionen bei neuen Tickets |
|
||
| Eskalationsregeln | Automatische Aktionen bei überfälligen oder liegengebliebenen Tickets |
|
||
| Wiederkehrende Tickets | Regelmäßig neu erstellte Tickets (z. B. monatliche Checkliste) |
|
||
| Zeiterfassung | Erfasste Bearbeitungszeiten einsehen |
|
||
| Geschäftszeiten | Zeitfenster, in denen die SLA-Uhr läuft, inklusive Feiertage |
|
||
| Einstellungen | Name, Logo, Zeitzone, E-Mail, Cron-Jobs, Datenschutz, Design u. v. m. |
|
||
| Backup | Manuelle und automatische Sicherungen |
|
||
| System-Update | Programm und Datenbank aktualisieren |
|
||
|
||
### Kundenportal-Design (Themes)
|
||
|
||
Unter **Einstellungen → Design** lassen sich mehrere Themes als ZIP-Datei hochladen, aktivieren und löschen. Ein aktiviertes Theme gilt für das ganze Kundenportal. Mit **„Standarddesign nutzen“** wird es wieder deaktiviert. Der Anzeigename wird aus dem Dateinamen der ZIP übernommen; lädt man ein Theme mit gleichem Namen erneut hoch, ersetzt es die vorhandene Version. Fertige Themes liegen im Ordner `theme-packages/`. Außerdem könnt ihr Themes direkt aus dem Katalog der Plugin-Webseite installieren: Auf derselben Seite erscheint unter **„Themes aus dem Katalog“** das Angebot automatisch. Prüfsumme und Signatur (mit dem unter Plugins hinterlegten Herausgeber-Schlüssel) werden vor der Installation geprüft; aktiviert wird das Theme erst, wenn ihr es selbst aktiviert.
|
||
|
||
---
|
||
|
||
## E-Mails versenden (SMTP)
|
||
|
||
Das ist der wichtigste erste Schritt: Damit Kunden eine Bestätigung mit ihrer Ticketnummer bekommen, muss der E-Mail-Versand eingerichtet sein.
|
||
|
||
1. Adminportal → **Einstellungen → E-Mail**.
|
||
2. Server, Port, Benutzername, Passwort und Absenderadresse eures E-Mail-Anbieters eintragen. Diese Daten findet ihr im Kundenlogin eures Anbieters unter „E-Mail-Konten“ oder „Postfach-Einstellungen“.
|
||
3. Auf **„Test-Mail senden“** klicken. Kommt sie an, funktioniert der Versand.
|
||
|
||
**Eigener Versand pro Absenderadresse:** Unter Adminportal → **E-Mail-Adressen** kann jede Adresse einen eigenen SMTP-Server bekommen (Reiter „Abgehend (SMTP)“). Mit **„Testen“** prüft ihr Abruf und Versand jeder Adresse einzeln. Gibt es für eine Adresse keinen eigenen Server, wird der allgemeine verwendet.
|
||
|
||
**Häufigste Stolperfalle:** Die Absenderadresse einer Abteilung muss bei eurem Mail-Anbieter existieren und freigeschaltet sein. Sonst blockt der Anbieter den Versand. Im Zweifel die Adresse deaktivieren oder löschen, dann gilt die Standard-Absenderadresse.
|
||
|
||
Kommt trotz erfolgreicher Test-Mail eine bestimmte automatische Mail nicht an, zeigt das **Admin-Protokoll** die genaue Fehlermeldung des Anbieters.
|
||
|
||
---
|
||
|
||
## E-Mails automatisch abrufen (Postfächer)
|
||
|
||
Damit eine Mail an z. B. `support@eure-domain.de` automatisch als Ticket erscheint, braucht DeskHub Zugriff auf das Postfach per **IMAP**.
|
||
|
||
### Ein Postfach einrichten
|
||
|
||
1. Adminportal → **Postfächer (Abruf)** → „Neues Postfach“.
|
||
2. Server, Port, Benutzername und Passwort eintragen (meist unter „IMAP-Zugang“ beim Anbieter).
|
||
3. Optional eine **Standardabteilung** wählen, sonst entscheidet die Empfängeradresse.
|
||
4. Speichern und in der Liste auf **„Testen“** klicken. Läuft der Test, ruft DeskHub das Postfach ab, sobald die [Automatisierung](#automatisierung-cronjobs) aktiv ist.
|
||
|
||
### Mehrere Postfächer
|
||
|
||
Habt ihr getrennte Postfächer pro Abteilung (z. B. `technik@` und `vertrieb@`), legt ihr für jedes ein eigenes Postfach mit eigener Standardabteilung an. DeskHub ruft alle aktiven Postfächer nacheinander ab.
|
||
|
||
### Eine Adresse einer Abteilung zuordnen
|
||
|
||
Läuft alles in einem Sammelpostfach zusammen (z. B. per Weiterleitung), muss DeskHub wissen, welche Empfängeradresse zu welcher Abteilung gehört:
|
||
|
||
- Tragt bei einer Abteilung eine E-Mail-Adresse ein, dann legt DeskHub den Eintrag automatisch an.
|
||
- Oder legt unter Adminportal → **E-Mail-Adressen** weitere Adressen an, auch mehrere auf einmal (eine pro Zeile). Dort lässt sich zusätzlich ein **Hilfethema** festlegen, das Tickets über diese Adresse automatisch bekommen.
|
||
|
||
Ist eine Adresse nirgends hinterlegt, landet das Ticket in der Standardabteilung. Ist die zugeordnete Abteilung deaktiviert, wird ebenfalls die Standardabteilung genutzt.
|
||
|
||
### Nach dem Abruf
|
||
|
||
Pro Postfach legt ihr fest, was mit einer verarbeiteten Mail passiert: als gelesen markieren (Voreinstellung und sicherste Wahl), in einen Ordner verschieben oder löschen.
|
||
|
||
---
|
||
|
||
## Automatisierung (Cronjobs)
|
||
|
||
Einige Aufgaben müssen regelmäßig von selbst laufen:
|
||
|
||
- **E-Mail-Abruf** (alle 5 Minuten empfohlen)
|
||
- **SLA-Prüfung** (alle 15 Minuten)
|
||
- **Eskalationsregeln** (stündlich)
|
||
- **Wiederkehrende Tickets** (täglich)
|
||
- **Automatische Backups** (nach Zeitplan)
|
||
- **Datenanonymisierung** (täglich)
|
||
|
||
Dafür gibt es unter Adminportal → **Einstellungen → Cron-Jobs** drei Wege:
|
||
|
||
**Option A – Automatischer Hintergrund-Betrieb (Standard):** Ist von Anfang an aktiv. Sobald jemand die Website, das Backend oder eine App nutzt, prüft DeskHub im Hintergrund, ob etwas fällig ist, und führt es aus. Hat eure Seite regelmäßig Besucher, reicht das für die meisten Fälle.
|
||
|
||
**Option B – Echter Server-Cronjob:** Mit eigenem (v)Server und Shell-Zugriff trägt DeskHub per Klick auf **„Jetzt installieren“** die nötigen Cronjobs selbst ein. Dann läuft alles zuverlässig zur exakten Zeit, auch nachts ohne Besucher. Auf einfachem Webhosting ohne Shell ist der Knopf ausgeblendet, dort übernimmt Option A.
|
||
|
||
**Option C – Manuell:** Jede Aufgabe hat einen Knopf **„Jetzt ausführen“**.
|
||
|
||
Nach der Installation müsst ihr nichts tun, Option A läuft von selbst.
|
||
|
||
---
|
||
|
||
## SLA-Pläne
|
||
|
||
Ein SLA-Plan legt fest, wie schnell reagiert und gelöst werden soll. Unter Adminportal → **SLA-Pläne** legt ihr Pläne mit Reaktions- und Lösungszeit an und weist sie Abteilungen oder Hilfethemen zu.
|
||
|
||
Welche Zeiten für ein Ticket gelten, entscheidet diese Reihenfolge:
|
||
|
||
1. SLA-Plan des **Hilfethemas**
|
||
2. SLA-Plan der **Abteilung**
|
||
3. Zeiten der **Priorität**
|
||
|
||
So kann ein Premium-Hilfethema schneller reagieren müssen als der Rest der Abteilung. Die Geschäftszeiten und Feiertage gelten weiterhin.
|
||
|
||
---
|
||
|
||
## Gespeicherte Ansichten
|
||
|
||
In der Ticketliste lassen sich die aktuellen Filter (Status, Zuweisung, Abteilung, Priorität, Überfälligkeit usw.) als **Ansicht** speichern. Gespeicherte Ansichten erscheinen als Schnellauswahl über der Liste. Ihr könnt sie für euch behalten oder mit dem ganzen Team teilen. Gemeinsame Ansichten sind in Web, Windows-App und Android-App gleich verfügbar. Speichern und Löschen funktioniert direkt über der Ticketliste („Aktuelle Filter als Ansicht speichern“, ✕ neben der Ansicht). Löschen können der Ersteller einer Ansicht und alle Admins.
|
||
|
||
---
|
||
|
||
## Berichte und Bericht-Baukasten
|
||
|
||
Unter **Berichte** gibt es die Standardauswertungen. Der **Bericht-Baukasten** erlaubt eigene Auswertungen:
|
||
|
||
- **Gruppieren nach:** Abteilung, Hilfethema, Mitarbeiter, Team, Priorität, Status, Quelle, Tag, Woche oder Monat
|
||
- **Kennzahlen:** Tickets gesamt, offen, gelöst/geschlossen, überfällig, durchschnittliche erste Antwort und Lösungszeit sowie SLA-Erfüllung bei Antwort und Lösung
|
||
- **Zeitraum und Filter:** nach Abteilung, Priorität, Mitarbeiter, Hilfethema, Status und Quelle
|
||
- **Speichern und teilen:** Berichte lassen sich benennen, speichern und mit dem Team teilen
|
||
- **Export** als CSV (kompatibel mit Excel)
|
||
|
||
Jeder sieht nur Zahlen aus Abteilungen, auf die er Zugriff hat. Der Baukasten ist auch in Windows-App und Android-App verfügbar.
|
||
|
||
---
|
||
|
||
## Integrationen: API-Schlüssel und Webhooks
|
||
|
||
Mit **API-Schlüsseln** und **Webhooks** verbindet ihr DeskHub mit anderen Systemen (z. B. Monitoring, Formulare, Chat-Tools).
|
||
|
||
**API-Schlüssel** (Adminportal → API-Schlüssel): Ein Schlüssel erlaubt einem anderen System, Tickets in DeskHub anzulegen. Beim Erstellen wird der Schlüssel **einmalig** angezeigt, danach nie wieder; notiert ihn sofort. Pro Schlüssel legt ihr fest, ob er Tickets anlegen und/oder lesen darf, und optional, von welchen IP-Adressen er benutzt werden darf. Schlüssel lassen sich jederzeit deaktivieren. Es gilt eine Begrenzung auf 60 Tickets pro Minute.
|
||
|
||
**Webhooks** (Adminportal → Webhooks): DeskHub meldet Ereignisse an eine Adresse eures Systems: Ticket erstellt, Antwort geschrieben, Status geändert, Ticket zugewiesen. Jede Meldung ist mit eurem geheimen Schlüssel signiert, damit das Empfängersystem die Echtheit prüfen kann. Der Zustellstatus steht in der Liste. Schlägt eine Adresse zehnmal hintereinander fehl, wird der Webhook automatisch deaktiviert. Adressen im internen Netzwerk sind aus Sicherheitsgründen nicht erlaubt.
|
||
|
||
Die technische Beschreibung für Entwickler steht im Abschnitt [API und Webhooks (für Entwickler)](#api-und-webhooks-für-entwickler).
|
||
|
||
---
|
||
|
||
## Rechte und Rollen
|
||
|
||
Nicht jeder im Team soll vollen Admin-Zugriff haben. Dafür gibt es **Rollen**:
|
||
|
||
1. Adminportal → **Rollen** → „Neue Rolle“.
|
||
2. Namen vergeben (z. B. „Teamleitung Technik“).
|
||
3. Ticket-Berechtigungen ankreuzen (antworten, Notizen, zuweisen, schließen, löschen …).
|
||
4. Optional einzelne **Adminportal-Bereiche** freischalten (z. B. nur „Abteilungen“ und „Mitarbeiter“). Das macht die Person zum **Co-Admin** für genau diese Bereiche.
|
||
5. Unter **Mitarbeiter** die Rolle zuweisen.
|
||
|
||
### Rolle pro Abteilung
|
||
|
||
Eine Person kann in verschiedenen Abteilungen unterschiedliche Rollen haben, etwa „Teamleitung“ in Technik und „Agent“ in Vertrieb. Das stellt ihr im Mitarbeiter-Konto unter den zusätzlichen Abteilungen ein. Die Rechte in einem Ticket richten sich nach der Abteilung dieses Tickets, in Web und in beiden Apps. Eine deaktivierte Rolle ersetzt DeskHub durch die Standardrechte eines Agenten.
|
||
|
||
Einige Bereiche (Backup, System-Update, Ticket-Regeln, Ticket-Felder, Seiten, Kundenverzeichnis, Plugins, API-Schlüssel, Webhooks) bleiben bewusst immer echten Admins vorbehalten. Ein Co-Admin kann sich oder andere nie zum echten Admin machen.
|
||
|
||
---
|
||
|
||
## Überwachung und Störungsmeldungen
|
||
|
||
DeskHub überwacht sich selbst und meldet Probleme, bevor Kunden sie bemerken:
|
||
|
||
- **Postfach nicht erreichbar:** Schlägt der E-Mail-Abruf mehrfach hintereinander fehl, erscheint für Verantwortliche ein rotes Banner im Mitarbeiterbereich und in den Apps. Außerdem bekommen die Admins eine E-Mail (höchstens einmal pro 24 Stunden) und eine weitere, sobald das Postfach wieder funktioniert.
|
||
- **Abruf veraltet:** Wurde länger nicht abgerufen, gibt es einen Hinweis.
|
||
- **Versand fehlgeschlagen:** Scheitern ausgehende Mails, steht das ebenfalls im Banner.
|
||
- **Keine Verbindung zum Server:** Die Windows-App und die Android-App zeigen ein Banner, wenn der Server nicht erreichbar ist. Sie versuchen automatisch wieder, die Verbindung herzustellen, zusätzlich gibt es einen Knopf **„Jetzt erneut versuchen“**.
|
||
|
||
Die Details zu einer Störung seht ihr unter Adminportal → E-Mail-Adressen und Postfächer (Abruf).
|
||
|
||
---
|
||
|
||
## Windows-App und Android-App
|
||
|
||
Beide Apps sind für Mitarbeiter und Admins gedacht und haben ein helles und ein dunkles Design (umschaltbar oder automatisch nach System).
|
||
|
||
**Download:** Im Mitarbeiterbereich gibt es im Menü den Punkt **„Apps“**. Dort laden angemeldete Mitarbeiter die Windows- und die Android-App herunter und sehen Version, Größe, Prüfsumme, eine Kurzanleitung und die Serveradresse zum Kopieren. Ohne Anmeldung sind die Dateien nicht erreichbar.
|
||
|
||
**Für Admins – Apps bereitstellen:** Legt die fertigen Dateien per FTP in den Ordner `app_downloads` auf dem Server, genau mit diesen Namen: `DeskHub-Setup.exe` (Windows) und `DeskHub.apk` (Android). Zum Aktualisieren ersetzt ihr die Datei einfach. Die Seite „Apps“ zeigt automatisch Größe, Datum und Prüfsumme der neuen Datei. Der Ordner wird bei System-Updates nie überschrieben und ist nur über die Anmeldung erreichbar.
|
||
|
||
**Einrichtung:**
|
||
|
||
1. App installieren und öffnen.
|
||
2. Beim ersten Start die Adresse eurer DeskHub-Installation eingeben (z. B. `https://eure-domain.de`). Die App merkt sie sich.
|
||
3. Mit dem Mitarbeiter-Konto anmelden.
|
||
|
||
**Was die Apps können:**
|
||
|
||
- Tickets bearbeiten (antworten, Notizen, zuweisen, Status ändern, lösen, schließen), Übersicht, Kundenverzeichnis, internen Chat mit Kollegen
|
||
- Gespeicherte Ansichten nutzen und Berichte aus dem Bericht-Baukasten ansehen
|
||
- Störungs- und Verbindungsbanner
|
||
- Admins und Co-Admins finden zusätzlich die **Verwaltung** mit fast allen Adminportal-Bereichen, je nach zugewiesenen Rechten: Abteilungen, Prioritäten, SLA-Pläne, Hilfethemen, E-Mail-Adressen (inkl. Test), Wissensdatenbank, E-Mail-Vorlagen, Organisationen, Mitarbeiter, Teams, Rollen, Admin-Protokoll, Eskalationsregeln, Zeiterfassung, Geschäftszeiten, Sperrliste, Aufgaben
|
||
- Systemnahe Bereiche (Backup, System-Update, Plugins, API-Schlüssel, Webhooks, Postfächer, Ticket-Regeln, Ticket-Felder, Seiten, Einstellungen) gibt es bewusst nur in der Weboberfläche
|
||
|
||
**Updates:** Die Android-App wird nur dann über die alte Version installiert, wenn sie mit demselben Signaturschlüssel erstellt wurde und eine höhere Versionsnummer hat. Nach einem Update die App einmal ganz schließen und neu öffnen.
|
||
|
||
---
|
||
|
||
## System-Update und Datenbank-Update
|
||
|
||
Adminportal → **System-Update** hat zwei Teile:
|
||
|
||
**Neue Programmversion installieren:** Zeigt verfügbare Versionen und installiert die gewählte mit einem Klick (oder per hochgeladener ZIP). Vor jedem Update wird automatisch ein Backup erstellt. Eure Konfiguration, die Datenbank, hochgeladene Dateien, bereitgestellte Apps, Backups und Plugins werden nie überschrieben. Der Download erfolgt nur über eine geprüfte, verschlüsselte Verbindung. Danach wird die Datenbank automatisch angepasst.
|
||
|
||
**Datenbank aktualisieren:** Die Karte „Datenbank“ zeigt, ob die Datenbank zum installierten Programm passt. Wenn nicht, erscheint dort und für Admins oben auf jeder Seite ein Hinweis. Der Knopf **„Datenbank aktualisieren“** erstellt zuerst ein Backup und spielt dann alle fehlenden Änderungen ein. Das ist der richtige Weg, wenn ihr Dateien per FTP hochgeladen habt. Scheitert das Backup, wird die Datenbank nicht angefasst.
|
||
|
||
Nach jedem Update: Browser-Cache leeren (Strg + F5).
|
||
|
||
---
|
||
|
||
## Import aus osTicket
|
||
|
||
Wer von osTicket auf DeskHub umzieht, kann den Bestand übernehmen: Kunden, Abteilungen, Hilfethemen, Tickets, Nachrichten (Kundennachrichten, Antworten, interne Notizen), Mitlesende und Anhänge. Unterstützt werden SQL-Dumps von osTicket 1.10 bis 1.18, als phpMyAdmin-Export oder mit `mysqldump`, auch mit einem anderen Tabellenpräfix als `ost_`.
|
||
|
||
### Vorbereitung
|
||
|
||
1. **Backup von DeskHub erstellen** (Adminportal → Backup). Der Import lässt sich wiederholen, ohne etwas doppelt anzulegen, ein Backup ist trotzdem sinnvoll.
|
||
2. **Mitarbeiter in DeskHub anlegen.** osTicket-Mitarbeiter werden über die **E-Mail-Adresse** den DeskHub-Mitarbeitern zugeordnet. Wer in DeskHub fehlt, kann nicht zugewiesen werden: Seine Tickets werden unzugewiesen importiert, seine Antworten ohne Mitarbeiter übernommen. Legt deshalb vorher alle Kollegen mit derselben E-Mail-Adresse an wie in osTicket.
|
||
3. **Dump erstellen.** In osTicket (oder phpMyAdmin) die komplette Datenbank als SQL exportieren. Der Dump darf groß sein: Ein Export mit mehreren hundert MB (Anhänge und Sitzungsdaten) funktioniert, die Tabellen werden blockweise gelesen.
|
||
4. **Nur bei MySQL-Hosting mit knappen Limits:** Große Dateien legt ihr besser per FTP in den DeskHub-Ordner (Option 1), statt sie im Browser hochzuladen.
|
||
|
||
### Durchführung
|
||
|
||
Adminportal → **Einstellungen → „📥 osTicket Import“**.
|
||
|
||
1. **Hochladen:** Entweder den Dateinamen eintragen, wenn die SQL-Datei im DeskHub-Hauptordner liegt (**empfohlen**, vor allem bei großen Dateien), oder die Datei direkt hochladen (sie wird in 5-MB-Teilen übertragen).
|
||
2. **Analysieren:** DeskHub liest die Datei und zeigt, was sie enthält (Kunden, Tickets, Nachrichten, Abteilungen, Hilfethemen, Anhänge). Der Fortschrittsbalken läuft von selbst, das Fenster muss offen bleiben.
|
||
3. **Optionen:** Auswählen, was importiert werden soll. Die Reihenfolge ist fest: Kunden → Abteilungen und Hilfethemen → Tickets → Nachrichten → Anhänge. Anhänge setzen die Nachrichten voraus.
|
||
4. **Import:** Läuft in kleinen Schritten, mit Fortschritt je Bereich. Am Ende steht eine Zusammenfassung mit Hinweisen.
|
||
|
||
### Was dabei passiert
|
||
|
||
| osTicket | DeskHub |
|
||
|---|---|
|
||
| Kunden | Kunden mit Name und E-Mail-Adresse (ohne Adresse werden sie übersprungen). Zugangsdaten werden nicht übernommen, Kunden vergeben bei Bedarf ein neues Passwort. |
|
||
| Abteilungen, Hilfethemen | Fehlende werden angelegt, vorhandene mit **gleichem Namen** wiederverwendet. Hilfethemen kommen mit der richtigen Abteilung und Priorität. |
|
||
| Ticketstatus | Offen → offen, Gelöst → gelöst, Geschlossen und Archiviert → geschlossen. **Gelöschte Tickets werden nicht importiert.** |
|
||
| Priorität | Nach Namen, sonst nach Rangfolge (dringendste zuerst). |
|
||
| Mitarbeiter | Über die E-Mail-Adresse (siehe Vorbereitung). |
|
||
| Quelle | Web, E-Mail, Telefon und API werden übernommen, Sonstiges wird zu Web. |
|
||
| Zeiten | Erstellt, zuletzt geändert und gelöst/geschlossen bleiben erhalten. Die erste Antwort wird aus der ersten Mitarbeiter-Antwort abgeleitet. Offene Tickets bekommen neue SLA-Fristen nach euren Zeiten. |
|
||
| Nachrichten | Kundennachrichten werden als Text übernommen (Zitate früherer Mails werden entfernt), Antworten und interne Notizen behalten ihre Formatierung. Nachrichten ohne Text werden ausgelassen, außer sie haben einen Anhang. |
|
||
| Anhänge | Dateien bis 50 MB. Eingebettete Bilder in Mails (Logos, Signaturen) werden nicht als Anhang übernommen. Gespeichert wird unter einem zufälligen Namen, die Endung bleibt bei bekannten Dateitypen erhalten, alles andere wird `.bin`. |
|
||
|
||
### Gut zu wissen
|
||
|
||
- **Wiederholbar:** Vorhandene Ticketnummern und Kunden werden übersprungen, bereits importierte Nachrichten und Anhänge nicht doppelt angelegt. Ein abgebrochener Import lässt sich also einfach neu starten.
|
||
- **Löschen:** Auf der Optionsseite gibt es „Nur Nachrichten löschen“ und „Alle Tickets löschen“, falls ein Import neu beginnen soll. Beides löscht Daten in DeskHub unwiderruflich, auch **echte** Tickets, die nicht aus dem Import stammen.
|
||
- **Nach dem Import:** Stichproben ansehen (Ticketliste, ein paar Tickets mit Anhängen), ob die Abteilungen stimmen und ob Kunden ihre Tickets finden.
|
||
- **Nicht importiert:** Eigene Formularfelder, Aufgaben, Wissensdatenbank (FAQ), Benutzerkonten und Passwörter, Mitarbeiter-Konten, Vorlagen, Regeln und Einstellungen. Diese richtet ihr in DeskHub neu ein.
|
||
- **Dauer:** Ein Dump mit rund 1.700 Tickets und 450 MB Anhangsdaten braucht gut 3 Minuten für das Hochladen (bei Direkt-Upload) und etwa eine halbe Minute für Analyse und Import.
|
||
|
||
---
|
||
|
||
## Plugins verwenden
|
||
|
||
Mit Plugins rüstet ihr zusätzliche Funktionen nach, ohne DeskHub selbst zu verändern. Alles läuft unter Adminportal → **Plugins** (nur für echte Admins).
|
||
|
||
**Geprüfter Modus (Standard, wenn euer DeskHub einen offiziellen Katalog mitbringt):** Der Herausgeber eurer DeskHub-Version trägt vor dem Release seinen eigenen Katalog und seinen Signierschlüssel ein (siehe [Plugin- und Theme-Webseite](#plugin--und-theme-webseite)). Dann zeigt die Plugin-Seite oben **„Geprüfte Plugins“** mit dem aktuellen Angebot, und es gilt:
|
||
|
||
- Plugins **aus dem Katalog** müssen mit dem Schlüssel des Herausgebers **signiert** sein. Nicht signierte oder fremd signierte Katalog-Pakete werden abgelehnt.
|
||
- **Eigene Plugins** lassen sich zusätzlich über „Eigenes Plugin hochladen“ installieren, auch ohne Signatur (siehe unten). Sie sind in der Liste als „Eigenes Plugin / nicht vom Herausgeber geprüft“ markiert.
|
||
- Der Katalog lädt **automatisch**: Er erscheint ohne Klick, DeskHub hält ihn im Hintergrund alle 30 Minuten aktuell (über die Automatisierung), und bei Ausfall des Katalog-Servers bleibt der zuletzt geladene Stand sichtbar. Gibt es für ein installiertes Plugin eine neuere Version, erscheint für Admins oben auf jeder Seite der Hinweis „Plugin-Updates verfügbar“. Installiert wird ein Update nie von selbst, sondern erst, wenn ihr „Aktualisieren“ wählt. Mit „Katalog aktualisieren“ lässt sich der Abruf auf Wunsch sofort auslösen.
|
||
|
||
Katalog und Schlüssel sind **fest in DeskHub eingebaut** (`includes/catalog_defaults.php`, Teil des Programmcodes). Es gibt keine Einstellung, Umgebungsvariable oder Oberfläche, mit der Admins den Katalog ändern oder den Signaturzwang für Katalog-Plugins abschalten können. Der Katalog ist zusätzlich durch einen **Zugangsschlüssel** geschützt, den DeskHub bei jedem Abruf mitschickt (nur an den offiziellen Katalog, nur über https). Er hält zufällige Besucher fern, ist aber kein Geheimnis gegenüber Admins, die den DeskHub-Code lesen können. Ändern lässt sich das nur durch den Herausgeber mit einer neuen DeskHub-Version. Themes sind davon nur beim Katalog betroffen: Er ist vorgegeben und Themes müssen signiert sein; der manuelle Theme-Upload (nur CSS, Bilder, Schriften) bleibt möglich.
|
||
|
||
**Aus dem Katalog installieren (ohne offiziellen Katalog):** Die Plugin-Webseite (siehe [Plugin- und Theme-Webseite](#plugin--und-theme-webseite)) liefert einen Katalog. Tragt unter Plugins → „Katalog und Herausgeber-Schlüssel“ die Katalog-Adresse und den öffentlichen Herausgeber-Schlüssel ein (den Schlüssel liefert der Betreiber der Webseite, abrufbar unter `/publisher-key.php`) und aktiviert „Nur signierte Plugins installieren“. Danach seht ihr alle Plugins mit Version, Beschreibung und angeforderten Berechtigungen und installiert sie mit einem Klick. DeskHub lädt nur über https, vergleicht die Prüfsumme und prüft die Signatur, bevor etwas installiert wird.
|
||
|
||
**Manuell / eigene Plugins installieren** (auch im geprüften Modus möglich, damit ihr selbst entwickelte Plugins nutzen könnt):
|
||
|
||
1. Plugin als ZIP-Datei bereithalten. Nennt der Anbieter eine Prüfsumme (SHA-256) oder eine Signatur, tragt sie ein, dann wird das Paket vor der Installation geprüft.
|
||
2. ZIP hochladen und bestätigen, dass ihr der Quelle vertraut.
|
||
3. Das Plugin ist danach **noch inaktiv**. Mit **„Aktivieren“** schaltet ihr es ein. Vorher bestätigt ihr die **Berechtigungen**, die das Plugin anfordert (siehe unten). Dabei wird ein Backup erstellt und das Plugin legt bei Bedarf eigene Datenbank-Tabellen an.
|
||
|
||
**Berechtigungen:** Jedes Plugin nennt, welche Erweiterungspunkte es nutzen will: auf Ticket-Ereignisse reagieren, im Hintergrund laufen, Menüpunkte und Seiten anlegen, Bausteine in der Ticketansicht zeigen, eigene API-Endpunkte bereitstellen, eigene Datenbank-Tabellen anlegen. Ihr seht die Liste vor dem Aktivieren und bestätigt sie. DeskHub lässt das Plugin nur diese Erweiterungspunkte registrieren. Fordert eine neue Version zusätzliche Berechtigungen an, wird das Plugin **automatisch angehalten**, bis ihr die neuen bestätigt habt. Das gilt auch, wenn jemand Dateien per FTP austauscht.
|
||
|
||
**Verwalten:** Plugins lassen sich deaktivieren, durch eine neuere Version ersetzen (gleiche Datei erneut hochladen) und entfernen. Beim Entfernen könnt ihr wählen, ob die Daten des Plugins gelöscht werden sollen.
|
||
|
||
**Sicherheit, bitte unbedingt beachten:**
|
||
|
||
- Ein Plugin ist Programmcode und läuft mit **allen Rechten des Systems**, also auch mit Zugriff auf die gesamte Datenbank. Es gibt keine Abschirmung: Die Berechtigungen begrenzen nur, welche Erweiterungspunkte ein Plugin nutzen darf, nicht was sein Code sonst tut. Wirklichen Schutz bietet die **Herkunft**: Installiert nur Plugins aus Quellen, denen ihr vertraut, und aktiviert „Nur signierte Plugins installieren“.
|
||
- **Signatur:** Eine Signatur belegt, dass ein Paket unverändert vom Inhaber des hinterlegten Herausgeber-Schlüssels stammt. Ein verändertes Paket, eine fremde Signatur oder eine auf eine andere Version übertragene Signatur wird abgelehnt. In der Plugin-Liste steht bei jedem Plugin „Signiert“ oder „Nicht signiert“ und woher es kam.
|
||
- Fehler in einem Plugin legen das System nicht lahm: Das Ticket oder die Seite funktioniert weiter. Nach drei Fehlern wird das Plugin automatisch deaktiviert, der Fehlertext steht in der Plugin-Liste.
|
||
- **Notausschalter:** Legt auf dem Server im Ordner `plugins` eine leere Datei namens `.disabled` an, dann wird kein Plugin mehr geladen. Zum Wiederaktivieren die Datei löschen.
|
||
- Der Ordner `plugins` wird bei System-Updates nie überschrieben.
|
||
|
||
### Mitgeliefertes Plugin: Tagesbericht per E-Mail
|
||
|
||
Unter `docs/plugins/tagesbericht-1.0.0.zip` liegt ein fertiges Plugin. Es schickt Mitarbeitern jeden Morgen eine Übersicht: offene, unzugewiesene, überfällige und eigene Tickets, Zugänge und Erledigungen der letzten 24 Stunden sowie die fünf ältesten offenen Tickets. Jeder sieht nur Tickets seiner Abteilungen.
|
||
|
||
Nach Installation und Aktivierung findet ihr im Menü den Punkt **„Tagesbericht“**: Dort schaltet ihr den Versand ein, legt Uhrzeit, Werktage und Empfänger fest und könnt einen **Testbericht** an euch schicken. Voraussetzung ist der eingerichtete E-Mail-Versand.
|
||
|
||
---
|
||
|
||
## Plugins entwickeln
|
||
|
||
Dieser Abschnitt richtet sich an Entwickler. Ein vollständiges, lauffähiges Beispiel liegt in `docs/plugin-beispiel/`, ein praxisnahes in `docs/plugins/tagesbericht/`.
|
||
|
||
### Aufbau
|
||
|
||
Ein Plugin ist ein Ordner, der als ZIP installiert wird:
|
||
|
||
```
|
||
mein-plugin/
|
||
plugin.json Pflicht: Beschreibung
|
||
plugin.php Startdatei (Name über "entry" änderbar), registriert die Erweiterungen
|
||
pages/*.php Seiten, die als Menüpunkt registriert sind
|
||
migrations/ Datenbank-Änderungen (*.sql)
|
||
assets/ js, css, Bilder
|
||
```
|
||
|
||
Die ZIP darf die Dateien direkt im Wurzelverzeichnis oder in genau einem Unterordner enthalten. Erlaubte Dateitypen: `php, json, sql, js, css, png, jpg, jpeg, gif, svg, webp, md, txt, html`. Versteckte Dateien (`.htaccess` usw.) und Pfade mit `..` werden abgelehnt. Größe: maximal 10 MB. Direkte Aufrufe von `.php`, `.sql` und `.json` im Plugin-Ordner sind per `.htaccess` gesperrt (nginx: eigene Regel nötig).
|
||
|
||
### plugin.json
|
||
|
||
```json
|
||
{
|
||
"slug": "mein-plugin",
|
||
"name": "Mein Plugin",
|
||
"version": "1.0.0",
|
||
"description": "Kurze Beschreibung",
|
||
"author": "Name",
|
||
"requires": "1.0.0",
|
||
"entry": "plugin.php",
|
||
"permissions": ["hooks.tickets", "ui.menu"]
|
||
}
|
||
```
|
||
|
||
| Feld | Bedeutung |
|
||
|---|---|
|
||
| `slug` | Pflicht. Eindeutiger Name: Kleinbuchstaben, Ziffern, `_` und `-`, 2–41 Zeichen. Reserviert sind `core`, `system`, `admin`, `staff`, `api`. |
|
||
| `name`, `version` | Pflicht. Version im Format `1.0.0`. |
|
||
| `requires` | Optional. Mindestversion von DeskHub; ist die installierte kleiner, wird die Installation abgelehnt. |
|
||
| `entry` | Optional. Startdatei, Standard `plugin.php`. |
|
||
| `permissions` | Optional. Liste der Erweiterungspunkte, die das Plugin nutzen will (siehe unten). Unbekannte Werte lehnt DeskHub ab. |
|
||
|
||
### Berechtigungen
|
||
|
||
Ein Plugin muss die Erweiterungspunkte, die es registriert, in `permissions` angeben. Der Admin bestätigt die Liste bei der Aktivierung. Versucht ein Plugin einen nicht deklarierten Erweiterungspunkt zu registrieren, wird die Registrierung abgelehnt und im Plugin vermerkt (das Plugin läuft sonst weiter).
|
||
|
||
| Berechtigung | erlaubt |
|
||
|---|---|
|
||
| `hooks.tickets` | `plugin_add_hook` für `ticket.*`-Ereignisse und Filter mit `ticket.`-Präfix |
|
||
| `hooks.cron` | `plugin_add_hook('cron.run', …)` |
|
||
| `ui.menu` | `plugin_register_menu` (Menüpunkt und Seite) |
|
||
| `ui.sidebar` | `plugin_add_filter('ticket.view.sidebar', …)` |
|
||
| `api.endpoints` | `plugin_register_api` |
|
||
| `db.migrations` | Dateien in `migrations/` (werden beim Aktivieren eingespielt) |
|
||
|
||
Nicht geschützt sind `plugin_setting`, `plugin.uninstall.<slug>` und eigene Hooks zwischen Plugins. Wichtig: Das ist eine Prüfung der **Erweiterungspunkte**, keine Sandbox. Beliebiger PHP-Code im Plugin kann weiterhin auf Datenbank und Dateien zugreifen.
|
||
|
||
### Erweiterungen registrieren
|
||
|
||
Die Startdatei wird bei jedem Seitenaufruf geladen, solange das Plugin aktiv ist. Sie sollte nur registrieren und schnell sein. Die Funktionen DeskHubs (`get_db()`, `e()`, `send_mail()`, `has_permission()` usw.) stehen zur Verfügung.
|
||
|
||
| Funktion | Zweck |
|
||
|---|---|
|
||
| `plugin_add_hook($hook, $fn, $priority = 10)` | Auf ein Ereignis reagieren. Rückgabewert wird ignoriert. |
|
||
| `plugin_add_filter($hook, $fn, $priority = 10)` | Einen Wert ergänzen oder verändern. Der Rückgabewert ersetzt den Wert, die Funktion erhält `($wert, $kontext)`. |
|
||
| `plugin_register_menu($label, $seite, $recht = null)` | Menüpunkt, der `pages/<seite>.php` öffnet. Optional ein Recht (z. B. `'view_reports'`), das der Mitarbeiter haben muss. |
|
||
| `plugin_register_api($name, $fn, $recht = null)` | Eigener Endpunkt `GET/POST /api/staff/v1/plugin.php?p=<slug>&endpoint=<name>` mit Bearer-Token der Mitarbeiter-API. `$fn($staff, $request)` gibt ein Array zurück, das als JSON ausgeliefert wird. |
|
||
| `plugin_setting($slug, $key, $default)` / `plugin_set_setting($slug, $key, $wert)` | Eigene Einstellungen. Sie werden beim Entfernen des Plugins mitgelöscht. |
|
||
| `plugin_hook($hook, $daten)` | Eigenes Ereignis auslösen, auf das andere Plugins reagieren können. |
|
||
|
||
### Ereignisse (Hooks)
|
||
|
||
| Hook | Wann | Daten |
|
||
|---|---|---|
|
||
| `ticket.created` | Ticket wurde erstellt (Portal, E-Mail, Chat, Mitarbeiter, API) | `event`, `ticketId` |
|
||
| `ticket.replied` | Antwort oder Notiz wurde geschrieben | `event`, `ticketId`, `author` (`staff`/`customer`), `internal` |
|
||
| `ticket.status_changed` | Status hat sich geändert | `event`, `ticketId`, `previousStatus` |
|
||
| `ticket.assigned` | Zuweisung hat sich geändert | `event`, `ticketId` |
|
||
| `cron.run` | Etwa alle 5 Minuten durch die Automatisierung | `time` |
|
||
| `plugin.uninstall.<slug>` | Beim Entfernen mit „Daten löschen“ | `slug` |
|
||
|
||
Filter: `ticket.view.sidebar` ergänzt einen HTML-Block in der Seitenleiste der Ticketansicht. Kontext: `ticketId`, `ticket`, `staff`. Das Plugin liefert fertiges HTML und muss alle Ausgaben selbst mit `e()` maskieren.
|
||
|
||
Ereignisse enthalten nur die ID. Weitere Daten holt das Plugin selbst aus der Datenbank.
|
||
|
||
### Seiten
|
||
|
||
Eine registrierte Seite `pages/log.php` erscheint im normalen Mitarbeiter-Layout (Kopf, Menü, Fuß). Verfügbar sind `$staff` (angemeldeter Mitarbeiter) und `$pdo`. Es wird nur ausgeliefert, was das Plugin selbst per `plugin_register_menu` registriert hat. Formulare müssen `csrf_field()` enthalten und beim Absenden `verify_csrf()` aufrufen. Weiterleitungen nach dem Speichern sind nicht möglich (die Seite wird innerhalb des Layouts eingebunden), zeigt das Ergebnis also direkt auf derselben Seite an.
|
||
|
||
### Datenbank
|
||
|
||
Dateien in `migrations/` werden beim Aktivieren in Dateinamen-Reihenfolge einmalig ausgeführt und protokolliert. Statements trennt ein `;`. Unterschiede zwischen den Datenbanken lösen Dialekt-Dateien:
|
||
|
||
- `001_tabelle.sqlite.sql` läuft nur auf SQLite
|
||
- `001_tabelle.mysql.sql` läuft nur auf MySQL
|
||
- `001_tabelle.sql` läuft auf beiden
|
||
|
||
Präfixt eure Tabellen mit dem Plugin-Namen (z. B. `plugin_meinplugin_log`). Zum Aufräumen beim Entfernen reagiert ihr auf `plugin.uninstall.<slug>` und löscht dort eure Tabellen.
|
||
|
||
### Fehlerverhalten
|
||
|
||
Jeder Aufruf von Plugin-Code ist abgesichert: Ein geworfener Fehler wird protokolliert und dem Plugin zugeordnet, die aufrufende Seite läuft normal weiter. Nach 3 Fehlern seit der letzten Aktivierung wird das Plugin automatisch deaktiviert. Schwere Fehler (Fatal Error, Syntaxfehler) lassen sich nicht abfangen; DeskHub deaktiviert das gerade ausgeführte Plugin beim nächsten Seitenaufruf. Plugins sollten Fehler daher möglichst selbst behandeln und nur Unerwartetes werfen.
|
||
|
||
### Mini-Beispiel
|
||
|
||
`plugin.json`:
|
||
|
||
```json
|
||
{ "slug": "ticket-zaehler", "name": "Ticket-Zähler", "version": "1.0.0" }
|
||
```
|
||
|
||
`plugin.php`:
|
||
|
||
```php
|
||
<?php
|
||
// Zählt neue Tickets und zeigt die Zahl in der Ticketansicht und auf einer eigenen Seite.
|
||
plugin_add_hook('ticket.created', function (array $e) {
|
||
$n = (int) plugin_setting('ticket-zaehler', 'anzahl', '0');
|
||
plugin_set_setting('ticket-zaehler', 'anzahl', (string) ($n + 1));
|
||
});
|
||
|
||
plugin_add_filter('ticket.view.sidebar', function (string $html, array $ctx) {
|
||
$n = (int) plugin_setting('ticket-zaehler', 'anzahl', '0');
|
||
return $html . '<div class="card" style="margin-top:16px;padding:14px 16px">Seit Plugin-Start: '
|
||
. $n . ' neue Tickets</div>';
|
||
});
|
||
|
||
plugin_register_menu('Ticket-Zähler', 'uebersicht');
|
||
```
|
||
|
||
`pages/uebersicht.php`:
|
||
|
||
```php
|
||
<h1>Ticket-Zähler</h1>
|
||
<p><?= (int) plugin_setting('ticket-zaehler', 'anzahl', '0') ?> neue Tickets seit der Aktivierung.</p>
|
||
```
|
||
|
||
### Paketieren und testen
|
||
|
||
1. Den Plugin-Ordner als ZIP packen (die Dateien direkt im Wurzelverzeichnis oder in genau einem Unterordner).
|
||
2. Als Admin unter Plugins hochladen, aktivieren, ausprobieren.
|
||
3. Tritt ein Fehler auf, steht er in der Plugin-Liste. Notausschalter: leere Datei `plugins/.disabled`.
|
||
|
||
### Signieren und veröffentlichen
|
||
|
||
Wer Plugins oder Themes verteilt, signiert sie mit einem eigenen Schlüsselpaar (RSA, SHA-256). Das Werkzeug dafür liegt im Entwickler-Paket unter `tools/plugin-sign.php`:
|
||
|
||
```bash
|
||
php tools/plugin-sign.php keygen ./schluessel # einmalig: privater + öffentlicher Schlüssel
|
||
php tools/plugin-sign.php sign mein-plugin.zip ./schluessel/herausgeber-privat.pem
|
||
php tools/plugin-sign.php sign-theme mein-theme.zip ./schluessel/herausgeber-privat.pem nordlicht 1.0.0
|
||
```
|
||
|
||
Die Ausgabe nennt SHA-256 und Signatur. Signiert wird die Nachricht `deskhub-plugin`, Name (bei Themes `theme-<slug>`), Version und SHA-256 des ZIP, getrennt durch Zeilenumbrüche, mit RSA-SHA256, Ergebnis in Base64. So lässt sich eine Signatur nicht auf eine andere Version oder ein anderes Paket übertragen. Den **privaten Schlüssel nie weitergeben**, den öffentlichen geben Admins in DeskHub unter Plugins ein.
|
||
|
||
Einfacher ist die [Plugin- und Theme-Webseite](#plugin--und-theme-webseite): Sie prüft hochgeladene Pakete, signiert automatisch und stellt den Katalog bereit. Das Katalogformat für DeskHub (zum Nachbauen einer eigenen Quelle):
|
||
|
||
```json
|
||
{ "plugins": [ {
|
||
"slug": "tagesbericht", "name": "Tagesbericht per E-Mail", "version": "1.0.0",
|
||
"description": "…", "author": "…", "requires": "1.0.0", "permissions": ["hooks.cron", "ui.menu"],
|
||
"downloadUrl": "https://plugins.example.de/download.php?type=plugin&slug=tagesbericht&version=1.0.0",
|
||
"sha256": "<SHA-256 der ZIP, 64 Hexzeichen>", "signature": "<Base64-Signatur, optional>"
|
||
} ] }
|
||
```
|
||
|
||
Für Themes heißt die Liste `themes` (ohne `requires` und `permissions`). Adressen müssen `https://` verwenden und dürfen nicht auf interne Ziele zeigen.
|
||
|
||
---
|
||
|
||
## Plugin- und Theme-Webseite
|
||
|
||
Im Ordner `plugin-webseite/` liegt eine fertige, eigenständige Webseite, von der DeskHub-Installationen Plugins und Themes laden. Sie läuft auf eigenem Webspace (PHP 8.1, SQLite) und braucht kein DeskHub. Sie bietet den Katalog für DeskHub und eine geschützte Verwaltung zum Veröffentlichen mit allen Versionen, Prüfsummen und Signaturstatus. Es gibt keine öffentliche Übersichtsseite. Hochgeladene Pakete werden geprüft (Dateitypen, Pfade, `plugin.json`, Berechtigungen) und automatisch mit eurem Schlüssel signiert. Einrichtung in zwei Minuten per `php einrichten.php`, Details in `plugin-webseite/README.md`.
|
||
|
||
**Geprüfte Plugins für eure Kunden:** `php einrichten.php` (und in der Verwaltung der Bereich „Einstellungen für DeskHub“) gibt die drei Werte aus, die in `includes/catalog_defaults.php` von DeskHub eingetragen werden: Katalog-Adresse für Plugins, Katalog-Adresse für Themes und euren öffentlichen Schlüssel. Tragt sie vor dem Bauen eines Releases ein. Alle Installationen mit diesem Release laden dann nur Plugins, die ihr auf der Webseite veröffentlicht, also geprüft und signiert habt. Die Datei wird bei System-Updates durch die des Releases ersetzt, Kunden können die Vorgabe also nicht versehentlich verlieren. Dieser Ordner wird bei System-Updates nicht auf Kunden-Installationen kopiert.
|
||
|
||
**Zugangsschutz des Katalogs:** `docker-build.sh` / `docker-build.ps1` erzeugen beim ersten Bauen einen Zugangsschlüssel (`schluessel/katalog-zugangsschluessel.txt`) und geben ihn am Ende aus. Tragt ihn in `includes/catalog_defaults.php` als `access_key` ein. Ohne diesen Schlüssel liefern Katalog, Downloads, Vorschaubilder und `publisher-key.php` nur `401`. `health.php` bleibt offen (Docker-Healthcheck). Nach dem Bauen: Image auf dem Server austauschen und ein DeskHub-Release mit dem eingetragenen Schlüssel veröffentlichen.
|
||
|
||
---
|
||
|
||
## API und Webhooks (für Entwickler)
|
||
|
||
Dieser Abschnitt beschreibt die Schnittstellen für Fremdsysteme. Einrichten (Schlüssel erzeugen, Webhooks eintragen) tun Admins im Adminportal, siehe [Integrationen](#integrationen-api-schlüssel-und-webhooks). Alle Beispiele nutzen `https://support.example.de` als Adresse eurer Installation.
|
||
|
||
### Ticket-API
|
||
|
||
Basis-Adresse: `https://support.example.de/api/public/v1/tickets.php`
|
||
|
||
**Authentifizierung:** Jeder Aufruf braucht einen API-Schlüssel (Format `dh_` plus 48 Hexzeichen), entweder im Header `X-API-Key: dh_…` oder als `Authorization: Bearer dh_…`. Der Schlüssel wird im Adminportal unter **API-Schlüssel** erzeugt und nur einmal angezeigt. Er hat die Rechte „Tickets anlegen“ und/oder „Tickets lesen“ und kann auf IP-Adressen beschränkt sein. Aufrufe von nicht erlaubten Adressen werden wie ein falscher Schlüssel behandelt (401). Verwendet die API nur über HTTPS und nur in serverseitigem Code, nie im Browser eurer Besucher.
|
||
|
||
Anfragen und Antworten sind JSON (UTF-8). Fehler haben immer diese Form:
|
||
|
||
```json
|
||
{ "error": { "code": "INVALID_EMAIL", "message": "Bitte eine gültige E-Mail-Adresse angeben." } }
|
||
```
|
||
|
||
#### Ticket anlegen
|
||
|
||
`POST /api/public/v1/tickets.php`, Recht „Tickets anlegen“, Header `Content-Type: application/json`.
|
||
|
||
| Feld | Pflicht | Beschreibung |
|
||
|---|---|---|
|
||
| `name` | ja | Name des Anfragenden, höchstens 120 Zeichen |
|
||
| `email` | ja | Gültige E-Mail-Adresse des Anfragenden (hierhin gehen die Antworten) |
|
||
| `subject` | ja | Betreff, höchstens 255 Zeichen |
|
||
| `message` | ja | Nachricht, höchstens 50.000 Zeichen |
|
||
| `helpTopicId` | nein | ID eines aktiven Hilfethemas; legt Abteilung und Priorität fest, sofern nicht selbst angegeben |
|
||
| `departmentId` | nein | ID der Abteilung |
|
||
| `priorityId` | nein | ID der Priorität |
|
||
|
||
Die IDs seht ihr im Adminportal in der Adresszeile beim Bearbeiten (`…?edit=<ID>`). Ohne Angaben gelten die Standardabteilung und die erste Priorität der Prioritätenliste. Ticket-Regeln, SLA-Pläne und Benachrichtigungen laufen wie bei jedem anderen Ticket. Der Kunde bekommt die übliche Bestätigungs-E-Mail. Das Ticket hat die Quelle `api`.
|
||
|
||
```bash
|
||
curl -X POST https://support.example.de/api/public/v1/tickets.php \
|
||
-H "X-API-Key: dh_0123456789abcdef0123456789abcdef0123456789abcdef" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"name":"Erika Muster","email":"erika@example.de","subject":"Rechnung fehlt","message":"Bitte Rechnung 4711 erneut senden.","helpTopicId":3}'
|
||
```
|
||
|
||
Antwort `201 Created`:
|
||
|
||
```json
|
||
{ "number": "T-1042", "status": "open" }
|
||
```
|
||
|
||
#### Ticketstatus abfragen
|
||
|
||
`GET /api/public/v1/tickets.php?number=T-1042&email=erika@example.de`, Recht „Tickets lesen“.
|
||
|
||
Beide Parameter sind Pflicht. Die E-Mail-Adresse muss zum Ticket passen, sonst antwortet die API mit 404 (so erfährt niemand etwas über fremde Tickets). Interne Notizen werden nie ausgegeben.
|
||
|
||
```json
|
||
{
|
||
"ticket": {
|
||
"number": "T-1042",
|
||
"subject": "Rechnung fehlt",
|
||
"status": "answered",
|
||
"createdAt": "2026-10-15 09:12:03",
|
||
"updatedAt": "2026-10-15 10:40:51",
|
||
"messages": [
|
||
{ "author": "customer", "message": "Bitte Rechnung 4711 erneut senden.", "createdAt": "2026-10-15 09:12:03" },
|
||
{ "author": "staff", "message": "Die Rechnung ist unterwegs.", "createdAt": "2026-10-15 10:40:51" }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
`status` ist einer von `open`, `pending`, `answered`, `on_hold`, `resolved`, `closed`. Zeiten sind Serverzeit im Format `JJJJ-MM-TT hh:mm:ss`. `author` ist `customer` oder `staff`.
|
||
|
||
#### Fehler und Grenzen
|
||
|
||
| HTTP | `code` | Bedeutung |
|
||
|---|---|---|
|
||
| 400 | `INVALID_JSON` | Der Anfragekörper ist kein gültiges JSON |
|
||
| 401 | `UNAUTHENTICATED` | Schlüssel fehlt, ist falsch, deaktiviert oder von dieser IP nicht erlaubt |
|
||
| 403 | `FORBIDDEN` | Dem Schlüssel fehlt das Recht für diese Aktion |
|
||
| 403 | `BANNED`, `REJECTED` | Absender ist gesperrt oder eine Ticket-Regel hat das Ticket abgelehnt |
|
||
| 404 | `NOT_FOUND` | Ticket nicht gefunden (oder falsche E-Mail-Adresse) |
|
||
| 405 | `METHOD_NOT_ALLOWED` | Erlaubt sind nur `GET` und `POST` |
|
||
| 413 | `TOO_LARGE` | Anfrage größer als 200 KB |
|
||
| 422 | `INVALID_NAME`, `INVALID_EMAIL`, `INVALID_SUBJECT`, `INVALID_MESSAGE`, `INVALID_TOPIC`, `INVALID_PRIORITY`, `MISSING_PARAMS` | Eingaben ungültig oder unvollständig |
|
||
| 429 | `RATE_LIMITED` | Mehr als 60 über die API angelegte Tickets pro Minute (gilt gemeinsam für alle Schlüssel) |
|
||
| 503 | `NO_DEPARTMENT` | Es ist keine aktive Abteilung eingerichtet |
|
||
|
||
Beim Anlegen gibt es keine Wiederholungssicherung: Sendet ihr dieselbe Anfrage zweimal, entstehen zwei Tickets. Wiederholt nach einem Netzwerkfehler also nur, wenn ihr prüfen könnt, ob das erste Ticket angekommen ist.
|
||
|
||
### Webhooks
|
||
|
||
Mit Webhooks meldet DeskHub Ereignisse sofort an eine Adresse eures Systems. Einrichten: Adminportal → **Webhooks** → Name, URL und die gewünschten Ereignisse wählen. Das **Secret** zum Prüfen der Signatur legt ihr selbst fest oder lasst es von DeskHub erzeugen. Es wird nur verschlüsselt gespeichert.
|
||
|
||
**Ereignisse:**
|
||
|
||
| Ereignis | Wann | Zusätzliche Felder |
|
||
|---|---|---|
|
||
| `ticket.created` | Neues Ticket (Portal, E-Mail, Chat, Mitarbeiter oder API) | – |
|
||
| `ticket.replied` | Antwort oder interne Notiz | `author` (`staff` oder `customer`); bei Mitarbeitern zusätzlich `internal` (`true` bei interner Notiz) |
|
||
| `ticket.status_changed` | Status hat sich geändert | `previousStatus` |
|
||
| `ticket.assigned` | Zuweisung hat sich geändert | – |
|
||
|
||
**Anfrage:** DeskHub sendet `POST` mit JSON (UTF-8) an eure URL, mit diesen Headern:
|
||
|
||
| Header | Inhalt |
|
||
|---|---|
|
||
| `Content-Type` | `application/json` |
|
||
| `User-Agent` | `DeskHub-Webhook/1` |
|
||
| `X-DeskHub-Event` | Ereignisname, z. B. `ticket.created` |
|
||
| `X-DeskHub-Signature` | `sha256=` plus HMAC-SHA256 des **rohen Anfragekörpers** mit eurem Secret als Schlüssel (Hex) |
|
||
|
||
**Beispiel für den Anfragekörper** (`ticket.status_changed`):
|
||
|
||
```json
|
||
{
|
||
"event": "ticket.status_changed",
|
||
"occurredAt": "2026-10-15T08:41:12+00:00",
|
||
"ticket": {
|
||
"number": "T-1042",
|
||
"subject": "Rechnung fehlt",
|
||
"status": "resolved",
|
||
"source": "web",
|
||
"priority": "Normal",
|
||
"department": "Buchhaltung",
|
||
"assignedTo": "Max Muster",
|
||
"requesterName": "Erika Muster",
|
||
"requesterEmail": "erika@example.de",
|
||
"createdAt": "2026-10-15 09:12:03",
|
||
"updatedAt": "2026-10-15 10:40:51"
|
||
},
|
||
"previousStatus": "answered"
|
||
}
|
||
```
|
||
|
||
`occurredAt` ist UTC im ISO-8601-Format, `assignedTo` ist `null`, wenn niemand zugewiesen ist. Es werden nur diese Angaben gesendet, nicht der Nachrichtentext.
|
||
|
||
**Signatur prüfen** (immer mit dem rohen Körper, vor dem JSON-Parsen, und mit einem zeitkonstanten Vergleich):
|
||
|
||
```php
|
||
$body = file_get_contents('php://input');
|
||
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
|
||
if (!hash_equals($expected, $_SERVER['HTTP_X_DESKHUB_SIGNATURE'] ?? '')) {
|
||
http_response_code(401);
|
||
exit;
|
||
}
|
||
```
|
||
|
||
```python
|
||
import hmac, hashlib
|
||
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
|
||
ok = hmac.compare_digest(expected, request.headers.get("X-DeskHub-Signature", ""))
|
||
```
|
||
|
||
**Zustellung:**
|
||
|
||
- Eure Adresse muss binnen 5 Sekunden mit einem Status `2xx` antworten. Alles andere (anderer Status, Timeout, Verbindungsfehler) zählt als Fehler. Weiterleitungen werden nicht verfolgt.
|
||
- Es gibt **keine automatische Wiederholung**. Antwortet euer System gerade nicht, geht dieses Ereignis verloren. Baut bei kritischen Abläufen einen Abgleich ein, etwa über die Ticket-API oder den Status in der Webhook-Liste.
|
||
- Die Zustellung läuft nach der Antwort an den Benutzer und bremst DeskHub nicht. Die Reihenfolge mehrerer Ereignisse ist nicht garantiert; `occurredAt` und `updatedAt` helfen beim Einordnen.
|
||
- Nach **10 Fehlern in Folge** wird der Webhook automatisch deaktiviert. Im Adminportal stehen letzter Status, Fehlertext und Zeitpunkt. Ein erfolgreicher Aufruf setzt den Fehlerzähler zurück. Nach dem Beheben aktiviert ihr den Webhook wieder.
|
||
- Erlaubt sind nur `http://` und `https://`, und die Adresse darf nicht auf interne Ziele zeigen (localhost, private Netze). Nutzt `https://`.
|
||
- Das Webhook-Secret ist von den API-Schlüsseln unabhängig.
|
||
|
||
---
|
||
|
||
## Sicherheit und Datenschutz
|
||
|
||
- **Sperrliste:** Einzelne E-Mail-Adressen oder ganze Domains blockieren. Mails von dort erzeugen kein Ticket mehr.
|
||
- **Automatische Anonymisierung:** Unter Einstellungen → Datenschutz legt ihr fest, nach wie vielen Monaten persönliche Daten (Name, E-Mail) in geschlossenen Tickets anonymisiert werden. Der Ticketinhalt bleibt für Statistiken erhalten.
|
||
- **Automatische Abmeldung:** Die Zeit bis zur Abmeldung bei Inaktivität ist einstellbar.
|
||
- **Passwörter und Zugangsdaten:** SMTP-/IMAP-Passwörter und Tokens werden verschlüsselt gespeichert. API-Schlüssel werden nur als Prüfsumme abgelegt und sind nach dem Erstellen nicht mehr einsehbar.
|
||
- **Updates und Plugins:** Updates werden über eine geprüfte, verschlüsselte Verbindung geladen. Plugins sind Programmcode mit vollen Rechten, installiert deshalb nur vertrauenswürdige.
|
||
- **Sicherheitsprüfung:** Adminportal → **Sicherheitsprüfung** prüft die Einrichtung dieser Installation und ruft interne Adressen selbst ab, um zu sehen, ob Konfiguration, Datenbank, Backups oder Programmcode von außen erreichbar wären. Nach der Installation und nach jeder Änderung am Webserver einmal ausführen.
|
||
- **Schutz vor HTML-Angriffen:** Texte in Antworten und HTML-E-Mails werden vor der Anzeige durch einen strengen Filter geschickt. Skripte, Formulare, eingebettete Inhalte und riskante Formatierungen werden entfernt; auch kaputtes oder absichtlich verstümmeltes HTML wird als Text maskiert.
|
||
- **Abteilungsgrenzen:** Mitarbeiter sehen Tickets, Anhänge, Ausdrucke und Kundenprofile nur für ihre Abteilungen, auch über direkte Links.
|
||
|
||
### Betrieb absichern (Checkliste)
|
||
|
||
1. **HTTPS** einrichten und die Website-URL (Einstellungen) auf `https://` stellen.
|
||
2. **Interne Ordner sperren.** Die mitgelieferte `.htaccess` erledigt das auf Apache. Auf **nginx** und anderen Servern gibt es keine `.htaccess`: Tragt diese Regeln in den `server`-Block ein (Pfad zu PHP-FPM anpassen):
|
||
|
||
```nginx
|
||
# Interne Ordner und Dateien nie ausliefern
|
||
location ~ ^/(config|database|includes|cron|backups|tests|tools|docs|desktop|mobile|theme-packages|vorschaubilder|plugin-webseite|app_downloads|\.git|\.gitea|\.github)(/|$) { return 404; }
|
||
location ~ ^/plugins/.+\.(php|sql|json|md|txt|log)$ { return 404; }
|
||
location ~ ^/(version\.php|offen\.txt|install\.sh|install_windows\.bat)$ { return 404; }
|
||
location ~* \.(sqlite3?|db|sql|log|bak|old|md|sh|bat|ps1|pem|key|env|ini|lock)$ { return 404; }
|
||
# Hochgeladene Dateien dürfen nie als Programm laufen
|
||
location ~* ^/uploads/.*\.(php\d?|phtml|phar|html?|xhtml|svgz?|xml|js)$ { return 403; }
|
||
# Nach der Installation: Installationsassistent sperren
|
||
location ^~ /install/ { return 404; }
|
||
```
|
||
|
||
Diese Regeln müssen **vor** dem `location ~ \.php$`-Block stehen, weil nginx den ersten passenden Regex-Block nimmt. Danach in der **Sicherheitsprüfung** kontrollieren, dass alles gesperrt ist.
|
||
3. **Reverse-Proxy (nginx, Traefik, Caddy, Cloudflare …):** Tragt in `config/config.php` unter `site` die Adresse oder den Bereich des Proxys ein, damit DeskHub die echte Besucher-IP und HTTPS erkennt. Der Proxy muss `X-Forwarded-For` und `X-Forwarded-Proto` setzen. Ohne diese Angabe sehen alle Besucher aus Sicht von DeskHub wie eine einzige IP aus, und die Anmelde-Sperre trifft alle gleichzeitig:
|
||
|
||
```php
|
||
'site' => [
|
||
// ...
|
||
'trusted_proxies' => ['127.0.0.1', '172.16.0.0/12'],
|
||
],
|
||
```
|
||
|
||
Tragt nur Proxys ein, die ihr selbst betreibt. Wer in dieser Liste steht, kann die IP-Adresse der Besucher festlegen.
|
||
4. **`app_key`** in `config/config.php` setzen (der Installer tut das) und nie ändern. Die Datei nach der Installation auf nur lesbar stellen (`chmod 640`).
|
||
5. **Ordner `install/` löschen**, **PHP-Fehleranzeige abschalten** (`display_errors = Off`), **Zwei-Faktor-Anmeldung** für alle Administratoren aktivieren (Profil → Sicherheit).
|
||
6. **Backups** einrichten und prüfen (siehe [Backup](#backup)), den Ordner `backups/` nie öffentlich machen.
|
||
7. **Eigenes Repository:** `config/config.php`, die Datenbank, Backups und Uploads gehören nie in ein Git-Repository. Die mitgelieferte `.gitignore` schließt sie aus.
|
||
8. Updates installieren: Sicherheitsverbesserungen kommen mit neuen Versionen.
|
||
|
||
---
|
||
|
||
## Backup
|
||
|
||
Adminportal → **Backup**:
|
||
|
||
- **Manuell:** Jederzeit ein Backup erstellen und herunterladen.
|
||
- **Automatisch:** Zeitplan (täglich, wöchentlich, monatlich), optional mit Upload per FTP auf einen zweiten Server und automatischer Rotation (alte Backups werden nach einer einstellbaren Anzahl gelöscht).
|
||
|
||
Außerdem erstellt DeskHub automatisch ein Backup vor jedem System-Update, jedem Datenbank-Update und jeder Plugin-Aktivierung.
|
||
|
||
**Prüfen und Wiederherstellen:**
|
||
|
||
- Jedes Backup enthält einen konsistenten Datenbank-Schnappschuss (SQLite) bzw. einen SQL-Dump (MySQL) und eine Inhaltsliste mit Prüfsummen.
|
||
- **✔️ Prüfen** kontrolliert ein Backup, ohne etwas zu verändern. Nach jedem manuellen und automatischen Backup passiert das von selbst; schlägt es fehl, erscheint im Adminportal eine Störungsmeldung („Backup defekt“).
|
||
- **♻️ Wiederherstellen** spielt Datenbank und (wählbar) Uploads, Plugins und App-Downloads zurück. Davor wird automatisch ein Sicherheits-Backup des aktuellen Stands erstellt. Zur Bestätigung gebt ihr `WIEDERHERSTELLEN` ein. Programmcode und `config.php` werden nie überschrieben. Ein Backup einer anderen Datenbankart (SQLite ↔ MySQL) wird abgelehnt.
|
||
|
||
---
|
||
|
||
## Automatische Tests (CI)
|
||
|
||
`php tests/run_all.php` führt alle PHP-Tests nacheinander aus (Exit-Code 1 bei Fehlern); mit Argument nur passende Tests, z. B. `php tests/run_all.php plugin`. Die Workflow-Datei `.gitea/workflows/tests.yml` startet bei jedem Push, jeder Pull-Request und nachts um 03:17 UTC: PHP 8.2 (Syntax und alle Tests), PHP 8.4 (nur Warnung), Windows-App-Oberflächentests (`npm test` unter xvfb), Android-Tests (`./gradlew testDebugUnitTest`) und der Bau des Docker-Images der Plugin-Webseite samt Zugangsschutz-Prüfung. Für GitHub die Datei nach `.github/workflows/` kopieren. Der Runner braucht für den Docker-Job Docker, für den Android-Job das Android-SDK.
|
||
|
||
---
|
||
|
||
## Hilfe, etwas funktioniert nicht
|
||
|
||
- **Admin-Protokoll** (Adminportal → Admin-Protokoll): Änderungen und fehlgeschlagene automatische E-Mails mit genauer Fehlermeldung.
|
||
- **E-Mail-Abruf:** Adminportal → Postfächer (Abruf) → beim betroffenen Postfach „Testen“. Das zeigt die Fehlermeldung des Mail-Servers.
|
||
- **E-Mail-Versand:** Einstellungen → E-Mail → „Test-Mail senden“, oder bei E-Mail-Adressen die einzelne Adresse testen.
|
||
- **Rotes oder gelbes Banner oben:** Das ist eine Störungsmeldung der Überwachung, siehe [Überwachung und Störungsmeldungen](#überwachung-und-störungsmeldungen).
|
||
- **„Datenbank veraltet“:** Unter System-Update auf „Datenbank aktualisieren“ klicken.
|
||
- **Ein Plugin macht Probleme:** Unter Plugins deaktivieren. Lässt sich die Seite nicht mehr öffnen, hilft die Datei `plugins/.disabled`.
|
||
- **Die App zeigt „Keine Verbindung“:** Erreichbarkeit der Seite im Browser prüfen. Sobald der Server wieder antwortet, verschwindet das Banner von selbst.
|