diff --git a/app/Livewire/Security/CloudProviderTokens.php b/app/Livewire/Security/CloudProviderTokens.php index f05b3c0ca..cfef30772 100644 --- a/app/Livewire/Security/CloudProviderTokens.php +++ b/app/Livewire/Security/CloudProviderTokens.php @@ -30,6 +30,60 @@ public function loadTokens() $this->tokens = CloudProviderToken::ownedByCurrentTeam()->get(); } + public function validateToken(int $tokenId) + { + try { + $token = CloudProviderToken::ownedByCurrentTeam()->findOrFail($tokenId); + $this->authorize('view', $token); + + if ($token->provider === 'hetzner') { + $isValid = $this->validateHetznerToken($token->token); + if ($isValid) { + $this->dispatch('success', 'Hetzner token is valid.'); + } else { + $this->dispatch('error', 'Hetzner token validation failed. Please check the token.'); + } + } elseif ($token->provider === 'digitalocean') { + $isValid = $this->validateDigitalOceanToken($token->token); + if ($isValid) { + $this->dispatch('success', 'DigitalOcean token is valid.'); + } else { + $this->dispatch('error', 'DigitalOcean token validation failed. Please check the token.'); + } + } else { + $this->dispatch('error', 'Unknown provider.'); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + + private function validateHetznerToken(string $token): bool + { + try { + $response = \Illuminate\Support\Facades\Http::withToken($token) + ->timeout(10) + ->get('https://api.hetzner.cloud/v1/servers?per_page=1'); + + return $response->successful(); + } catch (\Throwable $e) { + return false; + } + } + + private function validateDigitalOceanToken(string $token): bool + { + try { + $response = \Illuminate\Support\Facades\Http::withToken($token) + ->timeout(10) + ->get('https://api.digitalocean.com/v2/account'); + + return $response->successful(); + } catch (\Throwable $e) { + return false; + } + } + public function deleteToken(int $tokenId) { try { diff --git a/resources/views/livewire/security/cloud-provider-token-form.blade.php b/resources/views/livewire/security/cloud-provider-token-form.blade.php index 9ed7a5ca2..e803aa00c 100644 --- a/resources/views/livewire/security/cloud-provider-token-form.blade.php +++ b/resources/views/livewire/security/cloud-provider-token-form.blade.php @@ -14,13 +14,14 @@ - + @if (auth()->user()->currentTeam()->cloudProviderTokens->where('provider', $provider)->isEmpty())
Create an API token in the {{ ucfirst($provider) }} Console → choose + href='{{ $provider === 'hetzner' ? 'https://console.hetzner.com/projects' : '#' }}' + target='_blank' class='underline dark:text-white'>{{ ucfirst($provider) }} Console → choose Project → Security → API Tokens. @if ($provider === 'hetzner')

@@ -28,12 +29,12 @@ class='underline dark:text-white'>{{ ucfirst($provider) }} Console → choos class='underline dark:text-white'>Sign up here
(Coolify's affiliate link, only new accounts - supports us (€10) - and gives you €20) + and gives you €20) @endif
@endif - Validate & Add Token + Validate & Add Token @else {{-- Full page layout: horizontal, spacious --}}
@@ -49,7 +50,8 @@ class='underline dark:text-white'>Sign up here
- + @if (auth()->user()->currentTeam()->cloudProviderTokens->where('provider', $provider)->isEmpty())
Create an API token in the Hetzner Console → choose Project → Sec class='underline dark:text-white'>Sign up here
(Coolify's affiliate link, only new accounts - supports us (€10) - and gives you €20) + and gives you €20)
@endif
- Validate & Add Token + Validate & Add Token @endif diff --git a/resources/views/livewire/security/cloud-provider-tokens.blade.php b/resources/views/livewire/security/cloud-provider-tokens.blade.php index b3239c4a8..32a2cd2ab 100644 --- a/resources/views/livewire/security/cloud-provider-tokens.blade.php +++ b/resources/views/livewire/security/cloud-provider-tokens.blade.php @@ -20,16 +20,24 @@ class="flex flex-col gap-1 p-2 border dark:border-coolgray-200 hover:no-underlin
Created: {{ $savedToken->created_at->diffForHumans() }}
- @can('delete', $savedToken) - - @endcan +
+ @can('view', $savedToken) + + Validate Token + + @endcan + + @can('delete', $savedToken) + + @endcan +
@empty