single( "SELECT id, attempts FROM admin_login_attempts WHERE ip_address = ?", "s", [$ip] ); if (!$entry) { // Erster Fehlversuch $sql->set( "INSERT INTO admin_login_attempts (ip_address, attempts, last_attempt) VALUES (?, 1, NOW())", "s", [$ip] ); return; } $attempts = (int)$entry['attempts'] + 1; if ($attempts >= 3) { $sql->set( "UPDATE admin_login_attempts SET attempts = ?, locked_until = DATE_ADD(NOW(), INTERVAL 1 HOUR), last_attempt = NOW() WHERE id = ?", "ii", [$attempts, $entry['id']] ); } else { $sql->set( "UPDATE admin_login_attempts SET attempts = ?, last_attempt = NOW() WHERE id = ?", "ii", [$attempts, $entry['id']] ); } } function isIpLocked(string $ip, $sql): bool { global $sql; $entry = $sql->single( "SELECT locked_until FROM admin_login_attempts WHERE ip_address = ? AND locked_until IS NOT NULL AND locked_until > NOW()", "s", [$ip] ); return (bool)$entry; } function clearLoginAttempts(string $ip, $sql): void { global $sql; $sql->set( "DELETE FROM admin_login_attempts WHERE ip_address = ?", "s", [$ip] ); } ?>