54 lines
3.3 KiB
PHP
54 lines
3.3 KiB
PHP
<?php
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\License;
|
|
use App\Models\LicenseActivation;
|
|
use App\Services\Licensing\LicenseKey;
|
|
use App\Services\Licensing\LicenseSigner;
|
|
use App\Services\Licensing\LicenseTokenVerifier;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
final class LicenseActivationController extends Controller
|
|
{
|
|
public function activate(Request $request, LicenseSigner $signer): JsonResponse
|
|
{
|
|
$data = $request->validate([
|
|
'licenseKey'=>['required','string','max:128'],
|
|
'installationID'=>['required','uuid'],
|
|
'appVersion'=>['required','string','max:32'],
|
|
'platform'=>['required','string','max:32'],
|
|
]);
|
|
|
|
return DB::transaction(function () use ($data,$signer) {
|
|
$license = License::where('license_key_hash', LicenseKey::hash($data['licenseKey']))->lockForUpdate()->first();
|
|
if (!$license) throw ValidationException::withMessages(['licenseKey'=>'The licence key is not valid.']);
|
|
if (!$license->is_usable) return response()->json(['message'=>'This licence is expired or has been revoked.'], 403);
|
|
|
|
$activation = LicenseActivation::where('license_id',$license->id)->where('installation_id',strtolower($data['installationID']))->first();
|
|
if ($activation && $activation->deactivated_at === null) {
|
|
$activation->update(['last_seen_at'=>now(),'platform'=>$data['platform'],'app_version'=>$data['appVersion']]);
|
|
} else {
|
|
$activeCount = LicenseActivation::where('license_id',$license->id)->whereNull('deactivated_at')->count();
|
|
if ($activeCount >= $license->activation_limit) return response()->json(['message'=>'This licence has reached its activation limit. Deactivate another Mac first.'], 409);
|
|
if ($activation) $activation->update(['deactivated_at'=>null,'activated_at'=>now(),'last_seen_at'=>now(),'platform'=>$data['platform'],'app_version'=>$data['appVersion']]);
|
|
else LicenseActivation::create(['license_id'=>$license->id,'installation_id'=>strtolower($data['installationID']),'platform'=>$data['platform'],'app_version'=>$data['appVersion'],'activated_at'=>now(),'last_seen_at'=>now()]);
|
|
}
|
|
return response()->json(['licenseToken'=>$signer->sign($license, $data['installationID'])]);
|
|
});
|
|
}
|
|
|
|
public function deactivate(Request $request, LicenseTokenVerifier $verifier): JsonResponse
|
|
{
|
|
$data = $request->validate(['licenseToken'=>['required','string','max:8192'],'installationID'=>['required','uuid']]);
|
|
try { $payload = $verifier->verify($data['licenseToken']); }
|
|
catch (\Throwable) { return response()->json(['message'=>'The licence token is invalid.'], 400); }
|
|
if (strcasecmp((string)($payload['installationID'] ?? ''), $data['installationID']) !== 0) return response()->json(['message'=>'The installation does not match this licence token.'], 400);
|
|
LicenseActivation::where('license_id',(string)($payload['licenseID'] ?? ''))->where('installation_id',strtolower($data['installationID']))->whereNull('deactivated_at')->update(['deactivated_at'=>now(),'last_seen_at'=>now()]);
|
|
return response()->json((object)[]);
|
|
}
|
|
}
|