diff --git a/.github/docker/default.conf b/.github/docker/default.conf deleted file mode 100644 index a6bd58d720..0000000000 --- a/.github/docker/default.conf +++ /dev/null @@ -1,75 +0,0 @@ -# If using Ubuntu this file should be placed in: -# /etc/nginx/sites-available/ -# -# If using CentOS this file should be placed in: -# /etc/nginx/conf.d/ -# - -# The MIT License (MIT) -# -# Pterodactyl® -# Copyright © Dane Everitt and contributors -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -server { - listen 80; - server_name _; - - root /app/public; - index index.html index.htm index.php; - charset utf-8; - - location / { - try_files $uri $uri/ /index.php?$query_string; - } - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - - access_log off; - error_log /var/log/nginx/panel.app-error.log error; - - # allow larger file uploads and longer script runtimes - client_max_body_size 100m; - client_body_timeout 120s; - - sendfile off; - - location ~ \.php$ { - fastcgi_split_path_info ^(.+\.php)(/.+)$; - # the fastcgi_pass path needs to be changed accordingly when using CentOS - fastcgi_pass 127.0.0.1:9000; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param HTTP_PROXY ""; - fastcgi_intercept_errors off; - fastcgi_buffer_size 16k; - fastcgi_buffers 4 16k; - fastcgi_connect_timeout 300; - fastcgi_send_timeout 300; - fastcgi_read_timeout 300; - } - - location ~ /\.ht { - deny all; - } -} diff --git a/.github/docker/default_ssl.conf b/.github/docker/default_ssl.conf deleted file mode 100644 index 930a38daa6..0000000000 --- a/.github/docker/default_ssl.conf +++ /dev/null @@ -1,70 +0,0 @@ -# If using Ubuntu this file should be placed in: -# /etc/nginx/sites-available/ -# -server { - listen 80; - server_name ; - return 301 https://$server_name$request_uri; -} - -server { - listen 443 ssl http2; - server_name ; - - root /app/public; - index index.php; - - access_log /var/log/nginx/panel.app-access.log; - error_log /var/log/nginx/panel.app-error.log error; - - # allow larger file uploads and longer script runtimes - client_max_body_size 100m; - client_body_timeout 120s; - - sendfile off; - - # strengthen ssl security - ssl_certificate /etc/letsencrypt/live//fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live//privkey.pem; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; - - # See the link below for more SSL information: - # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html - # - # ssl_dhparam /etc/ssl/certs/dhparam.pem; - - # Add headers to serve security related headers - add_header Strict-Transport-Security "max-age=15768000; preload;"; - add_header X-Content-Type-Options nosniff; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Robots-Tag none; - add_header Content-Security-Policy "frame-ancestors 'self'"; - - location / { - try_files $uri $uri/ /index.php?$query_string; - } - - location ~ \.php$ { - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass 127.0.0.1:9000; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M"; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param HTTP_PROXY ""; - fastcgi_intercept_errors off; - fastcgi_buffer_size 16k; - fastcgi_buffers 4 16k; - fastcgi_connect_timeout 300; - fastcgi_send_timeout 300; - fastcgi_read_timeout 300; - include /etc/nginx/fastcgi_params; - } - - location ~ /\.ht { - deny all; - } -} diff --git a/.github/docker/www.conf b/.github/docker/www.conf deleted file mode 100644 index c0c17903f3..0000000000 --- a/.github/docker/www.conf +++ /dev/null @@ -1,16 +0,0 @@ -[www] - -user = nginx -group = nginx - -listen = 127.0.0.1:9000 -listen.owner = nginx -listen.group = nginx -listen.mode = 0750 - -pm = ondemand -pm.max_children = 9 -pm.process_idle_timeout = 10s -pm.max_requests = 200 - -clear_env = no \ No newline at end of file diff --git a/app/Console/Commands/Schedule/ProcessRunnableCommand.php b/app/Console/Commands/Schedule/ProcessRunnableCommand.php index d773cb2b2f..57a8bb48b8 100644 --- a/app/Console/Commands/Schedule/ProcessRunnableCommand.php +++ b/app/Console/Commands/Schedule/ProcessRunnableCommand.php @@ -6,6 +6,7 @@ use App\Models\Schedule; use Illuminate\Database\Eloquent\Builder; use App\Services\Schedules\ProcessScheduleService; +use Throwable; class ProcessRunnableCommand extends Command { @@ -13,10 +14,7 @@ class ProcessRunnableCommand extends Command protected $description = 'Process schedules in the database and determine which are ready to run.'; - /** - * Handle command execution. - */ - public function handle(): int + public function handle(ProcessScheduleService $processScheduleService): int { $schedules = Schedule::query() ->with('tasks') @@ -35,7 +33,7 @@ public function handle(): int $bar = $this->output->createProgressBar(count($schedules)); foreach ($schedules as $schedule) { $bar->clear(); - $this->processSchedule($schedule); + $this->processSchedule($processScheduleService, $schedule); $bar->advance(); $bar->display(); } @@ -50,20 +48,20 @@ public function handle(): int * never throw an exception out, otherwise you'll end up killing the entire run group causing * any other schedules to not process correctly. */ - protected function processSchedule(Schedule $schedule): void + protected function processSchedule(ProcessScheduleService $processScheduleService, Schedule $schedule): void { if ($schedule->tasks->isEmpty()) { return; } try { - $this->getLaravel()->make(ProcessScheduleService::class)->handle($schedule); + $processScheduleService->handle($schedule); $this->line(trans('command/messages.schedule.output_line', [ 'schedule' => $schedule->name, 'id' => $schedule->id, ])); - } catch (\Throwable|\Exception $exception) { + } catch (Throwable $exception) { logger()->error($exception, ['schedule_id' => $schedule->id]); $this->error(__('commands.schedule.process.no_tasks') . " #$schedule->id: " . $exception->getMessage()); diff --git a/app/Console/Commands/Server/BulkPowerActionCommand.php b/app/Console/Commands/Server/BulkPowerActionCommand.php index 52bcb3e428..1aae626850 100644 --- a/app/Console/Commands/Server/BulkPowerActionCommand.php +++ b/app/Console/Commands/Server/BulkPowerActionCommand.php @@ -19,26 +19,13 @@ class BulkPowerActionCommand extends Command protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.'; - /** - * BulkPowerActionCommand constructor. - */ - public function __construct(private DaemonPowerRepository $powerRepository, private ValidatorFactory $validator) - { - parent::__construct(); - } - - /** - * Handle the bulk power request. - * - * @throws \Illuminate\Validation\ValidationException - */ - public function handle(): void + public function handle(DaemonPowerRepository $powerRepository, ValidatorFactory $validator): void { $action = $this->argument('action'); $nodes = empty($this->option('nodes')) ? [] : explode(',', $this->option('nodes')); $servers = empty($this->option('servers')) ? [] : explode(',', $this->option('servers')); - $validator = $this->validator->make([ + $validator = $validator->make([ 'action' => $action, 'nodes' => $nodes, 'servers' => $servers, @@ -64,11 +51,14 @@ public function handle(): void } $bar = $this->output->createProgressBar($count); - $powerRepository = $this->powerRepository; - // @phpstan-ignore-next-line - $this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) { + + $this->getQueryBuilder($servers, $nodes)->get()->each(function ($server, int $index) use ($action, $powerRepository, &$bar): mixed { $bar->clear(); + if (!$server instanceof Server) { + return null; + } + try { $powerRepository->setServer($server)->send($action); } catch (Exception $exception) { @@ -82,6 +72,8 @@ public function handle(): void $bar->advance(); $bar->display(); + + return null; }); $this->line(''); diff --git a/app/Console/Commands/UpgradeCommand.php b/app/Console/Commands/UpgradeCommand.php index 145e6e0c6f..e464eb0a10 100644 --- a/app/Console/Commands/UpgradeCommand.php +++ b/app/Console/Commands/UpgradeCommand.php @@ -39,10 +39,6 @@ public function handle(): void $this->line($this->getUrl()); } - if (version_compare(PHP_VERSION, '7.4.0') < 0) { - $this->error(__('commands.upgrade.php_version') . ' [' . PHP_VERSION . '].'); - } - $user = 'www-data'; $group = 'www-data'; if ($this->input->isInteractive()) { diff --git a/app/Eloquent/BackupQueryBuilder.php b/app/Eloquent/BackupQueryBuilder.php new file mode 100644 index 0000000000..53f10a28f4 --- /dev/null +++ b/app/Eloquent/BackupQueryBuilder.php @@ -0,0 +1,24 @@ + + */ +class BackupQueryBuilder extends Builder +{ + public function nonFailed(): self + { + $this->where(function (Builder $query) { + $query + ->whereNull('completed_at') + ->orWhere('is_successful', true); + }); + + return $this; + } +} diff --git a/app/Enums/EditorLanguages.php b/app/Enums/EditorLanguages.php index 26f4520d93..91dcaebe78 100644 --- a/app/Enums/EditorLanguages.php +++ b/app/Enums/EditorLanguages.php @@ -91,7 +91,7 @@ enum EditorLanguages: string implements HasLabel case yaml = 'yaml'; case json = 'json'; - public function getLabel(): ?string + public function getLabel(): string { return $this->name; } diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 5fc4fe5e86..685aa0a553 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -20,6 +20,7 @@ use Symfony\Component\Mailer\Exception\TransportException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; +use Throwable; class Handler extends ExceptionHandler { @@ -179,10 +180,7 @@ public function invalidJson($request, ValidationException $exception): JsonRespo return response()->json(['errors' => $errors], $exception->status); } - /** - * Return the exception as a JSONAPI representation for use on API requests. - */ - protected function convertExceptionToArray(\Throwable $e, array $override = []): array + public static function exceptionToArray(Throwable $e, array $override = []): array { $match = self::$exceptionResponseCodes[get_class($e)] ?? null; @@ -214,7 +212,7 @@ protected function convertExceptionToArray(\Throwable $e, array $override = []): 'trace' => Collection::make($e->getTrace()) ->map(fn ($trace) => Arr::except($trace, ['args'])) ->all(), - 'previous' => Collection::make($this->extractPrevious($e)) + 'previous' => Collection::make(self::extractPrevious($e)) ->map(fn ($exception) => $exception->getTrace()) ->map(fn ($trace) => Arr::except($trace, ['args'])) ->all(), @@ -225,6 +223,14 @@ protected function convertExceptionToArray(\Throwable $e, array $override = []): return ['errors' => [array_merge($error, $override)]]; } + /** + * Return the exception as a JSONAPI representation for use on API requests. + */ + protected function convertExceptionToArray(Throwable $e, array $override = []): array + { + return self::exceptionToArray($e, $override); + } + /** * Return an array of exceptions that should not be reported. */ @@ -251,15 +257,12 @@ protected function unauthenticated($request, AuthenticationException $exception) * Extracts all the previous exceptions that lead to the one passed into this * function being thrown. * - * @return \Throwable[] + * @return Throwable[] */ - protected function extractPrevious(\Throwable $e): array + public static function extractPrevious(Throwable $e): array { $previous = []; while ($value = $e->getPrevious()) { - if (!$value instanceof \Throwable) { - break; - } $previous[] = $value; $e = $value; } @@ -273,7 +276,6 @@ protected function extractPrevious(\Throwable $e): array */ public static function toArray(\Throwable $e): array { - // @phpstan-ignore-next-line - return (new self(app()))->convertExceptionToArray($e); + return self::exceptionToArray($e); } } diff --git a/app/Extensions/Filesystem/S3Filesystem.php b/app/Extensions/Filesystem/S3Filesystem.php index 6ce793b996..6535dc6f31 100644 --- a/app/Extensions/Filesystem/S3Filesystem.php +++ b/app/Extensions/Filesystem/S3Filesystem.php @@ -1,28 +1,5 @@ and contributors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. */ - namespace App\Extensions\Filesystem; use Aws\S3\S3ClientInterface; diff --git a/app/Filament/Admin/Pages/Health.php b/app/Filament/Admin/Pages/Health.php index 651883dcf7..f1279f20fa 100644 --- a/app/Filament/Admin/Pages/Health.php +++ b/app/Filament/Admin/Pages/Health.php @@ -8,7 +8,7 @@ use Filament\Pages\Page; use Illuminate\Support\Facades\Artisan; use Spatie\Health\Commands\RunHealthChecksCommand; -use Spatie\Health\ResultStores\ResultStore; +use Facades\Spatie\Health\ResultStores\ResultStore; class Health extends Page { @@ -18,10 +18,12 @@ class Health extends Page protected static string $view = 'filament.pages.health'; - // @phpstan-ignore-next-line - protected $listeners = [ - 'refresh-component' => '$refresh', - ]; + protected function getListeners(): array + { + return [ + 'refresh-component' => '$refresh', + ]; + } public static function canAccess(): bool { @@ -39,8 +41,7 @@ protected function getActions(): array protected function getViewData(): array { - // @phpstan-ignore-next-line - $checkResults = app(ResultStore::class)->latestResults(); + $checkResults = ResultStore::latestResults(); if ($checkResults === null) { Artisan::call(RunHealthChecksCommand::class); @@ -68,8 +69,7 @@ public function refresh(): void public static function getNavigationBadge(): ?string { - // @phpstan-ignore-next-line - $results = app(ResultStore::class)->latestResults(); + $results = ResultStore::latestResults(); if ($results === null) { return null; @@ -91,8 +91,7 @@ public static function getNavigationBadgeColor(): string public static function getNavigationBadgeTooltip(): ?string { - // @phpstan-ignore-next-line - $results = app(ResultStore::class)->latestResults(); + $results = ResultStore::latestResults(); if ($results === null) { return null; @@ -113,8 +112,7 @@ public static function getNavigationBadgeTooltip(): ?string public static function getNavigationIcon(): string { - // @phpstan-ignore-next-line - $results = app(ResultStore::class)->latestResults(); + $results = ResultStore::latestResults(); if ($results === null) { return 'tabler-heart-question'; diff --git a/app/Filament/Admin/Resources/UserResource/Pages/EditUser.php b/app/Filament/Admin/Resources/UserResource/Pages/EditUser.php index 40c0f2957e..b17707b534 100644 --- a/app/Filament/Admin/Resources/UserResource/Pages/EditUser.php +++ b/app/Filament/Admin/Resources/UserResource/Pages/EditUser.php @@ -5,6 +5,7 @@ use App\Filament\Admin\Resources\UserResource; use App\Models\Role; use App\Models\User; +use App\Services\Helpers\LanguageService; use Filament\Actions\DeleteAction; use Filament\Forms\Components\CheckboxList; use Filament\Forms\Components\Hidden; @@ -40,7 +41,7 @@ public function form(Form $form): Form ->required() ->hidden() ->default('en') - ->options(fn (User $user) => $user->getAvailableLanguages()), + ->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages()), Hidden::make('skipValidation') ->default(true), CheckboxList::make('roles') diff --git a/app/Filament/Admin/Resources/UserResource/RelationManagers/ServersRelationManager.php b/app/Filament/Admin/Resources/UserResource/RelationManagers/ServersRelationManager.php index 52cba96188..a69801769e 100644 --- a/app/Filament/Admin/Resources/UserResource/RelationManagers/ServersRelationManager.php +++ b/app/Filament/Admin/Resources/UserResource/RelationManagers/ServersRelationManager.php @@ -12,6 +12,7 @@ use Filament\Tables\Columns\SelectColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Collection; class ServersRelationManager extends RelationManager { @@ -34,7 +35,9 @@ public function table(Table $table): Table ->label('Suspend All Servers') ->color('warning') ->action(function (SuspensionService $suspensionService) use ($user) { - foreach ($user->servers()->whereNot('status', ServerState::Suspended)->get() as $server) { + /** @var Collection $servers */ + $servers = $user->servers()->whereNot('status', ServerState::Suspended)->get(); + foreach ($servers as $server) { $suspensionService->handle($server, SuspendAction::Suspend); } }), @@ -43,7 +46,9 @@ public function table(Table $table): Table ->label('Unsuspend All Servers') ->color('primary') ->action(function (SuspensionService $suspensionService) use ($user) { - foreach ($user->servers()->where('status', ServerState::Suspended)->get() as $server) { + /** @var Collection $servers */ + $servers = $user->servers()->where('status', ServerState::Suspended)->get(); + foreach ($servers as $server) { $suspensionService->handle($server, SuspendAction::Unsuspend); } }), diff --git a/app/Filament/Components/Actions/ImportEggAction.php b/app/Filament/Components/Actions/ImportEggAction.php index f3026caed7..294e0433ed 100644 --- a/app/Filament/Components/Actions/ImportEggAction.php +++ b/app/Filament/Components/Actions/ImportEggAction.php @@ -10,7 +10,6 @@ use Filament\Forms\Components\Tabs\Tab; use Filament\Forms\Components\TextInput; use Filament\Notifications\Notification; -use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; class ImportEggAction extends Action { @@ -55,7 +54,6 @@ protected function setUp(): void $this->action(function (array $data, EggImporterService $eggImportService): void { try { if (!empty($data['egg'])) { - /** @var TemporaryUploadedFile[] $eggFile */ $eggFile = $data['egg']; foreach ($eggFile as $file) { diff --git a/app/Filament/Components/Tables/Actions/ImportEggAction.php b/app/Filament/Components/Tables/Actions/ImportEggAction.php index e8a82a3013..ae2fe68b4a 100644 --- a/app/Filament/Components/Tables/Actions/ImportEggAction.php +++ b/app/Filament/Components/Tables/Actions/ImportEggAction.php @@ -10,7 +10,6 @@ use Filament\Forms\Components\TextInput; use Filament\Notifications\Notification; use Filament\Tables\Actions\Action; -use Livewire\Features\SupportFileUploads\TemporaryUploadedFile; class ImportEggAction extends Action { @@ -55,7 +54,6 @@ protected function setUp(): void $this->action(function (array $data, EggImporterService $eggImportService): void { try { if (!empty($data['egg'])) { - /** @var TemporaryUploadedFile[] $eggFile */ $eggFile = $data['egg']; foreach ($eggFile as $file) { diff --git a/app/Filament/Components/Tables/Columns/DateTimeColumn.php b/app/Filament/Components/Tables/Columns/DateTimeColumn.php index 33dc08ec79..05793276e6 100644 --- a/app/Filament/Components/Tables/Columns/DateTimeColumn.php +++ b/app/Filament/Components/Tables/Columns/DateTimeColumn.php @@ -23,6 +23,6 @@ public function since(?string $timezone = null): static public function getTimezone(): string { - return auth()->user()?->timezone ?? config('app.timezone', 'UTC'); + return auth()->user()->timezone ?? config('app.timezone', 'UTC'); } } diff --git a/app/Filament/Pages/Auth/EditProfile.php b/app/Filament/Pages/Auth/EditProfile.php index 9e3f6e0273..911ff39fd2 100644 --- a/app/Filament/Pages/Auth/EditProfile.php +++ b/app/Filament/Pages/Auth/EditProfile.php @@ -7,6 +7,7 @@ use App\Models\ActivityLog; use App\Models\ApiKey; use App\Models\User; +use App\Services\Helpers\LanguageService; use App\Services\Users\ToggleTwoFactorService; use App\Services\Users\TwoFactorSetupService; use App\Services\Users\UserUpdateService; @@ -114,13 +115,12 @@ protected function getForms(): array ->prefixIcon('tabler-flag') ->live() ->default('en') - ->helperText(fn (User $user, $state) => new HtmlString($user->isLanguageTranslated($state) ? '' : " + ->helperText(fn ($state, LanguageService $languageService) => new HtmlString($languageService->isLanguageTranslated($state) ? '' : " Your language ($state) has not been translated yet! But never fear, you can help fix that by contributing directly here. - ") - ) - ->options(fn (User $user) => $user->getAvailableLanguages()), + ")) + ->options(fn (LanguageService $languageService) => $languageService->getAvailableLanguages()), ]), Tab::make('OAuth') @@ -202,38 +202,30 @@ protected function getForms(): array 'addLogoSpace' => true, 'logoSpaceWidth' => 13, 'logoSpaceHeight' => 13, + 'version' => Version::AUTO, + // 'outputInterface' => QRSvgWithLogo::class, + 'outputBase64' => false, + 'eccLevel' => EccLevel::H, // ECC level H is necessary when using logos + 'addQuietzone' => true, + // 'drawLightModules' => true, + 'connectPaths' => true, + 'drawCircularModules' => true, + // 'circleRadius' => 0.45, + 'svgDefs' => ' + + + + + + + ', ]); // https://github.com/chillerlan/php-qrcode/blob/main/examples/svgWithLogo.php - // QROptions - // @phpstan-ignore property.protected - $options->version = Version::AUTO; - // $options->outputInterface = QRSvgWithLogo::class; - // @phpstan-ignore property.protected - $options->outputBase64 = false; - // @phpstan-ignore property.protected - $options->eccLevel = EccLevel::H; // ECC level H is necessary when using logos - // @phpstan-ignore property.protected - $options->addQuietzone = true; - // $options->drawLightModules = true; - // @phpstan-ignore property.protected - $options->connectPaths = true; - // @phpstan-ignore property.protected - $options->drawCircularModules = true; - // $options->circleRadius = 0.45; - - // @phpstan-ignore property.protected - $options->svgDefs = ' - - - - - '; - $image = (new QRCode($options))->render($url); return [ diff --git a/app/Filament/Server/Resources/DatabaseResource/Pages/ListDatabases.php b/app/Filament/Server/Resources/DatabaseResource/Pages/ListDatabases.php index ab4b418e73..bce64b791f 100644 --- a/app/Filament/Server/Resources/DatabaseResource/Pages/ListDatabases.php +++ b/app/Filament/Server/Resources/DatabaseResource/Pages/ListDatabases.php @@ -6,7 +6,6 @@ use App\Filament\Components\Tables\Columns\DateTimeColumn; use App\Filament\Server\Resources\DatabaseResource; use App\Models\Database; -use App\Models\DatabaseHost; use App\Models\Permission; use App\Models\Server; use App\Services\Databases\DatabaseManagementService; @@ -99,7 +98,7 @@ protected function getHeaderActions(): array ->columnSpan(2) ->required() ->placeholder('Select Database Host') - ->options(fn () => $server->node->databaseHosts->mapWithKeys(fn (DatabaseHost $databaseHost) => [$databaseHost->id => $databaseHost->name])), + ->options(fn () => $server->node->databaseHosts->mapWithKeys(fn ($databaseHost) => [$databaseHost->id => $databaseHost->name])), TextInput::make('database') ->columnSpan(1) ->label('Database Name') diff --git a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php index 1f83193ba1..69ad897d16 100644 --- a/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php +++ b/app/Filament/Server/Resources/FileResource/Pages/ListFiles.php @@ -357,8 +357,7 @@ public function table(Table $table): Table ->action(function (Collection $files, $data, DaemonFileRepository $fileRepository) use ($server) { $location = resolve_path(join_paths($this->path, $data['location'])); - // @phpstan-ignore-next-line - $files = $files->map(fn ($file) => ['to' => $location, 'from' => $file->name])->toArray(); + $files = $files->map(fn ($file) => ['to' => $location, 'from' => $file['name']])->toArray(); $fileRepository ->setServer($server) ->renameFiles($this->path, $files); @@ -376,8 +375,7 @@ public function table(Table $table): Table BulkAction::make('archive') ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_ARCHIVE, $server)) ->action(function (Collection $files, DaemonFileRepository $fileRepository) use ($server) { - // @phpstan-ignore-next-line - $files = $files->map(fn ($file) => $file->name)->toArray(); + $files = $files->map(fn ($file) => $file['name'])->toArray(); $fileRepository ->setServer($server) @@ -398,8 +396,7 @@ public function table(Table $table): Table DeleteBulkAction::make() ->authorize(fn () => auth()->user()->can(Permission::ACTION_FILE_DELETE, $server)) ->action(function (Collection $files, DaemonFileRepository $fileRepository) use ($server) { - // @phpstan-ignore-next-line - $files = $files->map(fn ($file) => $file->name)->toArray(); + $files = $files->map(fn ($file) => $file['name'])->toArray(); $fileRepository ->setServer($server) ->deleteFiles($this->path, $files); diff --git a/app/Filament/Server/Widgets/ServerConsole.php b/app/Filament/Server/Widgets/ServerConsole.php index 851b4b3a30..f1ca9f3709 100644 --- a/app/Filament/Server/Widgets/ServerConsole.php +++ b/app/Filament/Server/Widgets/ServerConsole.php @@ -30,16 +30,25 @@ class ServerConsole extends Widget public string $input = ''; + private GetUserPermissionsService $getUserPermissionsService; + + private NodeJWTService $nodeJWTService; + + public function boot(GetUserPermissionsService $getUserPermissionsService, NodeJWTService $nodeJWTService): void + { + $this->getUserPermissionsService = $getUserPermissionsService; + $this->nodeJWTService = $nodeJWTService; + } + protected function getToken(): string { if (!$this->user || !$this->server || $this->user->cannot(Permission::ACTION_WEBSOCKET_CONNECT, $this->server)) { throw new HttpForbiddenException('You do not have permission to connect to this server\'s websocket.'); } - // @phpstan-ignore-next-line - $permissions = app(GetUserPermissionsService::class)->handle($this->server, $this->user); - // @phpstan-ignore-next-line - return app(NodeJWTService::class) + $permissions = $this->getUserPermissionsService->handle($this->server, $this->user); + + return $this->nodeJWTService ->setExpiresAt(now()->addMinutes(10)->toImmutable()) ->setUser($this->user) ->setClaims([ diff --git a/app/Http/Controllers/Api/Client/AccountController.php b/app/Http/Controllers/Api/Client/AccountController.php index 6a0862d6b5..eb1303539d 100644 --- a/app/Http/Controllers/Api/Client/AccountController.php +++ b/app/Http/Controllers/Api/Client/AccountController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Api\Client; +use Illuminate\Auth\SessionGuard; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Auth\AuthManager; @@ -63,8 +64,7 @@ public function updatePassword(UpdatePasswordRequest $request): JsonResponse // other devices functionality to work. $guard->setUser($user); - // This method doesn't exist in the stateless Sanctum world. - if (method_exists($guard, 'logoutOtherDevices')) { + if ($guard instanceof SessionGuard) { $guard->logoutOtherDevices($request->input('password')); } diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index ab1e441e24..9fc96e36d0 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -22,14 +22,11 @@ class BackupController extends ClientApiController { - /** - * BackupController constructor. - */ public function __construct( - private DaemonBackupRepository $daemonRepository, - private DeleteBackupService $deleteBackupService, - private InitiateBackupService $initiateBackupService, - private DownloadLinkService $downloadLinkService, + private readonly DaemonBackupRepository $daemonRepository, + private readonly DeleteBackupService $deleteBackupService, + private readonly InitiateBackupService $initiateBackupService, + private readonly DownloadLinkService $downloadLinkService, ) { parent::__construct(); } @@ -38,7 +35,7 @@ public function __construct( * Returns all the backups for a given server instance in a paginated * result set. * - * @throws \Illuminate\Auth\Access\AuthorizationException + * @throws AuthorizationException */ public function index(Request $request, Server $server): array { diff --git a/app/Http/Controllers/Api/Client/Servers/CommandController.php b/app/Http/Controllers/Api/Client/Servers/CommandController.php index f367c204d6..1591f38186 100644 --- a/app/Http/Controllers/Api/Client/Servers/CommandController.php +++ b/app/Http/Controllers/Api/Client/Servers/CommandController.php @@ -5,7 +5,6 @@ use Illuminate\Http\Response; use App\Models\Server; use App\Facades\Activity; -use Psr\Http\Message\ResponseInterface; use GuzzleHttp\Exception\BadResponseException; use Symfony\Component\HttpKernel\Exception\HttpException; use App\Http\Controllers\Api\Client\ClientApiController; @@ -28,7 +27,7 @@ public function index(SendCommandRequest $request, Server $server): Response $previous = $exception->getPrevious(); if ($previous instanceof BadResponseException) { - if ($previous->getResponse() instanceof ResponseInterface && $previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY) { + if ($previous->getResponse()->getStatusCode() === Response::HTTP_BAD_GATEWAY) { throw new HttpException(Response::HTTP_BAD_GATEWAY, 'Server must be online in order to send commands.', $exception); } } diff --git a/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php b/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php index 04d5ca29d8..73d9eef430 100644 --- a/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php +++ b/app/Http/Controllers/Api/Remote/SftpAuthenticationController.php @@ -158,6 +158,6 @@ protected function throttleKey(Request $request): string { $username = explode('.', strrev($request->input('username', ''))); - return strtolower(strrev($username[0] ?? '') . '|' . $request->ip()); + return strtolower(strrev($username[0]) . '|' . $request->ip()); } } diff --git a/app/Http/Controllers/Auth/AbstractLoginController.php b/app/Http/Controllers/Auth/AbstractLoginController.php deleted file mode 100644 index 4a6fa719f1..0000000000 --- a/app/Http/Controllers/Auth/AbstractLoginController.php +++ /dev/null @@ -1,106 +0,0 @@ -lockoutTime = config('auth.lockout.time'); - $this->maxLoginAttempts = config('auth.lockout.attempts'); - $this->auth = Container::getInstance()->make(AuthManager::class); - } - - /** - * Get the failed login response instance. - * - * @throws \App\Exceptions\DisplayException - */ - protected function sendFailedLoginResponse(Request $request, ?Authenticatable $user = null, ?string $message = null): never - { - $this->incrementLoginAttempts($request); - $this->fireFailedLoginEvent($user, [ - $this->getField($request->input('user')) => $request->input('user'), - ]); - - if ($request->route()->named('auth.login-checkpoint')) { - throw new DisplayException($message ?? trans('auth.two_factor.checkpoint_failed')); - } - - throw new DisplayException(trans('auth.failed')); - } - - /** - * Send the response after the user was authenticated. - */ - protected function sendLoginResponse(User $user, Request $request): JsonResponse - { - $request->session()->remove('auth_confirmation_token'); - $request->session()->regenerate(); - - $this->clearLoginAttempts($request); - - $this->auth->guard()->login($user, true); - - Event::dispatch(new DirectLogin($user, true)); - - return new JsonResponse([ - 'data' => [ - 'complete' => true, - 'intended' => $this->redirectPath(), - 'user' => $user->toReactObject(), - ], - ]); - } - - /** - * Determine if the user is logging in using an email or username. - */ - protected function getField(?string $input = null): string - { - return ($input && str_contains($input, '@')) ? 'email' : 'username'; - } - - /** - * Fire a failed login event. - */ - protected function fireFailedLoginEvent(?Authenticatable $user = null, array $credentials = []): void - { - Event::dispatch(new Failed('auth', $user, $credentials)); - } -} diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php deleted file mode 100644 index f58aded823..0000000000 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ /dev/null @@ -1,38 +0,0 @@ -ip(), $request->input('email'))); - - return $this->sendResetLinkResponse($request, Password::RESET_LINK_SENT); - } - - /** - * Get the response for a successful password reset link. - */ - protected function sendResetLinkResponse(Request $request, string $response): JsonResponse - { - return response()->json([ - 'status' => trans($response), - ]); - } -} diff --git a/app/Http/Controllers/Auth/LoginCheckpointController.php b/app/Http/Controllers/Auth/LoginCheckpointController.php deleted file mode 100644 index 8797f533be..0000000000 --- a/app/Http/Controllers/Auth/LoginCheckpointController.php +++ /dev/null @@ -1,124 +0,0 @@ -hasTooManyLoginAttempts($request)) { - $this->sendLockoutResponse($request); - } - - $details = $request->session()->get('auth_confirmation_token'); - if (!$this->hasValidSessionData($details)) { - $this->sendFailedLoginResponse($request, null, self::TOKEN_EXPIRED_MESSAGE); - } - - if (!hash_equals($request->input('confirmation_token') ?? '', $details['token_value'])) { - $this->sendFailedLoginResponse($request); - } - - $user = User::query()->find($details['user_id']); - if (!$user) { - $this->sendFailedLoginResponse($request, null, self::TOKEN_EXPIRED_MESSAGE); - } - - // Recovery tokens go through a slightly different pathway for usage. - if (!is_null($recoveryToken = $request->input('recovery_token'))) { - if ($this->isValidRecoveryToken($user, $recoveryToken)) { - Event::dispatch(new ProvidedAuthenticationToken($user, true)); - - return $this->sendLoginResponse($user, $request); - } - } else { - if ($this->google2FA->verifyKey($user->totp_secret, (string) $request->input('authentication_code'), config('panel.auth.2fa.window'))) { - Event::dispatch(new ProvidedAuthenticationToken($user)); - - return $this->sendLoginResponse($user, $request); - } - } - - $this->sendFailedLoginResponse($request, $user, !empty($recoveryToken) ? 'The recovery token provided is not valid.' : null); - } - - /** - * Determines if a given recovery token is valid for the user account. If we find a matching token - * it will be deleted from the database. - * - * @throws \Exception - */ - protected function isValidRecoveryToken(User $user, string $value): bool - { - foreach ($user->recoveryTokens as $token) { - if (password_verify($value, $token->token)) { - $token->delete(); - - return true; - } - } - - return false; - } - - /** - * Determines if the data provided from the session is valid or not. This - * will return false if the data is invalid, or if more time has passed than - * was configured when the session was written. - */ - protected function hasValidSessionData(array $data): bool - { - $validator = $this->validation->make($data, [ - 'user_id' => 'required|integer|min:1', - 'token_value' => 'required|string', - 'expires_at' => 'required', - ]); - - if ($validator->fails()) { - return false; - } - - if (!$data['expires_at'] instanceof CarbonInterface) { - return false; - } - - if ($data['expires_at']->isBefore(CarbonImmutable::now())) { - return false; - } - - return true; - } -} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php deleted file mode 100644 index 1501b6d66a..0000000000 --- a/app/Http/Controllers/Auth/LoginController.php +++ /dev/null @@ -1,77 +0,0 @@ -hasTooManyLoginAttempts($request)) { - $this->fireLockoutEvent($request); - $this->sendLockoutResponse($request); - } - - $username = $request->input('user'); - $user = User::query()->where($this->getField($username), $username)->first(); - if (!$user) { - $this->sendFailedLoginResponse($request); - } - - // Ensure that the account is using a valid username and password before trying to - // continue. Previously this was handled in the 2FA checkpoint, however that has - // a flaw in which you can discover if an account exists simply by seeing if you - // can proceed to the next step in the login process. - if (!password_verify($request->input('password'), $user->password)) { - $this->sendFailedLoginResponse($request, $user); - } - - if (!$user->use_totp) { - return $this->sendLoginResponse($user, $request); - } - - Activity::event('auth:checkpoint')->withRequestMetadata()->subject($user)->log(); - - $request->session()->put('auth_confirmation_token', [ - 'user_id' => $user->id, - 'token_value' => $token = Str::random(64), - 'expires_at' => CarbonImmutable::now()->addMinutes(5), - ]); - - return new JsonResponse([ - 'data' => [ - 'complete' => false, - 'confirmation_token' => $token, - ], - ]); - } -} diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php index 87403d1620..f12fe6818f 100644 --- a/app/Http/Controllers/Auth/OAuthController.php +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -15,12 +15,9 @@ class OAuthController extends Controller { - /** - * OAuthController constructor. - */ public function __construct( - private AuthManager $auth, - private UserUpdateService $updateService + private readonly AuthManager $auth, + private readonly UserUpdateService $updateService ) {} /** diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php deleted file mode 100644 index 8cceb714e1..0000000000 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ /dev/null @@ -1,100 +0,0 @@ -broker()->reset( - $this->credentials($request), - function ($user, $password) { - $this->resetPassword($user, $password); - } - ); - - // If the password was successfully reset, we will redirect the user back to - // the application's home authenticated view. If there is an error we can - // redirect them back to where they came from with their error message. - if ($response === Password::PASSWORD_RESET) { - return $this->sendResetResponse(); - } - - throw new DisplayException(trans($response)); - } - - /** - * Reset the given user's password. If the user has two-factor authentication enabled on their - * account do not automatically log them in. In those cases, send the user back to the login - * form with a note telling them their password was changed and to log back in. - * - * @param \Illuminate\Contracts\Auth\CanResetPassword|\App\Models\User $user - * @param string $password - * - * @throws \App\Exceptions\Model\DataValidationException - */ - protected function resetPassword($user, $password): void - { - /** @var User $user */ - $user->password = $this->hasher->make($password); - $user->setRememberToken(Str::random(60)); - $user->save(); - - event(new PasswordReset($user)); - - // If the user is not using 2FA log them in, otherwise skip this step and force a - // fresh login where they'll be prompted to enter a token. - if (!$user->use_totp) { - $this->guard()->login($user); - } - - $this->hasTwoFactor = $user->use_totp; - } - - /** - * Send a successful password reset response back to the callee. - */ - protected function sendResetResponse(): JsonResponse - { - return response()->json([ - 'success' => true, - 'redirect_to' => $this->redirectTo, - 'send_to_login' => $this->hasTwoFactor, - ]); - } -} diff --git a/app/Http/Controllers/Base/IndexController.php b/app/Http/Controllers/Base/IndexController.php deleted file mode 100644 index 397dbd4a66..0000000000 --- a/app/Http/Controllers/Base/IndexController.php +++ /dev/null @@ -1,23 +0,0 @@ -loader = $translator->getLoader(); - } - - /** - * Returns translation data given a specific locale and namespace. - */ - public function __invoke(Request $request): JsonResponse - { - $locales = explode(' ', $request->input('locale') ?? ''); - $namespaces = explode(' ', $request->input('namespace') ?? ''); - - $response = []; - foreach ($locales as $locale) { - $response[$locale] = []; - foreach ($namespaces as $namespace) { - $response[$locale][$namespace] = $this->i18n( - $this->loader->load($locale, str_replace('.', '/', $namespace)) - ); - } - } - - return new JsonResponse($response, 200, [ - // Cache this in the browser for an hour, and allow the browser to use a stale - // cache for up to a day after it was created while it fetches an updated set - // of translation keys. - 'Cache-Control' => 'public, max-age=3600, stale-while-revalidate=86400', - 'ETag' => md5(json_encode($response, JSON_THROW_ON_ERROR)), - ]); - } - - /** - * Convert standard Laravel translation keys that look like ":foo" - * into key structures that are supported by the front-end i18n - * library, like "{{foo}}". - */ - protected function i18n(array $data): array - { - foreach ($data as $key => $value) { - if (is_array($value)) { - $data[$key] = $this->i18n($value); - } else { - // Find a Laravel style translation replacement in the string and replace it with - // one that the front-end is able to use. This won't always be present, especially - // for complex strings or things where we'd never have a backend component anyways. - // - // For example: - // "Hello :name, the :notifications.0.title notification needs :count actions :foo.0.bar." - // - // Becomes: - // "Hello {{name}}, the {{notifications.0.title}} notification needs {{count}} actions {{foo.0.bar}}." - $data[$key] = preg_replace('/:([\w.-]+\w)([^\w:]?|$)/m', '{{$1}}$2', $value); - } - } - - return $data; - } -} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 91d25ff850..06b064c59f 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -2,24 +2,17 @@ namespace App\Http\Middleware; -use App\Filament\App\Resources\ServerResource\Pages\ListServers; use Illuminate\Http\Request; use Illuminate\Auth\AuthManager; -class RedirectIfAuthenticated +readonly class RedirectIfAuthenticated { - /** - * RedirectIfAuthenticated constructor. - */ public function __construct(private AuthManager $authManager) {} - /** - * Handle an incoming request. - */ public function handle(Request $request, \Closure $next, ?string $guard = null): mixed { if ($this->authManager->guard($guard)->check()) { - return redirect(ListServers::getUrl()); + return redirect('/'); } return $next($request); diff --git a/app/Livewire/Installer/PanelInstaller.php b/app/Livewire/Installer/PanelInstaller.php index c55b2e8c4f..9a14685e81 100644 --- a/app/Livewire/Installer/PanelInstaller.php +++ b/app/Livewire/Installer/PanelInstaller.php @@ -47,8 +47,7 @@ public function getMaxWidth(): MaxWidth|string public static function isInstalled(): bool { - // This defaults to true so existing panels count as "installed" - return env('APP_INSTALLED', true); + return config('app.installed'); } public function mount(): void diff --git a/app/Livewire/Installer/Steps/RequirementsStep.php b/app/Livewire/Installer/Steps/RequirementsStep.php index 258f76cab5..0ba9bc518f 100644 --- a/app/Livewire/Installer/Steps/RequirementsStep.php +++ b/app/Livewire/Installer/Steps/RequirementsStep.php @@ -14,7 +14,8 @@ class RequirementsStep public static function make(): Step { - $correctPhpVersion = version_compare(PHP_VERSION, self::MIN_PHP_VERSION) >= 0; + $compare = version_compare(phpversion(), self::MIN_PHP_VERSION); + $correctPhpVersion = $compare >= 0; $fields = [ Section::make('PHP Version') diff --git a/app/Models/ActivityLog.php b/app/Models/ActivityLog.php index 94df56848c..83daf066c0 100644 --- a/app/Models/ActivityLog.php +++ b/app/Models/ActivityLog.php @@ -85,12 +85,7 @@ protected function casts(): array public function actor(): MorphTo { - $morph = $this->morphTo(); - if (method_exists($morph, 'withTrashed')) { - return $morph->withTrashed(); - } - - return $morph; + return $this->morphTo()->withTrashed(); } public function subjects(): HasMany diff --git a/app/Models/AuditLog.php b/app/Models/AuditLog.php index d091773eae..4529336731 100644 --- a/app/Models/AuditLog.php +++ b/app/Models/AuditLog.php @@ -60,7 +60,7 @@ public function server(): BelongsTo */ public static function instance(string $action, array $metadata, bool $isSystem = false): self { - /** @var \Illuminate\Http\Request $request */ + /** @var ?Request $request */ $request = Container::getInstance()->make('request'); if ($isSystem || !$request instanceof Request) { $request = null; diff --git a/app/Models/Backup.php b/app/Models/Backup.php index d6e4be65a2..e214f8bd00 100644 --- a/app/Models/Backup.php +++ b/app/Models/Backup.php @@ -2,7 +2,7 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Builder; +use App\Eloquent\BackupQueryBuilder; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -81,10 +81,11 @@ public function server(): BelongsTo } /** - * Returns a query filtering only non-failed backups for a specific server. + * @param \Illuminate\Database\Query\Builder $query + * @return BackupQueryBuilder<\Illuminate\Database\Eloquent\Model> */ - public function scopeNonFailed(Builder $query): void + public function newEloquentBuilder($query): BackupQueryBuilder { - $query->whereNull('completed_at')->orWhere('is_successful', true); + return new BackupQueryBuilder($query); } } diff --git a/app/Models/File.php b/app/Models/File.php index 9f9f6f2aa4..d726f79f2e 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -130,8 +130,7 @@ public function getSchema(): array public function getRows(): array { try { - /** @var DaemonFileRepository $fileRepository */ - $fileRepository = app(DaemonFileRepository::class)->setServer(self::$server); // @phpstan-ignore-line + $fileRepository = (new DaemonFileRepository())->setServer(self::$server); if (!is_null(self::$searchTerm)) { $contents = cache()->remember('file_search_' . self::$path . '_' . self::$searchTerm, now()->addMinute(), fn () => $fileRepository->search(self::$searchTerm, self::$path)); diff --git a/app/Models/Node.php b/app/Models/Node.php index 3a1cb4ce33..d8dbab90d0 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -307,8 +307,7 @@ public function systemInformation(): array { return once(function () { try { - // @phpstan-ignore-next-line - return resolve(DaemonConfigurationRepository::class) + return (new DaemonConfigurationRepository()) ->setNode($this) ->getSystemInformation(); } catch (Exception $exception) { diff --git a/app/Models/Server.php b/app/Models/Server.php index b9a5d409d7..cdffbed46c 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -342,6 +342,9 @@ public function transfer(): HasOne return $this->hasOne(ServerTransfer::class)->whereNull('successful')->orderByDesc('id'); } + /** + * @return HasMany + */ public function backups(): HasMany { return $this->hasMany(Backup::class); @@ -487,7 +490,7 @@ public function formatResource(string $resourceKey, bool $limit = false, ServerR public function condition(): Attribute { return Attribute::make( - get: fn () => $this->isSuspended() ? 'Suspended' : $this->status?->value ?? $this->retrieveStatus(), + get: fn () => $this->isSuspended() ? 'Suspended' : $this->status->value ?? $this->retrieveStatus(), ); } diff --git a/app/Models/User.php b/app/Models/User.php index 9e7fd435a2..a1b1fb5e77 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -20,7 +20,6 @@ use Illuminate\Database\Eloquent\Builder; use App\Models\Traits\HasAccessTokens; use Illuminate\Auth\Passwords\CanResetPassword; -use App\Traits\Helpers\AvailableLanguages; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Database\Eloquent\Relations\MorphToMany; @@ -30,6 +29,7 @@ use App\Notifications\SendPasswordReset as ResetPasswordNotification; use Filament\Facades\Filament; use Illuminate\Database\Eloquent\Model as IlluminateModel; +use ResourceBundle; use Spatie\Permission\Traits\HasRoles; /** @@ -89,7 +89,6 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac { use Authenticatable; use Authorizable {can as protected canned; } - use AvailableLanguages; use CanResetPassword; use HasAccessTokens; use HasRoles; @@ -179,9 +178,8 @@ protected function casts(): array protected static function booted(): void { static::creating(function (self $user) { - $user->uuid = Str::uuid()->toString(); - - $user->timezone = env('APP_TIMEZONE', 'UTC'); + $user->uuid ??= Str::uuid()->toString(); + $user->timezone ??= config('app.timezone'); return true; }); @@ -206,8 +204,8 @@ public static function getRules(): array { $rules = parent::getRules(); - $rules['language'][] = new In(array_keys((new self())->getAvailableLanguages())); - $rules['timezone'][] = new In(array_values(DateTimeZone::listIdentifiers())); + $rules['language'][] = new In(array_values(array_filter(ResourceBundle::getLocales(''), fn ($lang) => preg_match('/^[a-z]{2}$/', $lang)))); + $rules['timezone'][] = new In(DateTimeZone::listIdentifiers()); $rules['username'][] = new Username(); return $rules; diff --git a/app/PHPStan/ForbiddenGlobalFunctionsRule.php b/app/PHPStan/ForbiddenGlobalFunctionsRule.php index 545cc60fb7..b9c5cb6abf 100644 --- a/app/PHPStan/ForbiddenGlobalFunctionsRule.php +++ b/app/PHPStan/ForbiddenGlobalFunctionsRule.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; +use PHPStan\Rules\RuleErrorBuilder; class ForbiddenGlobalFunctionsRule implements Rule { @@ -28,7 +29,10 @@ public function processNode(Node $node, Scope $scope): array $functionName = (string) $node->name; if (in_array($functionName, $this->forbiddenFunctions, true)) { return [ - sprintf('Usage of global function "%s" is forbidden.', $functionName), + RuleErrorBuilder::message(sprintf( + 'Usage of global function "%s" is forbidden.', + $functionName, + ))->identifier('myCustomRules.forbiddenGlobalFunctions')->build(), ]; } } diff --git a/app/Services/Activity/ActivityLogService.php b/app/Services/Activity/ActivityLogService.php index 621800a4e0..243edb62d8 100644 --- a/app/Services/Activity/ActivityLogService.php +++ b/app/Services/Activity/ActivityLogService.php @@ -3,6 +3,7 @@ namespace App\Services\Activity; use Illuminate\Support\Arr; +use Throwable; use Webmozart\Assert\Assert; use Illuminate\Support\Collection; use App\Models\ActivityLog; @@ -141,9 +142,8 @@ public function log(?string $description = null): ActivityLog try { return $this->save(); - } catch (\Throwable|\Exception $exception) { + } catch (Throwable $exception) { if (config('app.env') !== 'production') { - /* @noinspection PhpUnhandledExceptionInspection */ throw $exception; } @@ -216,9 +216,7 @@ protected function getActivity(): ActivityLog if ($actor = $this->targetable->actor()) { $this->actor($actor); } elseif ($user = $this->manager->guard()->user()) { - if ($user instanceof Model) { - $this->actor($user); - } + $this->actor($user); } return $this->activity; diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index b00fd9c4d9..506448d256 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -14,7 +14,7 @@ class InitiateBackupService { - private ?array $ignoredFiles; + private array $ignoredFiles; private bool $isLocked = false; @@ -22,10 +22,10 @@ class InitiateBackupService * InitiateBackupService constructor. */ public function __construct( - private ConnectionInterface $connection, - private DaemonBackupRepository $daemonBackupRepository, - private DeleteBackupService $deleteBackupService, - private BackupManager $backupManager + private readonly ConnectionInterface $connection, + private readonly DaemonBackupRepository $daemonBackupRepository, + private readonly DeleteBackupService $deleteBackupService, + private readonly BackupManager $backupManager ) {} /** diff --git a/app/Services/Databases/DeployServerDatabaseService.php b/app/Services/Databases/DeployServerDatabaseService.php index 6cf60fb190..c4aa2988a6 100644 --- a/app/Services/Databases/DeployServerDatabaseService.php +++ b/app/Services/Databases/DeployServerDatabaseService.php @@ -8,18 +8,10 @@ use App\Models\DatabaseHost; use App\Exceptions\Service\Database\NoSuitableDatabaseHostException; -class DeployServerDatabaseService +readonly class DeployServerDatabaseService { - /** - * DeployServerDatabaseService constructor. - */ public function __construct(private DatabaseManagementService $managementService) {} - /** - * @throws \Throwable - * @throws \App\Exceptions\Service\Database\TooManyDatabasesException - * @throws \App\Exceptions\Service\Database\DatabaseClientFeatureNotEnabledException - */ public function handle(Server $server, array $data): Database { Assert::notEmpty($data['database'] ?? null); diff --git a/app/Services/Helpers/LanguageService.php b/app/Services/Helpers/LanguageService.php new file mode 100644 index 0000000000..1a4d86444d --- /dev/null +++ b/app/Services/Helpers/LanguageService.php @@ -0,0 +1,40 @@ +mapWithKeys(function ($path) { + $code = basename($path); + + return [$code => title_case(Locale::getDisplayName($code, $code))]; + })->toArray(); + } +} diff --git a/app/Services/Nodes/NodeJWTService.php b/app/Services/Nodes/NodeJWTService.php index 325fe04c08..2a5b1a3ffd 100644 --- a/app/Services/Nodes/NodeJWTService.php +++ b/app/Services/Nodes/NodeJWTService.php @@ -3,6 +3,7 @@ namespace App\Services\Nodes; use Carbon\CarbonImmutable; +use DateTimeImmutable; use Illuminate\Support\Str; use App\Models\Node; use App\Models\User; @@ -18,7 +19,7 @@ class NodeJWTService private ?User $user = null; - private ?\DateTimeImmutable $expiresAt; + private DateTimeImmutable $expiresAt; private ?string $subject = null; @@ -73,9 +74,7 @@ public function handle(Node $node, ?string $identifiedBy, string $algo = 'md5'): ->issuedAt(CarbonImmutable::now()) ->canOnlyBeUsedAfter(CarbonImmutable::now()->subMinutes(5)); - if ($this->expiresAt) { - $builder = $builder->expiresAt($this->expiresAt); - } + $builder = $builder->expiresAt($this->expiresAt); if (!empty($this->subject)) { $builder = $builder->relatedTo($this->subject)->withHeader('sub', $this->subject); diff --git a/app/Services/Schedules/ProcessScheduleService.php b/app/Services/Schedules/ProcessScheduleService.php index 601e1b0c3d..4d24f63fff 100644 --- a/app/Services/Schedules/ProcessScheduleService.php +++ b/app/Services/Schedules/ProcessScheduleService.php @@ -2,6 +2,7 @@ namespace App\Services\Schedules; +use App\Models\Task; use Exception; use App\Models\Schedule; use Illuminate\Contracts\Bus\Dispatcher; @@ -12,18 +13,14 @@ class ProcessScheduleService { - /** - * ProcessScheduleService constructor. - */ public function __construct(private ConnectionInterface $connection, private Dispatcher $dispatcher, private DaemonServerRepository $serverRepository) {} /** * Process a schedule and push the first task onto the queue worker. - * - * @throws \Throwable */ public function handle(Schedule $schedule, bool $now = false): void { + /** @var ?Task $task */ $task = $schedule->tasks()->orderBy('sequence_id')->first(); if (!$task) { diff --git a/app/Traits/Helpers/AvailableLanguages.php b/app/Traits/Helpers/AvailableLanguages.php deleted file mode 100644 index aafffbbab1..0000000000 --- a/app/Traits/Helpers/AvailableLanguages.php +++ /dev/null @@ -1,57 +0,0 @@ -getFilesystemInstance()->directories(base_path('lang')))->mapWithKeys(function ($path) { - $code = basename($path); - - $value = Locale::getDisplayName($code, $code); - - return [$code => title_case($value)]; - })->toArray(); - } - - public function isLanguageTranslated(string $countryCode = 'en'): bool - { - return in_array($countryCode, self::TRANSLATED, true); - } - - /** - * Return an instance of the filesystem for getting a folder listing. - */ - private function getFilesystemInstance(): Filesystem - { - // @phpstan-ignore-next-line - return $this->filesystem = $this->filesystem ?: app()->make(Filesystem::class); - } -} diff --git a/app/Transformers/Api/Application/BaseTransformer.php b/app/Transformers/Api/Application/BaseTransformer.php index baf8c76cb0..397158a138 100644 --- a/app/Transformers/Api/Application/BaseTransformer.php +++ b/app/Transformers/Api/Application/BaseTransformer.php @@ -24,7 +24,7 @@ abstract class BaseTransformer extends TransformerAbstract /** * BaseTransformer constructor. */ - public function __construct() + final public function __construct() { // Transformers allow for dependency injection on the handle method. if (method_exists($this, 'handle')) { @@ -40,7 +40,7 @@ abstract public function getResourceName(): string; /** * Sets the request on the instance. */ - public function setRequest(Request $request): self + public function setRequest(Request $request): static { $this->request = $request; @@ -49,13 +49,10 @@ public function setRequest(Request $request): self /** * Returns a new transformer instance with the request set on the instance. - * - * @return static */ - public static function fromRequest(Request $request): self + public static function fromRequest(Request $request): static { - // @phpstan-ignore-next-line - return app(static::class)->setRequest($request); + return (new static())->setRequest($request); } /** diff --git a/app/helpers.php b/app/helpers.php index 3bf7aaf307..f1033bdfc0 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -49,8 +49,7 @@ function join_paths(string $base, string ...$paths): string if (!function_exists('resolve_path')) { function resolve_path(string $path): string { - // @phpstan-ignore-next-line - $parts = array_filter(explode('/', $path), 'strlen'); + $parts = array_filter(explode('/', $path), fn (string $p) => strlen($p) > 0); $absolutes = []; foreach ($parts as $part) { diff --git a/composer.json b/composer.json index 508e263742..b2d2fec92f 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "require-dev": { "barryvdh/laravel-ide-helper": "^3.0", "fakerphp/faker": "^1.23.1", - "larastan/larastan": "^2.9.6", + "larastan/larastan": "^3.0", "laravel/pint": "^1.15.3", "laravel/sail": "^1.29.1", "mockery/mockery": "^1.6.11", diff --git a/composer.lock b/composer.lock index 1b2f590efe..2b63b57a53 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": "4c83ce23eb3e0fab5738cdd7212e4fe3", + "content-hash": "3605a7db1271bc67e1f1ce1bf0d80b18", "packages": [ { "name": "abdelhamiderrahmouni/filament-monaco-editor", @@ -1413,29 +1413,27 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -1443,7 +1441,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1454,9 +1452,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "doctrine/event-manager", @@ -1784,16 +1782,16 @@ }, { "name": "egulias/email-validator", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" + "reference": "b115554301161fa21467629f1e1391c1936de517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", - "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", + "reference": "b115554301161fa21467629f1e1391c1936de517", "shasum": "" }, "require": { @@ -1839,7 +1837,7 @@ ], "support": { "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" + "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" }, "funding": [ { @@ -1847,7 +1845,7 @@ "type": "github" } ], - "time": "2023-10-06T06:47:41+00:00" + "time": "2024-12-27T00:36:43+00:00" }, { "name": "filament/actions", @@ -2953,23 +2951,23 @@ }, { "name": "laravel/framework", - "version": "v11.31.0", + "version": "v11.37.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40" + "reference": "6cb103d2024b087eae207654b3f4b26646119ba5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/365090ed2c68244e3141cdb5e247cdf3dfba2c40", - "reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40", + "url": "https://api.github.com/repos/laravel/framework/zipball/6cb103d2024b087eae207654b3f4b26646119ba5", + "reference": "6cb103d2024b087eae207654b3f4b26646119ba5", "shasum": "" }, "require": { "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", "composer-runtime-api": "^2.2", "doctrine/inflector": "^2.0.5", - "dragonmantank/cron-expression": "^3.3.2", + "dragonmantank/cron-expression": "^3.4", "egulias/email-validator": "^3.2.1|^4.0", "ext-ctype": "*", "ext-filter": "*", @@ -2979,38 +2977,39 @@ "ext-session": "*", "ext-tokenizer": "*", "fruitcake/php-cors": "^1.3", - "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/guzzle": "^7.8.2", "guzzlehttp/uri-template": "^1.0", "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", - "laravel/serializable-closure": "^1.3", - "league/commonmark": "^2.2.1", - "league/flysystem": "^3.8.0", + "laravel/serializable-closure": "^1.3|^2.0", + "league/commonmark": "^2.6", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "league/uri": "^7.5.1", "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.72.2|^3.0", + "nesbot/carbon": "^2.72.2|^3.4", "nunomaduro/termwind": "^2.0", "php": "^8.2", "psr/container": "^1.1.1|^2.0.1", "psr/log": "^1.0|^2.0|^3.0", "psr/simple-cache": "^1.0|^2.0|^3.0", "ramsey/uuid": "^4.7", - "symfony/console": "^7.0", - "symfony/error-handler": "^7.0", - "symfony/finder": "^7.0", - "symfony/http-foundation": "^7.0", - "symfony/http-kernel": "^7.0", - "symfony/mailer": "^7.0", - "symfony/mime": "^7.0", - "symfony/polyfill-php83": "^1.28", - "symfony/process": "^7.0", - "symfony/routing": "^7.0", - "symfony/uid": "^7.0", - "symfony/var-dumper": "^7.0", + "symfony/console": "^7.0.3", + "symfony/error-handler": "^7.0.3", + "symfony/finder": "^7.0.3", + "symfony/http-foundation": "^7.2.0", + "symfony/http-kernel": "^7.0.3", + "symfony/mailer": "^7.0.3", + "symfony/mime": "^7.0.3", + "symfony/polyfill-php83": "^1.31", + "symfony/process": "^7.0.3", + "symfony/routing": "^7.0.3", + "symfony/uid": "^7.0.3", + "symfony/var-dumper": "^7.0.3", "tijsverkoyen/css-to-inline-styles": "^2.2.5", - "vlucas/phpdotenv": "^5.4.1", - "voku/portable-ascii": "^2.0" + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" }, "conflict": { - "mockery/mockery": "1.6.8", "tightenco/collect": "<5.5.33" }, "provide": { @@ -3057,29 +3056,32 @@ }, "require-dev": { "ably/ably-php": "^1.0", - "aws/aws-sdk-php": "^3.235.5", + "aws/aws-sdk-php": "^3.322.9", "ext-gmp": "*", - "fakerphp/faker": "^1.23", - "league/flysystem-aws-s3-v3": "^3.0", - "league/flysystem-ftp": "^3.0", - "league/flysystem-path-prefixing": "^3.3", - "league/flysystem-read-only": "^3.3", - "league/flysystem-sftp-v3": "^3.0", - "mockery/mockery": "^1.6", - "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^9.5", - "pda/pheanstalk": "^5.0", + "fakerphp/faker": "^1.24", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^2.4", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "orchestra/testbench-core": "^9.6", + "pda/pheanstalk": "^5.0.6", + "php-http/discovery": "^1.15", "phpstan/phpstan": "^1.11.5", - "phpunit/phpunit": "^10.5|^11.0", - "predis/predis": "^2.0.2", + "phpunit/phpunit": "^10.5.35|^11.3.6", + "predis/predis": "^2.3", "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.0", - "symfony/http-client": "^7.0", - "symfony/psr-http-message-bridge": "^7.0" + "symfony/cache": "^7.0.3", + "symfony/http-client": "^7.0.3", + "symfony/psr-http-message-bridge": "^7.0.3", + "symfony/translation": "^7.0.3" }, "suggest": { "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", "ext-apcu": "Required to use the APC cache driver.", "ext-fileinfo": "Required to use the Filesystem class.", @@ -3093,16 +3095,16 @@ "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", "filp/whoops": "Required for friendly error pages in development (^2.14.3).", "laravel/tinker": "Required to use the tinker console command (^2.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", - "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", - "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", - "league/flysystem-read-only": "Required to use read-only disks (^3.3)", - "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", "mockery/mockery": "Required to use mocking (^1.6).", - "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", - "predis/predis": "Required to use the predis connector (^2.0.2).", + "predis/predis": "Required to use the predis connector (^2.3).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", @@ -3121,6 +3123,7 @@ }, "autoload": { "files": [ + "src/Illuminate/Collections/functions.php", "src/Illuminate/Collections/helpers.php", "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php", @@ -3158,7 +3161,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-11-12T15:36:15+00:00" + "time": "2025-01-02T20:10:21+00:00" }, { "name": "laravel/helpers", @@ -3342,16 +3345,16 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.3.6", + "version": "v1.3.7", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "f865a58ea3a0107c336b7045104c75243fa59d96" + "reference": "4f48ade902b94323ca3be7646db16209ec76be3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f865a58ea3a0107c336b7045104c75243fa59d96", - "reference": "f865a58ea3a0107c336b7045104c75243fa59d96", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/4f48ade902b94323ca3be7646db16209ec76be3d", + "reference": "4f48ade902b94323ca3be7646db16209ec76be3d", "shasum": "" }, "require": { @@ -3399,7 +3402,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2024-11-11T17:06:04+00:00" + "time": "2024-11-14T18:34:49+00:00" }, { "name": "laravel/socialite", @@ -3742,16 +3745,16 @@ }, { "name": "league/commonmark", - "version": "2.5.3", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0" + "reference": "d990688c91cedfb69753ffc2512727ec646df2ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad", + "reference": "d990688c91cedfb69753ffc2512727ec646df2ad", "shasum": "" }, "require": { @@ -3776,8 +3779,9 @@ "phpstan/phpstan": "^1.8.2", "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 || ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "symfony/finder": "^5.3 | ^6.0 | ^7.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", "vimeo/psalm": "^4.24.0 || ^5.0.0" }, @@ -3787,7 +3791,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.6-dev" + "dev-main": "2.7-dev" } }, "autoload": { @@ -3844,7 +3848,7 @@ "type": "tidelift" } ], - "time": "2024-08-16T11:46:16+00:00" + "time": "2024-12-29T14:10:59+00:00" }, { "name": "league/config", @@ -4484,20 +4488,20 @@ }, { "name": "league/uri", - "version": "7.4.1", + "version": "7.5.1", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4" + "reference": "81fb5145d2644324614cc532b28efd0215bda430" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/bedb6e55eff0c933668addaa7efa1e1f2c417cc4", - "reference": "bedb6e55eff0c933668addaa7efa1e1f2c417cc4", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.3", + "league/uri-interfaces": "^7.5", "php": "^8.1" }, "conflict": { @@ -4562,7 +4566,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.4.1" + "source": "https://github.com/thephpleague/uri/tree/7.5.1" }, "funding": [ { @@ -4570,20 +4574,20 @@ "type": "github" } ], - "time": "2024-03-23T07:42:40+00:00" + "time": "2024-12-08T08:40:02+00:00" }, { "name": "league/uri-interfaces", - "version": "7.4.1", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "8d43ef5c841032c87e2de015972c06f3865ef718" + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/8d43ef5c841032c87e2de015972c06f3865ef718", - "reference": "8d43ef5c841032c87e2de015972c06f3865ef718", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", "shasum": "" }, "require": { @@ -4646,7 +4650,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.1" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" }, "funding": [ { @@ -4654,7 +4658,7 @@ "type": "github" } ], - "time": "2024-03-23T07:42:40+00:00" + "time": "2024-12-08T08:18:47+00:00" }, { "name": "livewire/livewire", @@ -4801,16 +4805,16 @@ }, { "name": "monolog/monolog", - "version": "3.8.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", - "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", "shasum": "" }, "require": { @@ -4888,7 +4892,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.8.0" + "source": "https://github.com/Seldaek/monolog/tree/3.8.1" }, "funding": [ { @@ -4900,7 +4904,7 @@ "type": "tidelift" } ], - "time": "2024-11-12T13:57:08+00:00" + "time": "2024-12-05T17:15:07+00:00" }, { "name": "mtdowling/jmespath.php", @@ -4970,16 +4974,16 @@ }, { "name": "nesbot/carbon", - "version": "3.8.2", + "version": "3.8.4", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947" + "reference": "129700ed449b1f02d70272d2ac802357c8c30c58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947", - "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58", + "reference": "129700ed449b1f02d70272d2ac802357c8c30c58", "shasum": "" }, "require": { @@ -5011,10 +5015,6 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.x-dev", - "dev-2.x": "2.x-dev" - }, "laravel": { "providers": [ "Carbon\\Laravel\\ServiceProvider" @@ -5024,6 +5024,10 @@ "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" } }, "autoload": { @@ -5072,7 +5076,7 @@ "type": "tidelift" } ], - "time": "2024-11-07T17:46:48+00:00" + "time": "2024-12-27T09:25:35+00:00" }, { "name": "nette/schema", @@ -5282,31 +5286,31 @@ }, { "name": "nunomaduro/termwind", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3" + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/42c84e4e8090766bbd6445d06cd6e57650626ea3", - "reference": "42c84e4e8090766bbd6445d06cd6e57650626ea3", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.2", - "symfony/console": "^7.1.5" + "symfony/console": "^7.1.8" }, "require-dev": { - "illuminate/console": "^11.28.0", - "laravel/pint": "^1.18.1", + "illuminate/console": "^11.33.2", + "laravel/pint": "^1.18.2", "mockery/mockery": "^1.6.12", "pestphp/pest": "^2.36.0", - "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan": "^1.12.11", "phpstan/phpstan-strict-rules": "^1.6.1", - "symfony/var-dumper": "^7.1.5", + "symfony/var-dumper": "^7.1.8", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -5349,7 +5353,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.2.0" + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" }, "funding": [ { @@ -5365,7 +5369,7 @@ "type": "github" } ], - "time": "2024-10-15T16:15:16+00:00" + "time": "2024-11-21T10:39:51+00:00" }, { "name": "openspout/openspout", @@ -7871,16 +7875,16 @@ }, { "name": "symfony/clock", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "97bebc53548684c17ed696bc8af016880f0f098d" + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/97bebc53548684c17ed696bc8af016880f0f098d", - "reference": "97bebc53548684c17ed696bc8af016880f0f098d", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", "shasum": "" }, "require": { @@ -7925,7 +7929,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.1.6" + "source": "https://github.com/symfony/clock/tree/v7.2.0" }, "funding": [ { @@ -7941,20 +7945,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/console", - "version": "v7.1.8", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { @@ -8018,7 +8022,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.8" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -8034,20 +8038,20 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:23:19+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/css-selector", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66" + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", - "reference": "4aa4f6b3d6749c14d3aa815eef8226632e7bbc66", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", "shasum": "" }, "require": { @@ -8083,7 +8087,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.1.6" + "source": "https://github.com/symfony/css-selector/tree/v7.2.0" }, "funding": [ { @@ -8099,20 +8103,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -8120,12 +8124,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -8150,7 +8154,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -8166,20 +8170,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/error-handler", - "version": "v7.1.7", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "010e44661f4c6babaf8c4862fe68c24a53903342" + "reference": "6150b89186573046167796fa5f3f76601d5145f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/010e44661f4c6babaf8c4862fe68c24a53903342", - "reference": "010e44661f4c6babaf8c4862fe68c24a53903342", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", + "reference": "6150b89186573046167796fa5f3f76601d5145f8", "shasum": "" }, "require": { @@ -8225,7 +8229,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.1.7" + "source": "https://github.com/symfony/error-handler/tree/v7.2.1" }, "funding": [ { @@ -8241,20 +8245,20 @@ "type": "tidelift" } ], - "time": "2024-11-05T15:34:55+00:00" + "time": "2024-12-07T08:50:44+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "87254c78dd50721cfd015b62277a8281c5589702" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702", - "reference": "87254c78dd50721cfd015b62277a8281c5589702", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { @@ -8305,7 +8309,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.1.6" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -8321,20 +8325,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -8343,12 +8347,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -8381,7 +8385,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -8397,20 +8401,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/finder", - "version": "v7.1.6", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8" + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8", - "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", "shasum": "" }, "require": { @@ -8445,7 +8449,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.6" + "source": "https://github.com/symfony/finder/tree/v7.2.2" }, "funding": [ { @@ -8461,7 +8465,7 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:31:23+00:00" + "time": "2024-12-30T19:00:17+00:00" }, { "name": "symfony/html-sanitizer", @@ -8628,16 +8632,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v3.5.0", + "version": "v3.5.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", "shasum": "" }, "require": { @@ -8645,12 +8649,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -8686,7 +8690,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" }, "funding": [ { @@ -8702,24 +8706,25 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-12-07T08:49:48+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.1.8", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f4419ec69ccfc3f725a4de7c20e4e57626d10112" + "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4419ec69ccfc3f725a4de7c20e4e57626d10112", - "reference": "f4419ec69ccfc3f725a4de7c20e4e57626d10112", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/62d1a43796ca3fea3f83a8470dfe63a4af3bc588", + "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, @@ -8763,7 +8768,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.1.8" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.2" }, "funding": [ { @@ -8779,20 +8784,20 @@ "type": "tidelift" } ], - "time": "2024-11-09T09:16:45+00:00" + "time": "2024-12-30T19:00:17+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.8", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "33fef24e3dc79d6d30bf4936531f2f4bd2ca189e" + "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/33fef24e3dc79d6d30bf4936531f2f4bd2ca189e", - "reference": "33fef24e3dc79d6d30bf4936531f2f4bd2ca189e", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3c432966bd8c7ec7429663105f5a02d7e75b4306", + "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306", "shasum": "" }, "require": { @@ -8821,7 +8826,7 @@ "symfony/twig-bridge": "<6.4", "symfony/validator": "<6.4", "symfony/var-dumper": "<6.4", - "twig/twig": "<3.0.4" + "twig/twig": "<3.12" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" @@ -8849,7 +8854,7 @@ "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0", - "twig/twig": "^3.0.4" + "twig/twig": "^3.12" }, "type": "library", "autoload": { @@ -8877,7 +8882,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.1.8" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.2" }, "funding": [ { @@ -8893,20 +8898,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T14:25:32+00:00" + "time": "2024-12-31T14:59:40+00:00" }, { "name": "symfony/mailer", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd" + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/69c9948451fb3a6a4d47dc8261d1794734e76cdd", - "reference": "69c9948451fb3a6a4d47dc8261d1794734e76cdd", + "url": "https://api.github.com/repos/symfony/mailer/zipball/e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc", "shasum": "" }, "require": { @@ -8915,7 +8920,7 @@ "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", + "symfony/mime": "^7.2", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -8957,7 +8962,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.1.6" + "source": "https://github.com/symfony/mailer/tree/v7.2.0" }, "funding": [ { @@ -8973,7 +8978,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-25T15:21:05+00:00" }, { "name": "symfony/mailgun-mailer", @@ -9046,16 +9051,16 @@ }, { "name": "symfony/mime", - "version": "v7.1.6", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "caa1e521edb2650b8470918dfe51708c237f0598" + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/caa1e521edb2650b8470918dfe51708c237f0598", - "reference": "caa1e521edb2650b8470918dfe51708c237f0598", + "url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283", + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283", "shasum": "" }, "require": { @@ -9110,7 +9115,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.1.6" + "source": "https://github.com/symfony/mime/tree/v7.2.1" }, "funding": [ { @@ -9126,7 +9131,7 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:11:02+00:00" + "time": "2024-12-07T08:50:44+00:00" }, { "name": "symfony/polyfill-ctype", @@ -9154,8 +9159,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9230,8 +9235,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9309,8 +9314,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9391,8 +9396,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9475,8 +9480,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9549,8 +9554,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9629,8 +9634,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9711,8 +9716,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9836,16 +9841,16 @@ }, { "name": "symfony/process", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892" + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/42783370fda6e538771f7c7a36e9fa2ee3a84892", - "reference": "42783370fda6e538771f7c7a36e9fa2ee3a84892", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { @@ -9877,7 +9882,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.8" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { @@ -9893,20 +9898,20 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:23:19+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/routing", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a" + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/66a2c469f6c22d08603235c46a20007c0701ea0a", - "reference": "66a2c469f6c22d08603235c46a20007c0701ea0a", + "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", "shasum": "" }, "require": { @@ -9958,7 +9963,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.1.6" + "source": "https://github.com/symfony/routing/tree/v7.2.0" }, "funding": [ { @@ -9974,20 +9979,20 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:31:23+00:00" + "time": "2024-11-25T11:08:51+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -10000,12 +10005,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -10041,7 +10046,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -10057,20 +10062,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { @@ -10128,7 +10133,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.8" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -10144,24 +10149,25 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:21+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/translation", - "version": "v7.1.6", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f" + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/b9f72ab14efdb6b772f85041fa12f820dee8d55f", - "reference": "b9f72ab14efdb6b772f85041fa12f820dee8d55f", + "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/translation-contracts": "^2.5|^3.0" }, @@ -10222,7 +10228,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.1.6" + "source": "https://github.com/symfony/translation/tree/v7.2.2" }, "funding": [ { @@ -10238,20 +10244,20 @@ "type": "tidelift" } ], - "time": "2024-09-28T12:35:13+00:00" + "time": "2024-12-07T08:18:10+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -10259,12 +10265,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -10300,7 +10306,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -10316,20 +10322,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/uid", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "65befb3bb2d503bbffbd08c815aa38b472999917" + "reference": "2d294d0c48df244c71c105a169d0190bfb080426" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/65befb3bb2d503bbffbd08c815aa38b472999917", - "reference": "65befb3bb2d503bbffbd08c815aa38b472999917", + "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", + "reference": "2d294d0c48df244c71c105a169d0190bfb080426", "shasum": "" }, "require": { @@ -10374,7 +10380,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.1.6" + "source": "https://github.com/symfony/uid/tree/v7.2.0" }, "funding": [ { @@ -10390,20 +10396,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8" + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8", - "reference": "7bb01a47b1b00428d32b5e7b4d3b2d1aa58d3db8", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", "shasum": "" }, "require": { @@ -10419,7 +10425,7 @@ "symfony/http-kernel": "^6.4|^7.0", "symfony/process": "^6.4|^7.0", "symfony/uid": "^6.4|^7.0", - "twig/twig": "^3.0.4" + "twig/twig": "^3.12" }, "bin": [ "Resources/bin/var-dump-server" @@ -10457,7 +10463,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.8" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" }, "funding": [ { @@ -10473,7 +10479,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T15:46:42+00:00" + "time": "2024-11-08T15:48:14+00:00" }, { "name": "symfony/yaml", @@ -10548,31 +10554,33 @@ }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "v2.2.7", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb" + "reference": "0d72ac1c00084279c1816675284073c5a337c20d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb", - "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d", + "reference": "0d72ac1c00084279c1816675284073c5a337c20d", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", - "php": "^5.5 || ^7.0 || ^8.0", - "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + "php": "^7.4 || ^8.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^8.5.21 || ^9.5.10" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -10595,9 +10603,9 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0" }, - "time": "2023-12-08T13:03:43+00:00" + "time": "2024-12-21T16:25:41+00:00" }, { "name": "vlucas/phpdotenv", @@ -10685,16 +10693,16 @@ }, { "name": "voku/portable-ascii", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "b56450eed252f6801410d810c8e1727224ae0743" + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", - "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", "shasum": "" }, "require": { @@ -10719,7 +10727,7 @@ "authors": [ { "name": "Lars Moelleken", - "homepage": "http://www.moelleken.org/" + "homepage": "https://www.moelleken.org/" } ], "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", @@ -10731,7 +10739,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" }, "funding": [ { @@ -10755,7 +10763,7 @@ "type": "tidelift" } ], - "time": "2022-03-08T17:03:00+00:00" + "time": "2024-11-21T01:49:47+00:00" }, { "name": "webbingbrasil/filament-copyactions", @@ -11356,53 +11364,53 @@ }, { "name": "larastan/larastan", - "version": "v2.9.11", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "54eccd35d1732b9ee4392c25aec606a6a9c521e7" + "reference": "b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/54eccd35d1732b9ee4392c25aec606a6a9c521e7", - "reference": "54eccd35d1732b9ee4392c25aec606a6a9c521e7", + "url": "https://api.github.com/repos/larastan/larastan/zipball/b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f", + "reference": "b2e24e1605cff1d1097ccb6fb8af3bbd1dfe1c6f", "shasum": "" }, "require": { "ext-json": "*", - "illuminate/console": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/container": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/contracts": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/database": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/http": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.16", - "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.16", - "php": "^8.0.2", + "illuminate/console": "^11.15.0", + "illuminate/container": "^11.15.0", + "illuminate/contracts": "^11.15.0", + "illuminate/database": "^11.15.0", + "illuminate/http": "^11.15.0", + "illuminate/pipeline": "^11.15.0", + "illuminate/support": "^11.15.0", + "php": "^8.2", "phpmyadmin/sql-parser": "^5.9.0", - "phpstan/phpstan": "^1.12.5" + "phpstan/phpstan": "^2.0.2" }, "require-dev": { "doctrine/coding-standard": "^12.0", - "laravel/framework": "^9.52.16 || ^10.28.0 || ^11.16", - "mockery/mockery": "^1.5.1", - "nikic/php-parser": "^4.19.1", - "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.2", - "orchestra/testbench-core": "^7.33.0 || ^8.13.0 || ^9.0.9", - "phpstan/phpstan-deprecation-rules": "^1.2", - "phpunit/phpunit": "^9.6.13 || ^10.5.16" + "laravel/framework": "^11.15.0", + "mockery/mockery": "^1.6", + "nikic/php-parser": "^5.3", + "orchestra/canvas": "^v9.1.3", + "orchestra/testbench-core": "^9.5.2", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpunit/phpunit": "^10.5.16" }, "suggest": { "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" }, "type": "phpstan-extension", "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - }, "phpstan": { "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-master": "2.0-dev" } }, "autoload": { @@ -11437,27 +11445,15 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.9.11" + "source": "https://github.com/larastan/larastan/tree/v3.0.2" }, "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, { "url": "https://github.com/canvural", "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" } ], - "time": "2024-11-11T23:11:00+00:00" + "time": "2024-11-26T23:15:21+00:00" }, { "name": "laravel/pint", @@ -12059,16 +12055,16 @@ }, { "name": "phpmyadmin/sql-parser", - "version": "5.10.1", + "version": "5.10.2", "source": { "type": "git", "url": "https://github.com/phpmyadmin/sql-parser.git", - "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17" + "reference": "72afbce7e4b421593b60d2eb7281e37a50734df8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/b14fd66496a22d8dd7f7e2791edd9e8674422f17", - "reference": "b14fd66496a22d8dd7f7e2791edd9e8674422f17", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/72afbce7e4b421593b60d2eb7281e37a50734df8", + "reference": "72afbce7e4b421593b60d2eb7281e37a50734df8", "shasum": "" }, "require": { @@ -12142,24 +12138,24 @@ "type": "other" } ], - "time": "2024-11-10T04:10:31+00:00" + "time": "2024-12-05T15:04:09+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.10", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "fc463b5d0fe906dcf19689be692c65c50406a071" + "reference": "2392d360fdf54ea253aa6c68cad1d4ba2e54e927" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/fc463b5d0fe906dcf19689be692c65c50406a071", - "reference": "fc463b5d0fe906dcf19689be692c65c50406a071", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2392d360fdf54ea253aa6c68cad1d4ba2e54e927", + "reference": "2392d360fdf54ea253aa6c68cad1d4ba2e54e927", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -12200,7 +12196,7 @@ "type": "github" } ], - "time": "2024-11-11T15:37:09+00:00" + "time": "2024-12-31T07:30:03+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/config/app.php b/config/app.php index e673f72690..58e4e544ff 100644 --- a/config/app.php +++ b/config/app.php @@ -10,6 +10,8 @@ 'timezone' => 'UTC', + 'installed' => env('APP_INSTALLED', true), + 'exceptions' => [ 'report_all' => env('APP_REPORT_ALL_EXCEPTIONS', false), ], diff --git a/phpstan.neon b/phpstan.neon index 3731172cea..b6d00a69da 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,6 +12,14 @@ parameters: level: 6 ignoreErrors: - - '#no value type specified in iterable#' - - '#Unable to resolve the template type#' - - '#does not specify its types#' + - identifier: argument.templateType + - identifier: missingType.generics + - identifier: missingType.iterableValue + - identifier: property.notFound + + # We are getting and setting environment variables directly + - + identifier: larastan.noEnvCallsOutsideOfConfig + paths: + - app/Console/Commands/Environment/*.php + - app/Filament/Admin/Pages/Settings.php diff --git a/routes/auth.php b/routes/auth.php index 9f43a95be3..8b3196a8d0 100644 --- a/routes/auth.php +++ b/routes/auth.php @@ -3,5 +3,7 @@ use Illuminate\Support\Facades\Route; use App\Http\Controllers\Auth; +Route::redirect('/login', '/login')->name('auth.login'); + Route::get('/oauth/redirect/{driver}', [Auth\OAuthController::class, 'redirect'])->name('auth.oauth.redirect'); Route::get('/oauth/callback/{driver}', [Auth\OAuthController::class, 'callback'])->name('auth.oauth.callback')->withoutMiddleware('guest');