feat(license): implement Hardware-ID v2, multi-platform Linux support, StateStore LLS2 hardening, and AI Agent docs

This commit is contained in:
Deploymentcenter Bot
2026-08-06 11:39:21 +02:00
parent e9dbe793e2
commit 70b35f7b8b
16 changed files with 1602 additions and 41 deletions
+68 -9
View File
@@ -15,12 +15,16 @@ class LicenseService
public function validate(array $requestData, string $clientIp): array
{
$productSlug = trim($requestData['product'] ?? '');
$licenseKey = trim($requestData['license_key'] ?? '');
$hardwareId = trim($requestData['hardware_id'] ?? '');
$nonce = trim($requestData['nonce'] ?? '');
$hostname = trim($requestData['hostname'] ?? '');
$appVersion = trim($requestData['app_version'] ?? '');
$productSlug = trim($requestData['product'] ?? '');
$licenseKey = trim($requestData['license_key'] ?? '');
$hardwareId = trim($requestData['hardware_id'] ?? '');
$legacyHardwareId = trim($requestData['legacy_hardware_id'] ?? '');
$hwidVersion = (int)($requestData['hwid_version'] ?? 1);
$hwidSource = trim($requestData['hwid_source'] ?? '') ?: null;
$platform = trim($requestData['platform'] ?? '') ?: null;
$nonce = trim($requestData['nonce'] ?? '');
$hostname = trim($requestData['hostname'] ?? '');
$appVersion = trim($requestData['app_version'] ?? '');
$issuedAt = time();
$endpoints = $this->getEndpoints();
@@ -96,10 +100,47 @@ class LicenseService
}
// 4. Activation management
// 4.1 Try match by hardware_id (v2)
$stmt = $this->db->prepare('SELECT * FROM license_activations WHERE license_id = :lic_id AND hardware_id = :hw_id');
$stmt->execute([':lic_id' => $license['id'], ':hw_id' => $hardwareId]);
$activation = $stmt->fetch();
// 4.2 If not found by v2 hardware_id, try migration matching by legacy_hardware_id (v1)
if (!$activation && !empty($legacyHardwareId)) {
$legStmt = $this->db->prepare('SELECT * FROM license_activations WHERE license_id = :lic_id AND hardware_id = :legacy_hw_id');
$legStmt->execute([':lic_id' => $license['id'], ':legacy_hw_id' => $legacyHardwareId]);
$legacyActivation = $legStmt->fetch();
if ($legacyActivation) {
// Migrate activation to v2 format
$migUpd = $this->db->prepare('
UPDATE license_activations
SET hardware_id = :hw_id, hwid_version = :ver, hwid_source = :src, platform = :plat, last_seen = NOW(), hostname = :host, app_version = :app_ver
WHERE id = :id
');
$migUpd->execute([
':hw_id' => $hardwareId,
':ver' => $hwidVersion,
':src' => $hwidSource,
':plat' => $platform,
':host' => $hostname,
':app_ver' => $appVersion,
':id' => $legacyActivation['id']
]);
Audit::log($this->db, 'api', 'hwid_migrated', [
'license_id' => $license['id'],
'old_hardware_id' => $legacyHardwareId,
'new_hardware_id' => $hardwareId,
'hwid_source' => $hwidSource,
'platform' => $platform,
'ip' => $clientIp
]);
$activation = $legacyActivation;
}
}
if ($activation) {
if ((int)$activation['is_blocked'] === 1) {
return $makePayload('revoked', [
@@ -107,8 +148,20 @@ class LicenseService
'message' => 'This hardware activation is blocked'
]);
}
$upd = $this->db->prepare('UPDATE license_activations SET last_seen = NOW(), hostname = :host, app_version = :ver WHERE id = :id');
$upd->execute([':host' => $hostname, ':ver' => $appVersion, ':id' => $activation['id']]);
$upd = $this->db->prepare('
UPDATE license_activations
SET last_seen = NOW(), hostname = :host, app_version = :ver, hwid_version = :hw_ver,
hwid_source = COALESCE(:hw_src, hwid_source), platform = COALESCE(:plat, platform)
WHERE id = :id
');
$upd->execute([
':host' => $hostname,
':ver' => $appVersion,
':hw_ver' => $hwidVersion,
':hw_src' => $hwidSource,
':plat' => $platform,
':id' => $activation['id']
]);
} else {
$cntStmt = $this->db->prepare('SELECT COUNT(*) FROM license_activations WHERE license_id = :lic_id AND is_blocked = 0');
$cntStmt->execute([':lic_id' => $license['id']]);
@@ -121,10 +174,16 @@ class LicenseService
]);
}
$ins = $this->db->prepare('INSERT INTO license_activations (license_id, hardware_id, hostname, app_version) VALUES (:lic_id, :hw_id, :host, :ver)');
$ins = $this->db->prepare('
INSERT INTO license_activations (license_id, hardware_id, hwid_version, hwid_source, platform, hostname, app_version)
VALUES (:lic_id, :hw_id, :hw_ver, :hw_src, :plat, :host, :ver)
');
$ins->execute([
':lic_id' => $license['id'],
':hw_id' => $hardwareId,
':hw_ver' => $hwidVersion,
':hw_src' => $hwidSource,
':plat' => $platform,
':host' => $hostname,
':ver' => $appVersion
]);