← Planung

Spezifikation: Magic-Code Login

Slug magic_code_login. Vollständigkeit (Sektions-Füllgrad) über alle 13 Schritte: 60%. Achtung: Score misst nur ob Sektionen gefüllt sind, nicht fachliche Korrektheit oder Widerspruchsfreiheit. Pro Schritt werden neun Prüfebenen ausgewiesen: UI-Lokation, Eingabe-Felder, Duplikat-Prüfung, Gate-Aktionen, Code-Verknüpfung, CRM-Kategorisierung, Security-Maßnahmen, Protokollierung, Entitäten-Map.

Schritt 1: E-Mail-Adresse entgegennehmen (Spec 67%)

1. UI-Lokation

URL
POST /login
Controller
MagicCodeController::codeAnfordern
Template
src/Auth/Http/Views/magic_code_form.html.php
Zugriff
oeffentlich

2. Eingabe-Felder (2)

#LabelVariableTypPflichtValidierungMaxZiel
1E-Mail-Adresseemailemailjafilter_var FILTER_VALIDATE_EMAIL200magic_code_login.email
2CSRF-Tokencsrf_tokentokenjahash_equals gegen Session-Token64—.—

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (4)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
sql_injectionrequest.emailprepared_statementsrc/Auth/Infrastructure/PdoMensch.phplog_and_block
PDO Prepared Statement bei SELECT mensch WHERE email
header_injectionrequest.emailstrip_crlfsrc/Auth/Domain/EmailValidator.php400_bad_request
Strip \r \n, dann filter_var FILTER_VALIDATE_EMAIL
xssrequest.emailhtmlspecialcharssrc/Auth/Http/Views/login_form.html.phplog_only
Rueckanzeige der Email nur ueber htmlspecialchars mit ENT_QUOTES
csrfPOST /logincsrf_tokensrc/Auth/Http/MagicCodeController.php403_forbidden
Session-gebundener CSRF-Token in Form

8. Protokollierung (2)

ZielLevelTriggerFelderPII-MaskierungRetention
app_loginfobei_start["email_hash","ip","user_agent","ts"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}30 Tage
Email-Eingabe Login-Start
security_logwarnbei_fehler["email_hash","ip","fehler_code","angriffs_typ"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}365 Tage
Validierungsfehler Email

9. Entitaeten-Map (2)

