CluPilotCloud/app/Livewire/Security.php

71 lines
2.3 KiB
PHP

<?php
namespace App\Livewire;
use App\Livewire\Concerns\ResolvesCustomer;
use App\Models\SecurityBlock;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
/**
* Die Sperrliste der eigenen Instanzen — das Ziel, auf das die Mail aus
* BlockAddress verlinkt (route('portal.security'), siehe deren
* SecurityBlockMail), und der Ort, an dem ein Kunde eine eigene
* Fehlalarm-Sperre selbst vorzeitig aufheben kann.
*/
#[Layout('layouts.portal-app')]
class Security extends Component
{
use ResolvesCustomer;
/**
* ConfirmReleaseBlock dispatches this back (R23) — das Modal selbst
* mutiert nichts. Es ist ohne die Middleware dieser Seite erreichbar
* (R20), deshalb wird hier — wie im Modal auch, aber unabhaengig davon —
* erneut geprueft, dass die Sperre zu einer Instanz DIESES Kunden
* gehoert, statt der uebergebenen uuid zu vertrauen. Eine fremde oder
* eine Host-Sperre (kein instance_id) gibt es hier nie zu sehen.
*/
#[On('block-release-confirmed')]
public function onReleaseConfirmed(string $uuid): void
{
$customer = $this->customer();
$block = SecurityBlock::query()
->where('uuid', $uuid)
->whereHas('instance', fn ($q) => $q->where('customer_id', $customer?->id))
->first();
abort_if($block === null, 403);
$block->release(auth()->user());
$this->dispatch('notify', message: __('security.blocks_released'));
}
public function render()
{
$customer = $this->customer();
$blocks = $customer
? SecurityBlock::query()
->whereHas('instance', fn ($q) => $q->where('customer_id', $customer->id))
->orderByDesc('blocked_at')
->get()
: collect();
// Aktiv/Verlauf wird hier gesplittet, nicht per zweiter Abfrage:
// scopeActive() prueft dieselben zwei Felder, die die Menge schon in
// der Hand haelt.
return view('livewire.security', [
'active' => $blocks->filter(
fn (SecurityBlock $b) => $b->released_at === null && $b->expires_at->isFuture()
)->values(),
'history' => $blocks->filter(
fn (SecurityBlock $b) => $b->released_at !== null || $b->expires_at->isPast()
)->values(),
]);
}
}