🚀 Enhance authorization and exception handling across Livewire components and SecurityMonitor

- **SecurityMonitor:** Added logic to record and prevent logging of locked-property exceptions, while ensuring non-security exceptions are properly forwarded.
- **Livewire `Members/Admin`:** Centralized authorization logic in private methods, enforced access control on actions, and moved allowed pubkeys to class constant for maintainability.
- **Livewire `News`:** Enforced authorization for editing and deleting news with guard methods and ensured unauthorized users can't access data.
- **Bootstrap exceptions:** Implemented custom exception handling to record Livewire-related security issues while preventing redundant logs.
- Updated tests with new behavior verification covering access control and exception responses.
This commit is contained in:
HolgerHatGarKeineNode
2026-06-02 19:23:51 +02:00
parent 59bc440a59
commit 5f28bfedd4
6 changed files with 251 additions and 34 deletions
@@ -41,6 +41,7 @@ class extends Component {
#[Locked]
public ?\App\Models\EinundzwanzigPleb $currentPleb = null;
#[Locked]
public ?int $confirmDeleteId = null;
public function mount(): void
@@ -58,7 +59,9 @@ class extends Component {
$this->isAllowed = true;
}
$this->loadNews();
if ($this->isAllowed) {
$this->loadNews();
}
}
#[Computed]
@@ -93,6 +96,8 @@ class extends Component {
public function save(): void
{
$this->ensureCanEdit();
$this->validate([
'file' => 'required|file|mimes:pdf',
'form.category' => 'required|string|in:'.implode(',', NewsCategory::values()),
@@ -119,11 +124,15 @@ class extends Component {
public function confirmDelete(int $id): void
{
$this->ensureCanEdit();
$this->confirmDeleteId = $id;
}
public function delete(): void
{
$this->ensureCanEdit();
$news = Notification::query()->findOrFail($this->confirmDeleteId);
$news->delete();
$this->loadNews();
@@ -131,9 +140,21 @@ class extends Component {
public function removeFile(): void
{
$this->ensureCanEdit();
$this->file->delete();
$this->file = null;
}
private function canEditNews(): bool
{
return NostrAuth::user()?->isBoardMember() ?? false;
}
private function ensureCanEdit(): void
{
abort_unless($this->canEditNews(), 403);
}
};
?>