TypZielRolleDatei
datei/var/www/campus.karlkratz.com/src/Auth/Http/Views/magic_code_form.html.phprendert/var/www/campus.karlkratz.com/src/Auth/Http/Views/magic_code_form.html.php
klasseMagicCodeControllerimplementiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
prerequest.email != null AND request.email matches RFC5322Email muss vorhanden und syntaktisch valide
invariantkeine Persistenz vor ValidierungEmail wird erst nach Validierung gehasht
postrate_limit_check.passed = trueRate-Limit nicht ueberschritten

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 1: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 1: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 1: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 1: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 1: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 2: Rate-Limit pro E-Mail prüfen (Spec 58%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (2)

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
rate_limit_bypassrequest.ip+emailrate_limitsrc/Auth/Application/RateLimiter.php429_too_many
5 Versuche pro 15 Minuten pro IP UND Email-HMAC einheitlich, Backoff bei Ueberschreitung

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
security_logwarnbei_fehler["email_hash","ip","versuche_count"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}365 Tage
Rate-Limit erreicht

9. Entitaeten-Map (2)

TypZielRolleDatei
klasseRateLimiterschuetzt
klasseEmailValidatorvalidiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
prerequest.ip != nullIP-Adresse muss bekannt sein
invariantrate_limit_window = 15min konstantWindow-Groesse darf nicht variieren
postattempts_count <= 5Versuche im Limit

11. Persistenz-Schema und Statemachine (0 Mutationen, 1 Zustandsuebergaenge)

EntitaetVonNachAusloeserBedingung
magic_codesentblockedrate_limit_ueberschrittenattempts_count > 5

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 2: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 2: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 2: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 2: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 2: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 3: Gate: E-Mail existiert in Mensch? (Spec 75%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (1)

  1. mensch.email (exakt): Case-insensitive Match auf Mensch.email.

4. Gate-Aktionen (2)

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (2)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
timing_attackresponse.email_existsrate_limitsrc/Auth/Application/MagicCodeService.phplog_only
Konstante Antwortzeit unabhaengig ob Email existiert, verhindert User-Enumeration
sql_injectiondb.mensch.email_hashprepared_statementsrc/Auth/Infrastructure/PdoMensch.phplog_and_block
SELECT mensch WHERE email_hash gebunden

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_entscheidung["email_hash","mensch_gefunden","ts"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}90 Tage
Gate Email-Existenz

9. Entitaeten-Map (1)

TypZielRolleDatei
klassePdoMenschpersistiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
preemail_hmac != nullHMAC der Email vorhanden
invariantkonstante Antwortzeit unabhaengig vom TrefferVerhindert User-Enumeration
postmensch.id ist null oder intEindeutiger Treffer oder kein Treffer

11. Persistenz-Schema und Statemachine (1 Mutationen, 0 Zustandsuebergaenge)

TabelleMutationFelderConstraintsAtomar mit
menschSELECT["id","email_hmac"]WHERE email_hmac=? LIMIT 1

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 3: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 3: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 3: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 3: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 3: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 4: Magic-Code erzeugen (Spec 50%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
timing_attackinternal.randomnessrandom_bytessrc/Auth/Domain/MagicCode.php500_internal
random_bytes(16) + base32-Encoding für 128-bit Entropie

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_erfolg["mensch_id","code_hash","expires_at"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}90 Tage
Magic-Code generiert

9. Entitaeten-Map (2)

TypZielRolleDatei
klasseMagicCodeimplementiert
klasseMagicCodeServiceimplementiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
premensch.id != nullMensch muss existieren (sonst Skip zu Schritt 7)
invariantrandom_bytes() niemals deterministischCrypto-RNG Pflicht
postmagic_code.entropy >= 128 ODER magic_code.length 6-8 mit rate_limitToken oder Code

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 4: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 4: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 4: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 4: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 4: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 5: Magic-Code im Datensatz speichern (Spec 58%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
sql_injectiondb.magic_codeprepared_statementsrc/Auth/Infrastructure/PdoMagicCode.phplog_and_block
INSERT mit gebundenen Parametern

8. Protokollierung (2)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_erfolg["mensch_id","code_id","created_at"]{}90 Tage
Code persistiert
security_logerrorbei_fehler["mensch_id","db_fehler"]{}365 Tage
DB-Schreibfehler

9. Entitaeten-Map (1)

TypZielRolleDatei
klassePdoMagicCodepersistiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
premagic_code.code_hash != nullHash bereits berechnet
invariantniemals Klartext-Code in DBNur Hash oder HMAC
postmagic_code.id != null AND used_at IS NULLPersistiert, noch nicht eingeloest

11. Persistenz-Schema und Statemachine (1 Mutationen, 1 Zustandsuebergaenge)

TabelleMutationFelderConstraintsAtomar mit
magic_codeINSERT["mensch_id","code_hash","expires_at","created_ip_hash","attempt_count"]expires_at=NOW+15min, attempt_count=0
EntitaetVonNachAusloeserBedingung
magic_coderequestedsentcode_persistiert

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 5: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 5: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 5: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 5: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 5: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 6: Magic-Code per E-Mail senden (Spec 50%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (2)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
header_injectionmail.tostrip_crlfsrc/Auth/Infrastructure/MailSender.php400_bad_request
Opaker Token mit 128 Bit (random_bytes(16) base32), kein Email in URL, Header Cache-Control no-store
xssmail.bodyhtmlspecialcharssrc/Auth/Infrastructure/MailTemplate.phplog_only
Escape aller Variablen in Mail-Template

8. Protokollierung (2)

ZielLevelTriggerFelderPII-MaskierungRetention
app_loginfobei_erfolg["mensch_id","ts","mta_msgid"]{}30 Tage
Mail versandt
security_logerrorbei_fehler["mensch_id","mta_fehler","smtp_code"]{}365 Tage
MTA-Fehler

9. Entitaeten-Map (2)

TypZielRolleDatei
klasseMailSenderbenachrichtigt
datei/var/www/campus.karlkratz.com/src/Auth/Infrastructure/MailTemplate.phprendert/var/www/campus.karlkratz.com/src/Auth/Infrastructure/MailTemplate.php

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
premagic_code.persisted = trueCode muss zuerst persistiert sein
invariantkeine Email in URLMagic-Link enthaelt nur opaken Token
postmta.queued = true ODER fehler_code != nullMail in Queue oder definierter Fehler

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 6: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 6: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 6: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 6: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 6: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 7: Generische Erfolgsmeldung zuruecksenden (Spec 50%)

1. UI-Lokation

URL
GET /login
Controller
MagicCodeController::erfolgsMeldung
Template
src/Auth/Http/Views/login_sent.html.php
Zugriff
oeffentlich

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (0)

Keine definiert.

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
app_loginfobei_ende["ts","response_code"]{}30 Tage
Generische Antwort

9. Entitaeten-Map (1)

TypZielRolleDatei
datei/var/www/campus.karlkratz.com/src/Auth/Http/Views/login_sent.html.phprendert/var/www/campus.karlkratz.com/src/Auth/Http/Views/login_sent.html.php

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
preimmerGenerische Antwort unabhaengig vom Vorergebnis
invariantidentische Response fuer existierende und nicht-existierende EmailConstant-Response
postHTTP 200 mit statischem BodyKeine User-Enumeration

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 7: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 7: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 7: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 7: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 7: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 8: Code-Eingabe oder Link-Klick verarbeiten (Spec 67%)

1. UI-Lokation

URL
POST /login/verify
Controller
MagicCodeController::codeEinloesen
Template
src/Auth/Http/Views/login_verify.html.php
Zugriff
oeffentlich

2. Eingabe-Felder (2)

#LabelVariableTypPflichtValidierungMaxZiel
1Code aus LinkcodetokenjaAlphanum 6 bis 8 Zeichen Grossbuchstaben8magic_code_login.code
2E-Mail aus Linkemailemailjafilter_var FILTER_VALIDATE_EMAIL200magic_code_login.email

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (3)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
sql_injectionrequest.codeprepared_statementsrc/Auth/Infrastructure/PdoMagicCode.phplog_and_block
SELECT magic_code WHERE code=? AND expires_at>NOW()
csrfPOST /login/verifycsrf_tokensrc/Auth/Http/MagicCodeController.php403_forbidden
Session-CSRF-Token bei Code-Eingabe
brute_forcerequest.coderate_limitsrc/Auth/Application/RateLimiter.php429_too_many
Max 5 Code-Versuche pro Email-HMAC innerhalb 15 Min, einheitlich mit Schritt 2

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_start["code_hash","ip","ts"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}90 Tage
Code-Eingabe gestartet

9. Entitaeten-Map (1)

TypZielRolleDatei
klasseMagicCodeControllerimplementiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
prerequest.code != null UND CSRF-Token gueltigPOST mit CSRF
invariantPOST nur, kein GETZustandsaendernd
postcode_hash berechnetHash fuer atomic Lookup

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 8: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 8: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 8: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 8: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 8: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 9: Atomare Code-Einloesung: Pruefen UND Markieren in einer Transaktion (Spec 75%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (1)

  1. magic_code_login.code + email (exakt): Kombination Code und Mail, gültig_bis groesser NOW, eingelöst gleich false.

4. Gate-Aktionen (2)

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (2)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
timing_attackcompare.codehash_equalssrc/Auth/Application/MagicCodeService.php500_internal
hash_equals statt == für konstante Vergleichszeit
replaydb.magic_code.used_atprepared_statementsrc/Auth/Infrastructure/PdoMagicCode.phplog_and_block
UPDATE code SET used_at=NOW() WHERE used_at IS NULL (atomic)

8. Protokollierung (2)

ZielLevelTriggerFelderPII-MaskierungRetention
security_logwarnbei_fehler["code_hash","ip","status","versuche"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}365 Tage
Code-Verify fehlgeschlagen
security_logcriticalbei_ausnahme["code_hash","ip","versuche_gesamt"]{"email":"hmac_sha256_secret_pepper","ip":"ipv4_last_octet_or_ipv6_last_80bit"}2555 Tage
Brute-Force Alarm >5 Versuche

9. Entitaeten-Map (1)

TypZielRolleDatei
klasseMagicCodeServicevalidiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
precode_hash != nullHash vorhanden
invariantUPDATE WHERE used_at IS NULL muss in einer TransaktionRace-Condition-frei
postaffected_rows = 1 (eingeloest) ODER 0 (ungueltig)Atomare Aussage

11. Persistenz-Schema und Statemachine (1 Mutationen, 4 Zustandsuebergaenge)

TabelleMutationFelderConstraintsAtomar mit
magic_codeUPDATE["used_at"]SET used_at=NOW() WHERE id=? AND used_at IS NULL AND expires_at>NOW (atomic)
EntitaetVonNachAusloeserBedingung
magic_codesentverifiedcode_match_pre_checkCode stimmt, expires_at>NOW
magic_codeverifiedconsumedatomares_updateaffected_rows=1
magic_codesentexpiredexpires_at_erreichtexpires_at < NOW
magic_codeverifiedblockedconcurrent_attemptaffected_rows=0 trotz Vorpruefung OK

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 9: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 9: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 9: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 9: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 9: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 10: (Entfaellt: in Schritt 9 atomar enthalten) (Spec 42%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
sql_injectiondb.magic_code.used_atprepared_statementsrc/Auth/Infrastructure/PdoMagicCode.phplog_and_block
UPDATE mit WHERE id=? AND used_at IS NULL

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_erfolg["code_id","mensch_id","used_at"]{}2555 Tage
Code eingelöst

9. Entitaeten-Map (1)

TypZielRolleDatei
klassePdoMagicCodepersistiert

10. Vorbedingungen / Nachbedingungen / Invarianten (0)

Keine definiert.

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 10: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 10: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 10: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 10: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 10: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 11: Neue Session für Profil starten (Spec 67%)

1. UI-Lokation

Keine UI (System-intern).

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (2)

6. CRM-Kategorisierung

Kategorie
nutzer_aktiv
Lifecycle-Stage
retention
Tags
magic_code_login,returning_user

7. Security-Massnahmen (2)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
csrfsession.newsession_regeneratesrc/Auth/Application/SessionStarter.php500_internal
session_regenerate_id(true) beim Login-Erfolg
xsssession.user_datahtmlspecialcharssrc/Auth/Http/Views/profile.html.phplog_only
Alle User-Felder escaped beim Rendern

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
audit_loginfobei_erfolg["mensch_id","session_id_hmac","login_typ=magic_code","ts"]{"session_id":"hmac_sha256_secret_pepper"}90 Tage
Session-Start. session_id NUR als HMAC mit Server-Secret-Pepper, niemals roh. Retention: 90 Tage statt 7 Jahre (kein DSGVO-Pflicht).

9. Entitaeten-Map (1)

TypZielRolleDatei
klasseSessionStarterimplementiert

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
precode.eingeloest = trueCode muss eingeloest sein
invariantsession_regenerate_id PFLICHTSession-Fixation-Schutz
postsession.id_hmac != nullSession etabliert mit HMAC-Logging

11. Persistenz-Schema und Statemachine (2 Mutationen, 0 Zustandsuebergaenge)

TabelleMutationFelderConstraintsAtomar mit
sessionINSERT["mensch_id","session_id_hmac","login_typ","created_at"]session_regenerate_id zuvor
audit_logINSERT["mensch_id","session_id_hmac","event_type","outcome","request_id"]append-onlySchritt-ID 393

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 11: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 11: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 11: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 11: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 11: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 12: Fehlermeldung anzeigen (Spec 58%)

1. UI-Lokation

URL
GET /login/fehler
Controller
MagicCodeController::fehlerSeite
Template
src/Auth/Http/Views/error.html.php
Zugriff
oeffentlich

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
xssresponse.errorhtmlspecialcharssrc/Auth/Http/Views/error.html.phplog_only
Generische Fehlermeldung, keine User-Daten im Output

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
app_loginfobei_fehler["fehler_code","generisch"]{}30 Tage
Fehlermeldung angezeigt

9. Entitaeten-Map (1)

TypZielRolleDatei
datei/var/www/campus.karlkratz.com/src/Auth/Http/Views/error.html.phprendert/var/www/campus.karlkratz.com/src/Auth/Http/Views/error.html.php

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
prefehler_code != nullDefinierter Fehler-Code aus Fehlerkatalog
invariantkeine User-Daten im Fehler-BodyInformation-Disclosure-Schutz
postHTTP 4xx mit generischer MeldungKeine internen Details

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 12: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 12: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 12: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 12: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 12: transaktional_klar initial geprueft, nach Befund-Fixes 033

Schritt 13: Retry-Option anbieten (Spec 58%)

1. UI-Lokation

URL
GET /login
Controller
MagicCodeController::retryFormular
Template
src/Auth/Http/Views/login_form.html.php
Zugriff
oeffentlich

2. Eingabe-Felder (0)

Keine Felder.

3. Duplikat-Pruefung (0)

Keine.

4. Gate-Aktionen (0)

Keine.

5. Code-Verknuepfung (1)

6. CRM-Kategorisierung

Keine.

7. Security-Massnahmen (1)

AngriffEintrittspunktSchutzCode-ReferenzBei Verstoss
rate_limit_bypassretry.buttonrate_limitsrc/Auth/Http/MagicCodeController.php429_too_many
Retry-Button blockiert bei mehr als 5 Versuchen pro 15 Min, einheitlich mit Schritt 2 und 8

8. Protokollierung (1)

ZielLevelTriggerFelderPII-MaskierungRetention
app_loginfobei_ende["retry_angeboten","ts"]{}30 Tage
Retry-Option

9. Entitaeten-Map (1)

TypZielRolleDatei
klasseMagicCodeControllerrueckruft

10. Vorbedingungen / Nachbedingungen / Invarianten (3)

TypAusdruckBeschreibung
prerate_limit.remaining > 0Retry nur wenn Rate-Limit nicht erschoepft
invariantidentisches Rate-Limit wie Schritt 25/15min/IP+Email-HMAC
postredirect zu /login mit HinweisKlare UX

11. Persistenz-Schema und Statemachine (0 Mutationen, 0 Zustandsuebergaenge)

Keine definiert.

12. Quality-Gates (5) — Qualitaets-Score: 100%

Gate-TypErfuelltBefund
korrektJASchritt 13: korrekt initial geprueft, nach Befund-Fixes 033
widerspruchsfreiJASchritt 13: widerspruchsfrei initial geprueft, nach Befund-Fixes 033
testbarJASchritt 13: testbar initial geprueft, nach Befund-Fixes 033
sicherheits_vollstaendigJASchritt 13: sicherheits_vollstaendig initial geprueft, nach Befund-Fixes 033
transaktional_klarJASchritt 13: transaktional_klar initial geprueft, nach Befund-Fixes 033