102 lines
4.1 KiB
PHP
102 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Mail;
|
|
|
|
use App\Mail\Concerns\RidesALane;
|
|
use App\Mail\Concerns\SendsFromMailbox;
|
|
use App\Models\SecurityBlock;
|
|
use App\Services\Mail\MailCatalogue;
|
|
use App\Services\Mail\MailPurpose;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Mail\Mailable;
|
|
use Illuminate\Mail\Mailables\Content;
|
|
use Illuminate\Mail\Mailables\Envelope;
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
/**
|
|
* "Eine Adresse wurde wegen Anmeldeversuchen gesperrt."
|
|
*
|
|
* ZWEI Empfängerkreise, eine Mailart — und das ist keine Bequemlichkeit,
|
|
* sondern der Grund, warum diese Klasse beide Fälle ausdrücklich auseinander
|
|
* hält:
|
|
*
|
|
* - **Instanz-Sperre** → an den Inhaber. Text in der zweiten Person („bei
|
|
* Ihrer Cloud"), Anrede aus dem Kundendatensatz, Knopf auf die
|
|
* Sicherheitsseite des Portals (`portal.security`), wo er die Sperre
|
|
* einsehen und vorzeitig aufheben kann.
|
|
* - **Host-Sperre** → an die Betreiber mit `hosts.manage` (siehe
|
|
* `BlockAddress::notifyHostManagers()`). Eigener Text mit dem NAMEN des
|
|
* Hosts, keine Anrede, und der Knopf zeigt auf die Host-Detailseite der
|
|
* Konsole.
|
|
*
|
|
* Der Unterschied ist nicht kosmetisch: ein Betreiber hat im Portal kein
|
|
* Konto, und Host-Sperren erscheinen dort ohnehin nie. Ein Knopf auf
|
|
* `portal.security` in einer Host-Mail führt also zwangsläufig ins Leere —
|
|
* und ohne den Hostnamen im Text stünde in einer Meldung an jemanden mit
|
|
* einem Dutzend Maschinen nicht, welche gemeint ist.
|
|
*
|
|
* Aus dem SYSTEM-Postfach, genau wie NewDeviceSignInMail: das ist kein
|
|
* Gespräch, und eine Antwort darauf soll kein Ticket öffnen. Über die Wegwahl
|
|
* (`MailRoute`, Mailart `security-block`) kann der Betreiber sie auf ein
|
|
* anderes Postfach legen — dann geht sie auch über DESSEN SMTP-Konto, nicht
|
|
* nur mit dessen Absenderzeile.
|
|
*
|
|
* Die Drossel — höchstens eine Mail je Subjekt und Stunde — sitzt in
|
|
* BlockAddress, nicht hier: diese Klasse weiß nichts davon, ob sie gerade die
|
|
* erste oder die zehnte Sperre dieser Stunde beschreibt, und muss es auch
|
|
* nicht wissen.
|
|
*/
|
|
class SecurityBlockMail extends Mailable implements ShouldQueue
|
|
{
|
|
use Queueable, RidesALane, SendsFromMailbox, SerializesModels;
|
|
|
|
public function __construct(public SecurityBlock $block)
|
|
{
|
|
$this->mailer(MailCatalogue::mailer('security-block'));
|
|
}
|
|
|
|
public function envelope(): Envelope
|
|
{
|
|
$host = $this->block->host;
|
|
|
|
return $this->mailboxEnvelope(
|
|
MailPurpose::SYSTEM,
|
|
$host !== null
|
|
? __('security.mail_subject_host', ['host' => $host->name])
|
|
: __('security.mail_subject'),
|
|
'security-block',
|
|
);
|
|
}
|
|
|
|
public function content(): Content
|
|
{
|
|
$host = $this->block->host;
|
|
|
|
// instance() statt eines eigenen Customer-Parameters: der Aufrufer
|
|
// (BlockAddress) hat ohnehin nur den Datensatz, und ein zweiter Weg,
|
|
// an dieselbe Instanz zu kommen, wäre eine zweite Stelle, an der der
|
|
// Name veralten könnte.
|
|
$customer = $this->block->instance?->customer;
|
|
|
|
return new Content(view: 'mail.security-block', with: [
|
|
// Der Name des Hosts ist das Unterscheidungsmerkmal für die
|
|
// Ansicht: gesetzt heißt Host-Sperre, null heißt Instanz-Sperre.
|
|
// Ein zweites Flag daneben wäre eine zweite Wahrheit.
|
|
'hostName' => $host?->name,
|
|
'name' => (string) ($customer?->contact_name ?: $customer?->name ?: ''),
|
|
'ip' => $this->block->ip,
|
|
'attempts' => $this->block->attempts,
|
|
'blockedAt' => $this->block->blocked_at,
|
|
'expiresAt' => $this->block->expires_at,
|
|
// Der Betreiber hat im Portal kein Konto, und Host-Sperren stehen
|
|
// dort nie. Sein Weg zum Handgriff ist die Host-Detailseite der
|
|
// Konsole, auf der die Host-Sperren mit ihrem Aufheben-Knopf
|
|
// stehen (Aufgabe 6, App\Livewire\Admin\HostDetail).
|
|
'securityUrl' => $host !== null
|
|
? route('admin.hosts.show', $host)
|
|
: route('portal.security'),
|
|
]);
|
|
}
|
|
}
|