Die Auth-Strecke (Login, Registrierung, Passwort-Reset/-Bestaetigung, Magic-Link, E-Mail-Verifizierung, 2FA) war als einziger Backend-Bereich noch nicht durchgaengig __()-gewrappt. Alle sichtbaren deutschen Strings in __() gewickelt (Deutsch bleibt Schluessel). Eingebettete Links (AGB/ Datenschutz) und Alpine-x-text sauber segmentiert. Heading/Eyebrow und topRight-Label/-Link sowie der From-Banner werden jetzt im Auth-Layout am Ausgabepunkt uebersetzt (im #[Layout]-Attribut sind keine __()-Aufrufe moeglich). Leeres lang/en.json als Geruest fuer die spaetere EN-Befuellung. Kunden-, Admin-, Settings- und Component-Views waren bereits vollstaendig gewrappt (per Audit bestaetigt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
142 lines
5 KiB
PHP
142 lines
5 KiB
PHP
<?php
|
|
|
|
use Illuminate\Auth\Events\PasswordReset;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Password;
|
|
use Illuminate\Support\Facades\Session;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Validation\Rules;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\Locked;
|
|
use Livewire\Volt\Component;
|
|
|
|
new #[Layout('components.layouts.auth.pressekonto', ['heading' => 'Neues Passwort vergeben', 'eyebrow' => 'Passwort zurücksetzen'])] class extends Component {
|
|
#[Locked]
|
|
public string $token = '';
|
|
|
|
public string $email = '';
|
|
|
|
public string $password = '';
|
|
|
|
public string $password_confirmation = '';
|
|
|
|
/**
|
|
* Mount the component.
|
|
*/
|
|
public function mount(string $token): void
|
|
{
|
|
$this->token = $token;
|
|
|
|
$this->email = request()->string('email');
|
|
}
|
|
|
|
/**
|
|
* Reset the password for the given user.
|
|
*/
|
|
public function resetPassword(): void
|
|
{
|
|
$this->validate([
|
|
'token' => ['required'],
|
|
'email' => ['required', 'string', 'email'],
|
|
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
|
|
]);
|
|
|
|
$status = Password::reset(
|
|
$this->only('email', 'password', 'password_confirmation', 'token'),
|
|
function ($user) {
|
|
$user->forceFill([
|
|
'password' => Hash::make($this->password),
|
|
'remember_token' => Str::random(60),
|
|
])->save();
|
|
|
|
event(new PasswordReset($user));
|
|
}
|
|
);
|
|
|
|
if ($status != Password::PasswordReset) {
|
|
$this->addError('email', __($status));
|
|
|
|
return;
|
|
}
|
|
|
|
Session::flash('status', __($status));
|
|
|
|
$this->redirectRoute('login', navigate: true);
|
|
}
|
|
}; ?>
|
|
|
|
<div>
|
|
<p class="text-[13.5px] text-ink-2 leading-[1.6] !-mt-4 mb-6">
|
|
{{ __('Vergeben Sie ein neues Passwort für Ihr Konto. Mindestens 8 Zeichen, idealerweise eine Kombination aus Buchstaben, Zahlen und Sonderzeichen.') }}
|
|
</p>
|
|
|
|
<form wire:submit="resetPassword" class="space-y-[18px]" x-data="{ showPassword: false, showPasswordConfirmation: false }" novalidate>
|
|
|
|
<div>
|
|
<label class="field-label" for="auth-email">{{ __('E-Mail-Adresse') }}</label>
|
|
<input
|
|
id="auth-email"
|
|
type="email"
|
|
wire:model="email"
|
|
required
|
|
autocomplete="email"
|
|
class="field-input"
|
|
@error('email') aria-invalid="true" @enderror
|
|
/>
|
|
@error('email')
|
|
<p class="field-error">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div>
|
|
<label class="field-label" for="auth-password">{{ __('Neues Passwort') }}</label>
|
|
<div class="field-pw-wrap">
|
|
<input
|
|
id="auth-password"
|
|
wire:model="password"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
required
|
|
autocomplete="new-password"
|
|
class="field-input pr-[72px]"
|
|
:placeholder="__('Mindestens 8 Zeichen')"
|
|
@error('password') aria-invalid="true" @enderror
|
|
/>
|
|
<button
|
|
type="button"
|
|
class="field-affix"
|
|
@click="showPassword = !showPassword"
|
|
x-text="showPassword ? '{{ __('Verbergen') }}' : '{{ __('Anzeigen') }}'"
|
|
>{{ __('Anzeigen') }}</button>
|
|
</div>
|
|
@error('password')
|
|
<p class="field-error">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div>
|
|
<label class="field-label" for="auth-password-confirmation">{{ __('Passwort bestätigen') }}</label>
|
|
<div class="field-pw-wrap">
|
|
<input
|
|
id="auth-password-confirmation"
|
|
wire:model="password_confirmation"
|
|
:type="showPasswordConfirmation ? 'text' : 'password'"
|
|
required
|
|
autocomplete="new-password"
|
|
class="field-input pr-[72px]"
|
|
:placeholder="__('Neues Passwort wiederholen')"
|
|
/>
|
|
<button
|
|
type="button"
|
|
class="field-affix"
|
|
@click="showPasswordConfirmation = !showPasswordConfirmation"
|
|
x-text="showPasswordConfirmation ? '{{ __('Verbergen') }}' : '{{ __('Anzeigen') }}'"
|
|
>{{ __('Anzeigen') }}</button>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="auth-btn-primary !mt-[22px]" wire:loading.attr="disabled" wire:target="resetPassword">
|
|
<span wire:loading.remove wire:target="resetPassword">{{ __('Passwort zurücksetzen') }}</span>
|
|
<span wire:loading wire:target="resetPassword">{{ __('Passwort wird gespeichert …') }}</span>
|
|
</button>
|
|
</form>
|
|
</div>
|