diff --git a/app/Console/Commands/Node/MakeNodeCommand.php b/app/Console/Commands/Node/MakeNodeCommand.php index 2d3678a79..48a657c6c 100644 --- a/app/Console/Commands/Node/MakeNodeCommand.php +++ b/app/Console/Commands/Node/MakeNodeCommand.php @@ -24,6 +24,7 @@ class MakeNodeCommand extends Command {--overallocateCpu= : Enter the amount of cpu to overallocate (% or -1 to overallocate the maximum).} {--uploadSize= : Enter the maximum upload filesize.} {--daemonListeningPort= : Enter the daemon listening port.} + {--daemonConnectingPort= : Enter the daemon connecting port.} {--daemonSFTPPort= : Enter the daemon SFTP listening port.} {--daemonSFTPAlias= : Enter the daemon SFTP alias.} {--daemonBase= : Enter the base folder.}'; @@ -57,6 +58,7 @@ class MakeNodeCommand extends Command $data['cpu_overallocate'] = $this->option('overallocateCpu') ?? $this->ask(trans('commands.make_node.cpu_overallocate'), '-1'); $data['upload_size'] = $this->option('uploadSize') ?? $this->ask(trans('commands.make_node.upload_size'), '256'); $data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(trans('commands.make_node.daemonListen'), '8080'); + $data['daemon_connect'] = $this->option('daemonConnectingPort') ?? $this->ask(trans('commands.make_node.daemonConnect'), '8080'); $data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(trans('commands.make_node.daemonSFTP'), '2022'); $data['daemon_sftp_alias'] = $this->option('daemonSFTPAlias') ?? $this->ask(trans('commands.make_node.daemonSFTPAlias'), ''); $data['daemon_base'] = $this->option('daemonBase') ?? $this->ask(trans('commands.make_node.daemonBase'), '/var/lib/pelican/volumes'); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 9e52a5b81..48fbe6b84 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -7,7 +7,6 @@ use App\Console\Commands\Maintenance\CleanServiceBackupFilesCommand; use App\Console\Commands\Maintenance\PruneImagesCommand; use App\Console\Commands\Maintenance\PruneOrphanedBackupsCommand; use App\Console\Commands\Schedule\ProcessRunnableCommand; -use App\Jobs\NodeStatistics; use App\Models\ActivityLog; use App\Models\Webhook; use Illuminate\Console\Scheduling\Schedule; @@ -44,8 +43,6 @@ class Kernel extends ConsoleKernel $schedule->command(PruneImagesCommand::class)->daily(); $schedule->command(CheckEggUpdatesCommand::class)->hourly(); - $schedule->job(new NodeStatistics())->everyFiveSeconds()->withoutOverlapping(); - if (config('backups.prune_age')) { // Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted. $schedule->command(PruneOrphanedBackupsCommand::class)->everyThirtyMinutes(); diff --git a/app/Filament/Admin/Pages/Settings.php b/app/Filament/Admin/Pages/Settings.php index 84ec45ad8..53ecf4447 100644 --- a/app/Filament/Admin/Pages/Settings.php +++ b/app/Filament/Admin/Pages/Settings.php @@ -635,7 +635,6 @@ class Settings extends Page implements HasForms ->onColor('success') ->offColor('danger') ->live() - ->columnSpanFull() ->formatStateUsing(fn ($state): bool => (bool) $state) ->afterStateUpdated(fn ($state, Set $set) => $set('PANEL_SEND_INSTALL_NOTIFICATION', (bool) $state)) ->default(env('PANEL_SEND_INSTALL_NOTIFICATION', config('panel.email.send_install_notification'))), @@ -646,7 +645,6 @@ class Settings extends Page implements HasForms ->onColor('success') ->offColor('danger') ->live() - ->columnSpanFull() ->formatStateUsing(fn ($state): bool => (bool) $state) ->afterStateUpdated(fn ($state, Set $set) => $set('PANEL_SEND_REINSTALL_NOTIFICATION', (bool) $state)) ->default(env('PANEL_SEND_REINSTALL_NOTIFICATION', config('panel.email.send_reinstall_notification'))), diff --git a/app/Filament/Admin/Resources/NodeResource/Pages/CreateNode.php b/app/Filament/Admin/Resources/NodeResource/Pages/CreateNode.php index 65c4dd16e..7d79e790d 100644 --- a/app/Filament/Admin/Resources/NodeResource/Pages/CreateNode.php +++ b/app/Filament/Admin/Resources/NodeResource/Pages/CreateNode.php @@ -124,15 +124,10 @@ class CreateNode extends CreateRecord 'lg' => 1, ]), - TextInput::make('daemon_listen') - ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 1, - ]) - ->label(trans('admin/node.port')) - ->helperText(trans('admin/node.port_help')) + TextInput::make('daemon_connect') + ->columnSpan(1) + ->label(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port') : trans('admin/node.port')) + ->helperText(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port_help') : trans('admin/node.port_help')) ->minValue(1) ->maxValue(65535) ->default(8080) @@ -193,7 +188,21 @@ class CreateNode extends CreateRecord ->afterStateUpdated(function ($state, Set $set) { $set('scheme', $state === 'http' ? 'http' : 'https'); $set('behind_proxy', $state === 'https_proxy'); + + $set('daemon_connect', $state === 'https_proxy' ? 443 : 8080); + $set('daemon_listen', 8080); }), + + TextInput::make('daemon_listen') + ->columnSpan(1) + ->label(trans('admin/node.listen_port')) + ->helperText(trans('admin/node.listen_port_help')) + ->minValue(1) + ->maxValue(65535) + ->default(8080) + ->required() + ->integer() + ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), ]), Step::make('advanced') ->label(trans('admin/node.tabs.advanced_settings')) @@ -409,4 +418,13 @@ class CreateNode extends CreateRecord { return []; } + + protected function mutateFormDataBeforeCreate(array $data): array + { + if (!$data['behind_proxy']) { + $data['daemon_listen'] = $data['daemon_connect']; + } + + return $data; + } } diff --git a/app/Filament/Admin/Resources/NodeResource/Pages/EditNode.php b/app/Filament/Admin/Resources/NodeResource/Pages/EditNode.php index c93ad412b..66b375016 100644 --- a/app/Filament/Admin/Resources/NodeResource/Pages/EditNode.php +++ b/app/Filament/Admin/Resources/NodeResource/Pages/EditNode.php @@ -181,10 +181,10 @@ class EditNode extends EditRecord false => 'danger', ]) ->columnSpan(1), - TextInput::make('daemon_listen') + TextInput::make('daemon_connect') ->columnSpan(1) - ->label(trans('admin/node.port')) - ->helperText(trans('admin/node.port_help')) + ->label(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port') : trans('admin/node.port')) + ->helperText(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port_help') : trans('admin/node.port_help')) ->minValue(1) ->maxValue(65535) ->default(8080) @@ -239,7 +239,20 @@ class EditNode extends EditRecord ->afterStateUpdated(function ($state, Set $set) { $set('scheme', $state === 'http' ? 'http' : 'https'); $set('behind_proxy', $state === 'https_proxy'); + + $set('daemon_connect', $state === 'https_proxy' ? 443 : 8080); + $set('daemon_listen', 8080); }), + TextInput::make('daemon_listen') + ->columnSpan(1) + ->label(trans('admin/node.listen_port')) + ->helperText(trans('admin/node.listen_port_help')) + ->minValue(1) + ->maxValue(65535) + ->default(8080) + ->required() + ->integer() + ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), ]), Tab::make('adv') ->label(trans('admin/node.tabs.advanced_settings')) @@ -627,6 +640,15 @@ class EditNode extends EditRecord ]; } + protected function mutateFormDataBeforeSave(array $data): array + { + if (!$data['behind_proxy']) { + $data['daemon_listen'] = $data['daemon_connect']; + } + + return $data; + } + protected function afterSave(): void { $this->fillForm(); diff --git a/app/Filament/Admin/Resources/NodeResource/Widgets/NodeCpuChart.php b/app/Filament/Admin/Resources/NodeResource/Widgets/NodeCpuChart.php index 4cb23b787..b159a00b3 100644 --- a/app/Filament/Admin/Resources/NodeResource/Widgets/NodeCpuChart.php +++ b/app/Filament/Admin/Resources/NodeResource/Widgets/NodeCpuChart.php @@ -3,7 +3,6 @@ namespace App\Filament\Admin\Resources\NodeResource\Widgets; use App\Models\Node; -use Carbon\Carbon; use Filament\Support\RawJs; use Filament\Widgets\ChartWidget; use Illuminate\Support\Number; @@ -16,22 +15,34 @@ class NodeCpuChart extends ChartWidget public Node $node; + /** + * @var array + */ + protected array $cpuHistory = []; + + protected int $threads = 0; + protected function getData(): array { - $threads = $this->node->systemInformation()['cpu_count'] ?? 0; + $sessionKey = "node_stats.{$this->node->id}"; - $cpu = collect(cache()->get("nodes.{$this->node->id}.cpu_percent")) - ->slice(-10) - ->map(fn ($value, $key) => [ - 'cpu' => round($value * $threads, 2), - 'timestamp' => Carbon::createFromTimestamp($key, auth()->user()->timezone ?? 'UTC')->format('H:i:s'), - ]) - ->all(); + $data = $this->node->statistics(); + + $this->threads = session("{$sessionKey}.threads", $this->node->systemInformation()['cpu_count'] ?? 0); + + $this->cpuHistory = session("{$sessionKey}.cpu_history", []); + $this->cpuHistory[] = [ + 'cpu' => round($data['cpu_percent'] * $this->threads, 2), + 'timestamp' => now(auth()->user()->timezone ?? 'UTC')->format('H:i:s'), + ]; + + $this->cpuHistory = array_slice($this->cpuHistory, -60); + session()->put("{$sessionKey}.cpu_history", $this->cpuHistory); return [ 'datasets' => [ [ - 'data' => array_column($cpu, 'cpu'), + 'data' => array_column($this->cpuHistory, 'cpu'), 'backgroundColor' => [ 'rgba(96, 165, 250, 0.3)', ], @@ -39,7 +50,7 @@ class NodeCpuChart extends ChartWidget 'fill' => true, ], ], - 'labels' => array_column($cpu, 'timestamp'), + 'labels' => array_column($this->cpuHistory, 'timestamp'), 'locale' => auth()->user()->language ?? 'en', ]; } @@ -69,10 +80,10 @@ class NodeCpuChart extends ChartWidget public function getHeading(): string { - $threads = $this->node->systemInformation()['cpu_count'] ?? 0; + $data = array_slice(end($this->cpuHistory), -60); - $cpu = Number::format(collect(cache()->get("nodes.{$this->node->id}.cpu_percent"))->last() * $threads, maxPrecision: 2, locale: auth()->user()->language); - $max = Number::format($threads * 100, locale: auth()->user()->language); + $cpu = Number::format($data['cpu'], maxPrecision: 2, locale: auth()->user()->language); + $max = Number::format($this->threads * 100, locale: auth()->user()->language); return trans('admin/node.cpu_chart', ['cpu' => $cpu, 'max' => $max]); } diff --git a/app/Filament/Admin/Resources/NodeResource/Widgets/NodeMemoryChart.php b/app/Filament/Admin/Resources/NodeResource/Widgets/NodeMemoryChart.php index 23147f9cc..256c37e46 100644 --- a/app/Filament/Admin/Resources/NodeResource/Widgets/NodeMemoryChart.php +++ b/app/Filament/Admin/Resources/NodeResource/Widgets/NodeMemoryChart.php @@ -3,7 +3,6 @@ namespace App\Filament\Admin\Resources\NodeResource\Widgets; use App\Models\Node; -use Carbon\Carbon; use Filament\Support\RawJs; use Filament\Widgets\ChartWidget; use Illuminate\Support\Number; @@ -16,19 +15,36 @@ class NodeMemoryChart extends ChartWidget public Node $node; + /** + * @var array + */ + protected array $memoryHistory = []; + + protected int $totalMemory = 0; + protected function getData(): array { - $memUsed = collect(cache()->get("nodes.{$this->node->id}.memory_used"))->slice(-10) - ->map(fn ($value, $key) => [ - 'memory' => round(config('panel.use_binary_prefix') ? $value / 1024 / 1024 / 1024 : $value / 1000 / 1000 / 1000, 2), - 'timestamp' => Carbon::createFromTimestamp($key, auth()->user()->timezone ?? 'UTC')->format('H:i:s'), - ]) - ->all(); + $sessionKey = "node_stats.{$this->node->id}"; + + $data = $this->node->statistics(); + + $this->totalMemory = session("{$sessionKey}.total_memory", $data['memory_total']); + + $this->memoryHistory = session("{$sessionKey}.memory_history", []); + $this->memoryHistory[] = [ + 'memory' => round(config('panel.use_binary_prefix') + ? $data['memory_used'] / 1024 / 1024 / 1024 + : $data['memory_used'] / 1000 / 1000 / 1000, 2), + 'timestamp' => now(auth()->user()->timezone ?? 'UTC')->format('H:i:s'), + ]; + + $this->memoryHistory = array_slice($this->memoryHistory, -60); + session()->put("{$sessionKey}.memory_history", $this->memoryHistory); return [ 'datasets' => [ [ - 'data' => array_column($memUsed, 'memory'), + 'data' => array_column($this->memoryHistory, 'memory'), 'backgroundColor' => [ 'rgba(96, 165, 250, 0.3)', ], @@ -36,7 +52,7 @@ class NodeMemoryChart extends ChartWidget 'fill' => true, ], ], - 'labels' => array_column($memUsed, 'timestamp'), + 'labels' => array_column($this->memoryHistory, 'timestamp'), 'locale' => auth()->user()->language ?? 'en', ]; } @@ -66,16 +82,15 @@ class NodeMemoryChart extends ChartWidget public function getHeading(): string { - $latestMemoryUsed = collect(cache()->get("nodes.{$this->node->id}.memory_used"))->last(); - $totalMemory = collect(cache()->get("nodes.{$this->node->id}.memory_total"))->last(); + $latestMemoryUsed = array_slice(end($this->memoryHistory), -60); $used = config('panel.use_binary_prefix') - ? Number::format($latestMemoryUsed / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB' - : Number::format($latestMemoryUsed / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB'; + ? Number::format($latestMemoryUsed['memory'], maxPrecision: 2, locale: auth()->user()->language) .' GiB' + : Number::format($latestMemoryUsed['memory'], maxPrecision: 2, locale: auth()->user()->language) . ' GB'; $total = config('panel.use_binary_prefix') - ? Number::format($totalMemory / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB' - : Number::format($totalMemory / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB'; + ? Number::format($this->totalMemory / 1024 / 1024 / 1024, maxPrecision: 2, locale: auth()->user()->language) .' GiB' + : Number::format($this->totalMemory / 1000 / 1000 / 1000, maxPrecision: 2, locale: auth()->user()->language) . ' GB'; return trans('admin/node.memory_chart', ['used' => $used, 'total' => $total]); } diff --git a/app/Filament/Components/Tables/Columns/ServerEntryColumn.php b/app/Filament/Components/Tables/Columns/ServerEntryColumn.php index 3d02a8497..52e81c25e 100644 --- a/app/Filament/Components/Tables/Columns/ServerEntryColumn.php +++ b/app/Filament/Components/Tables/Columns/ServerEntryColumn.php @@ -6,5 +6,5 @@ use Filament\Tables\Columns\Column; class ServerEntryColumn extends Column { - protected string $view = 'tables.columns.server-entry-column'; + protected string $view = 'livewire.columns.server-entry-column'; } diff --git a/app/Filament/Server/Resources/AllocationResource.php b/app/Filament/Server/Resources/AllocationResource.php index 9719cc975..1e4a03275 100644 --- a/app/Filament/Server/Resources/AllocationResource.php +++ b/app/Filament/Server/Resources/AllocationResource.php @@ -77,7 +77,7 @@ class AllocationResource extends Resource Activity::event('server:allocation.delete') ->subject($allocation) - ->property('allocation', $allocation->toString()) + ->property('allocation', $allocation->address) ->log(); }), ]); diff --git a/app/Filament/Server/Resources/AllocationResource/Pages/ListAllocations.php b/app/Filament/Server/Resources/AllocationResource/Pages/ListAllocations.php index ee9526cc3..ad32aed40 100644 --- a/app/Filament/Server/Resources/AllocationResource/Pages/ListAllocations.php +++ b/app/Filament/Server/Resources/AllocationResource/Pages/ListAllocations.php @@ -32,7 +32,7 @@ class ListAllocations extends ListRecords Activity::event('server:allocation.create') ->subject($allocation) - ->property('allocation', $allocation->toString()) + ->property('allocation', $allocation->address) ->log(); }), ]; diff --git a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php index df598af21..54a4506ef 100644 --- a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php @@ -314,9 +314,9 @@ class ListFiles extends ListRecords ->label('') ->icon('tabler-trash') ->requiresConfirmation() - ->modalDescription(fn (File $file) => $file->name) - ->modalHeading('Delete file?') + ->modalHeading(fn (File $file) => trans('filament-actions::delete.single.modal.heading', ['label' => $file->name . ' ' . ($file->is_directory ? 'folder' : 'file')])) ->action(function (File $file) { + $this->deselectAllTableRecords(); $this->getDaemonFileRepository()->deleteFiles($this->path, [$file->name]); Activity::event('server:file.delete') diff --git a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php index 55e8023ac..c287addb6 100644 --- a/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php +++ b/app/Http/Controllers/Api/Client/Servers/NetworkAllocationController.php @@ -62,7 +62,7 @@ class NetworkAllocationController extends ClientApiController if ($original !== $allocation->notes) { Activity::event('server:allocation.notes') ->subject($allocation) - ->property(['allocation' => $allocation->toString(), 'old' => $original, 'new' => $allocation->notes]) + ->property(['allocation' => $allocation->address, 'old' => $original, 'new' => $allocation->notes]) ->log(); } @@ -87,7 +87,7 @@ class NetworkAllocationController extends ClientApiController Activity::event('server:allocation.primary') ->subject($allocation) - ->property('allocation', $allocation->toString()) + ->property('allocation', $allocation->address) ->log(); return $this->fractal->item($allocation) @@ -114,7 +114,7 @@ class NetworkAllocationController extends ClientApiController Activity::event('server:allocation.create') ->subject($allocation) - ->property('allocation', $allocation->toString()) + ->property('allocation', $allocation->address) ->log(); return $this->fractal->item($allocation) @@ -148,7 +148,7 @@ class NetworkAllocationController extends ClientApiController Activity::event('server:allocation.delete') ->subject($allocation) - ->property('allocation', $allocation->toString()) + ->property('allocation', $allocation->address) ->log(); return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); diff --git a/app/Jobs/NodeStatistics.php b/app/Jobs/NodeStatistics.php deleted file mode 100644 index d6815ce6c..000000000 --- a/app/Jobs/NodeStatistics.php +++ /dev/null @@ -1,35 +0,0 @@ -statistics(); - $timestamp = now()->getTimestamp(); - - foreach ($stats as $key => $value) { - $cacheKey = "nodes.{$node->id}.$key"; - $data = cache()->get($cacheKey, []); - - // Add current timestamp and value to the data array - $data[$timestamp] = $value; - - // Update the cache with the new data, expires in 1 minute - cache()->put($cacheKey, $data, now()->addMinute()); - } - } - } -} diff --git a/app/Livewire/ServerEntry.php b/app/Livewire/ServerEntry.php new file mode 100644 index 000000000..35b1a3095 --- /dev/null +++ b/app/Livewire/ServerEntry.php @@ -0,0 +1,64 @@ + +
+
+ +
+
+ +

+ {{ $server->name }} +

+
+ +
+
+

CPU

+

{{ Number::format(0, precision: 2, locale: auth()->user()->language ?? 'en') . '%' }}

+
+

{{ $server->formatResource('cpu', type: \App\Enums\ServerResourceType::Percentage, limit: true) }}

+
+
+

Memory

+

{{ convert_bytes_to_readable(0, decimals: 2) }}

+
+

{{ $server->formatResource('memory', limit: true) }}

+
+
+

Disk

+

{{ convert_bytes_to_readable(0, decimals: 2) }}

+
+

{{ $server->formatResource('disk', limit: true) }}

+
+ +
+
+ + HTML; + } +} diff --git a/app/Models/Allocation.php b/app/Models/Allocation.php index 39ae0ad60..bb642244f 100644 --- a/app/Models/Allocation.php +++ b/app/Models/Allocation.php @@ -121,11 +121,6 @@ class Allocation extends Model ); } - public function toString(): string - { - return $this->address; - } - /** * Gets information for the server associated with this allocation. */ diff --git a/app/Models/Node.php b/app/Models/Node.php index 7c7c62d58..c6ffb655d 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -38,6 +38,7 @@ use Symfony\Component\Yaml\Yaml; * @property string $daemon_token_id * @property string $daemon_token * @property int $daemon_listen + * @property int $daemon_connect * @property int $daemon_sftp * @property string|null $daemon_sftp_alias * @property string $daemon_base @@ -83,7 +84,7 @@ class Node extends Model implements Validatable 'memory', 'memory_overallocate', 'disk', 'disk_overallocate', 'cpu', 'cpu_overallocate', 'upload_size', 'daemon_base', - 'daemon_sftp', 'daemon_sftp_alias', 'daemon_listen', + 'daemon_sftp', 'daemon_sftp_alias', 'daemon_listen', 'daemon_connect', 'description', 'maintenance_mode', 'tags', ]; @@ -105,6 +106,7 @@ class Node extends Model implements Validatable 'daemon_sftp' => ['required', 'numeric', 'between:1,65535'], 'daemon_sftp_alias' => ['nullable', 'string'], 'daemon_listen' => ['required', 'numeric', 'between:1,65535'], + 'daemon_connect' => ['required', 'numeric', 'between:1,65535'], 'maintenance_mode' => ['boolean'], 'upload_size' => ['int', 'between:1,1024'], 'tags' => ['array'], @@ -125,6 +127,7 @@ class Node extends Model implements Validatable 'daemon_base' => '/var/lib/pelican/volumes', 'daemon_sftp' => 2022, 'daemon_listen' => 8080, + 'daemon_connect' => 8080, 'maintenance_mode' => false, 'tags' => '[]', ]; @@ -136,6 +139,7 @@ class Node extends Model implements Validatable 'disk' => 'integer', 'cpu' => 'integer', 'daemon_listen' => 'integer', + 'daemon_connect' => 'integer', 'daemon_sftp' => 'integer', 'daemon_token' => 'encrypted', 'behind_proxy' => 'boolean', @@ -171,7 +175,7 @@ class Node extends Model implements Validatable */ public function getConnectionAddress(): string { - return "$this->scheme://$this->fqdn:$this->daemon_listen"; + return "$this->scheme://$this->fqdn:$this->daemon_connect"; } /** diff --git a/app/Repositories/Daemon/DaemonServerRepository.php b/app/Repositories/Daemon/DaemonServerRepository.php index 551dc16fe..ae88ceadd 100644 --- a/app/Repositories/Daemon/DaemonServerRepository.php +++ b/app/Repositories/Daemon/DaemonServerRepository.php @@ -19,7 +19,7 @@ class DaemonServerRepository extends DaemonRepository public function getDetails(): array { try { - return $this->getHttpClient()->get("/api/servers/{$this->server->uuid}")->throw()->json(); + return $this->getHttpClient()->connectTimeout(1)->timeout(1)->get("/api/servers/{$this->server->uuid}")->throw()->json(); } catch (RequestException $exception) { $cfId = $exception->response->header('Cf-Ray'); $cfCache = $exception->response->header('Cf-Cache-Status'); diff --git a/app/Services/Servers/TransferServerService.php b/app/Services/Servers/TransferServerService.php index f394f4c7c..f9df5d647 100644 --- a/app/Services/Servers/TransferServerService.php +++ b/app/Services/Servers/TransferServerService.php @@ -47,7 +47,7 @@ class TransferServerService // Check if the node is viable for the transfer. $node = Node::query() - ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.cpu', 'nodes.memory_overallocate', 'nodes.disk_overallocate', 'nodes.cpu_overallocate']) + ->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_connect', 'nodes.memory', 'nodes.disk', 'nodes.cpu', 'nodes.memory_overallocate', 'nodes.disk_overallocate', 'nodes.cpu_overallocate']) ->withSum('servers', 'disk') ->withSum('servers', 'memory') ->withSum('servers', 'cpu') diff --git a/app/Traits/EnvironmentWriterTrait.php b/app/Traits/EnvironmentWriterTrait.php index 20a0c1680..5df4cdb1d 100644 --- a/app/Traits/EnvironmentWriterTrait.php +++ b/app/Traits/EnvironmentWriterTrait.php @@ -2,54 +2,20 @@ namespace App\Traits; -use Exception; +use Illuminate\Support\Env; +use RuntimeException; trait EnvironmentWriterTrait { - /** - * Escapes an environment value by looking for any characters that could - * reasonably cause environment parsing issues. Those values are then wrapped - * in quotes before being returned. - */ - public function escapeEnvironmentValue(string $value): string - { - if (!preg_match('/^\"(.*)\"$/', $value) && preg_match('/([^\w.\-+\/])+/', $value)) { - return sprintf('"%s"', addcslashes($value, '\\"')); - } - - return $value; - } - /** * Update the .env file for the application using the passed in values. * * @param array $values * - * @throws Exception + * @throws RuntimeException */ public function writeToEnvironment(array $values = []): void { - $path = base_path('.env'); - if (!file_exists($path)) { - throw new Exception('Cannot locate .env file, was this software installed correctly?'); - } - - $saveContents = file_get_contents($path); - if ($saveContents === false) { - $saveContents = ''; - } - - collect($values)->each(function ($value, $key) use (&$saveContents) { - $key = strtoupper($key); - $saveValue = sprintf('%s=%s', $key, $this->escapeEnvironmentValue($value ?? '')); - - if (preg_match_all('/^' . $key . '=(.*)$/m', $saveContents) < 1) { - $saveContents = $saveContents . PHP_EOL . $saveValue; - } else { - $saveContents = preg_replace('/^' . $key . '=(.*)$/m', $saveValue, $saveContents); - } - }); - - file_put_contents($path, $saveContents); + Env::writeVariables($values, base_path('.env'), true); } } diff --git a/composer.json b/composer.json index c420f548c..f1919ec74 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,10 @@ "doctrine/dbal": "~3.6.0", "filament/filament": "^3.3", "guzzlehttp/guzzle": "^7.9", - "laravel/framework": "^12.16", + "laravel/framework": "^12.17", "laravel/helpers": "^1.7", "laravel/sanctum": "^4.1", - "laravel/socialite": "^5.20", + "laravel/socialite": "^5.21", "laravel/tinker": "^2.10.1", "laravel/ui": "^4.6", "lcobucci/jwt": "~4.3.0", @@ -38,7 +38,7 @@ "spatie/laravel-data": "^4.15", "spatie/laravel-fractal": "^6.3", "spatie/laravel-health": "^1.34", - "spatie/laravel-permission": "^6.18", + "spatie/laravel-permission": "^6.19", "spatie/laravel-query-builder": "^6.3", "spatie/temporary-directory": "^2.3", "symfony/http-client": "^7.2", diff --git a/composer.lock b/composer.lock index f25312990..031416caf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6ae0adb5b2985ecea907ceb281a08926", + "content-hash": "9a250ae6162d7d877649172284b56c13", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -900,16 +900,16 @@ }, { "name": "anourvalar/eloquent-serialize", - "version": "1.3.1", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/AnourValar/eloquent-serialize.git", - "reference": "060632195821e066de1fc0f869881dd585e2f299" + "reference": "2f05023f1e465a91dc4f08483e6710325641a444" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/AnourValar/eloquent-serialize/zipball/060632195821e066de1fc0f869881dd585e2f299", - "reference": "060632195821e066de1fc0f869881dd585e2f299", + "url": "https://api.github.com/repos/AnourValar/eloquent-serialize/zipball/2f05023f1e465a91dc4f08483e6710325641a444", + "reference": "2f05023f1e465a91dc4f08483e6710325641a444", "shasum": "" }, "require": { @@ -960,9 +960,9 @@ ], "support": { "issues": "https://github.com/AnourValar/eloquent-serialize/issues", - "source": "https://github.com/AnourValar/eloquent-serialize/tree/1.3.1" + "source": "https://github.com/AnourValar/eloquent-serialize/tree/1.3.3" }, - "time": "2025-04-06T06:54:34+00:00" + "time": "2025-05-28T17:07:28+00:00" }, { "name": "aws/aws-crt-php", @@ -1020,16 +1020,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.343.18", + "version": "3.343.23", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "ae98d503173740cce23b30d2ba2737c49b0d9876" + "reference": "010869992129557cfbf2740d94d82ef3b5228462" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ae98d503173740cce23b30d2ba2737c49b0d9876", - "reference": "ae98d503173740cce23b30d2ba2737c49b0d9876", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/010869992129557cfbf2740d94d82ef3b5228462", + "reference": "010869992129557cfbf2740d94d82ef3b5228462", "shasum": "" }, "require": { @@ -1111,9 +1111,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.343.18" + "source": "https://github.com/aws/aws-sdk-php/tree/3.343.23" }, - "time": "2025-05-23T18:08:18+00:00" + "time": "2025-06-02T18:04:47+00:00" }, { "name": "aymanalhattami/filament-context-menu", @@ -1343,16 +1343,16 @@ }, { "name": "brick/math", - "version": "0.12.3", + "version": "0.13.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" + "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", + "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04", + "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04", "shasum": "" }, "require": { @@ -1391,7 +1391,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.3" + "source": "https://github.com/brick/math/tree/0.13.1" }, "funding": [ { @@ -1399,7 +1399,7 @@ "type": "github" } ], - "time": "2025-02-28T13:11:00+00:00" + "time": "2025-03-29T13:50:30+00:00" }, { "name": "calebporzio/sushi", @@ -1834,16 +1834,16 @@ }, { "name": "dedoc/scramble", - "version": "v0.12.19", + "version": "v0.12.22", "source": { "type": "git", "url": "https://github.com/dedoc/scramble.git", - "reference": "f6516eb82c7c86e57e2cfaead4a05b900e4b5ecc" + "reference": "3c06a756d4fc20a281638e8ba9941f6463000d78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dedoc/scramble/zipball/f6516eb82c7c86e57e2cfaead4a05b900e4b5ecc", - "reference": "f6516eb82c7c86e57e2cfaead4a05b900e4b5ecc", + "url": "https://api.github.com/repos/dedoc/scramble/zipball/3c06a756d4fc20a281638e8ba9941f6463000d78", + "reference": "3c06a756d4fc20a281638e8ba9941f6463000d78", "shasum": "" }, "require": { @@ -1855,11 +1855,15 @@ "spatie/laravel-package-tools": "^1.9.2" }, "require-dev": { + "larastan/larastan": "^3.3", "laravel/pint": "^v1.1.0", "nunomaduro/collision": "^7.0|^8.0", "orchestra/testbench": "^8.0|^9.0|^10.0", "pestphp/pest": "^2.34|^3.7", "pestphp/pest-plugin-laravel": "^2.3|^3.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.5|^11.5.3", "spatie/laravel-permission": "^6.10", "spatie/pest-plugin-snapshots": "^2.1" @@ -1898,7 +1902,7 @@ ], "support": { "issues": "https://github.com/dedoc/scramble/issues", - "source": "https://github.com/dedoc/scramble/tree/v0.12.19" + "source": "https://github.com/dedoc/scramble/tree/v0.12.22" }, "funding": [ { @@ -1906,7 +1910,7 @@ "type": "github" } ], - "time": "2025-04-23T09:41:53+00:00" + "time": "2025-06-03T07:50:53+00:00" }, { "name": "dflydev/dot-access-data", @@ -2630,16 +2634,16 @@ }, { "name": "filament/actions", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "66b509aa72fa882ce91218eb743684a9350bc3fb" + "reference": "151f776552ee10d70591c2649708bc4b0a7cba91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/66b509aa72fa882ce91218eb743684a9350bc3fb", - "reference": "66b509aa72fa882ce91218eb743684a9350bc3fb", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/151f776552ee10d70591c2649708bc4b0a7cba91", + "reference": "151f776552ee10d70591c2649708bc4b0a7cba91", "shasum": "" }, "require": { @@ -2679,20 +2683,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-19T07:25:24+00:00" + "time": "2025-06-03T06:15:27+00:00" }, { "name": "filament/filament", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "ed0a0109e6b2663247fcd73076c95c918bc5b412" + "reference": "94ee92244d2a64666fb8c1ea50cb7315ebceb63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/ed0a0109e6b2663247fcd73076c95c918bc5b412", - "reference": "ed0a0109e6b2663247fcd73076c95c918bc5b412", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/94ee92244d2a64666fb8c1ea50cb7315ebceb63b", + "reference": "94ee92244d2a64666fb8c1ea50cb7315ebceb63b", "shasum": "" }, "require": { @@ -2744,20 +2748,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-21T08:45:13+00:00" + "time": "2025-05-27T18:46:23+00:00" }, { "name": "filament/forms", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "eeb18e482b1addc5fe88d57f59d6b91cb71957ff" + "reference": "d73cdda057a4f5bd409eab9573101e73edb404cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/eeb18e482b1addc5fe88d57f59d6b91cb71957ff", - "reference": "eeb18e482b1addc5fe88d57f59d6b91cb71957ff", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/d73cdda057a4f5bd409eab9573101e73edb404cc", + "reference": "d73cdda057a4f5bd409eab9573101e73edb404cc", "shasum": "" }, "require": { @@ -2800,20 +2804,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-21T08:45:29+00:00" + "time": "2025-06-03T13:40:37+00:00" }, { "name": "filament/infolists", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "cc71f1c15f132660986384d302a33a2b20618a96" + "reference": "b54ff0fa89f654eca1c14edfd41a7e16ccb8165d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/cc71f1c15f132660986384d302a33a2b20618a96", - "reference": "cc71f1c15f132660986384d302a33a2b20618a96", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/b54ff0fa89f654eca1c14edfd41a7e16ccb8165d", + "reference": "b54ff0fa89f654eca1c14edfd41a7e16ccb8165d", "shasum": "" }, "require": { @@ -2851,11 +2855,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-04-23T06:39:44+00:00" + "time": "2025-06-02T09:43:23+00:00" }, { "name": "filament/notifications", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", @@ -2907,16 +2911,16 @@ }, { "name": "filament/support", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "537663fa2c5057aa236a189255b623b5124d32d8" + "reference": "4f9793ad3339301ca53ea6f2c984734f7ac38ce7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/537663fa2c5057aa236a189255b623b5124d32d8", - "reference": "537663fa2c5057aa236a189255b623b5124d32d8", + "url": "https://api.github.com/repos/filamentphp/support/zipball/4f9793ad3339301ca53ea6f2c984734f7ac38ce7", + "reference": "4f9793ad3339301ca53ea6f2c984734f7ac38ce7", "shasum": "" }, "require": { @@ -2962,20 +2966,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-21T08:45:20+00:00" + "time": "2025-06-03T06:16:13+00:00" }, { "name": "filament/tables", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "64806e3c13caeabb23a8668a7aaf1efc8395df96" + "reference": "1a107a8411549297b97d1142b1f7a5fa7a65e32b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/64806e3c13caeabb23a8668a7aaf1efc8395df96", - "reference": "64806e3c13caeabb23a8668a7aaf1efc8395df96", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/1a107a8411549297b97d1142b1f7a5fa7a65e32b", + "reference": "1a107a8411549297b97d1142b1f7a5fa7a65e32b", "shasum": "" }, "require": { @@ -3014,11 +3018,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2025-05-19T07:26:42+00:00" + "time": "2025-06-02T09:43:47+00:00" }, { "name": "filament/widgets", - "version": "v3.3.16", + "version": "v3.3.20", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -3790,20 +3794,20 @@ }, { "name": "laravel/framework", - "version": "v12.16.0", + "version": "v12.17.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "293bb1c70224faebfd3d4328e201c37115da055f" + "reference": "8729d084510480fdeec9b6ad198180147d4a7f06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/293bb1c70224faebfd3d4328e201c37115da055f", - "reference": "293bb1c70224faebfd3d4328e201c37115da055f", + "url": "https://api.github.com/repos/laravel/framework/zipball/8729d084510480fdeec9b6ad198180147d4a7f06", + "reference": "8729d084510480fdeec9b6ad198180147d4a7f06", "shasum": "" }, "require": { - "brick/math": "^0.11|^0.12", + "brick/math": "^0.11|^0.12|^0.13", "composer-runtime-api": "^2.2", "doctrine/inflector": "^2.0.5", "dragonmantank/cron-expression": "^3.4", @@ -4001,7 +4005,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-05-27T15:49:44+00:00" + "time": "2025-06-03T14:04:18+00:00" }, { "name": "laravel/helpers", @@ -6016,16 +6020,16 @@ }, { "name": "nette/utils", - "version": "v4.0.6", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "ce708655043c7050eb050df361c5e313cf708309" + "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309", - "reference": "ce708655043c7050eb050df361c5e313cf708309", + "url": "https://api.github.com/repos/nette/utils/zipball/e67c4061eb40b9c113b218214e42cb5a0dda28f2", + "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2", "shasum": "" }, "require": { @@ -6096,22 +6100,22 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.6" + "source": "https://github.com/nette/utils/tree/v4.0.7" }, - "time": "2025-03-30T21:06:30+00:00" + "time": "2025-06-03T04:55:08+00:00" }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", "shasum": "" }, "require": { @@ -6154,9 +6158,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-05-31T08:24:38+00:00" }, { "name": "nunomaduro/termwind", @@ -6457,19 +6461,20 @@ }, { "name": "phpdocumentor/reflection", - "version": "6.1.0", + "version": "6.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "bb4dea805a645553d6d989b23dad9f8041f39502" + "reference": "ab969af5e53c3bb400eea958b90b87ecc34f4dff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/bb4dea805a645553d6d989b23dad9f8041f39502", - "reference": "bb4dea805a645553d6d989b23dad9f8041f39502", + "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/ab969af5e53c3bb400eea958b90b87ecc34f4dff", + "reference": "ab969af5e53c3bb400eea958b90b87ecc34f4dff", "shasum": "" }, "require": { + "composer-runtime-api": "^2", "nikic/php-parser": "~4.18 || ^5.0", "php": "8.1.*|8.2.*|8.3.*|8.4.*", "phpdocumentor/reflection-common": "^2.1", @@ -6480,7 +6485,8 @@ }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/coding-standard": "^12.0", + "doctrine/coding-standard": "^13.0", + "eliashaeussler/phpunit-attributes": "^1.7", "mikey179/vfsstream": "~1.2", "mockery/mockery": "~1.6.0", "phpspec/prophecy-phpunit": "^2.0", @@ -6488,7 +6494,7 @@ "phpstan/phpstan": "^1.8", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^10.0", - "psalm/phar": "^5.24", + "psalm/phar": "^6.0", "rector/rector": "^1.0.0", "squizlabs/php_codesniffer": "^3.8" }, @@ -6500,6 +6506,9 @@ } }, "autoload": { + "files": [ + "src/php-parser/Modifiers.php" + ], "psr-4": { "phpDocumentor\\": "src/phpDocumentor" } @@ -6518,9 +6527,9 @@ ], "support": { "issues": "https://github.com/phpDocumentor/Reflection/issues", - "source": "https://github.com/phpDocumentor/Reflection/tree/6.1.0" + "source": "https://github.com/phpDocumentor/Reflection/tree/6.2.1" }, - "time": "2024-11-22T15:11:54+00:00" + "time": "2025-05-30T18:42:55+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -7705,20 +7714,20 @@ }, { "name": "ramsey/uuid", - "version": "4.7.6", + "version": "4.8.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088" + "reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28", + "reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13", "ext-json": "*", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" @@ -7727,26 +7736,23 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "captainhook/captainhook": "^5.10", + "captainhook/captainhook": "^5.25", "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.8", - "ergebnis/composer-normalize": "^2.15", - "mockery/mockery": "^1.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.2", - "php-mock/php-mock-mockery": "^1.3", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.9" + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", @@ -7781,19 +7787,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.7.6" + "source": "https://github.com/ramsey/uuid/tree/4.8.1" }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", - "type": "tidelift" - } - ], - "time": "2024-04-27T21:32:50+00:00" + "time": "2025-06-01T06:28:46+00:00" }, { "name": "revolt/event-loop", @@ -8859,16 +8855,16 @@ }, { "name": "spatie/laravel-permission", - "version": "6.18.0", + "version": "6.19.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-permission.git", - "reference": "3c05f04d12275dfbe462c8b4aae3290e586c2dde" + "reference": "0cd412dcad066d75caf0b977716809be7e7642fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/3c05f04d12275dfbe462c8b4aae3290e586c2dde", - "reference": "3c05f04d12275dfbe462c8b4aae3290e586c2dde", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/0cd412dcad066d75caf0b977716809be7e7642fd", + "reference": "0cd412dcad066d75caf0b977716809be7e7642fd", "shasum": "" }, "require": { @@ -8930,7 +8926,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/6.18.0" + "source": "https://github.com/spatie/laravel-permission/tree/6.19.0" }, "funding": [ { @@ -8938,7 +8934,7 @@ "type": "github" } ], - "time": "2025-05-14T03:32:23+00:00" + "time": "2025-05-31T00:50:27+00:00" }, { "name": "spatie/laravel-query-builder", @@ -9218,7 +9214,7 @@ }, { "name": "symfony/clock", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", @@ -9272,7 +9268,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.2.0" + "source": "https://github.com/symfony/clock/tree/v7.3.0" }, "funding": [ { @@ -9292,23 +9288,24 @@ }, { "name": "symfony/console", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" + "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", - "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44", + "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" + "symfony/string": "^7.2" }, "conflict": { "symfony/dependency-injection": "<6.4", @@ -9365,7 +9362,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.6" + "source": "https://github.com/symfony/console/tree/v7.3.0" }, "funding": [ { @@ -9381,11 +9378,11 @@ "type": "tidelift" } ], - "time": "2025-04-07T19:09:28+00:00" + "time": "2025-05-24T10:34:04+00:00" }, { "name": "symfony/css-selector", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -9430,7 +9427,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.2.0" + "source": "https://github.com/symfony/css-selector/tree/v7.3.0" }, "funding": [ { @@ -9517,16 +9514,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.2.5", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b" + "reference": "cf68d225bc43629de4ff54778029aee6dc191b83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", - "reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/cf68d225bc43629de4ff54778029aee6dc191b83", + "reference": "cf68d225bc43629de4ff54778029aee6dc191b83", "shasum": "" }, "require": { @@ -9539,9 +9536,11 @@ "symfony/http-kernel": "<6.4" }, "require-dev": { + "symfony/console": "^6.4|^7.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0" + "symfony/serializer": "^6.4|^7.0", + "symfony/webpack-encore-bundle": "^1.0|^2.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -9572,7 +9571,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.2.5" + "source": "https://github.com/symfony/error-handler/tree/v7.3.0" }, "funding": [ { @@ -9588,20 +9587,20 @@ "type": "tidelift" } ], - "time": "2025-03-03T07:12:39+00:00" + "time": "2025-05-29T07:19:49+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", "shasum": "" }, "require": { @@ -9652,7 +9651,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" }, "funding": [ { @@ -9668,7 +9667,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2025-04-22T09:11:45+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -9748,16 +9747,16 @@ }, { "name": "symfony/finder", - "version": "v7.2.2", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d", + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d", "shasum": "" }, "require": { @@ -9792,7 +9791,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.2" + "source": "https://github.com/symfony/finder/tree/v7.3.0" }, "funding": [ { @@ -9808,20 +9807,20 @@ "type": "tidelift" } ], - "time": "2024-12-30T19:00:17+00:00" + "time": "2024-12-30T19:00:26+00:00" }, { "name": "symfony/html-sanitizer", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/html-sanitizer.git", - "reference": "1bd0c8fd5938d9af3f081a7c43d360ddefd494ca" + "reference": "cf21254e982b12276329940ca4af5e623ee06c58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/1bd0c8fd5938d9af3f081a7c43d360ddefd494ca", - "reference": "1bd0c8fd5938d9af3f081a7c43d360ddefd494ca", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/cf21254e982b12276329940ca4af5e623ee06c58", + "reference": "cf21254e982b12276329940ca4af5e623ee06c58", "shasum": "" }, "require": { @@ -9861,7 +9860,7 @@ "sanitizer" ], "support": { - "source": "https://github.com/symfony/html-sanitizer/tree/v7.2.6" + "source": "https://github.com/symfony/html-sanitizer/tree/v7.3.0" }, "funding": [ { @@ -9877,20 +9876,20 @@ "type": "tidelift" } ], - "time": "2025-03-31T08:29:03+00:00" + "time": "2025-03-31T08:49:55+00:00" }, { "name": "symfony/http-client", - "version": "v7.2.4", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6" + "reference": "57e4fb86314015a695a750ace358d07a7e37b8a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/78981a2ffef6437ed92d4d7e2a86a82f256c6dc6", - "reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6", + "url": "https://api.github.com/repos/symfony/http-client/zipball/57e4fb86314015a695a750ace358d07a7e37b8a9", + "reference": "57e4fb86314015a695a750ace358d07a7e37b8a9", "shasum": "" }, "require": { @@ -9956,7 +9955,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.2.4" + "source": "https://github.com/symfony/http-client/tree/v7.3.0" }, "funding": [ { @@ -9972,7 +9971,7 @@ "type": "tidelift" } ], - "time": "2025-02-13T10:27:23+00:00" + "time": "2025-05-02T08:23:16+00:00" }, { "name": "symfony/http-client-contracts", @@ -10054,16 +10053,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6023ec7607254c87c5e69fb3558255aca440d72b" + "reference": "4236baf01609667d53b20371486228231eb135fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6023ec7607254c87c5e69fb3558255aca440d72b", - "reference": "6023ec7607254c87c5e69fb3558255aca440d72b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4236baf01609667d53b20371486228231eb135fd", + "reference": "4236baf01609667d53b20371486228231eb135fd", "shasum": "" }, "require": { @@ -10080,6 +10079,7 @@ "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", "symfony/cache": "^6.4.12|^7.1.5", + "symfony/clock": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -10112,7 +10112,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.2.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.3.0" }, "funding": [ { @@ -10128,20 +10128,20 @@ "type": "tidelift" } ], - "time": "2025-04-09T08:14:01+00:00" + "time": "2025-05-12T14:48:23+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec" + "reference": "ac7b8e163e8c83dce3abcc055a502d4486051a9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9dec01e6094a063e738f8945ef69c0cfcf792ec", - "reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ac7b8e163e8c83dce3abcc055a502d4486051a9f", + "reference": "ac7b8e163e8c83dce3abcc055a502d4486051a9f", "shasum": "" }, "require": { @@ -10149,8 +10149,8 @@ "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/event-dispatcher": "^7.3", + "symfony/http-foundation": "^7.3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -10226,7 +10226,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.2.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.3.0" }, "funding": [ { @@ -10242,20 +10242,20 @@ "type": "tidelift" } ], - "time": "2025-05-02T09:04:03+00:00" + "time": "2025-05-29T07:47:32+00:00" }, { "name": "symfony/mailer", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "998692469d6e698c6eadc7ef37a6530a9eabb356" + "reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/998692469d6e698c6eadc7ef37a6530a9eabb356", - "reference": "998692469d6e698c6eadc7ef37a6530a9eabb356", + "url": "https://api.github.com/repos/symfony/mailer/zipball/0f375bbbde96ae8c78e4aa3e63aabd486e33364c", + "reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c", "shasum": "" }, "require": { @@ -10306,7 +10306,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.2.6" + "source": "https://github.com/symfony/mailer/tree/v7.3.0" }, "funding": [ { @@ -10322,11 +10322,11 @@ "type": "tidelift" } ], - "time": "2025-04-04T09:50:51+00:00" + "time": "2025-04-04T09:51:09+00:00" }, { "name": "symfony/mailgun-mailer", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/mailgun-mailer.git", @@ -10375,7 +10375,7 @@ "description": "Symfony Mailgun Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.2.0" + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.3.0" }, "funding": [ { @@ -10395,16 +10395,16 @@ }, { "name": "symfony/mime", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "706e65c72d402539a072d0d6ad105fff6c161ef1" + "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/706e65c72d402539a072d0d6ad105fff6c161ef1", - "reference": "706e65c72d402539a072d0d6ad105fff6c161ef1", + "url": "https://api.github.com/repos/symfony/mime/zipball/0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9", + "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9", "shasum": "" }, "require": { @@ -10459,7 +10459,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.2.6" + "source": "https://github.com/symfony/mime/tree/v7.3.0" }, "funding": [ { @@ -10475,7 +10475,7 @@ "type": "tidelift" } ], - "time": "2025-04-27T13:34:41+00:00" + "time": "2025-02-19T08:51:26+00:00" }, { "name": "symfony/polyfill-ctype", @@ -11116,7 +11116,7 @@ }, { "name": "symfony/postmark-mailer", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/postmark-mailer.git", @@ -11166,7 +11166,7 @@ "description": "Symfony Postmark Mailer Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/postmark-mailer/tree/v7.2.6" + "source": "https://github.com/symfony/postmark-mailer/tree/v7.3.0" }, "funding": [ { @@ -11186,16 +11186,16 @@ }, { "name": "symfony/process", - "version": "v7.2.5", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d" + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", "shasum": "" }, "require": { @@ -11227,7 +11227,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.5" + "source": "https://github.com/symfony/process/tree/v7.3.0" }, "funding": [ { @@ -11243,20 +11243,20 @@ "type": "tidelift" } ], - "time": "2025-03-13T12:21:46+00:00" + "time": "2025-04-17T09:11:12+00:00" }, { "name": "symfony/routing", - "version": "v7.2.3", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "ee9a67edc6baa33e5fae662f94f91fd262930996" + "reference": "8e213820c5fea844ecea29203d2a308019007c15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/ee9a67edc6baa33e5fae662f94f91fd262930996", - "reference": "ee9a67edc6baa33e5fae662f94f91fd262930996", + "url": "https://api.github.com/repos/symfony/routing/zipball/8e213820c5fea844ecea29203d2a308019007c15", + "reference": "8e213820c5fea844ecea29203d2a308019007c15", "shasum": "" }, "require": { @@ -11308,7 +11308,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.2.3" + "source": "https://github.com/symfony/routing/tree/v7.3.0" }, "funding": [ { @@ -11324,7 +11324,7 @@ "type": "tidelift" } ], - "time": "2025-01-17T10:56:55+00:00" + "time": "2025-05-24T20:43:28+00:00" }, { "name": "symfony/service-contracts", @@ -11411,16 +11411,16 @@ }, { "name": "symfony/string", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", - "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125", + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125", "shasum": "" }, "require": { @@ -11478,7 +11478,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.6" + "source": "https://github.com/symfony/string/tree/v7.3.0" }, "funding": [ { @@ -11494,20 +11494,20 @@ "type": "tidelift" } ], - "time": "2025-04-20T20:18:16+00:00" + "time": "2025-04-20T20:19:01+00:00" }, { "name": "symfony/translation", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6" + "reference": "4aba29076a29a3aa667e09b791e5f868973a8667" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", - "reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", + "url": "https://api.github.com/repos/symfony/translation/zipball/4aba29076a29a3aa667e09b791e5f868973a8667", + "reference": "4aba29076a29a3aa667e09b791e5f868973a8667", "shasum": "" }, "require": { @@ -11517,6 +11517,7 @@ "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { + "nikic/php-parser": "<5.0", "symfony/config": "<6.4", "symfony/console": "<6.4", "symfony/dependency-injection": "<6.4", @@ -11530,7 +11531,7 @@ "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { - "nikic/php-parser": "^4.18|^5.0", + "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", "symfony/config": "^6.4|^7.0", "symfony/console": "^6.4|^7.0", @@ -11573,7 +11574,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.2.6" + "source": "https://github.com/symfony/translation/tree/v7.3.0" }, "funding": [ { @@ -11589,7 +11590,7 @@ "type": "tidelift" } ], - "time": "2025-04-07T19:09:28+00:00" + "time": "2025-05-29T07:19:49+00:00" }, { "name": "symfony/translation-contracts", @@ -11671,16 +11672,16 @@ }, { "name": "symfony/uid", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "2d294d0c48df244c71c105a169d0190bfb080426" + "reference": "7beeb2b885cd584cd01e126c5777206ae4c3c6a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", - "reference": "2d294d0c48df244c71c105a169d0190bfb080426", + "url": "https://api.github.com/repos/symfony/uid/zipball/7beeb2b885cd584cd01e126c5777206ae4c3c6a3", + "reference": "7beeb2b885cd584cd01e126c5777206ae4c3c6a3", "shasum": "" }, "require": { @@ -11725,7 +11726,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.2.0" + "source": "https://github.com/symfony/uid/tree/v7.3.0" }, "funding": [ { @@ -11741,24 +11742,25 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2025-05-24T14:28:13+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb" + "reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9c46038cd4ed68952166cf7001b54eb539184ccb", - "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/548f6760c54197b1084e1e5c71f6d9d523f2f78e", + "reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -11808,7 +11810,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.6" + "source": "https://github.com/symfony/var-dumper/tree/v7.3.0" }, "funding": [ { @@ -11824,20 +11826,20 @@ "type": "tidelift" } ], - "time": "2025-04-09T08:14:01+00:00" + "time": "2025-04-27T18:39:23+00:00" }, { "name": "symfony/yaml", - "version": "v7.2.6", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "0feafffb843860624ddfd13478f481f4c3cd8b23" + "reference": "cea40a48279d58dc3efee8112634cb90141156c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/0feafffb843860624ddfd13478f481f4c3cd8b23", - "reference": "0feafffb843860624ddfd13478f481f4c3cd8b23", + "url": "https://api.github.com/repos/symfony/yaml/zipball/cea40a48279d58dc3efee8112634cb90141156c2", + "reference": "cea40a48279d58dc3efee8112634cb90141156c2", "shasum": "" }, "require": { @@ -11880,7 +11882,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.6" + "source": "https://github.com/symfony/yaml/tree/v7.3.0" }, "funding": [ { @@ -11896,7 +11898,7 @@ "type": "tidelift" } ], - "time": "2025-04-04T10:10:11+00:00" + "time": "2025-04-04T10:10:33+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", diff --git a/database/Factories/NodeFactory.php b/database/Factories/NodeFactory.php index 030bd3e38..295c312ae 100644 --- a/database/Factories/NodeFactory.php +++ b/database/Factories/NodeFactory.php @@ -38,6 +38,7 @@ class NodeFactory extends Factory 'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH), 'daemon_token' => Str::random(Node::DAEMON_TOKEN_LENGTH), 'daemon_listen' => 8080, + 'daemon_connect' => 8080, 'daemon_sftp' => 2022, 'daemon_base' => '/var/lib/panel/volumes', 'maintenance_mode' => false, diff --git a/database/migrations/2025_06_02_073349_add_daemon_connect_to_nodes.php b/database/migrations/2025_06_02_073349_add_daemon_connect_to_nodes.php new file mode 100644 index 000000000..90f01b0bc --- /dev/null +++ b/database/migrations/2025_06_02_073349_add_daemon_connect_to_nodes.php @@ -0,0 +1,28 @@ +smallInteger('daemon_connect')->unsigned()->default(8080); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('daemon_connect'); + }); + } +}; diff --git a/lang/en/admin/node.php b/lang/en/admin/node.php index 582d3a808..6aed06229 100644 --- a/lang/en/admin/node.php +++ b/lang/en/admin/node.php @@ -45,6 +45,10 @@ return [ 'port' => 'Port', 'ports' => 'Ports', 'port_help' => 'If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.', + 'connect_port' => 'Connection Port', + 'connect_port_help' => 'Connections to wings will use this port. If you are using a reverse proxy this can differ from the listen port. When using Cloudflare proxy you should use 8443.', + 'listen_port' => 'Listening Port', + 'listen_port_help' => 'Wings will listen on this port.', 'display_name' => 'Display Name', 'ssl' => 'Communicate over SSL', 'panel_on_ssl' => 'Your Panel is using a secure SSL connection,
so your Daemon must too.', diff --git a/lang/en/commands.php b/lang/en/commands.php index b6fa6c9ca..659a7aa9b 100644 --- a/lang/en/commands.php +++ b/lang/en/commands.php @@ -36,6 +36,7 @@ return [ 'cpu_overallocate' => 'Enter the amount of cpu to over allocate by, -1 will disable checking and 0 will prevent creating new server', 'upload_size' => "'Enter the maximum filesize upload", 'daemonListen' => 'Enter the daemon listening port', + 'daemonConnect' => 'Enter the daemon connecting port (can be same as listen port)', 'daemonSFTP' => 'Enter the daemon SFTP listening port', 'daemonSFTPAlias' => 'Enter the daemon SFTP alias (can be empty)', 'daemonBase' => 'Enter the base folder', diff --git a/resources/views/livewire/columns/server-entry-column.blade.php b/resources/views/livewire/columns/server-entry-column.blade.php new file mode 100644 index 000000000..332b1a988 --- /dev/null +++ b/resources/views/livewire/columns/server-entry-column.blade.php @@ -0,0 +1,8 @@ +@php + /** @var \App\Models\Server $server */ + $server = $getRecord(); +@endphp + +
+ @livewire('server-entry', ['server' => $server, 'lazy' => true], key($server->id)) +
\ No newline at end of file diff --git a/resources/views/livewire/server-entry.blade.php b/resources/views/livewire/server-entry.blade.php new file mode 100644 index 000000000..27fb2def0 --- /dev/null +++ b/resources/views/livewire/server-entry.blade.php @@ -0,0 +1,47 @@ +
+
+
+ +
+
+ +

