From c70463fb9f2f7f4b31ae96b2a29024ef8311b533 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:31:29 +0200 Subject: [PATCH] fix(env): hide hardcoded compose values from users who cannot edit Hardcoded variables parsed from docker-compose are now redacted in the environment variable list unless the user can update the resource. The value is nulled server-side and flagged with is_value_hidden, so it no longer reaches the Livewire snapshot or rendered HTML. ShowHardcoded gets a locked isValueHidden property. When it is set, the copy button is hidden and the details modal shows "Hidden (only admins can view)" in place of the value. Previously the view checked member role only. Add tests covering redaction for members and visibility for owners. --- .../Shared/EnvironmentVariable/All.php | 9 +++++- .../EnvironmentVariable/ShowHardcoded.php | 4 +++ .../show-hardcoded.blade.php | 12 +++++-- .../ComposeContentVisibilityTest.php | 31 +++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Livewire/Project/Shared/EnvironmentVariable/All.php index 47080cd86b..cc45568d2e 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -753,7 +753,14 @@ class All extends Component } // Otherwise keep order from docker-compose file - return $hardcodedVars; + // Compose content is visible only to users who can edit the resource. + $canViewValues = auth()->user()?->can('update', $this->resource) ?? false; + + return $hardcodedVars->map(fn (array $variable): array => [ + ...$variable, + 'value' => $canViewValues ? $variable['value'] : null, + 'is_value_hidden' => ! $canViewValues, + ]); } /** @return list */ diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/ShowHardcoded.php b/app/Livewire/Project/Shared/EnvironmentVariable/ShowHardcoded.php index 8e85c40b17..a7d7a73602 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/ShowHardcoded.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/ShowHardcoded.php @@ -17,6 +17,9 @@ class ShowHardcoded extends Component #[Locked] public ?string $value = null; + #[Locked] + public bool $isValueHidden = true; + public ?string $comment = null; public ?string $serviceName = null; @@ -34,6 +37,7 @@ class ShowHardcoded extends Component { $this->key = $this->env['key']; $this->value = $this->env['value'] ?? null; + $this->isValueHidden = $this->env['is_value_hidden'] ?? true; $this->comment = $this->env['comment'] ?? null; $this->serviceName = $this->env['service_name'] ?? null; } diff --git a/resources/views/livewire/project/shared/environment-variable/show-hardcoded.blade.php b/resources/views/livewire/project/shared/environment-variable/show-hardcoded.blade.php index 5492d33f90..6750e9c3ea 100644 --- a/resources/views/livewire/project/shared/environment-variable/show-hardcoded.blade.php +++ b/resources/views/livewire/project/shared/environment-variable/show-hardcoded.blade.php @@ -29,7 +29,7 @@ - -
- @unless (auth()->user()?->isMember() ?? true) + @unless ($isValueHidden) @endunless @@ -41,7 +41,15 @@
- + @if ($isValueHidden) +
+ + +
+ @else + + @endif @if (filled($comment)) @endif diff --git a/tests/Feature/Authorization/ComposeContentVisibilityTest.php b/tests/Feature/Authorization/ComposeContentVisibilityTest.php index 830a945ed7..7b5a7491db 100644 --- a/tests/Feature/Authorization/ComposeContentVisibilityTest.php +++ b/tests/Feature/Authorization/ComposeContentVisibilityTest.php @@ -3,6 +3,7 @@ use App\Livewire\Project\Application\General as ApplicationGeneral; use App\Livewire\Project\Service\EditCompose; use App\Livewire\Project\Service\StackForm; +use App\Livewire\Project\Shared\EnvironmentVariable\All as EnvironmentVariables; use App\Models\Application; use App\Models\InstanceSettings; use App\Models\Project; @@ -86,3 +87,33 @@ it('keeps compose content available to an owner', function () { expect($component->get('dockerCompose'))->toContain('TOKEN:'); } }); + +it('keeps hardcoded compose values out of the member environment variable list', function () { + $this->actingAs($this->member); + session(['currentTeam' => $this->team]); + + foreach ([$this->application, $this->service] as $resource) { + $component = Livewire::test(EnvironmentVariables::class, ['resource' => $resource]) + ->call('loadEnvironmentVariables'); + + expect($component->instance()->hardcodedEnvironmentVariables->pluck('key')->all())->toBe(['TOKEN']) + ->and(json_encode($component->snapshot).$component->html()) + ->not->toContain('stored-raw-compose-value') + ->not->toContain('stored-generated-compose-value') + ->not->toContain('Copy value') + ->toContain('Hidden (only admins can view)'); + } +}); + +it('shows hardcoded compose values to an owner', function () { + $this->actingAs($this->owner); + session(['currentTeam' => $this->team]); + + foreach ([$this->application, $this->service] as $resource) { + Livewire::test(EnvironmentVariables::class, ['resource' => $resource]) + ->call('loadEnvironmentVariables') + ->assertSee('stored-raw-compose-value') + ->assertSeeHtml('Copy value') + ->assertDontSee('Hidden (only admins can view)'); + } +});