api
This commit is contained in:
163
api/v1/result/browser.quick.test.php
Normal file
163
api/v1/result/browser.quick.test.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
// /api/v1/browser.quick.test.php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
session_start();
|
||||
|
||||
// DB einbinden – Pfad abhängig von deinem Setup, aktuell:
|
||||
require $_SERVER['DOCUMENT_ROOT']. '/../config/db.php'; // stellt $pdo (PDO) bereit
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 1. JSON einlesen
|
||||
// ---------------------------------------------------------------------
|
||||
$raw = file_get_contents('php://input');
|
||||
$data = json_decode($raw, true);
|
||||
|
||||
if (!is_array($data)) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'ok' => false,
|
||||
'error' => 'Invalid JSON payload',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 2. User / Session ermitteln
|
||||
// ---------------------------------------------------------------------
|
||||
$userId = $_SESSION['user_id'] ?? null; // abhängig von deiner Login-Implementierung
|
||||
$isLoggedIn = $userId ? 1 : 0;
|
||||
$sessionId = session_id() ?: null;
|
||||
|
||||
$ipAddress = $_SERVER['REMOTE_ADDR'] ?? null;
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 3. Grobe Auswertung aus dem Report (optional)
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
$modeRequested = $data['mode_requested'] ?? 'unknown';
|
||||
$meta = $data['meta'] ?? [];
|
||||
|
||||
// Browser/OS-Parsing kannst du später ergänzen
|
||||
$browserName = null;
|
||||
$browserVersion = null;
|
||||
$osName = null;
|
||||
$osVersion = null;
|
||||
|
||||
// Gesamtmenge geschriebener/verifizierter Bytes aggregieren
|
||||
$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);
|
||||
}
|
||||
|
||||
// Kapazitätsstatus vorerst neutral
|
||||
$capacityStatus = 'unknown';
|
||||
|
||||
// Volume-/Stick-Daten aktuell noch nicht separat:
|
||||
$volumeLabel = null;
|
||||
$manufacturer = null;
|
||||
$modelName = null;
|
||||
$usbType = null;
|
||||
$filesystem = null;
|
||||
|
||||
// advertised_capacity_bytes kennen wir im Browser noch nicht:
|
||||
$advCapacityBytes = null;
|
||||
|
||||
// test_report_json = kompletter Report
|
||||
$testReportJson = $raw; // direkt als JSON-String speichern
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 4. Insert in web_quicktests
|
||||
// ---------------------------------------------------------------------
|
||||
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,
|
||||
CAST(:test_report_json AS JSON),
|
||||
:ip_address,
|
||||
:session_id
|
||||
)
|
||||
";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
$stmt->execute([
|
||||
'user_id' => $userId,
|
||||
'is_logged_in' => $isLoggedIn,
|
||||
'usb_device_id' => null, // Browser-Test ist erstmal nicht an gespeicherten Stick gekoppelt
|
||||
'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,
|
||||
]);
|
||||
|
||||
$id = (int)$pdo->lastInsertId();
|
||||
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
'id' => $id,
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'ok' => false,
|
||||
'error' => 'DB error',
|
||||
// 'debug' => $e->getMessage(), // nur zum Debuggen aktivieren
|
||||
]);
|
||||
}
|
||||
316
api/v1/target/quickcheck.php
Normal file
316
api/v1/target/quickcheck.php
Normal file
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
// api/v1/quickcheck.php
|
||||
|
||||
/**
|
||||
* Diese Funktion wird von api/index.php aufgerufen.
|
||||
* Sie liest die Eingaben, prüft Seriennummer + VID, und gibt ein Array zurück,
|
||||
* das dann als JSON ausgegeben wird.
|
||||
*/
|
||||
function quickcheck_handle_request(): array
|
||||
{
|
||||
// JSON Body hat Priorität
|
||||
$source = quickcheck_get_input();
|
||||
|
||||
$vid = isset($source['vid']) ? trim((string)$source['vid']) : '';
|
||||
$pid = isset($source['pid']) ? trim((string)$source['pid']) : '';
|
||||
$manufacturer = isset($source['manufacturer']) ? trim((string)$source['manufacturer']) : '';
|
||||
$serial = isset($source['serial']) ? trim((string)$source['serial']) : '';
|
||||
|
||||
if ($serial === '') {
|
||||
http_response_code(400);
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Missing required parameter: serial',
|
||||
];
|
||||
}
|
||||
|
||||
// Mini-VID-Datenbank (kannst du später aus Datei/DB laden)
|
||||
$VID_DB = [
|
||||
'0781' => 'SanDisk Corp.',
|
||||
'0951' => 'Kingston Technology',
|
||||
'054C' => 'Sony Corp.',
|
||||
'1B1C' => 'Corsair',
|
||||
'13FE' => 'Phison Electronics',
|
||||
'8564' => 'Transcend Information, Inc.',
|
||||
'090C' => 'Silicon Motion, Inc.',
|
||||
'174C' => 'ASMedia Technology',
|
||||
'0BC2' => 'Seagate',
|
||||
// ... nach Bedarf ergänzen
|
||||
];
|
||||
|
||||
$vendorInfo = quickcheck_lookup_vendor($vid, $VID_DB);
|
||||
$serialAnalysis = quickcheck_analyze_serial($serial);
|
||||
$consistencyInfo = quickcheck_evaluate_consistency($vendorInfo['vendor'] ?? null, $manufacturer, $serialAnalysis);
|
||||
|
||||
// Gesamtrating
|
||||
$rating = 'ok';
|
||||
if ($serialAnalysis['category'] === 'invalid') {
|
||||
$rating = 'invalid';
|
||||
} elseif ($serialAnalysis['category'] === 'very_suspicious' || $consistencyInfo['manufacturer_match'] === 'mismatch') {
|
||||
$rating = 'suspicious';
|
||||
} elseif ($serialAnalysis['category'] === 'suspicious') {
|
||||
$rating = 'needs_review';
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'rating' => $rating,
|
||||
'input' => [
|
||||
'vid' => $vid,
|
||||
'pid' => $pid,
|
||||
'manufacturer' => $manufacturer,
|
||||
'serial' => $serial,
|
||||
],
|
||||
'vendor_detected' => $vendorInfo,
|
||||
'serial_analysis' => $serialAnalysis,
|
||||
'consistency' => $consistencyInfo,
|
||||
'messages' => [
|
||||
'de' => [
|
||||
'Hinweis: Diese Prüfung kann keine Echtheit garantieren, sondern bewertet nur Plausibilität und Auffälligkeiten.',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Eingaben lesen: JSON-Body > POST > GET
|
||||
*/
|
||||
function quickcheck_get_input(): array
|
||||
{
|
||||
$contentType = $_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? '';
|
||||
$contentType = strtolower(trim(explode(';', $contentType)[0]));
|
||||
|
||||
if ($contentType === 'application/json') {
|
||||
$raw = file_get_contents('php://input');
|
||||
if ($raw !== false && $raw !== '') {
|
||||
$data = json_decode($raw, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_POST)) {
|
||||
return $_POST;
|
||||
}
|
||||
if (!empty($_GET)) {
|
||||
return $_GET;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* VID normalisieren + Lookup
|
||||
*/
|
||||
function quickcheck_normalize_vid(string $vid): ?string
|
||||
{
|
||||
$vid = strtoupper(trim($vid));
|
||||
$vid = preg_replace('/^0X/i', '', $vid);
|
||||
if ($vid === '' || !preg_match('/^[0-9A-F]{1,4}$/', $vid)) {
|
||||
return null;
|
||||
}
|
||||
return str_pad($vid, 4, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
function quickcheck_lookup_vendor(?string $vid, array $VID_DB): array
|
||||
{
|
||||
if (!$vid) {
|
||||
return [
|
||||
'vid' => null,
|
||||
'found' => false,
|
||||
'vendor' => null,
|
||||
'confidence' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$norm = quickcheck_normalize_vid($vid);
|
||||
if (!$norm) {
|
||||
return [
|
||||
'vid' => $vid,
|
||||
'found' => false,
|
||||
'vendor' => null,
|
||||
'confidence' => 0,
|
||||
'issue' => 'Invalid VID format',
|
||||
];
|
||||
}
|
||||
|
||||
if (isset($VID_DB[$norm])) {
|
||||
return [
|
||||
'vid' => $norm,
|
||||
'found' => true,
|
||||
'vendor' => $VID_DB[$norm],
|
||||
'confidence' => 1.0,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'vid' => $norm,
|
||||
'found' => false,
|
||||
'vendor' => null,
|
||||
'confidence' => 0.2,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Seriennummer grob analysieren (Plausibilität)
|
||||
*/
|
||||
function quickcheck_analyze_serial(string $serial): array
|
||||
{
|
||||
$serial = trim($serial);
|
||||
$length = strlen($serial);
|
||||
$issues = [];
|
||||
$score = 100;
|
||||
|
||||
if ($length === 0) {
|
||||
return [
|
||||
'serial' => $serial,
|
||||
'length' => 0,
|
||||
'issues' => ['empty'],
|
||||
'score' => 0,
|
||||
'category' => 'invalid',
|
||||
];
|
||||
}
|
||||
|
||||
if ($length < 4) {
|
||||
$issues[] = 'too_short_critical';
|
||||
$score -= 60;
|
||||
} elseif ($length < 8) {
|
||||
$issues[] = 'short_suspicious';
|
||||
$score -= 30;
|
||||
}
|
||||
|
||||
if ($length > 32) {
|
||||
$issues[] = 'very_long';
|
||||
$score -= 10;
|
||||
}
|
||||
|
||||
if (quickcheck_is_all_same_char($serial)) {
|
||||
$issues[] = 'all_same_char';
|
||||
$score -= 50;
|
||||
}
|
||||
|
||||
$simplePatterns = [
|
||||
'000000', '00000000', '000000000000',
|
||||
'111111', '123456', '12345678', 'ABCDEF', 'AABBCC'
|
||||
];
|
||||
if (in_array(strtoupper($serial), $simplePatterns, true)) {
|
||||
$issues[] = 'simple_pattern';
|
||||
$score -= 40;
|
||||
}
|
||||
|
||||
if (quickcheck_is_simple_sequence($serial)) {
|
||||
$issues[] = 'sequence_pattern';
|
||||
$score -= 25;
|
||||
}
|
||||
|
||||
$isNumeric = preg_match('/^[0-9]+$/', $serial) === 1;
|
||||
$isAlpha = preg_match('/^[A-Za-z]+$/', $serial) === 1;
|
||||
$isHex = preg_match('/^[0-9A-Fa-f]+$/', $serial) === 1;
|
||||
$isAlnum = preg_match('/^[A-Za-z0-9]+$/', $serial) === 1;
|
||||
|
||||
if ($isNumeric) {
|
||||
$issues[] = 'numeric_only';
|
||||
$score -= 10;
|
||||
} elseif ($isAlpha) {
|
||||
$issues[] = 'letters_only';
|
||||
$score -= 10;
|
||||
}
|
||||
|
||||
if ($isHex && !$isNumeric && $length >= 8 && $length <= 24) {
|
||||
$issues[] = 'hex_pattern_plausible';
|
||||
$score += 5;
|
||||
}
|
||||
|
||||
if ($isAlnum && !$isNumeric && !$isAlpha && $length >= 8) {
|
||||
$issues[] = 'alnum_mixed_plausible';
|
||||
$score += 5;
|
||||
}
|
||||
|
||||
if ($score > 100) $score = 100;
|
||||
if ($score < 0) $score = 0;
|
||||
|
||||
if ($length === 0) {
|
||||
$category = 'invalid';
|
||||
} elseif ($score >= 80) {
|
||||
$category = 'plausible';
|
||||
} elseif ($score >= 50) {
|
||||
$category = 'suspicious';
|
||||
} else {
|
||||
$category = 'very_suspicious';
|
||||
}
|
||||
|
||||
return [
|
||||
'serial' => $serial,
|
||||
'length' => $length,
|
||||
'issues' => array_values(array_unique($issues)),
|
||||
'score' => $score,
|
||||
'category' => $category,
|
||||
];
|
||||
}
|
||||
|
||||
function quickcheck_is_all_same_char(string $s): bool
|
||||
{
|
||||
return strlen($s) > 1 && preg_match('/^(.)\1+$/', $s) === 1;
|
||||
}
|
||||
|
||||
function quickcheck_is_simple_sequence(string $s): bool
|
||||
{
|
||||
$seqs = [
|
||||
'123456', '1234567', '12345678', '234567', '345678',
|
||||
'ABCDEFG', 'ABCDEF', 'ABCDE'
|
||||
];
|
||||
$ls = strtoupper($s);
|
||||
foreach ($seqs as $pattern) {
|
||||
if (strpos($ls, $ls) !== false && strpos($ls, $pattern) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Herstellerangabe vs. Vendor-Name bewerten
|
||||
*/
|
||||
function quickcheck_evaluate_consistency(?string $vendorName, string $userManufacturer, array $serialAnalysis): array
|
||||
{
|
||||
$vendorName = $vendorName ? trim($vendorName) : '';
|
||||
$userManufacturer = trim($userManufacturer);
|
||||
|
||||
$matchStatus = 'unknown';
|
||||
$notes = [];
|
||||
|
||||
if ($vendorName !== '' && $userManufacturer !== '') {
|
||||
$v = mb_strtolower($vendorName);
|
||||
$u = mb_strtolower($userManufacturer);
|
||||
|
||||
if (strpos($v, $u) !== false || strpos($u, $v) !== false) {
|
||||
$matchStatus = 'match';
|
||||
$notes[] = 'Herstellerangabe passt zur ermittelten Vendor-ID.';
|
||||
} else {
|
||||
$matchStatus = 'mismatch';
|
||||
$notes[] = 'Herstellerangabe weicht von der Vendor-ID ab.';
|
||||
}
|
||||
} elseif ($vendorName !== '') {
|
||||
$notes[] = 'Hersteller über Vendor-ID bekannt, aber keine Herstellerangabe des Nutzers.';
|
||||
} elseif ($userManufacturer !== '') {
|
||||
$notes[] = 'Hersteller vom Nutzer angegeben, aber keine oder unbekannte Vendor-ID.';
|
||||
} else {
|
||||
$notes[] = 'Keine Herstellerinformationen vorhanden.';
|
||||
}
|
||||
|
||||
$ratingHint = 'neutral';
|
||||
if ($serialAnalysis['category'] === 'very_suspicious' || $matchStatus === 'mismatch') {
|
||||
$ratingHint = 'suspicious';
|
||||
} elseif ($serialAnalysis['category'] === 'plausible' && $matchStatus === 'match') {
|
||||
$ratingHint = 'good';
|
||||
}
|
||||
|
||||
return [
|
||||
'manufacturer_match' => $matchStatus,
|
||||
'notes' => $notes,
|
||||
'consistency_hint' => $ratingHint,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user