3 Commits

2 changed files with 86 additions and 18 deletions
+3 -3
View File
@@ -1,18 +1,18 @@
{
"name": "Simple Math CAPTCHA",
"slug": "simple-math-captcha",
"version": "1.3.4",
"version": "1.5.0",
"author": "Ingo Höttges",
"author_homepage": "https://git.rosinenkot.de/ingo",
"homepage": "https://git.rosinenkot.de/ingo/simple-math-captcha",
"requires": "5.8",
"tested": "6.9",
"requires_php": "8.0",
"download_url": "https://git.rosinenkot.de/ingo/simple-math-captcha/archive/v1.3.4.zip",
"download_url": "https://git.rosinenkot.de/ingo/simple-math-captcha/archive/v1.5.0.zip",
"last_updated": "2026-04-23 08:00:00",
"sections": {
"description": "Minimalistische Mathe-CAPTCHA auf WordPress-Login, Passwort-Reset und Registrierung. Keine externen Requests, kein JavaScript, kein Tracking. Einstellungen unter <em>Einstellungen &rarr; Math CAPTCHA</em>: Maximaler Wert an der Lücke, maximale Summe, Position der Lücke (erster/zweiter Summand, Summe, Zufall).",
"changelog": "<h4>1.3.4</h4><ul><li>Eingabefeld inline in der Gleichung, schmal und rechteckig</li></ul><h4>1.2.0</h4><ul><li>Neue Option: maximale Summe; Default der Lücken-Position auf Zufall</li></ul><h4>1.1.0</h4><ul><li>Admin-Einstellungen: Maximaler Wert, Position der Lücke</li></ul>"
"changelog": "<h4>1.5.0</h4><ul><li>Settings-Checkboxen: CAPTCHA kann pro Formular (Login, Passwort-Reset, Registrierung) ein-/ausgeschaltet werden</li></ul><h4>1.4.0</h4><ul><li>Plugin ist in der Plugins-Liste nur noch für Administratoren (`manage_options`) sichtbar — Moderatoren/Autoren mit `activate_plugins` sehen den Eintrag nicht mehr</li></ul><h4>1.3.5</h4><ul><li>Bugfix: native WP-Fehlermeldung für falsche Anmeldedaten wird nicht mehr von Captcha-Fehler überdeckt</li></ul><h4>1.3.4</h4><ul><li>Eingabefeld inline in der Gleichung, schmal und rechteckig</li></ul><h4>1.2.0</h4><ul><li>Neue Option: maximale Summe; Default der Lücken-Position auf Zufall</li></ul><h4>1.1.0</h4><ul><li>Admin-Einstellungen: Maximaler Wert, Position der Lücke</li></ul>"
},
"icons": {
"default": "https://git.rosinenkot.de/ingo/simple-math-captcha/raw/branch/main/icon-128.png"
+83 -15
View File
@@ -5,7 +5,7 @@
* Keine externen Requests, kein JavaScript, kein Tracking, keine Tabellen.
* Loesung wird serverseitig als einmal-verwendbarer Transient gespeichert (10 min TTL).
* Einstellungen unter "Einstellungen > Math CAPTCHA".
* Version: 1.3.4
* Version: 1.5.0
* Author: Ingo Höttges
* License: GPL-2.0-or-later
*/
@@ -17,29 +17,56 @@ class Simple_Math_Captcha {
const PREFIX = 'smc_';
const TTL = 600; // 10 Minuten
const OPT_MAX = 'smc_max';
const OPT_MAX_SUM = 'smc_max_sum';
const OPT_POSITION = 'smc_position';
const OPT_MAX = 'smc_max';
const OPT_MAX_SUM = 'smc_max_sum';
const OPT_POSITION = 'smc_position';
const OPT_ENABLE_LOGIN = 'smc_enable_login';
const OPT_ENABLE_RESET = 'smc_enable_reset';
const OPT_ENABLE_REGISTER = 'smc_enable_register';
const POSITIONS = ['first', 'second', 'sum', 'random'];
const DEFAULT_MAX = 10;
const DEFAULT_MAX_SUM = 100;
const DEFAULT_POSITION = 'random';
const POSITIONS = ['first', 'second', 'sum', 'random'];
const DEFAULT_MAX = 10;
const DEFAULT_MAX_SUM = 100;
const DEFAULT_POSITION = 'random';
const DEFAULT_ENABLE = 1; // Defaults: alle drei Stellen aktiv
public function __construct() {
// Frontend-Hooks
add_action('login_form', [$this, 'render']);
add_action('lostpassword_form', [$this, 'render']);
if ((int) get_option('users_can_register', 0) === 1) {
// Frontend-Hooks — je nach Setting aktiv
if ($this->is_enabled(self::OPT_ENABLE_LOGIN)) {
add_action('login_form', [$this, 'render']);
add_filter('authenticate', [$this, 'verify_login'], 30, 3);
}
if ($this->is_enabled(self::OPT_ENABLE_RESET)) {
add_action('lostpassword_form', [$this, 'render']);
add_action('lostpassword_post', [$this, 'verify_lostpassword']);
}
if ($this->is_enabled(self::OPT_ENABLE_REGISTER) && (int) get_option('users_can_register', 0) === 1) {
add_action('register_form', [$this, 'render']);
add_filter('registration_errors', [$this, 'verify_register'], 10, 3);
}
add_filter('authenticate', [$this, 'verify_login'], 30, 3);
add_action('lostpassword_post', [$this, 'verify_lostpassword']);
// Admin-Einstellungen
// Admin-Einstellungen (nur fuer Admins sichtbar)
add_action('admin_init', [$this, 'register_settings']);
add_action('admin_menu', [$this, 'register_menu']);
// Plugin-Eintrag in der Plugins-Liste fuer Nicht-Admins ausblenden.
add_filter('all_plugins', [$this, 'hide_plugin_from_list']);
}
private function is_enabled(string $option): bool {
return (int) get_option($option, self::DEFAULT_ENABLE) === 1;
}
/**
* Entfernt das Plugin aus der "Plugins → Installierte Plugins"-Liste,
* falls der aktuelle Nutzer nicht manage_options hat. Dadurch sehen
* Moderatoren/Autoren den Eintrag nicht, selbst wenn ihre Custom-Rolle
* activate_plugins hat.
*/
public function hide_plugin_from_list(array $plugins): array {
if (current_user_can('manage_options')) { return $plugins; }
unset($plugins[plugin_basename(__FILE__)]);
return $plugins;
}
// ---- Rendering ----------------------------------------------------------
@@ -149,6 +176,13 @@ class Simple_Math_Captcha {
if (empty($_POST) || empty($_POST['log']) || empty($_POST['pwd'])) {
return $user;
}
// Wenn WordPress bereits einen Fehler hat (z. B. falsches Passwort),
// durchreichen — sonst wuerde unsere Captcha-Fehlermeldung den
// originalen Fehler ueberdecken und die native rote WP-Meldung
// fuer falsche Anmeldedaten ginge verloren.
if (is_wp_error($user)) {
return $user;
}
if (!$this->check()) {
return new WP_Error(
'captcha_failed',
@@ -221,6 +255,13 @@ class Simple_Math_Captcha {
return in_array((string) $v, self::POSITIONS, true) ? (string) $v : self::DEFAULT_POSITION;
},
]);
foreach ([self::OPT_ENABLE_LOGIN, self::OPT_ENABLE_RESET, self::OPT_ENABLE_REGISTER] as $opt) {
register_setting('smc_settings', $opt, [
'type' => 'boolean',
'default' => self::DEFAULT_ENABLE,
'sanitize_callback' => function ($v) { return empty($v) ? 0 : 1; },
]);
}
add_settings_section(
'smc_main',
@@ -285,6 +326,33 @@ class Simple_Math_Captcha {
'smc_settings',
'smc_main'
);
add_settings_field(
'smc_places',
__('CAPTCHA einsetzen bei', 'simple-math-captcha'),
function () {
$boxes = [
self::OPT_ENABLE_LOGIN => __('Login', 'simple-math-captcha'),
self::OPT_ENABLE_RESET => __('Passwort-Reset', 'simple-math-captcha'),
self::OPT_ENABLE_REGISTER => __('Registrierung', 'simple-math-captcha'),
];
echo '<fieldset>';
foreach ($boxes as $opt => $label) {
$v = $this->is_enabled($opt);
// Hidden-0 davor, damit "ausgeschaltet" auch gepostet wird.
echo '<label style="display:block; margin-bottom:4px;">'
. '<input type="hidden" name="' . esc_attr($opt) . '" value="0">'
. '<input type="checkbox" name="' . esc_attr($opt) . '" value="1"' . checked($v, true, false) . '> '
. esc_html($label) . '</label>';
}
echo '</fieldset>';
echo '<p class="description">'
. esc_html__('Auf welchen Formularen die Mathe-Frage angezeigt werden soll. Registrierung greift nur, wenn WordPress Selbst-Registrierung erlaubt.', 'simple-math-captcha')
. '</p>';
},
'smc_settings',
'smc_main'
);
}
public function register_menu(): void {