feat(license): implement Hardware-ID v2, multi-platform Linux support, StateStore LLS2 hardening, and AI Agent docs
This commit is contained in:
@@ -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
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user