<?php

/*
ET-Chat Copyright by SEDesign | ET-Chat v3.x.x Lizenz: CCPL | Autor: Evgeni Tcherkasski (info@s-e-d.de)
ET-Chat_T-FISH-MOD Weiterentwicklungen, Optimierungen und Ergänzungen am Code sind das geistige Eigentum von Tommy (Thomas Kuhn) und Harlekin (Bernd Witte).

Die darauf folgende Optimierungen und Ergänzungen am Code sind das Geistige Eigentum von Powermen (Christian K.) 
PHP 8/9 Ready, XML Parser, PDO Prepared Statements Get Set sicherheit usw.
*/

if (session_status() === PHP_SESSION_NONE) session_start();

require __DIR__ . "/config.php";

// Domain automatisch berechnen
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$hosto = $_SERVER['SERVER_NAME'] ?? 'localhost';
$scriptDir = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
$domain = $protocol . "://" . $hosto . ($scriptDir !== '' && $scriptDir !== '/' ? $scriptDir : '') . "/";

// ========== NEU: Funktionen für verbotene Benutzernamen ==========
function loadBannedWordsFromJson() {
    $jsonFile = __DIR__ . '/cache/verbotene_user_namen.json';
    if (!file_exists($jsonFile)) {
        return []; // keine Verbote
    }
    
    $content = file_get_contents($jsonFile);
    $words = json_decode($content, true);
    
    if (json_last_error() !== JSON_ERROR_NONE || !is_array($words)) {
        return [];
    }
    
    return $words;
}

function isUsernameAllowed($username, $bannedWords) {
    foreach ($bannedWords as $banned) {
        // Case-insensitive Prüfung (Groß-/Kleinschreibung egal)
        if (stripos($username, $banned) !== false) {
            return false;
        }
        // Exakte Übereinstimmung (auch case-insensitive)
        if (strcasecmp($username, $banned) === 0) {
            return false;
        }
    }
    return true;
}

// NEU: Prüft auf erlaubte Zeichen im Benutzernamen mit Sonderzeichen-Limit
function validateUsernameFormat($username) {
    // Erlaubte Zeichen:
    // \p{L} - Alle Buchstaben (a-z, A-Z, äöüß, etc.)
    // \p{N} - Alle Zahlen (0-9)
    // \s    - Leerzeichen (nur innerhalb)
    // Erlaubte Sonderzeichen: & @ . _ - + = # ~ € $ % §
    // 
    // Verboten bleiben: / \ ? < > : * | " ' ` ; , [ ] { } ( ) ^ ! 
    // und Steuerzeichen wie \t \n \r \f \v
    
    // Zuerst prüfen ob NUR erlaubte Zeichen verwendet werden
    if (!preg_match('/^[\p{L}\p{N}\s&@\._\-+=#~€$%§]+$/u', $username)) {
        return false;
    }
    
    // Prüfen auf maximal 3 Sonderzeichen aus der erlaubten Gruppe
    // ACHTUNG: Der Punkt . muss escaped werden \.
    // Die anderen Sonderzeichen sind in der Regex-Gruppe 
    if (preg_match_all('/[&@\._\-+=#~€$%§]/u', $username, $matches) > 3) {
        return false;  // Zu viele Sonderzeichen
    }
    
    return true;
}

// NEU: Zusätzliche Prüfung auf problematische Zeichenkombinationen
function hasDangerousPatterns($username) {
    $dangerous = [
        '../', '..\\', './', '.\\',
        '<!--', '-->', '<script', '</script',
        '<?php', '?>', '<%', '%>',
        'javascript:', 'vbscript:', 'onclick=', 'onload=',
        'union select', 'or 1=1', 'drop table', 'delete from',
        '--', '/*', '*/', ';--', "' or '", '" or "'
    ];
    
    $lowerUser = strtolower($username);
    foreach ($dangerous as $pattern) {
        if (strpos($lowerUser, strtolower($pattern)) !== false) {
            return true;
        }
    }
    return false;
}

// ========== ENDE NEU ==========