+ {{ $server->name }} + ({{ $server->formatResource('uptime', type: \App\Enums\ServerResourceType::Time) }}) +

+
+ +
+
+

CPU

+

{{ $server->formatResource('cpu_absolute', type: \App\Enums\ServerResourceType::Percentage) }}

+
+

{{ $server->formatResource('cpu', type: \App\Enums\ServerResourceType::Percentage, limit: true) }}

+
+
+

Memory

+

{{ $server->formatResource('memory_bytes') }}

+
+

{{ $server->formatResource('memory', limit: true) }}

+
+
+

Disk

+

{{ $server->formatResource('disk_bytes') }}

+
+

{{ $server->formatResource('disk', limit: true) }}

+
+ +
+
+
\ No newline at end of file diff --git a/resources/views/tables/columns/server-entry-column.blade.php b/resources/views/tables/columns/server-entry-column.blade.php deleted file mode 100644 index 152db35b6..000000000 --- a/resources/views/tables/columns/server-entry-column.blade.php +++ /dev/null @@ -1,63 +0,0 @@ -@php - use App\Enums\ServerResourceType; - - /** @var \App\Models\Server $server */ - $server = $getRecord(); -@endphp - - - - -
-
-
-
- -
-
- -

- {{ $server->name }} - ({{ $server->formatResource('uptime', type: ServerResourceType::Time) }}) -

