Skip to content

Commit a919ad1

Browse files
authored
[Feature] Add API Tokens management page (alexjustesen#1960)
1 parent 7199891 commit a919ad1

File tree

4 files changed

+211
-1
lines changed

4 files changed

+211
-1
lines changed

app/Filament/Pages/ApiTokens.php

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<?php
2+
3+
namespace App\Filament\Pages;
4+
5+
use Carbon\Carbon;
6+
use Filament\Forms\Components\CheckboxList;
7+
use Filament\Forms\Components\DateTimePicker;
8+
use Filament\Forms\Components\TextInput;
9+
use Filament\Forms\Concerns\InteractsWithForms;
10+
use Filament\Forms\Contracts\HasForms;
11+
use Filament\Infolists\Components\Section;
12+
use Filament\Infolists\Components\TextEntry;
13+
use Filament\Infolists\Concerns\InteractsWithInfolists;
14+
use Filament\Infolists\Contracts\HasInfolists;
15+
use Filament\Infolists\Infolist;
16+
use Filament\Pages\Page;
17+
use Filament\Support\Enums\FontFamily;
18+
use Filament\Support\Enums\MaxWidth;
19+
use Filament\Tables\Actions\Action;
20+
use Filament\Tables\Actions\ActionGroup;
21+
use Filament\Tables\Actions\DeleteAction;
22+
use Filament\Tables\Columns\TextColumn;
23+
use Filament\Tables\Concerns\InteractsWithTable;
24+
use Filament\Tables\Contracts\HasTable;
25+
use Filament\Tables\Table;
26+
use Illuminate\Database\Eloquent\Relations\MorphMany;
27+
use Illuminate\Support\Facades\Auth;
28+
use Illuminate\Support\HtmlString;
29+
30+
class ApiTokens extends Page implements HasForms, HasInfolists, HasTable
31+
{
32+
use InteractsWithForms, InteractsWithInfolists, InteractsWithTable;
33+
34+
protected static ?string $navigationIcon = 'tabler-api';
35+
36+
protected static string $view = 'filament.pages.api-tokens';
37+
38+
protected static ?string $title = 'API Tokens';
39+
40+
protected static ?string $navigationGroup = 'Settings';
41+
42+
protected static ?int $navigationSort = 5;
43+
44+
public ?string $token = '';
45+
46+
public static function canAccess(): bool
47+
{
48+
return Auth::user()->is_admin;
49+
}
50+
51+
public function tokenInfolist(Infolist $infolist): Infolist
52+
{
53+
return $infolist
54+
->state([
55+
'token' => $this->token,
56+
])
57+
->schema([
58+
Section::make()
59+
->columns(1)
60+
->schema([
61+
TextEntry::make('token')
62+
->label('API Token')
63+
->formatStateUsing(fn (string $state) => explode('|', $state)[1])
64+
->helperText('Copy and save the token above, this token will not be shown again!')
65+
->color('gray')
66+
->copyable()
67+
->copyableState(fn (string $state) => explode('|', $state)[1])
68+
->fontFamily(FontFamily::Mono),
69+
]),
70+
]);
71+
}
72+
73+
public function table(Table $table): Table
74+
{
75+
return $table
76+
->relationship(fn (): MorphMany => Auth::user()->tokens())
77+
->headerActions([
78+
Action::make('createToken')
79+
->form([
80+
TextInput::make('token_name')
81+
->label('Name')
82+
->maxLength('100')
83+
->required(),
84+
CheckboxList::make('token_abilities')
85+
->label('Abilities')
86+
->options([
87+
'result:read' => 'Read results',
88+
])
89+
->descriptions([
90+
'result:read' => new HtmlString('Allow the token to retrieve result data.'),
91+
])
92+
->required()
93+
->bulkToggleable(),
94+
DateTimePicker::make('token_expires_at')
95+
->label('Expires at')
96+
->nullable(),
97+
])
98+
->action(function (array $data) {
99+
$token = Auth::user()->createToken(
100+
name: $data['token_name'],
101+
abilities: $data['token_abilities'],
102+
expiresAt: $data['token_expires_at'] ? Carbon::parse($data['token_expires_at']) : null,
103+
);
104+
105+
$this->token = $token->plainTextToken;
106+
})
107+
->label('Create API Token')
108+
->modal('createToken')
109+
->modalWidth(MaxWidth::ExtraLarge),
110+
])
111+
->columns([
112+
TextColumn::make('id')
113+
->label('ID')
114+
->sortable(),
115+
TextColumn::make('name')
116+
->searchable(),
117+
TextColumn::make('last_used_at')
118+
->alignEnd()
119+
->dateTime()
120+
->sortable(),
121+
TextColumn::make('expires_at')
122+
->alignEnd()
123+
->dateTime()
124+
->sortable(),
125+
])
126+
->actions([
127+
ActionGroup::make([
128+
DeleteAction::make(),
129+
]),
130+
])
131+
->bulkActions([
132+
// ...
133+
]);
134+
}
135+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"livewire/livewire": "^3.5.17",
3232
"lorisleiva/laravel-actions": "^2.8.4",
3333
"maennchen/zipstream-php": "^2.4",
34+
"ryangjchandler/blade-tabler-icons": "^2.3",
3435
"spatie/laravel-settings": "^3.4",
3536
"spatie/laravel-webhook-server": "^3.8.2",
3637
"timokoerber/laravel-one-time-operations": "^1.4.4"

composer.lock

Lines changed: 64 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<x-filament-panels::page>
2+
@filled($token)
3+
<div>
4+
{{ $this->tokenInfolist }}
5+
</div>
6+
@endfilled
7+
8+
<div>
9+
{{ $this->table }}
10+
</div>
11+
</x-filament-panels::page>

0 commit comments

Comments
 (0)