// ==================== Funktion: Passwortstärke prüfen ====================
function isPasswordStrongEnough($password): bool {
    $criteriaMet = 0;
    $criteriaMet += (int) preg_match("/[A-Z]/", $password);
    $criteriaMet += (int) preg_match("/[a-z]/", $password);
    $criteriaMet += (int) preg_match("/[0-9]/", $password);
    $criteriaMet += (int) preg_match("/[\W_]/", $password);
    return strlen($password) >= 8 && $criteriaMet >= 3;
}

// PHPMailer prüfen
if (!file_exists("PHPMailer/src/PHPMailer.php") ||
    !file_exists("PHPMailer/src/SMTP.php") ||
    !file_exists("PHPMailer/src/Exception.php")) {
    echo "<script>alert('Die PHPMailer-Bibliothek fehlt.');</script>";
    die("PHPMailer konnte nicht gefunden werden.");
}

require "PHPMailer/src/PHPMailer.php";
require "PHPMailer/src/SMTP.php";
require "PHPMailer/src/Exception.php";

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

// DB Verbindung
$conn = new mysqli($sqlhost, $sqluser, $sqlpass, $database);
if ($conn->connect_error) die("Verbindung zur Datenbank fehlgeschlagen: " . $conn->connect_error);
$conn->set_charset("utf8mb4");
//$conn->query("SET time_zone = '+00:00'");

// ==================== Allgemeine Styles ====================
$style = '
<style>
input, label, button, small { margin-bottom: 15px; }
small { font-size: 11px; color: red; }
</style>';

$content = "";
$mode = $_GET["passwort"] ?? "registrieren";
ob_start();

