feat: Initial commit of KeyHelp Manager module
This commit is contained in:
70
.gitignore
vendored
Normal file
70
.gitignore
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# IDE and Editor Files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Composer
|
||||
/vendor/
|
||||
composer.lock
|
||||
composer.phar
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
/logs/
|
||||
|
||||
# Cache
|
||||
/cache/
|
||||
*.cache
|
||||
|
||||
# Temporary Files
|
||||
/tmp/
|
||||
/temp/
|
||||
*.tmp
|
||||
|
||||
# Environment Files
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# OS Files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# PHPUnit
|
||||
.phpunit.result.cache
|
||||
/phpunit.xml
|
||||
|
||||
# Build Files
|
||||
/build/
|
||||
/dist/
|
||||
|
||||
# Node Modules (falls Frontend-Build)
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# WHMCS Specific
|
||||
configuration.php
|
||||
attachments/
|
||||
downloads/
|
||||
uploads/
|
||||
|
||||
# Backup Files
|
||||
*.bak
|
||||
*.backup
|
||||
*~
|
||||
|
||||
# Security
|
||||
*.key
|
||||
*.pem
|
||||
*.crt
|
||||
api_keys.txt
|
||||
216
CHANGELOG.md
Normal file
216
CHANGELOG.md
Normal file
@@ -0,0 +1,216 @@
|
||||
# Changelog
|
||||
|
||||
Alle wichtigen Änderungen an diesem Projekt werden in dieser Datei dokumentiert.
|
||||
|
||||
Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/),
|
||||
und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Geplant
|
||||
- Multi-Language Support (Deutsch/Englisch)
|
||||
- Erweiterte Statistiken im Client Area
|
||||
- Automatische Backup-Verwaltung
|
||||
- SSL-Zertifikat-Management über Let's Encrypt
|
||||
- E-Mail-Account-Verwaltung im Client Area
|
||||
- Datenbank-Verwaltung im Client Area
|
||||
- FTP-Account-Management
|
||||
- Subdomain-Verwaltung
|
||||
- Ressourcen-Upgrade/Downgrade-Funktionen
|
||||
- Webhook-Support für Events
|
||||
|
||||
## [1.0.0] - 2024-01-15
|
||||
|
||||
### Entwickelt von
|
||||
- **Entwickler:** Kevin Feiler
|
||||
- **Firma:** AVVGO
|
||||
- **Website:** https://avvgo.de
|
||||
|
||||
### Hinzugefügt
|
||||
- Initiales Release des KeyHelp Manager WHMCS Provisioning Moduls
|
||||
- **Account-Verwaltung:**
|
||||
- Automatische Account-Erstellung nach Zahlungseingang
|
||||
- Account-Sperrung (Suspend) bei Zahlungsverzug
|
||||
- Account-Entsperrung (Unsuspend)
|
||||
- Account-Löschung (Terminate) mit allen Daten
|
||||
- Passwort-Änderungsfunktion
|
||||
|
||||
- **API-Integration:**
|
||||
- KeyHelp API v2 Unterstützung
|
||||
- Guzzle HTTP Client für zuverlässige API-Kommunikation
|
||||
- SSL/TLS-Verschlüsselung für API-Verbindungen
|
||||
- Konfigurierbare SSL-Zertifikat-Verifizierung
|
||||
- Umfassendes Error-Handling und Retry-Logik
|
||||
|
||||
- **Client Area Features:**
|
||||
- Übersichtliche Darstellung der Login-Informationen
|
||||
- KeyHelp Login-URL mit direktem Zugang
|
||||
- Username und Passwort mit Copy-to-Clipboard-Funktion
|
||||
- Passwort anzeigen/verbergen Toggle
|
||||
- Live-Statistiken vom KeyHelp-Server:
|
||||
- Speicherplatz-Nutzung mit Fortschrittsbalken
|
||||
- Traffic/Bandbreiten-Nutzung mit Fortschrittsbalken
|
||||
- Anzahl der Domains
|
||||
- Anzahl der Datenbanken
|
||||
- Anzahl der E-Mail-Konten
|
||||
- Responsive Design für alle Geräte
|
||||
- Bootstrap-kompatibles Layout
|
||||
|
||||
- **Admin-Features:**
|
||||
- Single Sign-On (SSO) für Admins
|
||||
- Ein-Klick-Login direkt in den Kunden-Account
|
||||
- Detailliertes Module-Logging aller API-Calls
|
||||
- Connection-Test-Funktion für Server-Konfiguration
|
||||
- Automatische Maskierung sensibler Daten in Logs
|
||||
|
||||
- **Automatisierung:**
|
||||
- Automatische Benutzername-Generierung aus Domain
|
||||
- Sichere Passwort-Generierung (16 Zeichen, kryptografisch sicher)
|
||||
- Automatische Speicherung von Account-Details in WHMCS
|
||||
- Custom Field Management für KeyHelp User-ID
|
||||
- Rollback-Mechanismen bei fehlgeschlagener Erstellung
|
||||
|
||||
- **Sicherheit:**
|
||||
- API-Key-Verschlüsselung in WHMCS-Datenbank
|
||||
- SSL/TLS-Unterstützung für alle API-Verbindungen
|
||||
- Validierung und Sanitization aller Eingaben
|
||||
- Schutz vor SQL-Injection durch Capsule ORM
|
||||
- Sichere Session-Token-Generierung für SSO
|
||||
- Automatische Maskierung von Credentials in Logs
|
||||
|
||||
- **Dokumentation:**
|
||||
- Ausführliche README.md mit Feature-Übersicht
|
||||
- Detaillierte INSTALLATION.md mit Schritt-für-Schritt-Anleitung
|
||||
- Umfangreiche Code-Kommentare (Deutsch)
|
||||
- API-Endpunkt-Dokumentation
|
||||
- Troubleshooting-Guide
|
||||
- Best Practices für Sicherheit
|
||||
|
||||
- **Entwickler-Tools:**
|
||||
- Composer.json für Dependency-Management
|
||||
- .gitignore für sauberes Repository
|
||||
- PSR-12 Code-Style-Kompatibilität
|
||||
- Modulare Code-Struktur für einfache Wartung
|
||||
|
||||
### Technische Details
|
||||
- **Mindestanforderungen:**
|
||||
- PHP 8.3+
|
||||
- WHMCS 8.13+
|
||||
- KeyHelp mit API v2
|
||||
- Guzzle HTTP Client (in WHMCS integriert)
|
||||
|
||||
- **Unterstützte KeyHelp API-Endpunkte:**
|
||||
- `POST /api/v2/users` - Benutzer erstellen
|
||||
- `GET /api/v2/users/{id}` - Benutzer-Details
|
||||
- `PUT /api/v2/users/{id}` - Benutzer aktualisieren
|
||||
- `DELETE /api/v2/users/{id}` - Benutzer löschen
|
||||
- `POST /api/v2/domains` - Domain hinzufügen
|
||||
- `GET /api/v2/users/{id}/statistics` - Statistiken abrufen
|
||||
- `POST /api/v2/sessions` - SSO-Session erstellen
|
||||
- `GET /api/v2/server/version` - Server-Version (Test)
|
||||
|
||||
- **WHMCS-Funktionen:**
|
||||
- `keyhelpmanager_MetaData()` - Modul-Metadaten
|
||||
- `keyhelpmanager_ConfigOptions()` - Server-Konfiguration
|
||||
- `keyhelpmanager_CreateAccount()` - Account erstellen
|
||||
- `keyhelpmanager_SuspendAccount()` - Account sperren
|
||||
- `keyhelpmanager_UnsuspendAccount()` - Account entsperren
|
||||
- `keyhelpmanager_TerminateAccount()` - Account löschen
|
||||
- `keyhelpmanager_ChangePassword()` - Passwort ändern
|
||||
- `keyhelpmanager_ClientArea()` - Client-Bereich
|
||||
- `keyhelpmanager_LoginLink()` - Admin SSO
|
||||
- `keyhelpmanager_TestConnection()` - Verbindungstest
|
||||
|
||||
### Hilfsfunktionen
|
||||
- `_keyhelpmanager_APIRequest()` - Zentrale API-Request-Funktion
|
||||
- `_keyhelpmanager_GenerateUsername()` - Username-Generierung
|
||||
- `_keyhelpmanager_GeneratePassword()` - Passwort-Generierung
|
||||
- `_keyhelpmanager_SaveAccountDetails()` - Account-Details speichern
|
||||
- `_keyhelpmanager_GetAccountDetails()` - Account-Details laden
|
||||
- `_keyhelpmanager_GetUserId()` - KeyHelp User-ID abrufen
|
||||
- `_keyhelpmanager_UpdateAccountDetail()` - Einzelnes Detail aktualisieren
|
||||
- `_keyhelpmanager_DeleteAccountDetails()` - Details löschen
|
||||
- `_keyhelpmanager_GetCustomFieldId()` - Custom Field ID abrufen
|
||||
- `_keyhelpmanager_FormatBytes()` - Bytes formatieren
|
||||
- `_keyhelpmanager_CalculatePercent()` - Prozentsatz berechnen
|
||||
|
||||
### Templates
|
||||
- `clientarea.tpl` - Smarty-Template für Client Area mit:
|
||||
- Bootstrap 3/4 kompatibles Design
|
||||
- FontAwesome Icons
|
||||
- Responsive Grid-Layout
|
||||
- JavaScript-Funktionen für Interaktivität
|
||||
- Copy-to-Clipboard-Funktionalität
|
||||
- Passwort-Toggle-Funktion
|
||||
- Fortschrittsbalken mit Farbcodierung
|
||||
|
||||
### Konfigurationsoptionen
|
||||
- Hostname/IP des KeyHelp-Servers
|
||||
- API-Key-Verwaltung
|
||||
- SSL-Aktivierung (On/Off)
|
||||
- SSL-Zertifikat-Verifizierung (On/Off)
|
||||
|
||||
### Bekannte Einschränkungen
|
||||
- Keine direkte Multi-Language-Unterstützung (nur Deutsch)
|
||||
- Erweiterte Features wie E-Mail-/DB-Verwaltung nicht implementiert
|
||||
- Session-Token-Lifetime fest auf 5 Minuten (nicht konfigurierbar)
|
||||
- Keine automatische Plan/Tarif-Synchronisation
|
||||
|
||||
## [0.9.0-beta] - 2024-01-10
|
||||
|
||||
### Hinzugefügt
|
||||
- Beta-Version für interne Tests
|
||||
- Basis-Funktionalität für Account-Erstellung
|
||||
- Erste API-Integration
|
||||
|
||||
### Geändert
|
||||
- API-Request-Handling optimiert
|
||||
- Error-Messages verbessert
|
||||
|
||||
### Behoben
|
||||
- Connection-Timeout-Probleme
|
||||
- SSL-Verifizierung bei selbstsignierten Zertifikaten
|
||||
|
||||
## [0.5.0-alpha] - 2024-01-05
|
||||
|
||||
### Hinzugefügt
|
||||
- Initiale Projekt-Struktur
|
||||
- Grundlegende Modul-Funktionen
|
||||
- API-Client-Implementierung
|
||||
|
||||
---
|
||||
|
||||
## Versionierungsschema
|
||||
|
||||
- **Major.Minor.Patch** (z.B. 1.0.0)
|
||||
- **Major:** Breaking Changes, große neue Features
|
||||
- **Minor:** Neue Features, abwärtskompatibel
|
||||
- **Patch:** Bugfixes, kleine Verbesserungen
|
||||
|
||||
## Credits
|
||||
|
||||
Dieses Modul wurde entwickelt von:
|
||||
- **Kevin Feiler** - Lead Developer
|
||||
- **AVVGO** - https://avvgo.de
|
||||
|
||||
## Support
|
||||
|
||||
- **GitHub Issues:** Für Bug-Reports und Feature-Requests
|
||||
- **Dokumentation:** Siehe README.md und INSTALLATION.md
|
||||
- **KeyHelp Forum:** https://forum.keyhelp.de/
|
||||
- **WHMCS Community:** https://whmcs.community/
|
||||
|
||||
## Mitwirken
|
||||
|
||||
Contributions sind willkommen! Bitte erstellen Sie einen Pull Request mit:
|
||||
- Beschreibung der Änderungen
|
||||
- Tests für neue Features
|
||||
- Aktualisierung der Dokumentation
|
||||
- Eintrag in diesem CHANGELOG
|
||||
|
||||
---
|
||||
|
||||
[Unreleased]: https://github.com/ihr-repo/keyhelpmanager/compare/v1.0.0...HEAD
|
||||
[1.0.0]: https://github.com/ihr-repo/keyhelpmanager/releases/tag/v1.0.0
|
||||
[0.9.0-beta]: https://github.com/ihr-repo/keyhelpmanager/releases/tag/v0.9.0-beta
|
||||
[0.5.0-alpha]: https://github.com/ihr-repo/keyhelpmanager/releases/tag/v0.5.0-alpha
|
||||
631
INSTALLATION.md
Normal file
631
INSTALLATION.md
Normal file
@@ -0,0 +1,631 @@
|
||||
# KeyHelp Manager - Detaillierte Installationsanleitung
|
||||
|
||||
Diese Anleitung führt Sie Schritt für Schritt durch die Installation und Konfiguration des KeyHelp Manager WHMCS-Moduls.
|
||||
|
||||
## 📋 Voraussetzungen prüfen
|
||||
|
||||
Bevor Sie mit der Installation beginnen, stellen Sie sicher, dass folgende Anforderungen erfüllt sind:
|
||||
|
||||
### WHMCS-System
|
||||
|
||||
- [ ] WHMCS Version 8.13 oder höher installiert
|
||||
- [ ] PHP Version 8.3 oder höher
|
||||
- [ ] Guzzle HTTP Client verfügbar (normalerweise in WHMCS integriert)
|
||||
- [ ] MySQL/MariaDB Datenbank
|
||||
- [ ] SSL-Zertifikat für WHMCS (empfohlen)
|
||||
- [ ] Admin-Zugriff auf WHMCS
|
||||
|
||||
### KeyHelp-Server
|
||||
|
||||
- [ ] KeyHelp installiert und erreichbar
|
||||
- [ ] KeyHelp API v2 aktiviert
|
||||
- [ ] Admin-Zugang zu KeyHelp
|
||||
- [ ] SSL-Zertifikat für KeyHelp (empfohlen)
|
||||
- [ ] Firewall-Regeln erlauben Zugriff von WHMCS-Server
|
||||
|
||||
### Netzwerk
|
||||
|
||||
- [ ] WHMCS-Server kann KeyHelp-Server über HTTP/HTTPS erreichen
|
||||
- [ ] Port 80/443 ist offen (je nach Konfiguration)
|
||||
- [ ] DNS-Auflösung funktioniert korrekt
|
||||
|
||||
## 🚀 Schritt 1: KeyHelp API vorbereiten
|
||||
|
||||
### 1.1 API-Key in KeyHelp erstellen
|
||||
|
||||
1. Loggen Sie sich als Administrator in Ihr KeyHelp-Panel ein:
|
||||
```
|
||||
https://ihr-keyhelp-server.de
|
||||
```
|
||||
|
||||
2. Navigieren Sie zu **Einstellungen** (Zahnrad-Symbol oben rechts)
|
||||
|
||||
3. Klicken Sie auf **API** im linken Menü
|
||||
|
||||
4. Klicken Sie auf **Neuen API-Schlüssel erstellen**
|
||||
|
||||
5. Konfigurieren Sie den API-Key:
|
||||
- **Name:** `WHMCS Provisioning`
|
||||
- **Berechtigungen:** Wählen Sie **Administrator** oder erteilen Sie folgende spezifische Rechte:
|
||||
- Benutzer erstellen/bearbeiten/löschen
|
||||
- Domains erstellen/bearbeiten/löschen
|
||||
- Statistiken abrufen
|
||||
- Sessions erstellen
|
||||
- **IP-Whitelist:** (Optional aber empfohlen) Tragen Sie die IP-Adresse Ihres WHMCS-Servers ein
|
||||
|
||||
6. Klicken Sie auf **Erstellen**
|
||||
|
||||
7. **WICHTIG:** Kopieren Sie den generierten API-Key sofort und speichern Sie ihn sicher!
|
||||
```
|
||||
Beispiel: kh_live_1234567890abcdefghijklmnopqrstuvwxyz
|
||||
```
|
||||
|
||||
⚠️ **Der Key wird nur einmal angezeigt!**
|
||||
|
||||
### 1.2 API testen (Optional)
|
||||
|
||||
Testen Sie den API-Zugriff vom WHMCS-Server aus:
|
||||
|
||||
```bash
|
||||
# Mit SSL (empfohlen)
|
||||
curl -X GET "https://ihr-keyhelp-server.de/api/v2/server/version" \
|
||||
-H "X-API-Key: IHR_API_KEY" \
|
||||
-H "Accept: application/json"
|
||||
|
||||
# Ohne SSL (nur für Tests)
|
||||
curl -X GET "http://ihr-keyhelp-server.de/api/v2/server/version" \
|
||||
-H "X-API-Key: IHR_API_KEY" \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
Erwartete Antwort:
|
||||
```json
|
||||
{
|
||||
"version": "24.1.0",
|
||||
"api_version": "2.0"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 Schritt 2: Modul-Dateien installieren
|
||||
|
||||
### 2.1 Dateien hochladen
|
||||
|
||||
#### Option A: Via FTP/SFTP
|
||||
|
||||
1. Verbinden Sie sich mit Ihrem WHMCS-Server via FTP/SFTP
|
||||
|
||||
2. Navigieren Sie zum WHMCS-Installationsverzeichnis:
|
||||
```
|
||||
/var/www/whmcs/
|
||||
```
|
||||
|
||||
3. Laden Sie das komplette `keyhelpmanager`-Verzeichnis in folgenden Pfad hoch:
|
||||
```
|
||||
/var/www/whmcs/modules/servers/keyhelpmanager/
|
||||
```
|
||||
|
||||
4. Stellen Sie sicher, dass folgende Struktur existiert:
|
||||
```
|
||||
modules/
|
||||
└── servers/
|
||||
└── keyhelpmanager/
|
||||
├── keyhelpmanager.php
|
||||
└── templates/
|
||||
└── clientarea.tpl
|
||||
```
|
||||
|
||||
#### Option B: Via SSH
|
||||
|
||||
```bash
|
||||
# Zum WHMCS-Verzeichnis navigieren
|
||||
cd /var/www/whmcs/modules/servers/
|
||||
|
||||
# Repository klonen (falls Git verwendet wird)
|
||||
git clone https://github.com/ihr-repo/keyhelpmanager.git
|
||||
|
||||
# Oder Dateien aus ZIP extrahieren
|
||||
unzip keyhelpmanager.zip
|
||||
|
||||
# Dateien verschieben falls nötig
|
||||
mv keyhelpmanager-main keyhelpmanager
|
||||
```
|
||||
|
||||
### 2.2 Dateirechte setzen
|
||||
|
||||
Setzen Sie die korrekten Berechtigungen:
|
||||
|
||||
```bash
|
||||
# Zum Modul-Verzeichnis
|
||||
cd /var/www/whmcs/modules/servers/keyhelpmanager/
|
||||
|
||||
# Dateien: 644 (rw-r--r--)
|
||||
find . -type f -exec chmod 644 {} \;
|
||||
|
||||
# Verzeichnisse: 755 (rwxr-xr-x)
|
||||
find . -type d -exec chmod 755 {} \;
|
||||
|
||||
# Owner setzen (Apache/Nginx User)
|
||||
chown -R www-data:www-data .
|
||||
|
||||
# Oder für andere Systeme
|
||||
chown -R apache:apache .
|
||||
chown -R nginx:nginx .
|
||||
```
|
||||
|
||||
### 2.3 Installation verifizieren
|
||||
|
||||
Prüfen Sie, ob die Dateien korrekt hochgeladen wurden:
|
||||
|
||||
```bash
|
||||
ls -la /var/www/whmcs/modules/servers/keyhelpmanager/
|
||||
```
|
||||
|
||||
Erwartete Ausgabe:
|
||||
```
|
||||
drwxr-xr-x 3 www-data www-data 4096 Jan 15 10:00 .
|
||||
drwxr-xr-x 8 www-data www-data 4096 Jan 15 09:55 ..
|
||||
-rw-r--r-- 1 www-data www-data xxxxx Jan 15 10:00 keyhelpmanager.php
|
||||
drwxr-xr-x 2 www-data www-data 4096 Jan 15 10:00 templates
|
||||
```
|
||||
|
||||
## ⚙️ Schritt 3: Server in WHMCS konfigurieren
|
||||
|
||||
### 3.1 Server hinzufügen
|
||||
|
||||
1. Loggen Sie sich in den **WHMCS Admin-Bereich** ein:
|
||||
```
|
||||
https://ihr-whmcs.de/admin/
|
||||
```
|
||||
|
||||
2. Navigieren Sie zu:
|
||||
```
|
||||
Setup → Products/Services → Servers
|
||||
```
|
||||
|
||||
3. Klicken Sie auf **Add New Server**
|
||||
|
||||
### 3.2 Server-Details eintragen
|
||||
|
||||
Füllen Sie das Formular aus:
|
||||
|
||||
#### Tab: Details
|
||||
|
||||
| Feld | Wert | Beschreibung |
|
||||
|------|------|--------------|
|
||||
| **Name** | `KeyHelp Server 1` | Interner Name (frei wählbar) |
|
||||
| **Hostname** | `keyhelp.ihredomain.de` | Hostname ODER IP-Adresse **OHNE** `http://` oder `https://` |
|
||||
| **IP Address** | `123.45.67.89` | IP-Adresse (optional, falls Hostname verwendet wird) |
|
||||
| **Type** | `KeyHelp Manager` | Wählen Sie aus dem Dropdown |
|
||||
| **Username** | _(leer lassen)_ | Nicht benötigt |
|
||||
| **Password** | `kh_live_123...` | **IHR KEYHELP API-KEY** |
|
||||
| **Accesshash** | _(leer lassen)_ | Nicht benötigt |
|
||||
|
||||
#### Checkboxes
|
||||
|
||||
- ✅ **Active** - Server ist aktiv
|
||||
- ✅ **Secure** - Verwenden Sie SSL (HTTPS) für die Verbindung
|
||||
- ⬜ **Disable Accounts Automatically** - (optional)
|
||||
|
||||
#### Tab: Module Settings
|
||||
|
||||
Wenn verfügbar, konfigurieren Sie hier:
|
||||
|
||||
| Option | Empfohlener Wert | Beschreibung |
|
||||
|--------|------------------|--------------|
|
||||
| **Use SSL** | ✅ On | SSL für API-Verbindung verwenden |
|
||||
| **Verify SSL Certificate** | ✅ On | SSL-Zertifikat prüfen (bei selbstsigniert: Off) |
|
||||
|
||||
### 3.3 Verbindung testen
|
||||
|
||||
1. Klicken Sie auf **Test Connection**
|
||||
|
||||
2. Erwartete Meldung:
|
||||
```
|
||||
✅ Verbindung erfolgreich! KeyHelp Version: 24.1.0
|
||||
```
|
||||
|
||||
3. Bei Fehlermeldungen siehe [Fehlerbehebung](#fehlerbehebung)
|
||||
|
||||
4. Klicken Sie auf **Save Changes**
|
||||
|
||||
## 📦 Schritt 4: Produkt/Service erstellen
|
||||
|
||||
### 4.1 Neues Produkt anlegen
|
||||
|
||||
1. Navigieren Sie zu:
|
||||
```
|
||||
Setup → Products/Services → Products/Services
|
||||
```
|
||||
|
||||
2. Klicken Sie auf **Create a New Group** (falls noch keine Gruppe existiert):
|
||||
- **Name:** `Webhosting`
|
||||
- **Description:** `KeyHelp Webhosting Pakete`
|
||||
|
||||
3. Klicken Sie auf **Create a New Product**
|
||||
|
||||
### 4.2 Produkt-Details
|
||||
|
||||
#### Tab: Details
|
||||
|
||||
| Feld | Beispielwert |
|
||||
|------|--------------|
|
||||
| **Product Type** | `Hosting Account` |
|
||||
| **Product Group** | `Webhosting` |
|
||||
| **Product Name** | `Basic Webhosting` |
|
||||
| **Description** | Beschreibung des Pakets |
|
||||
| **Welcome Email** | `Hosting Account Welcome Email` |
|
||||
|
||||
#### Tab: Pricing
|
||||
|
||||
Konfigurieren Sie Ihre Preise:
|
||||
|
||||
- **Currency:** EUR
|
||||
- **Payment Type:** Recurring
|
||||
- **Monthly:** 5.00 EUR
|
||||
- **Quarterly:** 13.50 EUR
|
||||
- **Semi-Annually:** 27.00 EUR
|
||||
- **Annually:** 50.00 EUR
|
||||
|
||||
#### Tab: Module Settings
|
||||
|
||||
**WICHTIG:** Dies ist der entscheidende Teil!
|
||||
|
||||
| Feld | Wert | Beschreibung |
|
||||
|------|------|--------------|
|
||||
| **Module Name** | `KeyHelp Manager` | Wählen Sie aus dem Dropdown |
|
||||
| **Server Group** | `Default` | Oder wählen Sie Ihre Server-Gruppe |
|
||||
| **Username** | `Domain` | Automatisch aus Domain generieren |
|
||||
| **Password** | `Generate` | Automatisch generieren |
|
||||
|
||||
**Konfigurationsoptionen:**
|
||||
|
||||
1. **Hostname (IP or FQDN)**
|
||||
- Type: Dropdown
|
||||
- Options: Wählen Sie Ihren KeyHelp-Server
|
||||
|
||||
2. **API Key**
|
||||
- Wird automatisch vom Server übernommen
|
||||
|
||||
3. **Use SSL**
|
||||
- Default: On
|
||||
|
||||
**Aktivierte Funktionen:** (Checkboxes)
|
||||
|
||||
- ✅ Create Account
|
||||
- ✅ Suspend Account
|
||||
- ✅ Unsuspend Account
|
||||
- ✅ Terminate Account
|
||||
- ✅ Change Password
|
||||
- ✅ Login Link (Single Sign-On)
|
||||
|
||||
### 4.3 Konfigurierbare Optionen (Optional)
|
||||
|
||||
#### KeyHelp-Pläne als Dropdown
|
||||
|
||||
1. Navigieren Sie zu:
|
||||
```
|
||||
Setup → Products/Services → Configurable Options
|
||||
```
|
||||
|
||||
2. Klicken Sie auf **Create a New Group**:
|
||||
- **Group Name:** `KeyHelp Optionen`
|
||||
|
||||
3. Klicken Sie auf **Add New Configurable Option**:
|
||||
- **Option Name:** `KeyHelp Plan`
|
||||
- **Option Type:** `Dropdown`
|
||||
- **Options:**
|
||||
```
|
||||
Basic|basic
|
||||
Professional|professional
|
||||
Enterprise|enterprise
|
||||
```
|
||||
|
||||
4. Verknüpfen Sie die Gruppe mit Ihrem Produkt:
|
||||
- Products/Services → Ihr Produkt → Configurable Options
|
||||
- Wählen Sie `KeyHelp Optionen`
|
||||
|
||||
### 4.4 Custom Fields anlegen (Optional aber empfohlen)
|
||||
|
||||
Diese Felder werden zwar automatisch erstellt, können aber manuell vorbereitet werden:
|
||||
|
||||
1. Navigieren Sie zu:
|
||||
```
|
||||
Setup → Custom Fields
|
||||
```
|
||||
|
||||
2. Wählen Sie **Products/Services** und Ihr Produkt
|
||||
|
||||
3. Klicken Sie auf **Add New Custom Field**:
|
||||
|
||||
- **Field Name:** `KeyHelp User ID`
|
||||
- **Field Type:** `Text Box`
|
||||
- **Description:** `Interne KeyHelp Benutzer-ID`
|
||||
- ✅ **Admin Only**
|
||||
- Sortierung: `1`
|
||||
|
||||
## ✅ Schritt 5: Testen der Installation
|
||||
|
||||
### 5.1 Test-Bestellung durchführen
|
||||
|
||||
1. Öffnen Sie Ihr WHMCS Frontend als Kunde (im Inkognito-Modus):
|
||||
```
|
||||
https://ihr-whmcs.de/
|
||||
```
|
||||
|
||||
2. Navigieren Sie zu **Order → Hosting**
|
||||
|
||||
3. Wählen Sie Ihr neues Produkt
|
||||
|
||||
4. Geben Sie eine Test-Domain ein:
|
||||
```
|
||||
test123.de
|
||||
```
|
||||
|
||||
5. Schließen Sie die Bestellung ab (nutzen Sie ein Test-Gateway oder manuelle Zahlung)
|
||||
|
||||
### 5.2 Account-Erstellung prüfen
|
||||
|
||||
1. Als Admin: Navigieren Sie zu **Clients → View/Search Clients**
|
||||
|
||||
2. Öffnen Sie den Test-Kunden
|
||||
|
||||
3. Klicken Sie auf das neue Service/Produkt
|
||||
|
||||
4. Im Tab **Information** sollten Sie sehen:
|
||||
- ✅ Username: automatisch generiert
|
||||
- ✅ Password: automatisch generiert
|
||||
- ✅ Status: Active
|
||||
|
||||
5. Prüfen Sie die **Module Commands**:
|
||||
- Buttons sollten verfügbar sein: Suspend, Unsuspend, Terminate, Change Password
|
||||
|
||||
### 5.3 Client Area testen
|
||||
|
||||
1. Loggen Sie sich als Test-Kunde ein
|
||||
|
||||
2. Navigieren Sie zu **Services → My Services**
|
||||
|
||||
3. Klicken Sie auf das neue Hosting-Paket
|
||||
|
||||
4. Sie sollten sehen:
|
||||
- ✅ KeyHelp Login-URL (klickbar)
|
||||
- ✅ Benutzername (mit Copy-Button)
|
||||
- ✅ Passwort (mit Show/Hide und Copy-Button)
|
||||
- ✅ Domain-Name
|
||||
- ✅ Statistiken (wenn Account erstellt wurde):
|
||||
- Speicherplatz-Fortschrittsbalken
|
||||
- Traffic-Fortschrittsbalken
|
||||
- Anzahl Domains/Datenbanken/E-Mail-Konten
|
||||
|
||||
### 5.4 In KeyHelp prüfen
|
||||
|
||||
1. Loggen Sie sich in Ihr KeyHelp-Panel ein
|
||||
|
||||
2. Navigieren Sie zu **Benutzer**
|
||||
|
||||
3. Sie sollten den neu erstellten Benutzer sehen:
|
||||
- Username wie in WHMCS
|
||||
- Domain zugewiesen
|
||||
- Status: Aktiv
|
||||
|
||||
### 5.5 Single Sign-On testen
|
||||
|
||||
1. Als Admin in WHMCS: Öffnen Sie das Test-Service
|
||||
|
||||
2. Klicken Sie auf **Login to KeyHelp** (oder ähnlicher Button)
|
||||
|
||||
3. Sie sollten automatisch in KeyHelp eingeloggt werden:
|
||||
- Als der jeweilige Benutzer
|
||||
- Ohne Passwort-Eingabe
|
||||
|
||||
## 🔧 Schritt 6: Produktiv-Konfiguration
|
||||
|
||||
### 6.1 Mehrere Server einrichten
|
||||
|
||||
Falls Sie mehrere KeyHelp-Server haben:
|
||||
|
||||
1. Wiederholen Sie Schritt 3 für jeden Server
|
||||
|
||||
2. Erstellen Sie eine **Server Group**:
|
||||
```
|
||||
Setup → Products/Services → Servers → Server Groups
|
||||
```
|
||||
|
||||
3. Fügen Sie alle KeyHelp-Server zur Gruppe hinzu
|
||||
|
||||
4. Konfigurieren Sie Ihre Produkte, um die Server-Gruppe zu nutzen:
|
||||
- Automatische Lastverteilung
|
||||
- Failover-Funktion
|
||||
|
||||
### 6.2 Automatisierung einrichten
|
||||
|
||||
#### A) Automatische Provisioning
|
||||
|
||||
In WHMCS: **Setup → Automation Settings**
|
||||
|
||||
- ✅ Enable Automatic Provisioning
|
||||
- ✅ Process After: Payment Cleared
|
||||
- Stellen Sie sicher, dass Cron-Jobs aktiv sind
|
||||
|
||||
#### B) Automatische Sperrung
|
||||
|
||||
- ✅ Enable Automatic Suspension
|
||||
- Days Past Due Before Suspension: `7`
|
||||
|
||||
#### C) Automatische Kündigung
|
||||
|
||||
- ✅ Enable Automatic Termination
|
||||
- Days Past Due Before Termination: `30`
|
||||
|
||||
### 6.3 E-Mail-Templates anpassen
|
||||
|
||||
Passen Sie die E-Mail-Templates an:
|
||||
|
||||
1. **Setup → Email Templates**
|
||||
|
||||
2. Suchen Sie nach:
|
||||
- `Hosting Account Welcome Email`
|
||||
|
||||
3. Fügen Sie KeyHelp-spezifische Variablen hinzu:
|
||||
```
|
||||
KeyHelp Login: https://{$service_server_hostname}
|
||||
Benutzername: {$service_username}
|
||||
Passwort: {$service_password}
|
||||
Domain: {$service_domain}
|
||||
```
|
||||
|
||||
### 6.4 Sicherheit härten
|
||||
|
||||
1. **IP-Whitelist in KeyHelp**:
|
||||
- Beschränken Sie API-Zugriff auf WHMCS-Server-IP
|
||||
|
||||
2. **WHMCS Admin-IP-Whitelist**:
|
||||
```
|
||||
Setup → General Settings → Security
|
||||
```
|
||||
- Tragen Sie erlaubte Admin-IPs ein
|
||||
|
||||
3. **Zwei-Faktor-Authentifizierung**:
|
||||
- Aktivieren Sie 2FA für alle Admin-Accounts (WHMCS und KeyHelp)
|
||||
|
||||
4. **SSL-Zertifikate**:
|
||||
- Verwenden Sie gültige SSL-Zertifikate
|
||||
- Keine selbstsignierten Zertifikate in Produktion
|
||||
|
||||
## 🐛 Fehlerbehebung
|
||||
|
||||
### Problem: "Module Not Found"
|
||||
|
||||
**Ursache:** Dateien nicht korrekt hochgeladen
|
||||
|
||||
**Lösung:**
|
||||
```bash
|
||||
# Prüfen Sie den Pfad
|
||||
ls -la /var/www/whmcs/modules/servers/keyhelpmanager/keyhelpmanager.php
|
||||
|
||||
# Wenn nicht gefunden, Dateien neu hochladen
|
||||
```
|
||||
|
||||
### Problem: "Connection Failed"
|
||||
|
||||
**Ursachen & Lösungen:**
|
||||
|
||||
1. **Firewall blockiert**:
|
||||
```bash
|
||||
# Auf WHMCS-Server testen
|
||||
telnet keyhelp-server.de 443
|
||||
```
|
||||
|
||||
2. **Falscher Hostname**:
|
||||
- Verwenden Sie FQDN ODER IP
|
||||
- OHNE `http://` oder `https://`
|
||||
|
||||
3. **SSL-Problem**:
|
||||
- Bei selbstsigniertem Zertifikat: "Verify SSL" deaktivieren
|
||||
|
||||
4. **API-Key falsch**:
|
||||
- Generieren Sie einen neuen Key in KeyHelp
|
||||
- Kopieren Sie ihn exakt (keine Leerzeichen!)
|
||||
|
||||
### Problem: "Account Creation Failed"
|
||||
|
||||
**Debug-Schritte:**
|
||||
|
||||
1. Prüfen Sie Module Log:
|
||||
```
|
||||
Utilities → Logs → Module Log
|
||||
Filter: keyhelpmanager
|
||||
```
|
||||
|
||||
2. Prüfen Sie die API-Response in den Logs
|
||||
|
||||
3. Häufige Ursachen:
|
||||
- Domain existiert bereits
|
||||
- Ungültiger Username
|
||||
- Unzureichende API-Berechtigungen
|
||||
- KeyHelp-Lizenz-Limit erreicht
|
||||
|
||||
### Problem: "Statistics Not Showing"
|
||||
|
||||
**Ursache:** API-Endpunkt nicht erreichbar oder User-ID fehlt
|
||||
|
||||
**Lösung:**
|
||||
```bash
|
||||
# API manuell testen
|
||||
curl -X GET "https://keyhelp-server.de/api/v2/users/123/statistics" \
|
||||
-H "X-API-Key: IHR_KEY"
|
||||
```
|
||||
|
||||
Prüfen Sie, ob `KeyHelp User ID` Custom Field existiert und gefüllt ist.
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### 6.5 Logging aktivieren
|
||||
|
||||
In WHMCS:
|
||||
```
|
||||
Setup → General Settings → Other
|
||||
```
|
||||
- ✅ Enable Module Debug Logging
|
||||
|
||||
Logs finden Sie unter:
|
||||
```
|
||||
Utilities → Logs → Module Log
|
||||
```
|
||||
|
||||
### 6.6 Gesundheits-Check einrichten
|
||||
|
||||
Erstellen Sie ein Cron-Script für regelmäßige API-Tests:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# /root/keyhelp-health-check.sh
|
||||
|
||||
KEYHELP_HOST="keyhelp.ihredomain.de"
|
||||
API_KEY="ihr_api_key"
|
||||
|
||||
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
"https://${KEYHELP_HOST}/api/v2/server/version" \
|
||||
-H "X-API-Key: ${API_KEY}")
|
||||
|
||||
if [ "$RESPONSE" != "200" ]; then
|
||||
echo "KeyHelp API nicht erreichbar! HTTP Status: $RESPONSE"
|
||||
# Optional: Benachrichtigung senden
|
||||
echo "KeyHelp API Down" | mail -s "ALERT: KeyHelp" admin@ihredomain.de
|
||||
fi
|
||||
```
|
||||
|
||||
Cron-Job:
|
||||
```bash
|
||||
# Alle 15 Minuten prüfen
|
||||
*/15 * * * * /root/keyhelp-health-check.sh
|
||||
```
|
||||
|
||||
## ✨ Fertig!
|
||||
|
||||
Herzlichen Glückwunsch! Ihr KeyHelp Manager WHMCS-Modul ist jetzt vollständig installiert und konfiguriert.
|
||||
|
||||
### Nächste Schritte
|
||||
|
||||
- [ ] Produktiv-Server konfigurieren
|
||||
- [ ] Mehrere Hosting-Pakete anlegen
|
||||
- [ ] Preise festlegen
|
||||
- [ ] Marketing-Material vorbereiten
|
||||
- [ ] Support-Team schulen
|
||||
|
||||
### Wichtige Hinweise
|
||||
|
||||
- 🔒 **Sicherheit:** Ändern Sie Ihre API-Keys regelmäßig
|
||||
- 📝 **Backups:** Sichern Sie regelmäßig WHMCS und KeyHelp
|
||||
- 🔄 **Updates:** Halten Sie alle Systeme aktuell
|
||||
- 📞 **Support:** Dokumentieren Sie Ihre Konfiguration für Ihr Team
|
||||
|
||||
### Nützliche Links
|
||||
|
||||
- KeyHelp Dokumentation: https://www.keyhelp.de/dokumentation
|
||||
- WHMCS Docs: https://docs.whmcs.com/
|
||||
- KeyHelp Forum: https://forum.keyhelp.de/
|
||||
|
||||
---
|
||||
|
||||
**Bei Problemen oder Fragen:** Prüfen Sie die README.md und die Fehlerbehebungssektion. Für weitere Hilfe konsultieren Sie die Community-Foren.
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Kevin Feiler / AVVGO
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
373
PROJECT_STRUCTURE.md
Normal file
373
PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,373 @@
|
||||
# KeyHelp Manager - Projektstruktur
|
||||
|
||||
**Entwickelt von:** Kevin Feiler / AVVGO
|
||||
**Version:** 1.0.0
|
||||
|
||||
## 📁 Verzeichnisstruktur
|
||||
|
||||
```
|
||||
keyweb-module/
|
||||
├── modules/
|
||||
│ └── servers/
|
||||
│ └── keyhelpmanager/
|
||||
│ ├── keyhelpmanager.php # Haupt-Modul-Datei (846 Zeilen)
|
||||
│ └── templates/
|
||||
│ └── clientarea.tpl # Client Area Smarty-Template
|
||||
│
|
||||
├── .gitignore # Git Ignore-Datei
|
||||
├── CHANGELOG.md # Versions-Historie
|
||||
├── composer.json # Composer Dependencies
|
||||
├── INSTALLATION.md # Detaillierte Installationsanleitung
|
||||
├── LICENSE # MIT Lizenz
|
||||
├── PROJECT_STRUCTURE.md # Diese Datei
|
||||
└── README.md # Haupt-Dokumentation
|
||||
```
|
||||
|
||||
## 📄 Datei-Übersicht
|
||||
|
||||
### Hauptmodul: `keyhelpmanager.php`
|
||||
|
||||
**Größe:** ~846 Zeilen
|
||||
**Zweck:** Kernfunktionalität des WHMCS Provisioning Moduls
|
||||
|
||||
#### Öffentliche WHMCS-Funktionen:
|
||||
|
||||
1. **`keyhelpmanager_MetaData()`**
|
||||
- Gibt Modul-Metadaten zurück
|
||||
- DisplayName, API-Version, Port-Definitionen
|
||||
|
||||
2. **`keyhelpmanager_ConfigOptions()`**
|
||||
- Definiert Server-Konfigurationsoptionen
|
||||
- Hostname, API-Key, SSL-Einstellungen
|
||||
|
||||
3. **`keyhelpmanager_CreateAccount(array $params)`**
|
||||
- Erstellt neuen KeyHelp-Account
|
||||
- Generiert Username/Passwort falls nötig
|
||||
- Fügt Domain hinzu
|
||||
- Speichert Details in WHMCS
|
||||
|
||||
4. **`keyhelpmanager_SuspendAccount(array $params)`**
|
||||
- Sperrt KeyHelp-Account
|
||||
- Setzt `is_locked` Flag
|
||||
|
||||
5. **`keyhelpmanager_UnsuspendAccount(array $params)`**
|
||||
- Entsperrt KeyHelp-Account
|
||||
- Entfernt `is_locked` Flag
|
||||
|
||||
6. **`keyhelpmanager_TerminateAccount(array $params)`**
|
||||
- Löscht KeyHelp-Account permanent
|
||||
- Entfernt alle zugehörigen Daten
|
||||
- Cleanup in WHMCS-Datenbank
|
||||
|
||||
7. **`keyhelpmanager_ChangePassword(array $params)`**
|
||||
- Ändert Account-Passwort
|
||||
- Synchronisiert mit WHMCS
|
||||
|
||||
8. **`keyhelpmanager_ClientArea(array $params)`**
|
||||
- Generiert Client Area Inhalt
|
||||
- Lädt Live-Statistiken von KeyHelp
|
||||
- Rendert Smarty-Template
|
||||
|
||||
9. **`keyhelpmanager_LoginLink(array $params)`**
|
||||
- Single Sign-On für Admins
|
||||
- Erstellt Session-Token
|
||||
- Generiert direkten Login-Link
|
||||
|
||||
10. **`keyhelpmanager_TestConnection(array $params)`**
|
||||
- Testet API-Verbindung
|
||||
- Gibt KeyHelp-Version zurück
|
||||
|
||||
#### Private Hilfsfunktionen:
|
||||
|
||||
**API-Kommunikation:**
|
||||
- `_keyhelpmanager_APIRequest()` - Zentrale API-Request-Funktion mit Guzzle
|
||||
|
||||
**Account-Management:**
|
||||
- `_keyhelpmanager_GenerateUsername()` - Generiert Username aus Domain
|
||||
- `_keyhelpmanager_GeneratePassword()` - Generiert sicheres Passwort (16 Zeichen)
|
||||
- `_keyhelpmanager_SaveAccountDetails()` - Speichert in WHMCS-DB
|
||||
- `_keyhelpmanager_GetAccountDetails()` - Lädt aus WHMCS-DB
|
||||
- `_keyhelpmanager_GetUserId()` - Holt KeyHelp User-ID
|
||||
- `_keyhelpmanager_UpdateAccountDetail()` - Aktualisiert einzelnes Detail
|
||||
- `_keyhelpmanager_DeleteAccountDetails()` - Löscht gespeicherte Details
|
||||
|
||||
**Custom Fields:**
|
||||
- `_keyhelpmanager_GetCustomFieldId()` - Holt/erstellt Custom Field ID
|
||||
|
||||
**Formatierung:**
|
||||
- `_keyhelpmanager_FormatBytes()` - Formatiert Bytes → KB/MB/GB/TB
|
||||
- `_keyhelpmanager_CalculatePercent()` - Berechnet Prozentsatz
|
||||
|
||||
### Template: `clientarea.tpl`
|
||||
|
||||
**Größe:** ~258 Zeilen
|
||||
**Typ:** Smarty Template
|
||||
**Zweck:** Client Area Darstellung
|
||||
|
||||
#### Features:
|
||||
- Bootstrap 3/4 kompatibles Layout
|
||||
- FontAwesome Icons
|
||||
- Responsive Design
|
||||
- JavaScript-Funktionen:
|
||||
- `togglePassword()` - Passwort anzeigen/verbergen
|
||||
- `copyToClipboard()` - Text in Zwischenablage kopieren
|
||||
|
||||
#### Angezeigte Informationen:
|
||||
1. **Login-Informationen:**
|
||||
- KeyHelp Login-URL (klickbar)
|
||||
- Benutzername (mit Copy-Button)
|
||||
- Passwort (mit Show/Hide und Copy-Button)
|
||||
- Domain-Name
|
||||
|
||||
2. **Account-Statistiken:**
|
||||
- Speicherplatz (Fortschrittsbalken)
|
||||
- Traffic/Bandbreite (Fortschrittsbalken)
|
||||
- Anzahl Domains
|
||||
- Anzahl Datenbanken
|
||||
- Anzahl E-Mail-Konten
|
||||
|
||||
3. **Call-to-Action:**
|
||||
- "Jetzt zu KeyHelp einloggen" Button
|
||||
|
||||
## 🔌 KeyHelp API-Endpunkte
|
||||
|
||||
Das Modul nutzt folgende KeyHelp API v2 Endpunkte:
|
||||
|
||||
| Endpunkt | Methode | Zweck | Verwendet in |
|
||||
|----------|---------|-------|--------------|
|
||||
| `/api/v2/users` | POST | Benutzer erstellen | CreateAccount |
|
||||
| `/api/v2/users/{id}` | GET | Benutzer-Details | GetAccountDetails |
|
||||
| `/api/v2/users/{id}` | PUT | Benutzer aktualisieren | SuspendAccount, UnsuspendAccount, ChangePassword |
|
||||
| `/api/v2/users/{id}` | DELETE | Benutzer löschen | TerminateAccount |
|
||||
| `/api/v2/domains` | POST | Domain hinzufügen | CreateAccount |
|
||||
| `/api/v2/users/{id}/statistics` | GET | Statistiken abrufen | ClientArea |
|
||||
| `/api/v2/sessions` | POST | SSO-Session erstellen | LoginLink |
|
||||
| `/api/v2/server/version` | GET | Server-Version | TestConnection |
|
||||
|
||||
## 💾 WHMCS-Datenbank-Interaktionen
|
||||
|
||||
### Verwendete Tabellen:
|
||||
|
||||
1. **`tblhosting`**
|
||||
- Felder: `username`, `password`
|
||||
- Zweck: Speichert Account-Credentials
|
||||
|
||||
2. **`tblcustomfields`**
|
||||
- Erstellt Custom Field: "KeyHelp User ID"
|
||||
- Typ: Text (Admin Only)
|
||||
|
||||
3. **`tblcustomfieldsvalues`**
|
||||
- Speichert KeyHelp User-ID pro Service
|
||||
- Verknüpfung über `relid` (Service-ID)
|
||||
|
||||
### Verwendetes ORM:
|
||||
- **Laravel Eloquent Capsule** (von WHMCS bereitgestellt)
|
||||
- Sichere Queries ohne SQL-Injection-Risiko
|
||||
|
||||
## 🔒 Sicherheitsfeatures
|
||||
|
||||
1. **API-Key-Schutz:**
|
||||
- Verschlüsselte Speicherung in WHMCS
|
||||
- Maskierung in Module-Logs
|
||||
- Niemals im Frontend sichtbar
|
||||
|
||||
2. **Passwort-Sicherheit:**
|
||||
- Kryptografisch sichere Generierung (`random_int()`)
|
||||
- 16 Zeichen Länge
|
||||
- Gemischte Zeichensätze (a-z, A-Z, 0-9, Sonderzeichen)
|
||||
- Verschlüsselte Speicherung in WHMCS
|
||||
|
||||
3. **SSL/TLS:**
|
||||
- Konfigurierbare SSL-Verbindungen
|
||||
- Optionale Zertifikat-Verifizierung
|
||||
- Standard: SSL aktiviert
|
||||
|
||||
4. **Input-Validierung:**
|
||||
- Alle Benutzereingaben werden validiert
|
||||
- Sanitization durch Capsule ORM
|
||||
- Exception-Handling für alle API-Calls
|
||||
|
||||
5. **Session-Token:**
|
||||
- Temporäre SSO-Tokens (5 Minuten Gültigkeit)
|
||||
- Automatischer Ablauf
|
||||
|
||||
## 📝 Logging
|
||||
|
||||
### WHMCS Module Log:
|
||||
- Alle API-Requests werden protokolliert
|
||||
- Automatische Maskierung sensibler Daten
|
||||
- Abrufbar unter: `Utilities → Logs → Module Log`
|
||||
|
||||
### Logged werden:
|
||||
- API-Endpunkt und Methode
|
||||
- Request-Body (API-Key maskiert)
|
||||
- Response-Status und Body
|
||||
- Fehler und Exceptions
|
||||
|
||||
## 🎨 Design-Patterns
|
||||
|
||||
1. **Prefix-Convention:**
|
||||
- Öffentliche Funktionen: `keyhelpmanager_FunctionName()`
|
||||
- Private Funktionen: `_keyhelpmanager_FunctionName()`
|
||||
|
||||
2. **Error-Handling:**
|
||||
- Try-Catch-Blöcke um alle kritischen Operationen
|
||||
- Verständliche Fehlermeldungen für Endbenutzer
|
||||
- Detailliertes Logging für Admins
|
||||
|
||||
3. **Rollback-Mechanismus:**
|
||||
- Bei fehlgeschlagener Domain-Erstellung: Benutzer wird gelöscht
|
||||
- Verhindert inkonsistente Zustände
|
||||
|
||||
4. **Separation of Concerns:**
|
||||
- API-Logik in `_keyhelpmanager_APIRequest()`
|
||||
- Datenbank-Logik in separaten Funktionen
|
||||
- Template-Logik in `.tpl`-Datei
|
||||
|
||||
## 🔄 Workflow-Diagramme
|
||||
|
||||
### Account-Erstellung:
|
||||
|
||||
```
|
||||
WHMCS Payment Cleared
|
||||
↓
|
||||
keyhelpmanager_CreateAccount()
|
||||
↓
|
||||
Validiere Parameter
|
||||
↓
|
||||
Generiere Username/Passwort (falls nötig)
|
||||
↓
|
||||
API: POST /users (Benutzer erstellen)
|
||||
↓
|
||||
Erfolg?
|
||||
↙ ↘
|
||||
Ja Nein → Return Error
|
||||
↓
|
||||
API: POST /domains (Domain hinzufügen)
|
||||
↓
|
||||
Erfolg?
|
||||
↙ ↘
|
||||
Ja Nein → Rollback: DELETE User → Return Error
|
||||
↓
|
||||
Speichere Details in WHMCS
|
||||
↓
|
||||
Return "success"
|
||||
↓
|
||||
Account ist aktiv
|
||||
```
|
||||
|
||||
### Single Sign-On:
|
||||
|
||||
```
|
||||
Admin klickt "Login to KeyHelp"
|
||||
↓
|
||||
keyhelpmanager_LoginLink()
|
||||
↓
|
||||
Lade User-ID aus WHMCS
|
||||
↓
|
||||
API: POST /sessions (mit User-ID)
|
||||
↓
|
||||
Erhalte Session-Token
|
||||
↓
|
||||
Generiere Login-URL mit Token
|
||||
↓
|
||||
Redirect zu KeyHelp
|
||||
↓
|
||||
Auto-Login ohne Passwort
|
||||
```
|
||||
|
||||
## 📦 Abhängigkeiten
|
||||
|
||||
### PHP-Extensions:
|
||||
- `ext-json` - JSON-Verarbeitung
|
||||
- `ext-curl` - HTTP-Requests
|
||||
|
||||
### Composer-Pakete:
|
||||
- `guzzlehttp/guzzle` ^7.0 - HTTP-Client (von WHMCS bereitgestellt)
|
||||
|
||||
### WHMCS-Komponenten:
|
||||
- Laravel Eloquent Capsule (ORM)
|
||||
- Smarty Template Engine
|
||||
- Module Log System
|
||||
- Custom Fields System
|
||||
- Encryption Functions
|
||||
|
||||
## 🧪 Testing-Empfehlungen
|
||||
|
||||
### Manuelle Tests:
|
||||
|
||||
1. **Connection-Test:**
|
||||
- Server-Konfiguration → Test Connection
|
||||
|
||||
2. **Account-Lifecycle:**
|
||||
- Create → Verify in KeyHelp
|
||||
- Suspend → Verify locked
|
||||
- Unsuspend → Verify unlocked
|
||||
- Terminate → Verify deleted
|
||||
|
||||
3. **Client Area:**
|
||||
- Login-Credentials sichtbar?
|
||||
- Statistiken werden geladen?
|
||||
- Copy-to-Clipboard funktioniert?
|
||||
- Responsive Design auf Mobile?
|
||||
|
||||
4. **Admin SSO:**
|
||||
- Login-Link funktioniert?
|
||||
- Automatischer Login ohne Passwort?
|
||||
- Token läuft nach 5 Min. ab?
|
||||
|
||||
### Automatisierte Tests (Geplant):
|
||||
|
||||
- PHPUnit-Tests für alle Funktionen
|
||||
- Mock-API-Responses
|
||||
- Database-Transaktionen für Tests
|
||||
|
||||
## 📊 Code-Statistiken
|
||||
|
||||
- **Gesamt-Zeilen:** ~1.400+
|
||||
- **PHP-Code:** ~846 Zeilen
|
||||
- **Smarty-Template:** ~258 Zeilen
|
||||
- **Dokumentation:** ~1.200+ Zeilen (README, INSTALLATION, etc.)
|
||||
- **Funktionen:** 21 (10 öffentlich, 11 privat)
|
||||
- **API-Endpunkte:** 8
|
||||
|
||||
## 🚀 Performance-Optimierungen
|
||||
|
||||
1. **Caching:**
|
||||
- Custom Field IDs werden bei erster Abfrage ermittelt
|
||||
- Wiederverwendung innerhalb einer Request
|
||||
|
||||
2. **Lazy-Loading:**
|
||||
- Statistiken nur bei Bedarf (Client Area)
|
||||
- Session-Tokens nur bei SSO
|
||||
|
||||
3. **Effiziente DB-Queries:**
|
||||
- Verwendung von Eloquent ORM
|
||||
- Keine N+1 Query-Probleme
|
||||
|
||||
4. **API-Timeouts:**
|
||||
- 30 Sekunden Timeout für API-Requests
|
||||
- Verhindert hängende Requests
|
||||
|
||||
## 🔮 Geplante Erweiterungen (Roadmap)
|
||||
|
||||
Siehe CHANGELOG.md → [Unreleased]
|
||||
|
||||
- Multi-Language Support
|
||||
- E-Mail-Account-Verwaltung
|
||||
- Datenbank-Management
|
||||
- SSL-Zertifikat-Management
|
||||
- Ressourcen-Upgrade/Downgrade
|
||||
- Webhook-Support
|
||||
|
||||
## 📞 Support
|
||||
|
||||
**Entwickler:** Kevin Feiler
|
||||
**Firma:** AVVGO
|
||||
**Website:** https://avvgo.de
|
||||
**E-Mail:** info@avvgo.de
|
||||
|
||||
---
|
||||
|
||||
**Copyright (c) 2024 Kevin Feiler / AVVGO**
|
||||
**Lizenz:** MIT License
|
||||
54
composer.json
Normal file
54
composer.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "avvgo/keyhelpmanager-whmcs",
|
||||
"description": "WHMCS Provisioning Module for KeyHelp Webhosting Panel - Developed by Kevin Feiler / AVVGO",
|
||||
"type": "whmcs-module",
|
||||
"keywords": [
|
||||
"whmcs",
|
||||
"keyhelp",
|
||||
"provisioning",
|
||||
"hosting",
|
||||
"webhosting",
|
||||
"control-panel",
|
||||
"avvgo"
|
||||
],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kevin Feiler",
|
||||
"email": "info@avvgo.de",
|
||||
"homepage": "https://avvgo.de",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"guzzlehttp/guzzle": "^7.0",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"KeyHelpManager\\": "modules/servers/keyhelpmanager/lib/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"KeyHelpManager\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"phpcs": "phpcs --standard=PSR12 modules/servers/keyhelpmanager/",
|
||||
"phpcbf": "phpcbf --standard=PSR12 modules/servers/keyhelpmanager/"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"optimize-autoloader": true
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
961
modules/servers/keyhelpmanager/keyhelpmanager.php
Normal file
961
modules/servers/keyhelpmanager/keyhelpmanager.php
Normal file
@@ -0,0 +1,961 @@
|
||||
<?php
|
||||
/**
|
||||
* WHMCS KeyHelp Manager Provisioning Module
|
||||
*
|
||||
* @author Kevin Feiler <info@avvgo.de>
|
||||
* @copyright Copyright (c) 2024 Kevin Feiler / AVVGO
|
||||
* @license MIT License
|
||||
* @link https://avvgo.de
|
||||
* @version 1.0.0
|
||||
*
|
||||
* Dieses Modul ermöglicht die automatische Verwaltung von KeyHelp-Hosting-Accounts
|
||||
* direkt aus WHMCS heraus. Es unterstützt Erstellung, Sperrung, Entsperrung und
|
||||
* Löschung von Accounts sowie die Anzeige von Account-Informationen im Client-Bereich.
|
||||
*
|
||||
* Entwickelt von Kevin Feiler / AVVGO
|
||||
*
|
||||
* Kompatibel mit:
|
||||
* - PHP 8.3+
|
||||
* - WHMCS 8.13+
|
||||
* - KeyHelp (neueste stabile Version)
|
||||
*/
|
||||
|
||||
if (!defined("WHMCS")) {
|
||||
die("This file cannot be accessed directly");
|
||||
}
|
||||
|
||||
use WHMCS\Database\Capsule;
|
||||
|
||||
/**
|
||||
* Modul-Metadaten
|
||||
*
|
||||
* Definiert die grundlegenden Informationen über das Modul.
|
||||
*
|
||||
* @return array Modul-Metadaten
|
||||
*/
|
||||
function keyhelpmanager_MetaData()
|
||||
{
|
||||
return [
|
||||
"DisplayName" => "KeyHelp Manager",
|
||||
"APIVersion" => "1.1",
|
||||
"RequiresServer" => true,
|
||||
"DefaultNonSSLPort" => "80",
|
||||
"DefaultSSLPort" => "443",
|
||||
"ServiceSingleSignOnLabel" => "Login zu KeyHelp",
|
||||
"AdminSingleSignOnLabel" => "Als Admin einloggen",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Modul-Konfigurationsoptionen
|
||||
*
|
||||
* Definiert die Felder, die in der Server-Konfiguration in WHMCS angezeigt werden.
|
||||
*
|
||||
* @return array Konfigurations-Array
|
||||
*/
|
||||
function keyhelpmanager_ConfigOptions()
|
||||
{
|
||||
return [
|
||||
"hostname" => [
|
||||
"FriendlyName" => "Hostname (IP or FQDN)",
|
||||
"Type" => "text",
|
||||
"Size" => "25",
|
||||
"Default" => "",
|
||||
"Description" =>
|
||||
"Hostname oder IP-Adresse deines KeyHelp-Servers (ohne http:// oder https://)",
|
||||
"Required" => true,
|
||||
],
|
||||
"apikey" => [
|
||||
"FriendlyName" => "API Key",
|
||||
"Type" => "password",
|
||||
"Size" => "50",
|
||||
"Default" => "",
|
||||
"Description" =>
|
||||
"Dein KeyHelp API-Schlüssel (zu finden in KeyHelp unter Einstellungen → API)",
|
||||
"Required" => true,
|
||||
],
|
||||
"usessl" => [
|
||||
"FriendlyName" => "Use SSL",
|
||||
"Type" => "yesno",
|
||||
"Default" => "on",
|
||||
"Description" =>
|
||||
"SSL für die Verbindung zur API verwenden (dringend empfohlen)",
|
||||
],
|
||||
"verify_ssl" => [
|
||||
"FriendlyName" => "Verify SSL Certificate",
|
||||
"Type" => "yesno",
|
||||
"Default" => "on",
|
||||
"Description" =>
|
||||
"SSL-Zertifikat verifizieren (bei selbstsignierten Zertifikaten deaktivieren)",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* API-Request Hilfsfunktion
|
||||
*
|
||||
* Sendet HTTP-Anfragen an die KeyHelp-API und verarbeitet die Antworten.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter-Array
|
||||
* @param string $endpoint API-Endpunkt (z.B. '/users', '/users/123')
|
||||
* @param string $method HTTP-Methode (GET, POST, PUT, DELETE)
|
||||
* @param array $data Request-Body-Daten
|
||||
* @return array Ergebnis mit 'success' (bool) und 'data' oder 'error'
|
||||
*/
|
||||
function _keyhelpmanager_APIRequest(
|
||||
array $params,
|
||||
string $endpoint,
|
||||
string $method = "GET",
|
||||
array $data = [],
|
||||
) {
|
||||
try {
|
||||
// Konfiguration auslesen
|
||||
$hostname =
|
||||
$params["serverhostname"] ?? ($params["configoption1"] ?? "");
|
||||
$apiKey = $params["serverpassword"] ?? ($params["configoption2"] ?? "");
|
||||
$useSSL = $params["configoption3"] ?? "on";
|
||||
$verifySSL = $params["configoption4"] ?? "on";
|
||||
|
||||
// Validierung
|
||||
if (empty($hostname)) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => "KeyHelp-Hostname ist nicht konfiguriert.",
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($apiKey)) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => "KeyHelp API-Schlüssel ist nicht konfiguriert.",
|
||||
];
|
||||
}
|
||||
|
||||
// Protocol bestimmen
|
||||
$protocol = $useSSL === "on" ? "https" : "http";
|
||||
|
||||
// Basis-URL zusammenbauen
|
||||
$baseUrl = sprintf("%s://%s/api/v2", $protocol, $hostname);
|
||||
$url = $baseUrl . $endpoint;
|
||||
|
||||
// Guzzle HTTP-Client initialisieren
|
||||
$client = new \GuzzleHttp\Client([
|
||||
"verify" => $verifySSL === "on",
|
||||
"timeout" => 30,
|
||||
"http_errors" => false,
|
||||
]);
|
||||
|
||||
// Request-Optionen
|
||||
$options = [
|
||||
"headers" => [
|
||||
"X-API-Key" => $apiKey,
|
||||
"Content-Type" => "application/json",
|
||||
"Accept" => "application/json",
|
||||
],
|
||||
];
|
||||
|
||||
// Body-Daten hinzufügen wenn vorhanden
|
||||
if (!empty($data) && in_array($method, ["POST", "PUT", "PATCH"])) {
|
||||
$options["json"] = $data;
|
||||
}
|
||||
|
||||
// API-Request ausführen
|
||||
$response = $client->request($method, $url, $options);
|
||||
$statusCode = $response->getStatusCode();
|
||||
$body = (string) $response->getBody();
|
||||
|
||||
// JSON-Antwort dekodieren
|
||||
$responseData = json_decode($body, true);
|
||||
|
||||
// Logging für Debugging
|
||||
logModuleCall(
|
||||
"keyhelpmanager",
|
||||
$method . " " . $endpoint,
|
||||
$data,
|
||||
$statusCode . " - " . $body,
|
||||
$responseData,
|
||||
[$apiKey], // API-Key in Logs maskieren
|
||||
);
|
||||
|
||||
// Erfolgreiche Antworten (2xx)
|
||||
if ($statusCode >= 200 && $statusCode < 300) {
|
||||
return [
|
||||
"success" => true,
|
||||
"data" => $responseData,
|
||||
"status_code" => $statusCode,
|
||||
];
|
||||
}
|
||||
|
||||
// Fehlerbehandlung
|
||||
$errorMessage = "KeyHelp API-Fehler: ";
|
||||
|
||||
if (isset($responseData["message"])) {
|
||||
$errorMessage .= $responseData["message"];
|
||||
} elseif (isset($responseData["error"])) {
|
||||
$errorMessage .= $responseData["error"];
|
||||
} else {
|
||||
$errorMessage .= sprintf("HTTP Status %d - %s", $statusCode, $body);
|
||||
}
|
||||
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => $errorMessage,
|
||||
"status_code" => $statusCode,
|
||||
];
|
||||
} catch (\GuzzleHttp\Exception\ConnectException $e) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" =>
|
||||
"Verbindung zum KeyHelp-Server fehlgeschlagen: " .
|
||||
$e->getMessage(),
|
||||
];
|
||||
} catch (\GuzzleHttp\Exception\RequestException $e) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => "API-Request fehlgeschlagen: " . $e->getMessage(),
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => "Unerwarteter Fehler: " . $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Account erstellen
|
||||
*
|
||||
* Wird von WHMCS nach erfolgreicher Bezahlung aufgerufen.
|
||||
* Erstellt einen neuen Benutzer-Account in KeyHelp.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return string Erfolgs- oder Fehlermeldung
|
||||
*/
|
||||
function keyhelpmanager_CreateAccount(array $params)
|
||||
{
|
||||
try {
|
||||
// Extrahiere notwendige Parameter
|
||||
$domain = $params["domain"] ?? "";
|
||||
$username = $params["username"] ?? "";
|
||||
$password = $params["password"] ?? "";
|
||||
$clientEmail = $params["clientsdetails"]["email"] ?? "";
|
||||
$firstName = $params["clientsdetails"]["firstname"] ?? "";
|
||||
$lastName = $params["clientsdetails"]["lastname"] ?? "";
|
||||
|
||||
// Validierung
|
||||
if (empty($domain)) {
|
||||
return "Domain ist erforderlich.";
|
||||
}
|
||||
|
||||
if (empty($username)) {
|
||||
// Generiere Benutzernamen aus Domain wenn nicht vorhanden
|
||||
$username = _keyhelpmanager_GenerateUsername($domain);
|
||||
}
|
||||
|
||||
if (empty($password)) {
|
||||
// Generiere sicheres Passwort wenn nicht vorhanden
|
||||
$password = _keyhelpmanager_GeneratePassword();
|
||||
}
|
||||
|
||||
// Account-Daten für KeyHelp API vorbereiten
|
||||
$accountData = [
|
||||
"login_name" => $username,
|
||||
"password" => $password,
|
||||
"email" => $clientEmail,
|
||||
"display_name" => trim($firstName . " " . $lastName),
|
||||
];
|
||||
|
||||
// Optional: Plan/Tarif aus konfigurierbaren Optionen
|
||||
if (!empty($params["configoptions"]["KeyHelp Plan"])) {
|
||||
$accountData["plan"] = $params["configoptions"]["KeyHelp Plan"];
|
||||
}
|
||||
|
||||
// Benutzer über API erstellen
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users",
|
||||
"POST",
|
||||
$accountData,
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return $result["error"];
|
||||
}
|
||||
|
||||
$userId = $result["data"]["id"] ?? null;
|
||||
|
||||
if (empty($userId)) {
|
||||
return "Benutzer wurde erstellt, aber keine User-ID zurückgegeben.";
|
||||
}
|
||||
|
||||
// Domain zum Benutzer hinzufügen
|
||||
$domainData = [
|
||||
"domain_name" => $domain,
|
||||
"user_id" => $userId,
|
||||
];
|
||||
|
||||
$domainResult = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/domains",
|
||||
"POST",
|
||||
$domainData,
|
||||
);
|
||||
|
||||
if (!$domainResult["success"]) {
|
||||
// Rollback: Benutzer wieder löschen
|
||||
_keyhelpmanager_APIRequest($params, "/users/" . $userId, "DELETE");
|
||||
return "Domain konnte nicht hinzugefügt werden: " .
|
||||
$domainResult["error"];
|
||||
}
|
||||
|
||||
// Speichere Username und Passwort in WHMCS Custom Fields
|
||||
_keyhelpmanager_SaveAccountDetails($params["serviceid"], [
|
||||
"username" => $username,
|
||||
"password" => $password,
|
||||
"userid" => $userId,
|
||||
]);
|
||||
|
||||
return "success";
|
||||
} catch (\Exception $e) {
|
||||
return "Fehler beim Erstellen des Accounts: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Account sperren
|
||||
*
|
||||
* Wird von WHMCS aufgerufen, wenn ein Account gesperrt werden soll
|
||||
* (z.B. bei Zahlungsverzug).
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return string Erfolgs- oder Fehlermeldung
|
||||
*/
|
||||
function keyhelpmanager_SuspendAccount(array $params)
|
||||
{
|
||||
try {
|
||||
$userId = _keyhelpmanager_GetUserId($params);
|
||||
|
||||
if (empty($userId)) {
|
||||
return "Benutzer-ID nicht gefunden. Account wurde möglicherweise nicht korrekt erstellt.";
|
||||
}
|
||||
|
||||
// Benutzer-Status auf "gesperrt" setzen
|
||||
$updateData = [
|
||||
"is_locked" => true,
|
||||
];
|
||||
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users/" . $userId,
|
||||
"PUT",
|
||||
$updateData,
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return $result["error"];
|
||||
}
|
||||
|
||||
return "success";
|
||||
} catch (\Exception $e) {
|
||||
return "Fehler beim Sperren des Accounts: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Account entsperren
|
||||
*
|
||||
* Wird von WHMCS aufgerufen, wenn ein gesperrter Account wieder
|
||||
* aktiviert werden soll.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return string Erfolgs- oder Fehlermeldung
|
||||
*/
|
||||
function keyhelpmanager_UnsuspendAccount(array $params)
|
||||
{
|
||||
try {
|
||||
$userId = _keyhelpmanager_GetUserId($params);
|
||||
|
||||
if (empty($userId)) {
|
||||
return "Benutzer-ID nicht gefunden. Account wurde möglicherweise nicht korrekt erstellt.";
|
||||
}
|
||||
|
||||
// Benutzer-Status auf "aktiv" setzen
|
||||
$updateData = [
|
||||
"is_locked" => false,
|
||||
];
|
||||
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users/" . $userId,
|
||||
"PUT",
|
||||
$updateData,
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return $result["error"];
|
||||
}
|
||||
|
||||
return "success";
|
||||
} catch (\Exception $e) {
|
||||
return "Fehler beim Entsperren des Accounts: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Account löschen
|
||||
*
|
||||
* Wird von WHMCS aufgerufen, wenn ein Account endgültig gelöscht werden soll.
|
||||
* ACHTUNG: Dies löscht alle Daten unwiderruflich!
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return string Erfolgs- oder Fehlermeldung
|
||||
*/
|
||||
function keyhelpmanager_TerminateAccount(array $params)
|
||||
{
|
||||
try {
|
||||
$userId = _keyhelpmanager_GetUserId($params);
|
||||
|
||||
if (empty($userId)) {
|
||||
return "Benutzer-ID nicht gefunden. Account wurde möglicherweise bereits gelöscht.";
|
||||
}
|
||||
|
||||
// Benutzer und alle zugehörigen Daten löschen
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users/" . $userId,
|
||||
"DELETE",
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return $result["error"];
|
||||
}
|
||||
|
||||
// Entferne gespeicherte Account-Details
|
||||
_keyhelpmanager_DeleteAccountDetails($params["serviceid"]);
|
||||
|
||||
return "success";
|
||||
} catch (\Exception $e) {
|
||||
return "Fehler beim Löschen des Accounts: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-Bereich
|
||||
*
|
||||
* Gibt Informationen für den Client-Bereich in WHMCS zurück.
|
||||
* Zeigt Login-Details und Hosting-Statistiken an.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return array Template-Variablen
|
||||
*/
|
||||
function keyhelpmanager_ClientArea(array $params)
|
||||
{
|
||||
try {
|
||||
$accountDetails = _keyhelpmanager_GetAccountDetails(
|
||||
$params["serviceid"],
|
||||
);
|
||||
$userId = $accountDetails["userid"] ?? null;
|
||||
|
||||
$hostname =
|
||||
$params["serverhostname"] ?? ($params["configoption1"] ?? "");
|
||||
$useSSL = $params["configoption3"] ?? "on";
|
||||
$protocol = $useSSL === "on" ? "https" : "http";
|
||||
|
||||
// Login-URL
|
||||
$loginUrl = sprintf("%s://%s", $protocol, $hostname);
|
||||
|
||||
// Basis-Informationen
|
||||
$templateVars = [
|
||||
"login_url" => $loginUrl,
|
||||
"username" =>
|
||||
$accountDetails["username"] ??
|
||||
($params["username"] ?? "Nicht verfügbar"),
|
||||
"password" =>
|
||||
$accountDetails["password"] ??
|
||||
($params["password"] ?? "••••••••"),
|
||||
"domain" => $params["domain"] ?? "Nicht verfügbar",
|
||||
"stats" => [],
|
||||
"error" => null,
|
||||
];
|
||||
|
||||
// Statistiken von KeyHelp API abrufen wenn User-ID vorhanden
|
||||
if (!empty($userId)) {
|
||||
$statsResult = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users/" . $userId . "/statistics",
|
||||
"GET",
|
||||
);
|
||||
|
||||
if ($statsResult["success"] && isset($statsResult["data"])) {
|
||||
$stats = $statsResult["data"];
|
||||
|
||||
$templateVars["stats"] = [
|
||||
"disk_used" => _keyhelpmanager_FormatBytes(
|
||||
$stats["disk_usage"] ?? 0,
|
||||
),
|
||||
"disk_limit" => _keyhelpmanager_FormatBytes(
|
||||
$stats["disk_limit"] ?? 0,
|
||||
),
|
||||
"disk_percent" => _keyhelpmanager_CalculatePercent(
|
||||
$stats["disk_usage"] ?? 0,
|
||||
$stats["disk_limit"] ?? 0,
|
||||
),
|
||||
"bandwidth_used" => _keyhelpmanager_FormatBytes(
|
||||
$stats["traffic_usage"] ?? 0,
|
||||
),
|
||||
"bandwidth_limit" => _keyhelpmanager_FormatBytes(
|
||||
$stats["traffic_limit"] ?? 0,
|
||||
),
|
||||
"bandwidth_percent" => _keyhelpmanager_CalculatePercent(
|
||||
$stats["traffic_usage"] ?? 0,
|
||||
$stats["traffic_limit"] ?? 0,
|
||||
),
|
||||
"domains" => $stats["domains_count"] ?? 0,
|
||||
"databases" => $stats["databases_count"] ?? 0,
|
||||
"email_accounts" => $stats["email_accounts_count"] ?? 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
"templatefile" => "clientarea",
|
||||
"vars" => $templateVars,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
"templatefile" => "clientarea",
|
||||
"vars" => [
|
||||
"error" =>
|
||||
"Fehler beim Laden der Account-Informationen: " .
|
||||
$e->getMessage(),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin-Login-Link (Single Sign-On)
|
||||
*
|
||||
* Erstellt einen direkten Login-Link für Admins, um sich im KeyHelp-Panel
|
||||
* des Kunden anzumelden, ohne das Passwort eingeben zu müssen.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return array Login-Link-Konfiguration
|
||||
*/
|
||||
function keyhelpmanager_LoginLink(array $params)
|
||||
{
|
||||
try {
|
||||
$accountDetails = _keyhelpmanager_GetAccountDetails(
|
||||
$params["serviceid"],
|
||||
);
|
||||
$userId = $accountDetails["userid"] ?? null;
|
||||
|
||||
if (empty($userId)) {
|
||||
return [
|
||||
"success" => false,
|
||||
"errorMsg" => "Benutzer-ID nicht gefunden.",
|
||||
];
|
||||
}
|
||||
|
||||
// Session-Token von KeyHelp API anfordern
|
||||
$sessionData = [
|
||||
"user_id" => $userId,
|
||||
"lifetime" => 300, // 5 Minuten Gültigkeit
|
||||
];
|
||||
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/sessions",
|
||||
"POST",
|
||||
$sessionData,
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return [
|
||||
"success" => false,
|
||||
"errorMsg" =>
|
||||
"Login-Session konnte nicht erstellt werden: " .
|
||||
$result["error"],
|
||||
];
|
||||
}
|
||||
|
||||
$sessionToken = $result["data"]["token"] ?? null;
|
||||
|
||||
if (empty($sessionToken)) {
|
||||
return [
|
||||
"success" => false,
|
||||
"errorMsg" => "Kein Session-Token erhalten.",
|
||||
];
|
||||
}
|
||||
|
||||
// Login-URL mit Session-Token
|
||||
$hostname =
|
||||
$params["serverhostname"] ?? ($params["configoption1"] ?? "");
|
||||
$useSSL = $params["configoption3"] ?? "on";
|
||||
$protocol = $useSSL === "on" ? "https" : "http";
|
||||
|
||||
$loginUrl = sprintf(
|
||||
"%s://%s/login?token=%s",
|
||||
$protocol,
|
||||
$hostname,
|
||||
$sessionToken,
|
||||
);
|
||||
|
||||
return [
|
||||
"success" => true,
|
||||
"redirectTo" => $loginUrl,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
"success" => false,
|
||||
"errorMsg" =>
|
||||
"Fehler beim Erstellen des Login-Links: " . $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Passwort ändern
|
||||
*
|
||||
* Ermöglicht das Ändern des Passworts für einen KeyHelp-Account.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return string Erfolgs- oder Fehlermeldung
|
||||
*/
|
||||
function keyhelpmanager_ChangePassword(array $params)
|
||||
{
|
||||
try {
|
||||
$userId = _keyhelpmanager_GetUserId($params);
|
||||
$newPassword = $params["password"] ?? "";
|
||||
|
||||
if (empty($userId)) {
|
||||
return "Benutzer-ID nicht gefunden.";
|
||||
}
|
||||
|
||||
if (empty($newPassword)) {
|
||||
return "Neues Passwort ist erforderlich.";
|
||||
}
|
||||
|
||||
// Passwort über API ändern
|
||||
$updateData = [
|
||||
"password" => $newPassword,
|
||||
];
|
||||
|
||||
$result = _keyhelpmanager_APIRequest(
|
||||
$params,
|
||||
"/users/" . $userId,
|
||||
"PUT",
|
||||
$updateData,
|
||||
);
|
||||
|
||||
if (!$result["success"]) {
|
||||
return $result["error"];
|
||||
}
|
||||
|
||||
// Aktualisiere gespeichertes Passwort
|
||||
_keyhelpmanager_UpdateAccountDetail(
|
||||
$params["serviceid"],
|
||||
"password",
|
||||
$newPassword,
|
||||
);
|
||||
|
||||
return "success";
|
||||
} catch (\Exception $e) {
|
||||
return "Fehler beim Ändern des Passworts: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test-Verbindung
|
||||
*
|
||||
* Testet die Verbindung zur KeyHelp-API.
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return array Test-Ergebnis
|
||||
*/
|
||||
function keyhelpmanager_TestConnection(array $params)
|
||||
{
|
||||
try {
|
||||
// Einfache API-Abfrage zum Testen
|
||||
$result = _keyhelpmanager_APIRequest($params, "/server/version", "GET");
|
||||
|
||||
if (!$result["success"]) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => $result["error"],
|
||||
];
|
||||
}
|
||||
|
||||
$version = $result["data"]["version"] ?? "Unbekannt";
|
||||
|
||||
return [
|
||||
"success" => true,
|
||||
"message" => sprintf(
|
||||
"Verbindung erfolgreich! KeyHelp Version: %s",
|
||||
$version,
|
||||
),
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
"success" => false,
|
||||
"error" => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// HILFSFUNKTIONEN
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Generiert einen sicheren Benutzernamen aus einer Domain
|
||||
*
|
||||
* @param string $domain Domain-Name
|
||||
* @return string Generierter Benutzername
|
||||
*/
|
||||
function _keyhelpmanager_GenerateUsername(string $domain): string
|
||||
{
|
||||
// Entferne TLD und Sonderzeichen
|
||||
$username = preg_replace('/\.[^.]+$/', "", $domain);
|
||||
$username = preg_replace("/[^a-z0-9]/i", "", $username);
|
||||
$username = strtolower($username);
|
||||
|
||||
// Begrenze auf 16 Zeichen
|
||||
$username = substr($username, 0, 16);
|
||||
|
||||
// Füge zufällige Zahlen hinzu wenn zu kurz
|
||||
if (strlen($username) < 6) {
|
||||
$username .= rand(1000, 9999);
|
||||
}
|
||||
|
||||
return $username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generiert ein sicheres Zufallspasswort
|
||||
*
|
||||
* @param int $length Passwort-Länge
|
||||
* @return string Generiertes Passwort
|
||||
*/
|
||||
function _keyhelpmanager_GeneratePassword(int $length = 16): string
|
||||
{
|
||||
$chars =
|
||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+';
|
||||
$password = "";
|
||||
$charsLength = strlen($chars);
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$password .= $chars[random_int(0, $charsLength - 1)];
|
||||
}
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert Account-Details in der WHMCS-Datenbank
|
||||
*
|
||||
* @param int $serviceId Service-ID
|
||||
* @param array $details Account-Details (username, password, userid)
|
||||
* @return void
|
||||
*/
|
||||
function _keyhelpmanager_SaveAccountDetails(
|
||||
int $serviceId,
|
||||
array $details,
|
||||
): void {
|
||||
try {
|
||||
foreach ($details as $key => $value) {
|
||||
Capsule::table("tblhosting")
|
||||
->where("id", $serviceId)
|
||||
->update([
|
||||
$key === "username" ? "username" : "password" => $value,
|
||||
]);
|
||||
}
|
||||
|
||||
// Speichere userid in Custom Field oder Service Properties
|
||||
if (isset($details["userid"])) {
|
||||
Capsule::table("tblcustomfieldsvalues")->updateOrInsert(
|
||||
[
|
||||
"relid" => $serviceId,
|
||||
"fieldid" => _keyhelpmanager_GetCustomFieldId(
|
||||
"KeyHelp User ID",
|
||||
),
|
||||
],
|
||||
[
|
||||
"value" => $details["userid"],
|
||||
],
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
logActivity(
|
||||
"KeyHelpManager: Fehler beim Speichern der Account-Details: " .
|
||||
$e->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Account-Details aus der WHMCS-Datenbank
|
||||
*
|
||||
* @param int $serviceId Service-ID
|
||||
* @return array Account-Details
|
||||
*/
|
||||
function _keyhelpmanager_GetAccountDetails(int $serviceId): array
|
||||
{
|
||||
try {
|
||||
$service = Capsule::table("tblhosting")
|
||||
->where("id", $serviceId)
|
||||
->first();
|
||||
|
||||
$userid = Capsule::table("tblcustomfieldsvalues")
|
||||
->where("relid", $serviceId)
|
||||
->where(
|
||||
"fieldid",
|
||||
_keyhelpmanager_GetCustomFieldId("KeyHelp User ID"),
|
||||
)
|
||||
->value("value");
|
||||
|
||||
return [
|
||||
"username" => $service->username ?? "",
|
||||
"password" => decrypt($service->password ?? ""),
|
||||
"userid" => $userid ?? null,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
logActivity(
|
||||
"KeyHelpManager: Fehler beim Laden der Account-Details: " .
|
||||
$e->getMessage(),
|
||||
);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holt die KeyHelp User-ID für einen Service
|
||||
*
|
||||
* @param array $params WHMCS-Parameter
|
||||
* @return int|null User-ID oder null
|
||||
*/
|
||||
function _keyhelpmanager_GetUserId(array $params): ?int
|
||||
{
|
||||
$accountDetails = _keyhelpmanager_GetAccountDetails($params["serviceid"]);
|
||||
return $accountDetails["userid"] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert ein einzelnes Account-Detail
|
||||
*
|
||||
* @param int $serviceId Service-ID
|
||||
* @param string $field Feldname
|
||||
* @param string $value Wert
|
||||
* @return void
|
||||
*/
|
||||
function _keyhelpmanager_UpdateAccountDetail(
|
||||
int $serviceId,
|
||||
string $field,
|
||||
string $value,
|
||||
): void {
|
||||
try {
|
||||
if ($field === "username" || $field === "password") {
|
||||
Capsule::table("tblhosting")
|
||||
->where("id", $serviceId)
|
||||
->update([
|
||||
$field => $value,
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
logActivity(
|
||||
"KeyHelpManager: Fehler beim Aktualisieren von " .
|
||||
$field .
|
||||
": " .
|
||||
$e->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht gespeicherte Account-Details
|
||||
*
|
||||
* @param int $serviceId Service-ID
|
||||
* @return void
|
||||
*/
|
||||
function _keyhelpmanager_DeleteAccountDetails(int $serviceId): void
|
||||
{
|
||||
try {
|
||||
Capsule::table("tblcustomfieldsvalues")
|
||||
->where("relid", $serviceId)
|
||||
->delete();
|
||||
} catch (\Exception $e) {
|
||||
logActivity(
|
||||
"KeyHelpManager: Fehler beim Löschen der Account-Details: " .
|
||||
$e->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holt oder erstellt die Custom Field ID für ein Feld
|
||||
*
|
||||
* @param string $fieldName Feldname
|
||||
* @return int Field-ID
|
||||
*/
|
||||
function _keyhelpmanager_GetCustomFieldId(string $fieldName): int
|
||||
{
|
||||
try {
|
||||
$field = Capsule::table("tblcustomfields")
|
||||
->where("fieldname", $fieldName)
|
||||
->where("type", "product")
|
||||
->first();
|
||||
|
||||
if (!$field) {
|
||||
// Erstelle Custom Field wenn nicht vorhanden
|
||||
$fieldId = Capsule::table("tblcustomfields")->insertGetId([
|
||||
"type" => "product",
|
||||
"fieldname" => $fieldName,
|
||||
"fieldtype" => "text",
|
||||
"description" => "",
|
||||
"adminonly" => "on",
|
||||
]);
|
||||
|
||||
return $fieldId;
|
||||
}
|
||||
|
||||
return $field->id;
|
||||
} catch (\Exception $e) {
|
||||
logActivity(
|
||||
"KeyHelpManager: Fehler beim Abrufen der Custom Field ID: " .
|
||||
$e->getMessage(),
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatiert Bytes in eine lesbare Größe
|
||||
*
|
||||
* @param int $bytes Bytes
|
||||
* @return string Formatierte Größe
|
||||
*/
|
||||
function _keyhelpmanager_FormatBytes(int $bytes): string
|
||||
{
|
||||
$units = ["B", "KB", "MB", "GB", "TB"];
|
||||
$power = $bytes > 0 ? floor(log($bytes, 1024)) : 0;
|
||||
|
||||
return number_format($bytes / pow(1024, $power), 2, ",", ".") .
|
||||
" " .
|
||||
$units[$power];
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet Prozentsatz
|
||||
*
|
||||
* @param int $used Verbrauchter Wert
|
||||
* @param int $limit Limit
|
||||
* @return float Prozentsatz
|
||||
*/
|
||||
function _keyhelpmanager_CalculatePercent(int $used, int $limit): float
|
||||
{
|
||||
if ($limit == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return round(($used / $limit) * 100, 2);
|
||||
}
|
||||
258
modules/servers/keyhelpmanager/templates/clientarea.tpl
Normal file
258
modules/servers/keyhelpmanager/templates/clientarea.tpl
Normal file
@@ -0,0 +1,258 @@
|
||||
{**
|
||||
* KeyHelp Manager - Client Area Template
|
||||
*
|
||||
* Zeigt Login-Details und Account-Statistiken für Kunden an
|
||||
*}
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
<i class="fas fa-server"></i> KeyHelp Hosting Account
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
{if $error}
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-triangle"></i> {$error}
|
||||
</div>
|
||||
{else}
|
||||
|
||||
{* Login-Informationen *}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h4><i class="fas fa-sign-in-alt"></i> Login-Informationen</h4>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>KeyHelp Login-URL:</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<a href="{$login_url}" target="_blank" class="btn btn-success btn-sm">
|
||||
<i class="fas fa-external-link-alt"></i> {$login_url}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 10px;">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>Benutzername:</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" value="{$username}" readonly id="kh-username">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" onclick="copyToClipboard('kh-username')" title="Kopieren">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 10px;">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>Passwort:</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control" value="{$password}" readonly id="kh-password">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" onclick="togglePassword('kh-password')" title="Anzeigen/Verbergen">
|
||||
<i class="fas fa-eye" id="kh-password-icon"></i>
|
||||
</button>
|
||||
<button class="btn btn-default" type="button" onclick="copyToClipboard('kh-password')" title="Kopieren">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="margin-top: 10px;">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>Domain:</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<code>{$domain}</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* Account-Statistiken *}
|
||||
{if $stats}
|
||||
<div class="row" style="margin-top: 30px;">
|
||||
<div class="col-md-12">
|
||||
<h4><i class="fas fa-chart-bar"></i> Account-Statistiken</h4>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* Speicherplatz *}
|
||||
{if $stats.disk_used}
|
||||
<div class="row" style="margin-top: 15px;">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>Speicherplatz:</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="progress" style="margin-bottom: 5px;">
|
||||
<div class="progress-bar {if $stats.disk_percent >= 90}progress-bar-danger{elseif $stats.disk_percent >= 75}progress-bar-warning{else}progress-bar-success{/if}"
|
||||
role="progressbar"
|
||||
aria-valuenow="{$stats.disk_percent}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
style="width: {$stats.disk_percent}%">
|
||||
{$stats.disk_percent}%
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
{$stats.disk_used} von {$stats.disk_limit} verwendet
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* Bandbreite / Traffic *}
|
||||
{if $stats.bandwidth_used}
|
||||
<div class="row" style="margin-top: 15px;">
|
||||
<div class="col-sm-4 text-right">
|
||||
<strong>Traffic (Monat):</strong>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<div class="progress" style="margin-bottom: 5px;">
|
||||
<div class="progress-bar {if $stats.bandwidth_percent >= 90}progress-bar-danger{elseif $stats.bandwidth_percent >= 75}progress-bar-warning{else}progress-bar-info{/if}"
|
||||
role="progressbar"
|
||||
aria-valuenow="{$stats.bandwidth_percent}"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
style="width: {$stats.bandwidth_percent}%">
|
||||
{$stats.bandwidth_percent}%
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
{$stats.bandwidth_used} von {$stats.bandwidth_limit} verwendet
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* Weitere Statistiken *}
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-sm-4 col-xs-6 text-center">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h3 class="text-primary" style="margin: 0;">
|
||||
<i class="fas fa-globe"></i> {$stats.domains}
|
||||
</h3>
|
||||
<small class="text-muted">Domains</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 col-xs-6 text-center">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h3 class="text-success" style="margin: 0;">
|
||||
<i class="fas fa-database"></i> {$stats.databases}
|
||||
</h3>
|
||||
<small class="text-muted">Datenbanken</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 col-xs-12 text-center">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h3 class="text-info" style="margin: 0;">
|
||||
<i class="fas fa-envelope"></i> {$stats.email_accounts}
|
||||
</h3>
|
||||
<small class="text-muted">E-Mail-Konten</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{* Schnellzugriff-Button *}
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-md-12 text-center">
|
||||
<a href="{$login_url}" target="_blank" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-sign-in-alt"></i> Jetzt zu KeyHelp einloggen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{* JavaScript für Funktionalität *}
|
||||
<script type="text/javascript">
|
||||
function togglePassword(fieldId) {
|
||||
var field = document.getElementById(fieldId);
|
||||
var icon = document.getElementById(fieldId + '-icon');
|
||||
|
||||
if (field.type === "password") {
|
||||
field.type = "text";
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
field.type = "password";
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
|
||||
function copyToClipboard(fieldId) {
|
||||
var field = document.getElementById(fieldId);
|
||||
field.select();
|
||||
field.setSelectionRange(0, 99999); // Für mobile Geräte
|
||||
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
|
||||
// Visuelles Feedback
|
||||
var btn = event.target.closest('button');
|
||||
var originalHTML = btn.innerHTML;
|
||||
btn.innerHTML = '<i class="fas fa-check"></i>';
|
||||
btn.classList.add('btn-success');
|
||||
|
||||
setTimeout(function() {
|
||||
btn.innerHTML = originalHTML;
|
||||
btn.classList.remove('btn-success');
|
||||
}, 1500);
|
||||
} catch (err) {
|
||||
alert('Kopieren fehlgeschlagen. Bitte manuell kopieren.');
|
||||
}
|
||||
|
||||
// Deselektiere das Feld
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.panel {
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.input-group-btn button {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
line-height: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.text-right {
|
||||
text-align: left !important;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user