Audit: dev/sicherheit/SICHERHEITSAUDIT-2026-10-07.md, Plan und Entscheidungen: dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md. - S-01 Legacy-Rechnungen fremder Kunden nur mit billing:manage (auch Kundenroute). - S-02 Kontaktzuordnung auf der Firmenanzeige verlangt companies:write, $id gesperrt. - S-03 CompanyMembershipObserver: automatische Firmenrechte werden bei jeder Adress-/Zuordnungsänderung sofort neu bewertet; memberships:resync-auto. - S-04 Passwortwechsel beendet alle anderen Sessions (PasswordChanger), Reset alle Sessions und offene Login-Links; Fortify PUT /user/password abgeschaltet. API-Tokens bleiben bestehen. - S-05 Google: email_verified Pflicht, feste Bindung über die Provider-ID; Erstverknüpfung bestehender Konten außerhalb gmail/hd nur per Bestätigungslink in derselben Browser-Session. - S-06 Frischer Identitätsnachweis (Passwort, App-Code, E-Mail-Code oder Passkey) vor E-Mail-Wechsel, erster 2FA-Einrichtung und Token-Erzeugung; Hinweis-Mails an die (bisherige) Kontoadresse. - Entscheidung 5: Passkeys (Fortify, @laravel/passkeys) für alle; Super-Admins und Admins bestätigen die Session für den Admin-Bereich per Passkey oder App-Code (EnsureStrongAdminAuthentication, Notfallschalter AUTH_REQUIRE_STRONG_ADMIN); Reset des zweiten Faktors durch Super-Admins. Neue Migration: create_passkeys_table. Suite 2.403 grün (1 übersprungen), Larastan ohne Meldung. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.6 KiB
PHP
78 lines
2.6 KiB
PHP
<?php
|
|
|
|
use App\Services\Auth\PasswordChanger;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Validation\Rules\Password;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Component;
|
|
|
|
new #[Layout('components.layouts.app')] class extends Component
|
|
{
|
|
public string $current_password = '';
|
|
|
|
public string $password = '';
|
|
|
|
public string $password_confirmation = '';
|
|
|
|
/**
|
|
* Update the password for the currently authenticated user.
|
|
*/
|
|
public function updatePassword(): void
|
|
{
|
|
try {
|
|
$validated = $this->validate([
|
|
'current_password' => ['required', 'string', 'current_password'],
|
|
'password' => ['required', 'string', Password::defaults(), 'confirmed'],
|
|
]);
|
|
} catch (ValidationException $e) {
|
|
$this->reset('current_password', 'password', 'password_confirmation');
|
|
|
|
throw $e;
|
|
}
|
|
|
|
app(PasswordChanger::class)->change(Auth::user(), $validated['password'], session()->driver());
|
|
|
|
$this->reset('current_password', 'password', 'password_confirmation');
|
|
|
|
$this->dispatch('password-updated');
|
|
}
|
|
}; ?>
|
|
|
|
<section class="w-full">
|
|
@include('partials.settings-heading')
|
|
|
|
<x-settings.layout :heading="__('Update password')" :subheading="__('Ensure your account is using a long, random password to stay secure')">
|
|
<form wire:submit="updatePassword" class="space-y-5">
|
|
<flux:input
|
|
wire:model="current_password"
|
|
:label="__('Current password')"
|
|
type="password"
|
|
required
|
|
autocomplete="current-password"
|
|
/>
|
|
<flux:input
|
|
wire:model="password"
|
|
:label="__('New password')"
|
|
type="password"
|
|
required
|
|
autocomplete="new-password"
|
|
/>
|
|
<flux:input
|
|
wire:model="password_confirmation"
|
|
:label="__('Confirm Password')"
|
|
type="password"
|
|
required
|
|
autocomplete="new-password"
|
|
/>
|
|
|
|
<div class="flex items-center gap-4 pt-2 border-t border-[color:var(--color-bg-rule)]">
|
|
<flux:button variant="primary" type="submit">{{ __('Save') }}</flux:button>
|
|
|
|
<x-action-message on="password-updated">
|
|
<span class="text-[12px] text-[color:var(--color-gain-deep)]">{{ __('Saved.') }}</span>
|
|
</x-action-message>
|
|
</div>
|
|
</form>
|
|
</x-settings.layout>
|
|
</section>
|