switch ($mode) {

    // =================== Passwort vergessen ===================
    case "vergessen":
        if ($_SERVER["REQUEST_METHOD"] === "POST") {
            $username = trim($_POST["username"]);

            $stmt = $conn->prepare("SELECT etchat_user_id, etchat_email FROM {$prefix}etchat_user WHERE etchat_username = ? AND etchat_userprivilegien != 'gast'");
            $stmt->bind_param("s", $username);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($result->num_rows === 0) {
                echo "<h2><font color='#FF0000'><b>Benutzer nicht gefunden.</b></font></h2><br>";
                echo "<button type='button' onclick=\"window.location.href='$domain'\">Zurück zum Login</button><br><br>";
                break;
            }

            $user = $result->fetch_assoc();
            $email = $user["etchat_email"];
            $userId = $user["etchat_user_id"];
            $token = bin2hex(random_bytes(32));
            $expiry = date("Y-m-d H:i:s", strtotime("+15 minutes"));

            $stmt = $conn->prepare("UPDATE {$prefix}etchat_user SET etchat_reset_token = ?, etchat_reset_token_expiry = ? WHERE etchat_user_id = ?");
            $stmt->bind_param("ssi", $token, $expiry, $userId);
            $stmt->execute();

            $mail = new PHPMailer(true);
            try {
                $mail->isSMTP();
                $mail->Host = $host;
                $mail->SMTPAuth = true;
                $mail->Username = $sendemail;
                $mail->Password = $mailpass;
                $mail->SMTPSecure = $smtpsecure;
                $mail->Port = $port;
                $mail->CharSet = "UTF-8";
                $mail->Encoding = "base64";
                $mail->setFrom($sendemail, "Passwort vergessen");
                $mail->addAddress($email, $username);
                $mail->isHTML(true);
                $mail->Subject = "Passwort zurücksetzen";
                $resetLink = "{$domain}/?passwort=zuruecksetzen&token={$token}&user={$username}";
                $mail->Body = "<p>Hallo {$username},</p><p>Hier ist dein Link zum Ändern deines Passworts:</p><a href='{$resetLink}'>{$resetLink}</a><br>Dieser Link ist 15 Minuten gültig.";
                $mail->send();

                echo "<script>alert('E-Mail wurde versendet. Bitte überprüfe dein Postfach.'); window.location.href='{$domain}';</script>";
            } catch (Exception $e) {
                echo "E-Mail konnte nicht gesendet werden: {$mail->ErrorInfo}";
            }
        }

        echo $style;
        ?>
        <h2>Passwort vergessen</h2>
        <form id="reg" method="POST">
            <input name="username" id="username" placeholder="Dein Chatname" required /><br>
            <button type="submit" id="submit_button">Passwort Ändern</button>
			<button id="submit_button" type="button" onclick="window.location.href='<?php echo $domain; ?>'">Zurück zum Login</button>
        </form>
        <?php
        break;

    // =================== Passwort zurücksetzen ===================
    case "zuruecksetzen":
        if ($_SERVER["REQUEST_METHOD"] === "POST") {
            $token = $_POST["token"];
            $newPassword = $_POST["password"];

            if (!isPasswordStrongEnough($newPassword)) {
                echo "<script>alert('Fehler: Passwort muss mind. 8 Zeichen lang sein und 3 der Kriterien enthalten.'); window.history.back();</script>";
                exit();
            }

            $stmt = $conn->prepare("SELECT etchat_user_id, etchat_reset_token_expiry FROM {$prefix}etchat_user WHERE etchat_reset_token = ? AND etchat_reset_token_expiry > NOW()");
            $stmt->bind_param("s", $token);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($result->num_rows > 0) {
                $user = $result->fetch_assoc();
                $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
                $stmt = $conn->prepare("UPDATE {$prefix}etchat_user SET etchat_userpw = ?, etchat_reset_token = NULL, etchat_reset_token_expiry = NULL WHERE etchat_user_id = ?");
                $stmt->bind_param("si", $hashedPassword, $user["etchat_user_id"]);
                $stmt->execute();

                echo "<script>alert('Passwort zurückgesetzt.'); window.location.href='{$domain}';</script>";
            } else {
                echo "<script>alert('Ungültiger Token oder Token abgelaufen.'); window.location.href='{$domain}';</script>";
            }
        }

        echo $style;
        ?>
			<h2>Passwort zurücksetzen</h2>
			<?php if (isset($_GET['user'])): ?>
			    <p style="text-align: center; color: red; font-weight: bold;">Benutzer: <?php echo htmlspecialchars($_GET['user']); ?></p>
			<?php endif; ?>
		<form id="reg" method="POST">
			<input type="hidden" name="token" value="<?php echo htmlspecialchars(
       $_GET["token"]
   ); ?>" />

		   	<p style="text-align: center;margin-top: 0px;">Das Passwort muss mindestens 8 Zeichen lang sein und 3 der folgenden Kriterien enthalten: Großbuchstaben, Kleinbuchstaben, Zahlen, Sonderzeichen.</p>
			<input name="password" id="password" placeholder="Neues Passwort" required type="password" />
			<small id="pw_strength" style="color: red;"></small><br>
			<input id="confirm_password" name="confirm_password" placeholder="Passwort wiederholen" type="password" required />
			<small id="pwcheck" style="display:none;">Die Passwörter stimmen nicht überein.</small>
			<p style="text-align: center;margin-top: 0px;margin-bottom: 0px;"><input type="checkbox" onclick="machText(this.checked,this.form)">Passwort anzeigen</p>
			<button type="submit" id="submit_button">Neues Passwort speichern</button>
			<button id="submit_button" type="button" onclick="window.location.href='<?php echo $domain; ?>'">Zurück zum Login</button>
		</form>
        <?php
        break;

