some work on the license manager

This commit is contained in:
2026-07-10 16:55:48 +02:00
parent af80c7d582
commit 4a15f1e351
9 changed files with 736 additions and 624 deletions
+41 -30
View File
@@ -109,7 +109,7 @@ protected function getApplicationKeyPair(): array
* @param string $privateKey The private key to use for signing
* @return string
*/
protected function generateSignature($licenseData, $privateKey)
protected function sign($licenseData, $privateKey)
{
$licenseJson = json_encode($licenseData);
if ($licenseJson === false) throw new \Exception('Fehler beim JSON-Encode der Lizenzdaten: ' . json_last_error_msg());
@@ -155,7 +155,7 @@ public function store(Request $request)
'expiration_date' => $snakeCaseData['expiration_date'],
];
$signature = $this->generateSignature($licenseData, $keyPair['privateKey']);
$signature = $this->sign($licenseData, $keyPair['privateKey']);
$license = License::create([
'name' => $snakeCaseData['name'],
@@ -170,51 +170,62 @@ public function store(Request $request)
return ApiDataTransformer::snakeToCamel($license->toArray());
}
/**
* Validate the license signature and expiration date.
*
* @param \Illuminate\Http\Request $request The HTTP request containing the license data
* @return array
*/
public function validate(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|string',
'email' => 'required|email',
'product' => 'required|string',
'version' => 'required|string',
'isPerpetual' => 'required|boolean',
'expirationDate' => 'nullable|date',
'signature' => 'required|string',
]);
return $this->isValid(ApiDataTransformer::camelToSnake($validatedData));
}
/**
* Validate the license signature and expiration date.
*
* The validation logic should be portable to other languages.
*
* @param \Illuminate\Http\Request $request The HTTP request containing the license ID
* @param array $licenseData The license data to validate
* @return array
*/
public function validate(Request $request)
protected function isValid(array $licenseData)
{
// Get the license ID from the request
$licenseId = $request->input('license_id');
// Find the license
$license = License::findOrFail($licenseId);
$publicKey = Storage::disk('local')->get($this->publicKeyPath());
$licenseData = [
'name' => $license->name,
'email' => $license->email,
'product' => $license->product,
'version' => $license->version,
'is_perpetual' => $license->is_perpetual,
'expiration_date' => $license->expiration_date,
];
// Convert the license data to JSON
$licenseJson = json_encode($licenseData);
// Verify the signature
$signature = base64_decode($license->signature);
$signature = base64_decode($licenseData['signature']);
$isSignatureValid = openssl_verify($licenseJson, $signature, $publicKey, OPENSSL_ALGO_SHA256);
// Check the expiration date if the license is not perpetual
$isExpired = false;
if (!$license->is_perpetual && $license->expiration_date) {
$isExpired = now()->gt($license->expiration_date);
if (!$licenseData['is_perpetual'] && $licenseData['expiration_date']) {
$isExpired = now()->gt($licenseData['expiration_date']);
}
// Return the validation result
// Return the validation info
return [
'is_valid' => $isSignatureValid === 1 && !$isExpired,
'is_signature_valid' => $isSignatureValid === 1,
'is_expired' => $isExpired,
'isValid' => $isSignatureValid === 1 && !$isExpired,
'isSignatureValid' => $isSignatureValid === 1,
'isExpired' => $isExpired,
];
}
@@ -246,7 +257,7 @@ public function download(int $id)
// Create a response with the JSON file
$response = response($licenseJson, 200, [
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename="' . $licenseData['product'] . '.json"',
'Content-Disposition' => 'attachment; filename="' . $licenseData['product'] . '.license"',
]);
return $response;
@@ -296,7 +307,7 @@ public function update(Request $request, int $id)
];
// Generate the signature
$signature = $this->generateSignature($licenseData, $privateKey);
$signature = $this->sign($licenseData, $privateKey);
// Update the license
$license->update([