Files
Tarnax/appstore/website/app/Services/LicenseService.php
T
2026-11-04 16:47:55 +00:00

35 lines
2.2 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Str;
class LicenseService {
public function issue(int $userId,int $purchaseId): void {
if(DB::table('licenses')->where('purchase_id',$purchaseId)->exists()){return;}
$key='TNX-'.Str::upper(bin2hex(random_bytes(20)));
DB::table('licenses')->insert(['user_id'=>$userId,'purchase_id'=>$purchaseId,'key_hash'=>hash('sha256',$key),'key_encrypted'=>Crypt::encryptString($key),'status'=>'active','device_limit'=>2,'created_at'=>now(),'updated_at'=>now()]);
}
public function activate(string $key,string $device): array {
return DB::transaction(function()use($key,$device){
$license=DB::table('licenses')->where('key_hash',hash('sha256',$key))->lockForUpdate()->first();
abort_unless($license && $license->status==='active',403,'Invalid or revoked license.');
$deviceHash=hash('sha256',$device);$existing=DB::table('activations')->where('license_id',$license->id)->where('device_hash',$deviceHash)->first();
abort_if(!$existing && DB::table('activations')->where('license_id',$license->id)->count()>=$license->device_limit,409,'Device limit reached.');
$token=bin2hex(random_bytes(32));
DB::table('activations')->updateOrInsert(['license_id'=>$license->id,'device_hash'=>$deviceHash],['token_hash'=>hash('sha256',$token),'last_seen_at'=>now(),'created_at'=>now(),'updated_at'=>now()]);
return ['activation_token'=>$token,'valid'=>true,'check_again_in'=>86400];
},3);
}
public function check(string $token,bool $deactivate=false): array {
return DB::transaction(function()use($token,$deactivate){
$activation=DB::table('activations')->where('token_hash',hash('sha256',$token))->first();
abort_unless($activation,403,'Invalid activation.');
$license=DB::table('licenses')->where('id',$activation->license_id)->lockForUpdate()->first();
if($deactivate){DB::table('activations')->where('id',$activation->id)->delete();return ['deactivated'=>true];}
abort_unless($license->status==='active',403,'License revoked.');
DB::table('activations')->where('id',$activation->id)->update(['last_seen_at'=>now()]);
return ['valid'=>true,'check_again_in'=>86400];
},3);
}
}