Admin: Add ability to mange access tokens and manually create tokens
This commit is contained in:
parent
b412ad3fca
commit
d9177b9435
58
app/Livewire/RegistrationToken.php
Normal file
58
app/Livewire/RegistrationToken.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Services\SynapseService;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class RegistrationToken extends Component
|
||||
{
|
||||
public $tokens = [];
|
||||
|
||||
public $registrationToken;
|
||||
|
||||
protected SynapseService $synapseService;
|
||||
|
||||
public function boot(SynapseService $synapseService)
|
||||
{
|
||||
$this->synapseService = $synapseService;
|
||||
}
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->fetchTokens();
|
||||
}
|
||||
|
||||
public function fetchTokens()
|
||||
{
|
||||
$this->tokens = $this->synapseService->fetchTokens();
|
||||
}
|
||||
|
||||
public function revokeToken(string $token)
|
||||
{
|
||||
if ($this->synapseService->revokeToken($token)) {
|
||||
$this->fetchTokens();
|
||||
}
|
||||
}
|
||||
|
||||
public function createToken()
|
||||
{
|
||||
$this->registrationToken = $this->synapseService->createRegistrationToken();
|
||||
|
||||
// Open modal
|
||||
$this->modal('registration-token')->show();
|
||||
}
|
||||
|
||||
public function resetToken()
|
||||
{
|
||||
$this->registrationToken = null;
|
||||
$this->fetchTokens();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.registration-token');
|
||||
}
|
||||
}
|
@ -9,15 +9,24 @@ use Illuminate\Support\Facades\Log;
|
||||
|
||||
class SynapseService
|
||||
{
|
||||
protected string $AUTH_TOKEN;
|
||||
protected string $SYNAPSE_ENDPOINT;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->AUTH_TOKEN = Settings::get('synapse_access_token', '');
|
||||
$this->SYNAPSE_ENDPOINT = Settings::get('synapse_endpoint', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create registration token
|
||||
*/
|
||||
public function createRegistrationToken(): ?string
|
||||
{
|
||||
$token = Settings::get('synapse_access_token', '');
|
||||
$endpoint = Settings::get('synapse_endpoint', '');
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => "Bearer $token",
|
||||
'Authorization' => "Bearer $this->AUTH_TOKEN",
|
||||
'Content-Type' => 'application/json'
|
||||
])->post($endpoint . '/_synapse/admin/v1/registration_tokens/new', [
|
||||
])->post("$this->SYNAPSE_ENDPOINT/_synapse/admin/v1/registration_tokens/new", [
|
||||
'uses_allowed' => 1,
|
||||
'length' => 12,
|
||||
'expiry_time' => now()->addWeek()->valueOf(),
|
||||
@ -34,4 +43,34 @@ class SynapseService
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all active registration tokens from Synapse
|
||||
*/
|
||||
public function fetchTokens(): ?array
|
||||
{
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => "Bearer $this->AUTH_TOKEN",
|
||||
'Content-Type' => 'application/json'
|
||||
])->get("$this->SYNAPSE_ENDPOINT/_synapse/admin/v1/registration_tokens?valid=true");
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json()['registration_tokens'] ?? [];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke registration token
|
||||
*/
|
||||
public function revokeToken(string $token): ?bool
|
||||
{
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => "Bearer $this->AUTH_TOKEN",
|
||||
'Content-Type' => 'application/json'
|
||||
])->delete("$this->SYNAPSE_ENDPOINT/_synapse/admin/v1/registration_tokens/$token");
|
||||
|
||||
return $response->successful();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
<flux:navlist variant="outline">
|
||||
<flux:navlist.group :heading="__('Platform')" class="grid">
|
||||
<flux:navlist.item icon="document-text" :href="route('dashboard')" :current="request()->routeIs('dashboard')" wire:navigate>{{ __('Applications') }}</flux:navlist.item>
|
||||
<flux:navlist.item icon="key" :href="route('registration.tokens')" :current="request()->routeIs('registration.tokens')" wire:navigate>{{ __('Tokens') }}</flux:navlist.item>
|
||||
<flux:navlist.item icon="wrench-screwdriver" :href="route('settings.synapse')" :current="request()->routeIs('settings.synapse')" wire:navigate>{{ __('Synapse') }}</flux:navlist.item>
|
||||
</flux:navlist.group>
|
||||
</flux:navlist>
|
||||
|
66
resources/views/livewire/registration-token.blade.php
Normal file
66
resources/views/livewire/registration-token.blade.php
Normal file
@ -0,0 +1,66 @@
|
||||
<div class="flex items-start max-md:flex-col">
|
||||
|
||||
<div class="flex-1 self-stretch max-md:pt-6">
|
||||
<div class="relative mb-6 w-full">
|
||||
<flux:heading size="xl" level="1">{{ __('Registration Tokens') }}</flux:heading>
|
||||
<flux:subheading size="lg" class="mb-6">{{ __('Manage matrix registration tokens') }}
|
||||
</flux:subheading>
|
||||
<flux:separator variant="subtle" />
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end pb-5">
|
||||
<flux:button wire:click="createToken">Create token</flux:button>
|
||||
</div>
|
||||
|
||||
<flux:modal name="registration-token" wire:close="resetToken" class="md:w-96">
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<flux:heading size="lg">Registration token</flux:heading>
|
||||
</div>
|
||||
|
||||
<flux:input class="mb-2" icon="key" value="{{ $registrationToken }}" readonly copyable />
|
||||
</div>
|
||||
</flux:modal>
|
||||
|
||||
<div class="bg-white dark:bg-zinc-900 shadow-md rounded-lg overflow-hidden">
|
||||
<table class="min-w-full text-sm text-left text-zinc-700 dark:text-zinc-300">
|
||||
<thead class="bg-zinc-100 dark:bg-zinc-950 text-xs uppercase text-zinc-500 dark:text-zinc-400">
|
||||
<tr>
|
||||
<th class="px-4 py-2 text-left hidden md:block">Token</th>
|
||||
<th class="px-4 py-2">Uses allowed</th>
|
||||
<th class="px-4 py-2">Pending</th>
|
||||
<th class="px-4 py-2">Completed</th>
|
||||
<th class="px-4 py-2">Expiry time</th>
|
||||
<th class="px-4 py-2">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($tokens as $token)
|
||||
<tr class="border-b dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-950">
|
||||
<td class="px-4 py-4 font-mono text-sm hidden md:block align-middle">{{ $token['token'] }}
|
||||
</td>
|
||||
<td class="px-4 py-2">
|
||||
{{ $token['uses_allowed'] }}
|
||||
</td>
|
||||
<td class="px-4 py-2">{{ $token['pending'] }}</td>
|
||||
<td class="px-4 py-2 text-sm">{{ $token['completed'] }}</td>
|
||||
<td class="px-4 py-2">
|
||||
{{ $token['expiry_time'] ? Carbon\Carbon::createFromTimestampMs($token['expiry_time'])->toDateTimeString() : 'Never' }}
|
||||
</td>
|
||||
<td>
|
||||
<flux:button class="cursor-pointer" size="sm"
|
||||
wire:click="revokeToken('{{ (string) $token['token'] }}')">
|
||||
Revoke
|
||||
</flux:button>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-4 text-gray-500">No tokens found.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Livewire\RegistrationToken;
|
||||
use App\Livewire\Settings\Appearance;
|
||||
use App\Livewire\Settings\Password;
|
||||
use App\Livewire\Settings\Profile;
|
||||
@ -13,13 +14,14 @@ Route::view('dashboard', 'dashboard')
|
||||
->middleware(['auth', 'verified', App\Http\Middleware\IsAdmin::class])
|
||||
->name('dashboard');
|
||||
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Route::middleware(['auth', App\Http\Middleware\IsAdmin::class])->group(function () {
|
||||
Route::redirect('settings', 'settings/profile');
|
||||
|
||||
Route::get('settings/profile', Profile::class)->name('settings.profile');
|
||||
Route::get('settings/password', Password::class)->name('settings.password');
|
||||
Route::get('settings/appearance', Appearance::class)->name('settings.appearance');
|
||||
Route::get('settings/synapse', Synapse::class)->name('settings.synapse');
|
||||
Route::get('registration-tokens', RegistrationToken::class)->name('registration.tokens');
|
||||
});
|
||||
|
||||
require __DIR__ . '/auth.php';
|
||||
|
Loading…
x
Reference in New Issue
Block a user