From 2fb5093c7f634f6c77b13ca08e604401791b9fd6 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Sun, 30 Nov 2025 02:51:15 +0100 Subject: [PATCH] api --- api/.htaccess | 28 ++++ api/index.php | 65 ++++---- api/router.internal.php | 100 +++++++++++ api/router.v1.php | 43 +++++ api/target/.htaccess | 11 -- api/target/browser.quick.test.php | 155 ------------------ .../result/browser.quick.test.php} | 14 +- api/{ => v1}/target/quickcheck.php | 2 +- .../assets/js/fakecheck/fakecheck.browser.js | 4 +- 9 files changed, 217 insertions(+), 205 deletions(-) create mode 100644 api/.htaccess create mode 100644 api/router.internal.php create mode 100644 api/router.v1.php delete mode 100644 api/target/.htaccess delete mode 100644 api/target/browser.quick.test.php rename api/{result/browser-quick-test.php => v1/result/browser.quick.test.php} (89%) rename api/{ => v1}/target/quickcheck.php (99%) diff --git a/api/.htaccess b/api/.htaccess new file mode 100644 index 0000000..ab8df66 --- /dev/null +++ b/api/.htaccess @@ -0,0 +1,28 @@ +RewriteEngine On + +# -------------------------------------------------------------- +# 1) Direkter Aufruf von PHP-Dateien verhindern und auf index.php routen +# Beispiel: +# /v1/browser.quick.test.php -> /index.php (mit REQUEST_URI erhalten) +# -------------------------------------------------------------- +RewriteCond %{REQUEST_URI} !/index\.php$ +RewriteRule ^(.+)\.php$ /index.php [QSA,L] + +# -------------------------------------------------------------- +# 2) Echte Dateien (JSON, JS, CSS, Bilder etc.) normal ausliefern +# -------------------------------------------------------------- +RewriteCond %{REQUEST_FILENAME} -f +RewriteRule ^ - [L] + +# -------------------------------------------------------------- +# 3) Echte Verzeichnisse normal ausliefern +# -------------------------------------------------------------- +RewriteCond %{REQUEST_FILENAME} -d +RewriteRule ^ - [L] + +# -------------------------------------------------------------- +# 4) Alles andere durch index.php routen +# Beispiel: +# /v1/quickcheck -> index.php +# -------------------------------------------------------------- +RewriteRule ^ /index.php [QSA,L] diff --git a/api/index.php b/api/index.php index 41a41cf..c24e1be 100644 --- a/api/index.php +++ b/api/index.php @@ -1,49 +1,58 @@ false, - 'error' => 'Unknown endpoint', - 'path' => $path, - ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); - break; +// Root-Info (optional) +if ($path === '/') { + echo json_encode([ + 'ok' => true, + 'service' => 'usbcheck-api', + 'version' => 1, + 'endpoints' => [ + '/v1/quickcheck', + '/v1/browser.quick.test', + '/internal/* (geschützt)', + ], + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + exit; } +// Routing nach Bereich +if (str_starts_with($path, '/v1/')) { + require __DIR__ . '/router.v1.php'; + exit; +} +if (str_starts_with($path, '/internal/')) { + require __DIR__ . '/router.internal.php'; + exit; +} +// Fallback: unbekannter Bereich +http_response_code(404); +echo json_encode([ + 'ok' => false, + 'error' => 'Unknown API area', + 'path' => $path, +], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); diff --git a/api/router.internal.php b/api/router.internal.php new file mode 100644 index 0000000..589a701 --- /dev/null +++ b/api/router.internal.php @@ -0,0 +1,100 @@ + false, + 'error' => 'Authentication required', + ]); + exit; +} + +// Pfad erneut bestimmen +$uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH); +$path = rtrim($uri, '/'); + +// DB einbinden (für interne Tools brauchen wir oft DB) +require $_SERVER['DOCUMENT_ROOT'] . '/../config/db.php'; + +// interne Routen +switch ($path) { + // Beispiel: Aggregierte Stats + case '/internal/stats.overview': + internal_stats_overview($pdo); + break; + + // Beispiel: Wartung / Cleanup + case '/internal/maintenance.cleanup-tests': + internal_cleanup_tests($pdo); + break; + + default: + http_response_code(404); + echo json_encode([ + 'ok' => false, + 'error' => 'Unknown internal endpoint', + 'path' => $path, + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + break; +} + +/** + * Beispiel: einfache Übersicht für Admin-Dashboard + */ +function internal_stats_overview(PDO $pdo): void +{ + // alles nur Beispiel – du kannst die Queries anpassen + $totalQuicktests = (int)$pdo->query("SELECT COUNT(*) FROM web_quicktests")->fetchColumn(); + + $lastTestsStmt = $pdo->query(" + SELECT id, created_at, ip_address, measured_capacity_bytes + FROM web_quicktests + ORDER BY created_at DESC + LIMIT 10 + "); + + $lastTests = $lastTestsStmt ? $lastTestsStmt->fetchAll(PDO::FETCH_ASSOC) : []; + + echo json_encode([ + 'ok' => true, + 'stats' => [ + 'total_quicktests' => $totalQuicktests, + 'last_quicktests' => $lastTests, + ], + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); +} + +/** + * Beispiel: alte Tests aufräumen (z.B. älter als 90 Tage) + */ +function internal_cleanup_tests(PDO $pdo): void +{ + // je nach Schema musst du Feldnamen anpassen – hier: created_at + $stmt = $pdo->prepare(" + DELETE FROM web_quicktests + WHERE created_at < (NOW() - INTERVAL 90 DAY) + "); + + $stmt->execute(); + $deleted = $stmt->rowCount(); + + echo json_encode([ + 'ok' => true, + 'deleted' => $deleted, + 'note' => 'Tests älter als 90 Tage wurden entfernt (Beispiel-Implementierung).', + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); +} diff --git a/api/router.v1.php b/api/router.v1.php new file mode 100644 index 0000000..d67e4ee --- /dev/null +++ b/api/router.v1.php @@ -0,0 +1,43 @@ + false, 'error' => 'Handler quickcheck_handle_request not found']); + exit; + } + + $result = quickcheck_handle_request(); + echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + break; + + case '/v1/browser.quick.test': + require __DIR__ . '/v1/result/browser.quick.test.php'; + if (!function_exists('browser_quick_test_handle_request')) { + http_response_code(500); + echo json_encode(['ok' => false, 'error' => 'Handler browser_quick_test_handle_request not found']); + exit; + } + + browser_quick_test_handle_request(); + break; + + default: + http_response_code(404); + echo json_encode([ + 'ok' => false, + 'error' => 'Unknown v1 endpoint', + 'path' => $path, + ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + break; +} diff --git a/api/target/.htaccess b/api/target/.htaccess deleted file mode 100644 index 17eeed7..0000000 --- a/api/target/.htaccess +++ /dev/null @@ -1,11 +0,0 @@ -# api/target/.htaccess - - Require all denied - - - - Order allow,deny - Deny from all - - - diff --git a/api/target/browser.quick.test.php b/api/target/browser.quick.test.php deleted file mode 100644 index 3ea19d4..0000000 --- a/api/target/browser.quick.test.php +++ /dev/null @@ -1,155 +0,0 @@ - false, - 'error' => 'Invalid JSON payload', - ]; - } - - // 2. Session / User - // (falls index.php evtl. schon session_start() macht, ist das idempotent) - if (session_status() !== PHP_SESSION_ACTIVE) { - session_start(); - } - - $userId = $_SESSION['user_id'] ?? null; - $isLoggedIn = $userId ? 1 : 0; - $sessionId = session_id() ?: null; - - $ipAddress = $_SERVER['REMOTE_ADDR'] ?? null; - $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null; - - // 3. DB-Verbindung - // Dokumentroot der API-Subdomain zeigt auf /api, - // config liegt ein Level darüber: /config/db.php - require $_SERVER['DOCUMENT_ROOT'] . '/../config/db.php'; // $pdo - - if ($pdo instanceof PDO) { - $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - } - - // 4. Werte aus dem Report aggregieren (minimal) - $measuredBytes = 0; - - if (!empty($data['quick']) && is_array($data['quick'])) { - $measuredBytes += (int)($data['quick']['size_bytes'] ?? 0); - } - if (!empty($data['benchmark']) && is_array($data['benchmark'])) { - $measuredBytes += (int)($data['benchmark']['size_bytes'] ?? 0); - } - if (!empty($data['writeverify']) && is_array($data['writeverify'])) { - $measuredBytes += (int)($data['writeverify']['total_bytes'] ?? 0); - } - - // Browser/OS & Stick-Infos – erstmal noch leer, später aus meta/parsing füllen - $browserName = null; - $browserVersion = null; - $osName = null; - $osVersion = null; - - $volumeLabel = null; - $manufacturer = null; - $modelName = null; - $usbType = null; - $filesystem = null; - - $advCapacityBytes = null; - $capacityStatus = 'unknown'; - - // Kompletten Report als JSON-String speichern - $testReportJson = $raw; - - try { - $sql = " - INSERT INTO web_quicktests ( - user_id, - is_logged_in, - usb_device_id, - browser_name, - browser_version, - os_name, - os_version, - volume_label, - manufacturer, - model_name, - usb_type, - advertised_capacity_bytes, - measured_capacity_bytes, - capacity_status, - filesystem, - test_report_json, - ip_address, - session_id - ) VALUES ( - :user_id, - :is_logged_in, - :usb_device_id, - :browser_name, - :browser_version, - :os_name, - :os_version, - :volume_label, - :manufacturer, - :model_name, - :usb_type, - :adv_capacity, - :measured_capacity, - :capacity_status, - :filesystem, - :test_report_json, - :ip_address, - :session_id - ) - "; - - $stmt = $pdo->prepare($sql); - - $ok = $stmt->execute([ - 'user_id' => $userId, - 'is_logged_in' => $isLoggedIn, - 'usb_device_id' => null, - 'browser_name' => $browserName, - 'browser_version' => $browserVersion, - 'os_name' => $osName, - 'os_version' => $osVersion, - 'volume_label' => $volumeLabel, - 'manufacturer' => $manufacturer, - 'model_name' => $modelName, - 'usb_type' => $usbType, - 'adv_capacity' => $advCapacityBytes, - 'measured_capacity' => $measuredBytes ?: null, - 'capacity_status' => $capacityStatus, - 'filesystem' => $filesystem, - 'test_report_json' => $testReportJson, - 'ip_address' => $ipAddress, - 'session_id' => $sessionId, - ]); - - if (!$ok) { - $info = $stmt->errorInfo(); - throw new RuntimeException($info[2] ?? 'Unknown DB error during insert'); - } - - return [ - 'ok' => true, - 'id' => (int)$pdo->lastInsertId(), - ]; - } catch (Throwable $e) { - http_response_code(500); - return [ - 'ok' => false, - 'error' => 'DB error: ' . $e->getMessage(), - ]; - } -} diff --git a/api/result/browser-quick-test.php b/api/v1/result/browser.quick.test.php similarity index 89% rename from api/result/browser-quick-test.php rename to api/v1/result/browser.quick.test.php index 5a1e9d3..e7f399d 100644 --- a/api/result/browser-quick-test.php +++ b/api/v1/result/browser.quick.test.php @@ -1,12 +1,12 @@