// =================== Registrierung ===================
default:
// Aktivierung via Token mit Zeitprüfung
if (isset($_GET["token"])) {
    $token = $_GET["token"];
    $stmt = $conn->prepare("SELECT etchat_user_id, etchat_reset_token_expiry FROM {$prefix}etchat_user WHERE etchat_reset_token = ? AND etchat_userprivilegien = 'gast' AND etchat_reset_token_expiry > NOW()");
    $stmt->bind_param("s", $token);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows === 0) {
        $checkStmt = $conn->prepare("SELECT etchat_user_id FROM {$prefix}etchat_user WHERE etchat_reset_token = ? AND etchat_userprivilegien = 'gast' AND etchat_reset_token_expiry <= NOW()");
        $checkStmt->bind_param("s", $token);
        $checkStmt->execute();
        $expiredResult = $checkStmt->get_result();

        if ($expiredResult->num_rows > 0) {
            $deleteStmt = $conn->prepare("DELETE FROM {$prefix}etchat_user WHERE etchat_reset_token = ? AND etchat_userprivilegien = 'gast'");
            $deleteStmt->bind_param("s", $token);
            $deleteStmt->execute();
            echo "<script>alert('Ihr Aktivierungs-Link ist abgelaufen (gültig für 30 Minuten). Bitte registrieren Sie sich erneut.'); window.location.href='{$domain}?register';</script>";
        } else {
            echo "<script>alert('Aktivierungs-Token ungültig.'); window.location.href='{$domain}';</script>";
        }
        exit();
    }

    $user = $result->fetch_assoc();
    $stmt = $conn->prepare("UPDATE {$prefix}etchat_user SET etchat_userprivilegien = 'user', etchat_reset_token = NULL, etchat_reset_token_expiry = NULL WHERE etchat_user_id = ?");
    $stmt->bind_param("i", $user["etchat_user_id"]);
    $stmt->execute();
    
    // ========== COOKIE MIT JAVASCRIPT SETZEN ==========
    // Das funktioniert immer, weil es client-seitig passiert
    echo "<script>
        // Cookie mit JavaScript setzen (12 Stunden Gültigkeit)
        var expires = new Date();
        expires.setTime(expires.getTime() + (12 * 60 * 60 * 1000));
        document.cookie = 'cookie_etchat_nik_registered=1; expires=' + expires.toUTCString() + '; path=/; samesite=Lax';
        
        // Kurze Verzögerung damit der Cookie sicher gesetzt wird
        setTimeout(function() {
            alert('Account aktiviert!');
            window.location.href = '{$domain}';
        }, 100);
    </script>";
    exit();
}

	// Formular-Verarbeitung
	if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["username"])) {
		
		    // ========== NEU: Cookie-Sperre prüfen ==========
			if (isset($_COOKIE['cookie_etchat_nik_registered'])) {
				echo "<script>alert('Sie haben sich bereits in den letzten 12 Stunden registriert. Bitte versuchen Sie es morgen wieder.'); window.location.href='{$domain}';</script>";
				exit();
			}
			// ============================================
		
		$username = trim($_POST["username"]);
    
		// Zusätzliche Prüfung auf leeren Benutzernamen nach trim
		if (empty($username)) {
			echo "<script>alert('Der Benutzername darf nicht leer sein.'); window.history.back();</script>";
			exit();
		}
    
		// Längenprüfung (4-25 Zeichen)
		if (strlen($username) < 4 || strlen($username) > 25) {
			echo "<script>alert('Der Benutzername muss zwischen 4 und 25 Zeichen lang sein.'); window.history.back();</script>";
			exit();
		}
    
		// NEU: Prüfung auf erlaubte Zeichen
		if (!validateUsernameFormat($username)) {
			echo "<script>alert('!!! Der Benutzername enthält nicht erlaubte Zeichen oder zu viele Sonderzeichen (max. 3) !!!\\n\\nErlaubt sind:\\n- Buchstaben (A-Z, a-z, ÄÖÜäöüß)\\n- Zahlen (0-9)\\n- Leerzeichen (nur innerhalb)\\n- Sonderzeichen: & @ . _ - + = # ~ € $ % § (maximal 3 davon)\\n\\nNicht erlaubt sind z.B.: / \\ ? < > : * | \" \\' ` ; , [ ] { } ( ) ^ !'); window.history.back();</script>";
			exit();
		}
    
		// NEU: Prüfung auf gefährliche Muster
		if (hasDangerousPatterns($username)) {
			echo "<script>alert('!!! Der Benutzername enthält ungültige Zeichenkombinationen !!!'); window.history.back();</script>";
			exit();
		}
    
		// Prüfung auf verbotene Wörter aus JSON
		$bannedWords = loadBannedWordsFromJson();
		if (!isUsernameAllowed($username, $bannedWords)) {
			echo "<script>alert('!!! Dieser Benutzername ist nicht erlaubt !!! Bitte wähle einen anderen Namen.'); window.history.back();</script>";
			exit();
		}
		
		if (preg_match('/^[\s&@\._\-+=#~€$%§]+$/u', $username)) {
			echo "<script>alert('Der Benutzername muss mindestens einen Buchstaben oder eine Zahl enthalten.'); window.history.back();</script>";
			exit();
		}
		
		$username_safe = $username;
        $password = trim($_POST["password"]);
        $confirm_password = trim($_POST["confirm_password"]);
        $email = trim($_POST["email"]);
        $reg_ip = $_SERVER["REMOTE_ADDR"];

        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            echo "<script>alert('Ungültige E-Mail-Adresse.'); window.history.back();</script>";
            exit();
        }
        if ($password !== $confirm_password) {
            echo "<script>alert('Die Passwörter stimmen nicht überein.'); window.history.back();</script>";
            exit();
        }
        if (!isPasswordStrongEnough($password)) {
            echo "<script>alert('Passwort zu schwach. Mindestens 8 Zeichen, 3 von: Groß, Klein, Zahl, Sonderzeichen.'); window.history.back();</script>";
            exit();
        }

        // Prüfen ob Benutzername oder E-Mail bereits existiert
        $stmt = $conn->prepare("SELECT etchat_user_id, etchat_userprivilegien, etchat_reset_token_expiry FROM {$prefix}etchat_user WHERE etchat_username = ? OR etchat_email = ?");
        $stmt->bind_param("ss", $username, $email);
        $stmt->execute();
        $result = $stmt->get_result();

        $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
        $userprivilegien = "gast";
        $reg_timestamp = date("Y-m-d H:i:s");
        $token = bin2hex(random_bytes(16));
        $token_expiry = date("Y-m-d H:i:s", strtotime("+30 minutes"));

        if ($result->num_rows > 0) {
            $user = $result->fetch_assoc();
            if ($user["etchat_userprivilegien"] !== "gast") {
                echo "<script>alert('Benutzername oder E-Mail bereits vergeben.'); window.history.back();</script>";
                exit();
            }
            if (strtotime($user["etchat_reset_token_expiry"]) > time()) {
                echo "<script>alert('Registrierung bereits gestartet mit der E-Mailadresse. Bitte E-Mail bestätigen.'); window.history.back();</script>";
                exit();
            }

            // KORRIGIERT: Hier fehlte die user_id als letzter Parameter (i)
            $stmt = $conn->prepare("UPDATE {$prefix}etchat_user SET etchat_userpw=?, etchat_userprivilegien=?, etchat_email=?, etchat_reg_timestamp=?, etchat_reg_ip=?, etchat_reset_token=?, etchat_reset_token_expiry=? WHERE etchat_user_id=?");
            // 8 Platzhalter (7x ? für SET + 1x ? für WHERE)
            $stmt->bind_param("sssssssi", $hashedPassword, $userprivilegien, $email, $reg_timestamp, $reg_ip, $token, $token_expiry, $user["etchat_user_id"]);
            $stmt->execute();
        } else {
            $stmt = $conn->prepare("INSERT INTO {$prefix}etchat_user (etchat_username, etchat_userpw, etchat_userprivilegien, etchat_email, etchat_reg_timestamp, etchat_reg_ip, etchat_reset_token, etchat_reset_token_expiry) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
            $stmt->bind_param("ssssssss", $username_safe, $hashedPassword, $userprivilegien, $email, $reg_timestamp, $reg_ip, $token, $token_expiry);
            $stmt->execute();
        }

        // Mail mit Aktivierungslink
        $mail = new PHPMailer(true);
        try {
            $mail->isSMTP();
            $mail->Host = $host;
            $mail->SMTPAuth = true;
            $mail->Username = $sendemail;
            $mail->Password = $mailpass;
            $mail->SMTPSecure = $smtpsecure;
            $mail->Port = $port;
            $mail->CharSet = "UTF-8";
            $mail->Encoding = "base64";
            $mail->setFrom($sendemail, "Registrierung bestätigen");
            $mail->addAddress($email, $username);
            $mail->isHTML(true);
            $mail->Subject = "Registrierung bestätigen";
            $confirmLink = "{$domain}/?token={$token}";
            $mail->Body = "<p>Hallo {$username},</p><p>Bitte bestätige deine Registrierung:</p><a href='{$confirmLink}'>{$confirmLink}</a><br>Link 30 Minuten gültig.<br><br>Viel Spaß!<br><br>

								Sollten sie sich nicht bei uns Registriert haben, können sie diese E-Mail ignorieren.<br><br>

								Nach der Aktivierung sind sie kein Gast mehr und können sich mit Ihren<br>
								Benutzernname :<b> {$username}</b><br>
								und Ihren<br>
								Passwort:<b> {$password}</b><br>
								Ein Locken auf<br>
								{$domain}<br><br>

								Viel Spaß";
            $mail->send();

            echo "<script>alert('Registrierung erfolgreich. Bitte bestätige deine E-Mail.'); window.location.href='{$domain}';</script>";
        } catch (Exception $e) {
            echo "E-Mail konnte nicht gesendet werden: {$mail->ErrorInfo}";
        }
    }

    // =================== Registrierungsformular ===================
    echo $style;
    ?>
    <h2>Benutzer registrieren</h2>
    <form id="reg" method="POST" onsubmit="return checkPasswords();">
        <input name="username" id="username" placeholder="Dein Chatname min.4 Zeichen max.25" required minlength="4"/>
        <p style="text-align: center;margin-top: 0px;">Das Passwort muss mindestens 8 Zeichen lang sein und 3 der folgenden Kriterien enthalten: Großbuchstaben, Kleinbuchstaben, Zahlen, Sonderzeichen.</p>
        <input id="password" name="password" placeholder="Dein Passwort" type="password" required />
        <small id="pw_strength" style="color: red;"></small>
        <br>
        <input id="confirm_password" name="confirm_password" placeholder="Passwort wiederholen" type="password" required />
        <small id="pwcheck" style="display:none;">Die Passwörter stimmen nicht überein.</small>
        <p style="text-align: center;margin-top: 0px;margin-bottom: 0px;"><input type="checkbox" onclick="machText(this.checked,this.form)">Passwort anzeigen</p>
        <input name="email" id="email" placeholder="E-Mail-Adresse" type="email" required /><br>
        <small id="emailcheck" style="display:none; color:red; text-align:center;">Bitte gib eine gültige E-Mail-Adresse ein.</small><br>
        <button id="submit_button" type="submit">Registrieren</button>
        <button id="submit_button" type="button" onclick="window.location.href='?passwort=vergessen'">Passwort vergessen?</button>
        <button id="submit_button" type="button" onclick="window.location.href='<?php echo $domain; ?>'">Zurück zum Login</button>
    </form>
    <?php
    break;
}

