962 lines
26 KiB
PHP
962 lines
26 KiB
PHP
<?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);
|
|
}
|