-
- -
-
-

CPU

-

{{ $server->formatResource('cpu_absolute', type: ServerResourceType::Percentage) }}

-
-

{{ $server->formatResource('cpu', type: ServerResourceType::Percentage, limit: true) }}

-
-
-

Memory

-

{{ $server->formatResource('memory_bytes') }}

-
-

{{ $server->formatResource('memory', limit: true) }}

-
-
-

Disk

-

{{ $server->formatResource('disk_bytes') }}

-
-

{{ $server->formatResource('disk', limit: true) }}

-
- -
-
-
-
diff --git a/tests/Unit/Helpers/EnvironmentWriterTraitTest.php b/tests/Unit/Helpers/EnvironmentWriterTraitTest.php deleted file mode 100644 index 4678c0579..000000000 --- a/tests/Unit/Helpers/EnvironmentWriterTraitTest.php +++ /dev/null @@ -1,43 +0,0 @@ -escapeEnvironmentValue($input); - - $this->assertSame($expected, $output); - } - - public static function variableDataProvider(): array - { - return [ - ['foo', 'foo'], - ['abc123', 'abc123'], - ['val"ue', '"val\"ue"'], - ['val\'ue', '"val\'ue"'], - ['my test value', '"my test value"'], - ['mysql_p@assword', '"mysql_p@assword"'], - ['mysql_p#assword', '"mysql_p#assword"'], - ['mysql p@$$word', '"mysql p@$$word"'], - ['mysql p%word', '"mysql p%word"'], - ['mysql p#word', '"mysql p#word"'], - ['abc_@#test', '"abc_@#test"'], - ['test 123 $$$', '"test 123 $$$"'], - ['#password%', '"#password%"'], - ['$pass ', '"$pass "'], - ]; - } -} - -class FooClass -{ - use EnvironmentWriterTrait; -}