Name the server variable under a credential, not the internal key
tests / pest (push) Failing after 8m35s Details
tests / assets (push) Successful in 20s Details
tests / release (push) Has been skipped Details

Under each credential stood `stripe.secret`, `dns.token`,
`inbound_mail.password`, `monitoring.token` — identifiers out of
SecretVault::REGISTRY. They mean nothing on a settings page and there is
nowhere an operator could type them; asked about directly, and the answer is
no, that was not deliberate.

The env variable name is the useful one: it is what stands in the server
file, it is what the .env tab of this same page lists, and when the badge
beside it says "Aus der Serverdatei" it answers the obvious next question —
which line?

The registry key stays where it belongs: in wire:key and in the modal
arguments, as an identifier nobody reads. The test asserts on the text node
rather than on the key's absence from the HTML, because absence would have
demanded breaking the page to pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feature/betriebsmodus^2 v1.3.46
nexxo 2026-07-30 13:20:29 +02:00
parent a84251260c
commit f9993a1f48
3 changed files with 38 additions and 2 deletions

View File

@ -1 +1 @@
1.3.45
1.3.46

View File

@ -15,7 +15,15 @@
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h3 class="text-sm font-semibold text-ink">{{ $entry['label'] }}</h3>
<p class="mt-0.5 font-mono text-xs text-muted">{{ $entry['key'] }}</p>
{{-- The NAME OF THE SERVER VARIABLE, not the internal registry key.
It used to print `stripe.secret` an identifier from
SecretVault::REGISTRY that means nothing on this page and is not
something an operator can type anywhere. The env name is: it is
what stands in the server file, it is what the .env tab of this
same page lists, and when the badge beside this says "Aus der
Serverdatei" it is the answer to "which line?". --}}
<p class="mt-0.5 font-mono text-xs text-muted">{{ $entry['envKey'] }}</p>
</div>
<span class="inline-flex items-center gap-1.5 rounded-pill border px-2.5 py-0.5 text-xs font-medium
{{ $entry['source'] === 'stored' ? 'border-success-border bg-success-bg text-success'

View File

@ -476,3 +476,31 @@ it('saves .env once the page receives the confirmed event', function () {
expect(File::get($path))->toBe("CONFIRMED=value\n");
});
it('names the server variable under each credential, not the internal key', function () {
// It printed `stripe.secret` — an identifier out of SecretVault::REGISTRY
// that means nothing on a settings page and is not something an operator can
// type anywhere. The env name is what stands in the server file, what the
// .env tab of this same page lists, and the answer to "which line?" when the
// badge says the value comes from there.
$page = Livewire::actingAs(operator('Owner'), 'operator')->test(Integrations::class);
$page->assertSee('STRIPE_SECRET')
->assertSee('INBOUND_MAIL_PASSWORD')
->assertSee('HETZNER_DNS_TOKEN')
->assertSee('MONITORING_API_TOKEN');
// Not asserted by absence from the HTML: the key legitimately stays in
// wire:key and in the modal arguments, where it is an identifier nobody
// reads. What must not happen is printing it AS TEXT under the label.
$component = Illuminate\Support\Facades\File::get(
resource_path('views/components/admin/secret-field.blade.php')
);
$withoutComments = (string) preg_replace('/\{\{--.*?--\}\}/s', '', $component);
// Between tags, i.e. as a text node — the key stays inside attributes
// (wire:key, wire:click, the modal arguments), where it is an identifier
// nobody reads and removing it would break the page.
expect($withoutComments)->toMatch('/>\s*\{\{ \$entry\[.envKey.\] \}\}\s*</')
->and($withoutComments)->not->toMatch('/>\s*\{\{ \$entry\[.key.\] \}\}\s*</');
});