Skip to content

Commit

Permalink
fix: Api token manager
Browse files Browse the repository at this point in the history
  • Loading branch information
lewislarsen committed Aug 9, 2024
1 parent 0a27076 commit f668843
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 38 deletions.
81 changes: 45 additions & 36 deletions app/Livewire/Profile/APITokenManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

use App\Models\User;
use App\Services\SanctumAbilitiesService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Laravel\Sanctum\NewAccessToken;
use Laravel\Sanctum\PersonalAccessToken;
use Livewire\Component;
use Masmerise\Toaster\Toaster;

Expand All @@ -20,8 +21,6 @@
*
* This component handles the creation, deletion, and viewing of API tokens,
* as well as managing the abilities associated with each token.
*
* @property-read User|Authenticatable $user
*/
class APITokenManager extends Component
{
Expand All @@ -31,7 +30,7 @@ class APITokenManager extends Component
/** @var array<string, bool> The abilities for the new API token */
public array $abilities = [];

/** @var array<string, bool> The list of possible abilities */
/** @var array<string, array<string, array<string, string>>> The list of possible abilities */
public array $availableAbilities = [];

/** @var string|null The plain text value of the newly created token */
Expand All @@ -46,6 +45,9 @@ class APITokenManager extends Component
/** @var int|null The ID of the token whose abilities are being viewed */
public ?int $viewingTokenId = null;

/** @var Collection<int|string, PersonalAccessToken> The user's tokens */
public Collection $tokens;

/** @var SanctumAbilitiesService Service for managing Sanctum abilities */
private SanctumAbilitiesService $abilitiesService;

Expand All @@ -62,8 +64,12 @@ public function boot(SanctumAbilitiesService $sanctumAbilitiesService): void
*/
public function mount(): void
{
/* @phpstan-ignore-next-line */
$this->tokens = new Collection;
$this->resetAbilities();
$this->initializeExpandedGroups();
$this->availableAbilities = $this->abilitiesService->getAbilities();
$this->loadTokens();
}

/**
Expand Down Expand Up @@ -96,17 +102,21 @@ public function createApiToken(): void

$selectedAbilities = array_keys(array_filter($validated['abilities']));

$token = $this->user->createToken(
/** @var User $user */
$user = Auth::user();

$newAccessToken = $user->createToken(
$validated['name'],
$selectedAbilities
);

$this->displayTokenValue($token);
$this->displayTokenValue($newAccessToken);

Toaster::success('API Token has been created.');

$this->reset('name');
$this->resetAbilities();
$this->loadTokens();

$this->dispatch('created');
}
Expand All @@ -129,12 +139,15 @@ public function deleteApiToken(): void
return;
}

$this->user->tokens()->where('id', $this->apiTokenIdBeingDeleted)->delete();
/** @var User $user */
$user = Auth::user();

$user->tokens()->where('id', $this->apiTokenIdBeingDeleted)->delete();

Toaster::success('API Token has been revoked.');

$this->reset('apiTokenIdBeingDeleted');
$this->user->load('tokens');
$this->loadTokens();
$this->dispatch('close-modal', 'confirm-api-token-deletion');
}

Expand All @@ -147,45 +160,21 @@ public function viewTokenAbilities(int $tokenId): void
$this->dispatch('open-modal', 'view-token-abilities');
}

/**
* Get the authenticated user
*/
public function getUserProperty(): Authenticatable|User
{
/** @var User $user */
$user = Auth::user();

return $user;
}

/**
* Render the component.
*/
public function render(): View
{
$availableAbilities = $this->abilitiesService->getAbilities();
$tokens = $this->user->tokens()->latest()->get();

// Log the number of available abilities and tokens
Log::debug('APITokenManager rendering', [
'abilitiesCount' => count($availableAbilities),
'tokensCount' => $tokens->count(),
'abilitiesCount' => count($this->availableAbilities),
'tokensCount' => $this->tokens->count(),
]);

if ($availableAbilities === []) {
if ($this->availableAbilities === []) {
Log::warning('No abilities available in APITokenManager');
}

// Log a sample of abilities (first 3) if available
if ($availableAbilities !== []) {
$sampleAbilities = array_slice($availableAbilities, 0, 3, true);
Log::debug('Sample abilities', ['sample' => $sampleAbilities]);
}

return view('livewire.profile.api-token-manager', [
'availableAbilities' => $availableAbilities,
'tokens' => $tokens,
]);
return view('livewire.profile.api-token-manager');
}

/**
Expand Down Expand Up @@ -250,4 +239,24 @@ private function initializeExpandedGroups(): void
{
$this->expandedGroups = array_fill_keys(array_keys($this->abilitiesService->getAbilities()), false);
}

/**
* Load the user's tokens.
*/
private function loadTokens(): void
{
/** @var User $user */
$user = Auth::user();

$tokens = $user->tokens()->latest()->get();

/** @var Collection<int|string, PersonalAccessToken> $personalAccessTokens */
$personalAccessTokens = $tokens->map(function ($token): PersonalAccessToken {
return $token instanceof PersonalAccessToken
? $token
: new PersonalAccessToken($token->getAttributes());
});

$this->tokens = $personalAccessTokens;
}
}
4 changes: 2 additions & 2 deletions resources/views/livewire/profile/api-token-manager.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class="absolute left-0 bottom-full mb-2 w-48 bg-gray-800 text-white text-xs roun
</div>
</x-modal>

@if ($this->user->tokens->count() === 0)
@if ($this->tokens->isEmpty())
<x-no-content withBackground>
<x-slot name="icon">
@svg('heroicon-o-key', 'h-16 w-16 text-primary-900 dark:text-white inline')
Expand Down Expand Up @@ -182,7 +182,7 @@ class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
@foreach ($tokens as $token)
@foreach ($this->tokens as $token)
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
{{ $token->name }}
Expand Down

0 comments on commit f668843

Please sign in to comment.