$content = ob_get_clean();
echo $content;

// ==================== Einheitliches JS ====================
?>
<script>
function checkPasswordStrength(pw){ const c=[/[A-Z]/.test(pw),/[a-z]/.test(pw),/[0-9]/.test(pw),/[\W_]/.test(pw)]; const met=c.filter(Boolean).length; return pw.length<8||met<3?{ok:false,msg:"Passwort ist zu schwach"}:{ok:true,msg:"Passwort stark"};}
function updatePasswordUI(pwField,strengthField){ if(!pwField||!strengthField)return; const res=checkPasswordStrength(pwField.value); strengthField.textContent=res.msg; strengthField.style.color=res.ok?"green":"red";}
function checkPasswordsMatch(pwField,confirmField,msgField){ if(!pwField||!confirmField||!msgField)return true; if(pwField.value!==confirmField.value){msgField.style.display="inline"; return false;} msgField.style.display="none"; return true;}
function machText(chk,form){["password","confirm_password"].forEach(id=>{let f=form.querySelector("#"+id); if(f) f.type=chk?"text":"password";});}

document.querySelectorAll("form#reg").forEach(f=>{
    const pw=f.querySelector("#password");
    const pw2=f.querySelector("#confirm_password");
    const pwStrength=f.querySelector("#pw_strength");
    const pwCheck=f.querySelector("#pwcheck");
    const email=f.querySelector("#email");
    const emailCheck=f.querySelector("#emailcheck");

    if(pw) pw.addEventListener("input",()=>{updatePasswordUI(pw,pwStrength); checkPasswordsMatch(pw,pw2,pwCheck);});
    if(pw2) pw2.addEventListener("input",()=>checkPasswordsMatch(pw,pw2,pwCheck));
    if(email&&emailCheck) email.addEventListener("input",()=>{const p=/^[^\s@]+@[^\s@]+\.[^\s@]+$/; emailCheck.style.display=p.test(email.value)?"none":"block";});

    f.addEventListener("submit",e=>{if(!checkPasswordsMatch(pw,pw2,pwCheck)||!checkPasswordStrength(pw).ok){alert("Passwort zu schwach!"); e.preventDefault();}});
});
</script>