Move subnav menus into top-bar, apply Predictalytics glassmorphism design, add project edit and safe deletion modal, secure license deactivation, add API Swagger docs, and add Watchdog entity hierarchy tree with full CRUD
This commit is contained in:
@@ -5,12 +5,14 @@ declare(strict_types=1);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../../../../src/Core/Db.php';
|
||||
require_once __DIR__ . '/../../../../src/Core/Auth.php';
|
||||
require_once __DIR__ . '/../../../../src/Modules/License/Audit.php';
|
||||
require_once __DIR__ . '/../../../../src/Modules/License/KeyGen.php';
|
||||
require_once __DIR__ . '/../../../../src/Modules/License/RateLimiter.php';
|
||||
require_once __DIR__ . '/../../../../src/Modules/License/LicenseService.php';
|
||||
|
||||
use Deploymentcenter\Core\Db;
|
||||
use Deploymentcenter\Core\Auth;
|
||||
use Deploymentcenter\Modules\License\LicenseService;
|
||||
use Deploymentcenter\Modules\License\RateLimiter;
|
||||
|
||||
@@ -38,18 +40,36 @@ try {
|
||||
|
||||
$licenseService = new LicenseService($pdo);
|
||||
|
||||
// Validate Endpoint (Public API for clients)
|
||||
if (str_ends_with($uri, '/validate') && $method === 'POST') {
|
||||
$res = $licenseService->validate($inputData, $ip);
|
||||
sendResponse($res);
|
||||
}
|
||||
|
||||
// Deactivate Endpoint (AUTHENTICATED ONLY - Security Protection)
|
||||
if (str_ends_with($uri, '/deactivate') && $method === 'POST') {
|
||||
$authHeader = $_SERVER['HTTP_X_WATCHDOG_KEY'] ?? $_SERVER['HTTP_AUTHORIZATION'] ?? $_SERVER['HTTP_X_LICENSE_KEY'] ?? null;
|
||||
if ($authHeader && str_starts_with($authHeader, 'Bearer ')) {
|
||||
$authHeader = substr($authHeader, 7);
|
||||
}
|
||||
|
||||
$sharedKey = $config['security']['shared_key'] ?? '';
|
||||
$isAuthenticated = ($authHeader && hash_equals($sharedKey, $authHeader)) || Auth::isLoggedIn();
|
||||
|
||||
if (!$isAuthenticated) {
|
||||
sendResponse([
|
||||
'error' => 'Unauthorized',
|
||||
'message' => 'Authentication required for license deactivation. Pass Bearer token or master key.'
|
||||
], 401);
|
||||
}
|
||||
|
||||
$res = $licenseService->deactivate($inputData, $ip);
|
||||
sendResponse($res);
|
||||
}
|
||||
|
||||
// Status Endpoint
|
||||
if (str_ends_with($uri, '/status') && $method === 'GET') {
|
||||
sendResponse(['status' => 'ok', 'module' => 'LicenseLabrador', 'version' => '1.0']);
|
||||
sendResponse(['status' => 'ok', 'module' => 'Lizenzen', 'version' => '1.0']);
|
||||
}
|
||||
|
||||
sendResponse(['error' => 'Not Found', 'message' => 'Endpoint not found'], 404);
|
||||
|
||||
+504
-396
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@ class MonitorRepo
|
||||
?string $groupKey = null,
|
||||
?string $os = null
|
||||
): array {
|
||||
$nowUtc = date('Y-m-d H:i:s');
|
||||
$metricsJson = is_array($metrics) || is_object($metrics) ? json_encode($metrics, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : null;
|
||||
$state = ($status === 'ok') ? 'up' : (($status === 'warning') ? 'warning' : 'down');
|
||||
|
||||
@@ -78,6 +77,52 @@ class MonitorRepo
|
||||
return $this->getMonitor($source, $instance);
|
||||
}
|
||||
|
||||
public function updateMonitor(
|
||||
string $oldSource,
|
||||
string $newSource,
|
||||
string $instance,
|
||||
?string $groupKey,
|
||||
?string $parentSource,
|
||||
?string $notes,
|
||||
?string $url,
|
||||
?int $intervalSec,
|
||||
?string $icon = null,
|
||||
bool $isMuted = false
|
||||
): bool {
|
||||
$stmt = $this->db->prepare('
|
||||
UPDATE watchdog_monitors SET
|
||||
source = :new_source,
|
||||
group_key = :group_key,
|
||||
parent_source = :parent_source,
|
||||
notes = :notes,
|
||||
url = :url,
|
||||
expected_interval_sec = COALESCE(:interval, expected_interval_sec),
|
||||
icon = COALESCE(:icon, icon),
|
||||
is_muted = :is_muted,
|
||||
updated_utc = NOW()
|
||||
WHERE source = :old_source AND instance = :instance
|
||||
');
|
||||
|
||||
return $stmt->execute([
|
||||
':new_source' => $newSource,
|
||||
':group_key' => !empty($groupKey) ? $groupKey : null,
|
||||
':parent_source' => !empty($parentSource) ? $parentSource : null,
|
||||
':notes' => !empty($notes) ? $notes : null,
|
||||
':url' => !empty($url) ? $url : null,
|
||||
':interval' => $intervalSec,
|
||||
':icon' => !empty($icon) ? $icon : null,
|
||||
':is_muted' => $isMuted ? 1 : 0,
|
||||
':old_source' => $oldSource,
|
||||
':instance' => $instance,
|
||||
]);
|
||||
}
|
||||
|
||||
public function setParentSource(string $source, ?string $parentSource, string $instance = 'default'): bool
|
||||
{
|
||||
$stmt = $this->db->prepare('UPDATE watchdog_monitors SET parent_source = :parent, updated_utc = NOW() WHERE source = :s AND instance = :i');
|
||||
return $stmt->execute([':parent' => !empty($parentSource) ? $parentSource : null, ':s' => $source, ':i' => $instance]);
|
||||
}
|
||||
|
||||
public function updateState(int $id, string $state, ?string $reason = null): bool
|
||||
{
|
||||
$stmt = $this->db->prepare('UPDATE watchdog_monitors SET state = :state, metric_state_reason = :reason, updated_utc = NOW() WHERE id = :id');
|
||||
|
||||
Reference in New Issue
Block a user