festbench-web/resources/views/livewire/cli/authorize.blade.php

80 lines
No EOL
3 KiB
PHP

<?php
use App\Models\DeviceCode;
use Flux\Flux;
use Livewire\Attributes\Layout;
use Livewire\Component;
new #[Layout('components.layouts.app')] class extends Component {
public string $code = '';
public ?DeviceCode $device = null;
public bool $granted = false;
public bool $failed = false;
public function mount(string $code): void
{
$this->code = strtoupper(trim($code));
$this->device = DeviceCode::where('code', $this->code)->first();
// Unknown or expired codes never render a grant button.
$this->failed = $this->device === null || $this->device->expires_at->isPast();
}
public function grant(): void
{
if ($this->failed || $this->device === null) {
return;
}
$user = auth()->user();
if ($this->device->user_id !== null) {
$this->failed = true;
return;
}
// Mint a CLI token with abilities for the catalog (live now) and
// submissions (endpoint to come; ability is forward-compatible).
// The plaintext exists only here — stashed for one pickup by poll.
$plainText = $user->createToken('festbench-cli', ['gpus:read', 'results:submit'], now()->addYear());
$this->device->forceFill([
'user_id' => $user->id,
'personal_access_token_id' => $plainText->accessToken->id,
'plain_token' => $plainText->plainTextToken,
])->save();
$this->granted = true;
Flux::toast(variant: 'success', text: __('CLI connected. Return to your terminal.'));
}
};
?>
<div class="mx-auto max-w-md">
<flux:card>
<div class="flex flex-col items-center gap-4 text-center">
<flux:icon name="terminal" class="size-8 text-zinc-400" />
@if ($granted)
<flux:heading size="lg">{{ __('CLI connected') }}</flux:heading>
<flux:text>{{ __('The festbench CLI on your machine now has access. Return to your terminal to continue.') }}</flux:text>
@elseif ($failed)
<flux:heading size="lg">{{ __('Invalid or expired code') }}</flux:heading>
<flux:text>{{ __('This code does not exist or has expired. Re-run festbench login to get a fresh one.') }}</flux:text>
<flux:button variant="subtle" href="{{ route('home') }}" wire:navigate>{{ __('Back') }}</flux:button>
@else
<flux:heading size="lg">{{ __('Confirm CLI access') }}</flux:heading>
<flux:text>{{ __('A festbench CLI is requesting access to your account. Make sure the code below matches the one shown in your terminal.') }}</flux:text>
<div class="rounded-lg border border-zinc-200 bg-zinc-50 px-8 py-4 font-mono text-2xl font-bold tracking-widest dark:border-zinc-700 dark:bg-zinc-800">
{{ $code }}
</div>
<flux:button variant="primary" wire:click="grant" class="w-full">{{ __('Grant access') }}</flux:button>
@endif
</div>
</flux:card>
</div>