From df943b482803baa566849d1ccfeb0f8da1cb5ae3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 30 Sep 2026 18:10:10 +0200 Subject: [PATCH] fix(api): return 422 for a non-string custom_container_name_prefix --- .../Api/ApplicationsController.php | 8 ++++- .../Api/ApplicationSettingsApiTest.php | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index c45e03a281..32cdfb24d5 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -156,7 +156,7 @@ class ApplicationsController extends Controller : $request->input($field); } - if (array_key_exists('custom_container_name_prefix', $settings)) { + if (array_key_exists('custom_container_name_prefix', $settings) && is_scalar($settings['custom_container_name_prefix'] ?? '')) { $settings['custom_container_name_prefix'] = str($settings['custom_container_name_prefix'])->slug()->value() ?: null; } @@ -166,6 +166,12 @@ class ApplicationsController extends Controller private function containerNamePrefixValidationResponse(array $settings, Server $server, ?Application $application = null): ?JsonResponse { $prefix = $settings['custom_container_name_prefix'] ?? null; + if (! is_null($prefix) && ! is_string($prefix)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => ['custom_container_name_prefix' => ['The custom container name prefix field must be a string.']], + ], 422); + } if (! filled($prefix) || ! ApplicationSetting::isContainerNamePrefixInUse($prefix, $server, $application?->id)) { return null; } diff --git a/tests/Feature/Api/ApplicationSettingsApiTest.php b/tests/Feature/Api/ApplicationSettingsApiTest.php index 3e94ffa69c..8074be8bbe 100644 --- a/tests/Feature/Api/ApplicationSettingsApiTest.php +++ b/tests/Feature/Api/ApplicationSettingsApiTest.php @@ -549,3 +549,32 @@ test('PATCH /api/v1/applications/{uuid} rejects a container name prefix that is expect($this->application->fresh()->settings->custom_container_name_prefix)->toBeNull(); }); + +test('application creation rejects a non-string container name prefix with 422', function () { + Queue::fake(); + + $this->withHeaders(applicationSettingsApiHeaders($this->bearerToken)) + ->postJson('/api/v1/applications/public', [ + 'project_uuid' => $this->project->uuid, + 'environment_uuid' => $this->environment->uuid, + 'server_uuid' => $this->server->uuid, + 'git_repository' => 'https://gitlab.com/coolify/prefix-test', + 'git_branch' => 'main', + 'build_pack' => 'nixpacks', + 'ports_exposes' => '3000', + 'custom_container_name_prefix' => ['nested' => 'value'], + ]) + ->assertUnprocessable() + ->assertJsonValidationErrors('custom_container_name_prefix'); + + expect(Application::query()->where('git_repository', 'like', '%prefix-test%')->exists())->toBeFalse(); +}); + +test('PATCH /api/v1/applications/{uuid} rejects a non-string container name prefix with 422', function () { + $this->withHeaders(applicationSettingsApiHeaders($this->bearerToken)) + ->patchJson("/api/v1/applications/{$this->application->uuid}", ['custom_container_name_prefix' => ['a', 'b']]) + ->assertUnprocessable() + ->assertJsonValidationErrors('custom_container_name_prefix'); + + expect($this->application->fresh()->settings->custom_container_name_prefix)->toBeNull(); +});