4 Commits (96bc2c5a07863741ae1e8cf3259b8ff25fff9419)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
f40b762413 |
Zwei Empfaengerkreise, und eine Wegwahl, die auch das Konto verschiebt
Fix-Welle nach dem Gesamt-Review, Punkte 4 und 5. Beide sitzen in denselben
Dateien, deshalb ein Commit.
DIE HOST-MELDUNG WAR WORTWOERTLICH DIE KUNDENMAIL (Punkt 4).
notifyHostManagers() verschickte dieselbe SecurityBlockMail. Deren Text ist fuer
den Kunden geschrieben ("bei Ihrer Cloud", "…koennen Sie die Sperre auf der
Sicherheitsuebersicht aufheben"), der Knopf zeigte auf portal.security — wo ein
Betreiber kein Konto hat und Host-Sperren nie erscheinen —, welcher Host
betroffen ist stand nirgends, und die Anrede blieb leer, weil $block->instance
null ist.
Die Mail kann jetzt beide Faelle. Unterscheidungsmerkmal in der Ansicht ist
$hostName: gesetzt heisst Host-Sperre, null heisst Instanz-Sperre. Ein zweites
Flag daneben waere eine zweite Wahrheit.
- Betreff nennt den Host.
- Eigener Textblock (mail_heading_host, mail_preheader_host, mail_intro_host mit
"fehlgeschlagene SSH-Anmeldungen am Host :host"), eigene Tabellenzeile
field_host, eigener Hinweis mail_note_host.
- Der Knopf zeigt auf admin.hosts.show, also auf die Host-Detailseite der
Konsole, wo die Host-Sperren mit ihrem Aufheben-Knopf stehen.
- Keine Anrede im Host-Fall — sie war vorher leer, und der Empfaengerkreis ist
ohnehin mehrere Personen.
- Der Fehlalarm-Satz ist ein anderer und sagt, was ein Betreiber wissen will:
bestehende Verbindungen bleiben unberuehrt, die Regel steht unter
"established,related accept".
R19: die zwei Kommentare, die fuer Host-Sperren Unwahres behaupteten, sind
richtiggestellt — der Kopfkommentar von SecurityBlockMail und der
MailCatalogue-Eintrag. Beide beschreiben jetzt zwei Empfaengerkreise. Ein
Kommentar mit falscher Begruendung haelt den Naechsten vom Nachsehen ab.
DIE WEGWAHL VERSCHOB DEN ABSENDER, NICHT DAS KONTO (Punkt 5).
SecurityBlockMail nagelte mailer('cp_system') fest und holte das Postfach ueber
die Wegwahl. MailboxTransport loeste weiter ueber den ZWECK auf und
authentifizierte mit dessen Zugangsdaten. Legte der Betreiber security-block auf
info@ — der ausdrueckliche Anlass fuer Abschnitt 3a der Spec —, ging die Mail
mit From: info@ durch die SMTP-Sitzung von no-reply@. Viele Server weisen das ab
("553 5.7.1 Sender address rejected: not owned by user"), und dann verschwindet
ausgerechnet die Mail, die er gerade umgelegt hat. Betraf ALLE Mailarten.
Die Wegwahl bestimmt jetzt auch den Mailer. Die zweitbeste Loesung — die Auswahl
in der Konsole auf Postfaecher zu begrenzen, deren Konto benutzt wird — war
nicht noetig.
- config/mail.php erzeugt AUS MailCatalogue::all() je Mailart einen Mailer
cp_mail_<mailart> mit transport, purpose und mail_key. Erzeugt statt
aufgelistet, weil der Katalog ausdruecklich die EINE Liste ist; eine zweite
hier waere die, die beim siebzehnten Mail vergessen wird. Genauso statisch wie
die fuenf Zweck-Mailer: ein reines Array, keine Datenbank, auch unter
config:cache unveraendert.
- MailboxTransport nimmt den mail_key entgegen und loest damit ueber DIESELBE
MailRoute::purposeOrMailbox() auf, die auch der Umschlag fragt. Ohne
Schluessel entscheidet wie bisher allein der Zweck — jeder Mailer, der keinen
hat, verhaelt sich unveraendert.
- Jede Mailart mit Schluessel benennt ihren Mailer ueber
MailCatalogue::mailer(). Dessen Rueckfall auf cp_<zweck> fuer einen
unbekannten Schluessel ist nicht Zierde: DunningNoticeMail baut seinen
Schluessel aus der Mahnstufe, und ohne den Rueckfall waere eine Stufe
ausserhalb 0-3 ein "Mailer [...] is not defined" und damit ein Totalausfall
statt eines falschen Absenders.
- Betrifft alle Mailarten: 13 Mailables, die CloudReady-Notification und die
cloud-ready-Vorschau. ContactRequestMail bleibt auf cp_support — es hat keinen
Schluessel im Katalog, weil es keine eigene Mailart ist.
MailSenderOwnershipTest ist mitgezogen und dabei STRENGER geworden. Die alte
Fassung verglich "From-Zweck == Mailer-Zweck"; jetzt prueft sie, dass der
Katalog dem Zweck zustimmt, den der Umschlag verlangt. Katalog-Drift war bis
hierher nur als Warnung im Docblock von MailCatalogue festgehalten und durch
nichts erzwungen. Ein Literal, das selbst kein Schluessel ist, wird als PRAEFIX
behandelt (der Mahnlauf) — dann muessen alle Schluessel dahinter zustimmen, und
es muss mindestens einen geben.
MailPreviewTest fragte den Zweck bisher, indem es 'cp_' vom Mailer-Namen
abschnitt. Das war eine Zusicherung ueber das Namensschema, nicht ueber die
Zusage; sie liest den Zweck jetzt aus der Konfiguration des Mailers selbst.
tests/Feature/Mail/SenderAddressTest.php gehoert inhaltlich zur parallel
laufenden Sitzung. Vier Zusicherungen darin pruefen genau den Mailer-Namen, den
dieser Commit aendert, also sind sie mitgezogen — die Datei war dabei sauber,
es steckt keine fremde unfertige Arbeit in diesem Commit.
Committet mit ausdruecklicher Dateiangabe am Zeilenende, weil eine parallele
Sitzung an derselben Ablage arbeitet und der Index fremde Arbeit enthalten kann.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
|
|
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> |
|
|
|
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> |
|
|
|
3a4324fb6f |
Give people a way back in, and put the URL in English
tests / pest (push) Failing after 7m54s
Details
tests / assets (push) Successful in 21s
Details
tests / release (push) Has been skipped
Details
── The hole ──────────────────────────────────────────────────────────────── There was no password reset. Fortify's feature was commented out, so there was no link on the sign-in form, no page and no route — a customer who forgot their password was locked out of their own cloud until somebody opened a shell. On a product whose selling point is that you can ring somebody, that is a support call a week and an embarrassing one. Two pages of ours under Fortify's route names (R1/R2), because with views off Fortify registers only the POST endpoints. The mail is a Mailable in this product's design rather than the framework's MailMessage: somebody who has just been locked out is exactly the person a phishing mail is aimed at, and a message that looks nothing like the rest of our post is one they cannot check — ours carries the footer that names our domains. Three decisions worth stating, each with a test: The answer is identical whether the address is known or not. "No account with that address" turns the form into a way of finding out who is a customer. The reset kills every other session. Whoever knew the old password may still be signed in somewhere, and a reset that leaves them there has fixed nothing. It does NOT sign the visitor in. The link arrived by email, and a mailbox somebody else can read would otherwise be a session somebody else gets. ── /sicherheit → /security ───────────────────────────────────────────────── R13: paths are English. Mine was not. The old path stays as a permanent redirect because it has already gone out in mail footers. ── One wordmark ──────────────────────────────────────────────────────────── "Sometimes it says Cloud and sometimes it does not" — correct. It was on the footer, the placeholder and the maintenance screen, and absent from the header, the sidebar and the sign-in plate. The product is called CluPilot Cloud; that is the name on the invoices and in every mail, so it is now the name everywhere. The console sidebar takes the small size so the lockup, the ADMIN badge and the close button still share one line (R18). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |