This commit is contained in:
2026-07-21 23:39:19 +02:00
commit b33b217bdb
217 changed files with 32076 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
<?php
namespace App\Livewire\Admin;
use App\Models\ApiClient;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Computed;
use Livewire\Component;
class ApiKeys extends Component
{
public bool $formOpen = false;
public array $form = ['name' => '', 'description' => '', 'abilities' => []];
/**
* Only ever populated right after createToken() the plaintext secret
* is never stored anywhere (Sanctum only keeps the hash), so this is the
* one and only chance to show it. Cleared on every other action so a
* page refresh or subsequent click never brings it back.
*/
public ?string $newTokenPlaintext = null;
public ?string $newTokenClientName = null;
public static function availableAbilities(): array
{
return [
'tickets:read' => 'Odczyt zgłoszeń',
'tickets:write' => 'Zapis zgłoszeń (tworzenie, aktualizacja, wiadomości)',
'dictionaries:read' => 'Odczyt słowników (kategorie, statusy, priorytety, zespoły)',
'users:read' => 'Odczyt użytkowników',
];
}
#[Computed]
public function apiClients(): Collection
{
return ApiClient::query()
->with(['tokens' => fn ($q) => $q->latest()])
->orderByDesc('created_at')
->get();
}
public function openForm(): void
{
$this->reset('form');
$this->newTokenPlaintext = null;
$this->newTokenClientName = null;
$this->resetErrorBag();
$this->formOpen = true;
}
public function closeForm(): void
{
$this->formOpen = false;
}
public function submit(): void
{
$this->validate([
'form.name' => ['required', 'string', 'max:255'],
'form.description' => ['nullable', 'string', 'max:1000'],
'form.abilities' => ['required', 'array', 'min:1'],
'form.abilities.*' => ['string', 'in:'.implode(',', array_keys(static::availableAbilities()))],
]);
$client = ApiClient::query()->create([
'name' => $this->form['name'],
'description' => $this->form['description'] ?: null,
'created_by' => Auth::id(),
]);
$token = $client->createToken($this->form['name'], $this->form['abilities']);
$this->newTokenPlaintext = $token->plainTextToken;
$this->newTokenClientName = $client->name;
$this->formOpen = false;
unset($this->apiClients);
}
public function revoke(int $apiClientId): void
{
$this->newTokenPlaintext = null;
$this->newTokenClientName = null;
$client = ApiClient::query()->findOrFail($apiClientId);
$client->tokens()->delete();
$client->update(['revoked_at' => now()]);
unset($this->apiClients);
}
public function regenerate(int $apiClientId): void
{
$client = ApiClient::query()->findOrFail($apiClientId);
$abilities = $client->tokens()->latest()->first()?->abilities ?? [];
$client->tokens()->delete();
$token = $client->createToken($client->name, $abilities);
$client->update(['revoked_at' => null]);
$this->newTokenPlaintext = $token->plainTextToken;
$this->newTokenClientName = $client->name;
unset($this->apiClients);
}
public function dismissNewToken(): void
{
$this->newTokenPlaintext = null;
$this->newTokenClientName = null;
}
public function render()
{
return view('livewire.admin.api-keys');
}
}

File diff suppressed because it is too large Load Diff