- 83 Komponenten: Livewire\Volt\Component → Livewire\Component
- 73 Routen (admin, auth, customer): Volt::route() → Route::livewire()
- 88 Testdateien: Volt::test/actingAs → Livewire::test/actingAs
- VoltServiceProvider gelöscht; composer remove livewire/volt
- config/livewire.php auf v4-Schlüssel (component_layout, component_placeholder,
component_locations, make_command: SFC ohne ⚡). Der alte Schlüssel layout war
wirkungslos; alle gerouteten Komponenten setzen ihr Layout selbst.
- CLAUDE.md, AGENTS.md, boost.json, .cursorrules, Skill volt-development
- Roadmap: erledigt; Larastan erfasst SFCs weiterhin nicht (Blade-Dateien)
Suite 2.325 grün, einer übersprungen; Larastan und Pint ohne Meldung;
route:cache und view:cache laufen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
2.8 KiB
PHP
79 lines
2.8 KiB
PHP
<?php
|
||
|
||
use Livewire\Attributes\Layout;
|
||
use Livewire\Component;
|
||
|
||
new #[Layout('components.layouts.auth.pressekonto', ['heading' => 'Zwei-Faktor-Bestätigung', 'eyebrow' => 'Sicherheitsprüfung', 'showFromBanner' => false])] class extends Component {
|
||
public function mount(): void
|
||
{
|
||
// Ohne laufende Challenge (login.id aus dem ersten Schritt) hat die Seite
|
||
// keinen Kontext – zurück zum Login.
|
||
if (! session()->has('login.id')) {
|
||
$this->redirect(route('login'), navigate: false);
|
||
}
|
||
}
|
||
}; ?>
|
||
|
||
<div x-data="{ recovery: false }">
|
||
@if ($errors->any())
|
||
<div class="field-status mb-4" role="alert">
|
||
{{ $errors->first() }}
|
||
</div>
|
||
@endif
|
||
|
||
<p class="text-[13.5px] text-ink-2 leading-[1.65] !-mt-2 mb-6">
|
||
<span x-show="! recovery">
|
||
{{ __('Geben Sie den 6-stelligen Code aus Ihrer Authenticator-App ein.') }}
|
||
</span>
|
||
<span x-show="recovery" x-cloak>
|
||
{{ __('Geben Sie einen Ihrer Wiederherstellungs-Codes ein.') }}
|
||
</span>
|
||
</p>
|
||
|
||
{{-- Echter POST an Fortifys 2FA-Challenge-Controller (verifiziert gegen die
|
||
login.id aus der Session und loggt bei Erfolg ein). --}}
|
||
<form method="POST" action="/two-factor-challenge" class="space-y-[18px]">
|
||
@csrf
|
||
|
||
<div x-show="! recovery">
|
||
<label class="field-label" for="code">{{ __('Authentifizierungs-Code') }}</label>
|
||
<input
|
||
id="code"
|
||
name="code"
|
||
type="text"
|
||
inputmode="numeric"
|
||
autocomplete="one-time-code"
|
||
class="field-input"
|
||
placeholder="123456"
|
||
x-bind:disabled="recovery"
|
||
x-ref="code"
|
||
/>
|
||
</div>
|
||
|
||
<div x-show="recovery" x-cloak>
|
||
<label class="field-label" for="recovery_code">{{ __('Wiederherstellungs-Code') }}</label>
|
||
<input
|
||
id="recovery_code"
|
||
name="recovery_code"
|
||
type="text"
|
||
autocomplete="one-time-code"
|
||
class="field-input"
|
||
placeholder="xxxxxxxx-xxxxxxxx"
|
||
x-bind:disabled="! recovery"
|
||
/>
|
||
</div>
|
||
|
||
<button type="submit" class="auth-btn-primary !mt-[18px]">
|
||
{{ __('Bestätigen') }}
|
||
</button>
|
||
|
||
<button
|
||
type="button"
|
||
class="auth-btn-outline !mt-0"
|
||
x-on:click="recovery = ! recovery; $nextTick(() => (recovery ? document.getElementById('recovery_code') : $refs.code)?.focus())"
|
||
>
|
||
<span x-show="! recovery">{{ __('Wiederherstellungs-Code verwenden') }}</span>
|
||
<span x-show="recovery" x-cloak>{{ __('Code aus App verwenden') }}</span>
|
||
</button>
|
||
</form>
|
||
</div>
|