Commit Graph

3 Commits (a71340156267a62c20fed32d5f0379af94854a5b)

Author SHA1 Message Date
nexxo 51a97019a8 Sperren sehen und aufheben: Portalseite fuer den Inhaber, Abschnitte in der Konsole
Aufgabe 6 des Fruehwarnsystems. Der Inhaber sieht im Portal die Sperren SEINER
Instanzen und hebt sie dort auf; der Betreiber sieht in der Konsole alle, an der
Kunden- und an der Host-Detailseite, und auf der Uebersicht steht ein Hinweis,
solange irgendwo eine Sperre aktiv ist.

Aufgehoben wird ueber ein Bestaetigungs-Modal (R23), und das Modal mutiert
nichts: es wirft ein Ereignis, das die Seite auffaengt und an ihre eigene
Methode weiterreicht. Die Berechtigungspruefung bleibt damit an der einen
Stelle, an der sie schon stand — noetig, weil ein Modal ohne die Middleware der
Seite erreichbar ist (R20). Dazu die Berechtigung `instances.manage`, nach dem
Muster der bestehenden `instances.restart`-Migration; Abrechnung und Read-only
bleiben unberuehrt.

ACHTUNG, was hier sonst noch drinsteckt und NICHT zu dieser Aufgabe gehoert:
rund 150 Zeilen zum Versandtakt — das Merkmal `RidesALane`, vierzehn Mailables
und `MailLaneRoutingTest`. Die stammen aus einer PARALLEL laufenden Sitzung an
einem anderen Feature.

Wie das hineingeriet: der Implementierer dieser Aufgabe brach vor dem Commit ab
und liess seine fertige Arbeit ungespeichert im Baum. Ich habe sie dateigenau
mit `git add <dateien>` vorgemerkt, um nichts Fremdes mitzunehmen — und dabei
uebersehen, dass `git add` nur HINZUFUEGT: die andere Sitzung hatte ihre Arbeit
bereits vorgemerkt, und `git commit` schreibt den ganzen Index, nicht nur das
zuletzt Hinzugefuegte. Richtig waere `git commit -- <dateien>` gewesen.

Nichts ist verloren, und die volle Suite ist auf diesem Stand gruen (2571).
Aber diese Botschaft soll nicht behaupten, sie beschreibe alles, was hier steht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 15:53:24 +02:00
nexxo 5dcfee9957 Wegwahl je Mailart: welche Mail aus welchem Postfach geht
MailCatalogue haelt die eine Liste aller sechzehn Mailarten (Schluessel,
Beschriftung, Vorgabe-Zweck), aus MailPreviews herausgezogen, damit es
nur noch eine Stelle gibt, die beim naechsten Mailtyp vergessen werden
kann. MailRoute sitzt darueber: ein Eintrag ist eine Ausnahme fuer GENAU
diese eine Mailart, keine zweite Zuordnungsebene — ohne Eintrag oder bei
abgeschaltetem Zielpostfach faellt sie unveraendert auf den Zweck
zurueck, den MailboxResolver schon kennt.

SendsFromMailbox bekommt dafuer einen optionalen $mailKey; alle
bestehenden Aufrufer (inklusive ContactRequestMail, das mailboxAddresses
selbst zusammensetzt) bleiben bei null und damit beim alten Verhalten.
Jede Mailklasse und die CloudReady-Benachrichtigung nennen jetzt ihren
Katalog-Schluessel. Die Konsole bekommt eine vierte Karte unter der
Zweck-Zuordnung: eine Zeile je Mailart, ein <select> mit den aktiven
Postfaechern und "wie der Zweck (...)" als Vorgabe.

Der wichtigste Test schickt eine Mail ohne jeden Eintrag und prueft,
dass sie exakt beim bisherigen Postfach landet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 12:43:31 +02:00
nexxo 5b8c28595a Require a confirmed address before an account can use anything
Registration opened an account that could sign in immediately on an address
nobody had proved was theirs — and anybody can type a stranger's into a
registration form. Both halves were commented out: the Fortify feature and
MustVerifyEmail on the model.

`verified` sits on the whole portal group rather than on the pages that spend
money. An unconfirmed address is not a billing problem to be caught at
checkout; it is an account that may not belong to the person holding it, and
the servers, the users and the backups behind it are worth as much to whoever
typed the address as to whoever owns it.

The mail is a Mailable in this product's design rather than Laravel's
notification, which would arrive with the framework's logo, button and footer
as the first thing anybody ever receives from CluPilot. It also has to leave
through the SYSTEM mailbox like every other account mail, which the
notification path does not do on its own.

The link is signed and expires, and the address is part of what is signed — so
a link issued to a mistyped address stops working the moment the address is
corrected, rather than confirming an address nobody can read. Tests cover the
tampered link, the expired one, the corrected address, and one account trying
to confirm another.

The waiting page is ours (Fortify has views off) and offers the only two things
that move somebody forward: send it again, or sign out and register with the
address they meant. The resend is throttled, because otherwise it is a button
that makes the server send mail to an arbitrary address as fast as it can be
clicked. Somebody already confirmed is redirected away from it — the `verified`
middleware only guards the other direction.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 23:43:20 +02:00