Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8686af50d1 | |||
| 197f800c3a | |||
| 54d687c843 |
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "Simple Math CAPTCHA",
|
"name": "Simple Math CAPTCHA",
|
||||||
"slug": "simple-math-captcha",
|
"slug": "simple-math-captcha",
|
||||||
"version": "1.3.4",
|
"version": "1.5.0",
|
||||||
"author": "Ingo Höttges",
|
"author": "Ingo Höttges",
|
||||||
"author_homepage": "https://git.rosinenkot.de/ingo",
|
"author_homepage": "https://git.rosinenkot.de/ingo",
|
||||||
"homepage": "https://git.rosinenkot.de/ingo/simple-math-captcha",
|
"homepage": "https://git.rosinenkot.de/ingo/simple-math-captcha",
|
||||||
"requires": "5.8",
|
"requires": "5.8",
|
||||||
"tested": "6.9",
|
"tested": "6.9",
|
||||||
"requires_php": "8.0",
|
"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",
|
"last_updated": "2026-04-23 08:00:00",
|
||||||
"sections": {
|
"sections": {
|
||||||
"description": "Minimalistische Mathe-CAPTCHA auf WordPress-Login, Passwort-Reset und Registrierung. Keine externen Requests, kein JavaScript, kein Tracking. Einstellungen unter <em>Einstellungen → Math CAPTCHA</em>: Maximaler Wert an der Lücke, maximale Summe, Position der Lücke (erster/zweiter Summand, Summe, Zufall).",
|
"description": "Minimalistische Mathe-CAPTCHA auf WordPress-Login, Passwort-Reset und Registrierung. Keine externen Requests, kein JavaScript, kein Tracking. Einstellungen unter <em>Einstellungen → 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": {
|
"icons": {
|
||||||
"default": "https://git.rosinenkot.de/ingo/simple-math-captcha/raw/branch/main/icon-128.png"
|
"default": "https://git.rosinenkot.de/ingo/simple-math-captcha/raw/branch/main/icon-128.png"
|
||||||
|
|||||||
+83
-15
@@ -5,7 +5,7 @@
|
|||||||
* Keine externen Requests, kein JavaScript, kein Tracking, keine Tabellen.
|
* Keine externen Requests, kein JavaScript, kein Tracking, keine Tabellen.
|
||||||
* Loesung wird serverseitig als einmal-verwendbarer Transient gespeichert (10 min TTL).
|
* Loesung wird serverseitig als einmal-verwendbarer Transient gespeichert (10 min TTL).
|
||||||
* Einstellungen unter "Einstellungen > Math CAPTCHA".
|
* Einstellungen unter "Einstellungen > Math CAPTCHA".
|
||||||
* Version: 1.3.4
|
* Version: 1.5.0
|
||||||
* Author: Ingo Höttges
|
* Author: Ingo Höttges
|
||||||
* License: GPL-2.0-or-later
|
* License: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
@@ -17,29 +17,56 @@ class Simple_Math_Captcha {
|
|||||||
const PREFIX = 'smc_';
|
const PREFIX = 'smc_';
|
||||||
const TTL = 600; // 10 Minuten
|
const TTL = 600; // 10 Minuten
|
||||||
|
|
||||||
const OPT_MAX = 'smc_max';
|
const OPT_MAX = 'smc_max';
|
||||||
const OPT_MAX_SUM = 'smc_max_sum';
|
const OPT_MAX_SUM = 'smc_max_sum';
|
||||||
const OPT_POSITION = 'smc_position';
|
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 POSITIONS = ['first', 'second', 'sum', 'random'];
|
||||||
const DEFAULT_MAX = 10;
|
const DEFAULT_MAX = 10;
|
||||||
const DEFAULT_MAX_SUM = 100;
|
const DEFAULT_MAX_SUM = 100;
|
||||||
const DEFAULT_POSITION = 'random';
|
const DEFAULT_POSITION = 'random';
|
||||||
|
const DEFAULT_ENABLE = 1; // Defaults: alle drei Stellen aktiv
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
// Frontend-Hooks
|
// Frontend-Hooks — je nach Setting aktiv
|
||||||
add_action('login_form', [$this, 'render']);
|
if ($this->is_enabled(self::OPT_ENABLE_LOGIN)) {
|
||||||
add_action('lostpassword_form', [$this, 'render']);
|
add_action('login_form', [$this, 'render']);
|
||||||
if ((int) get_option('users_can_register', 0) === 1) {
|
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_action('register_form', [$this, 'render']);
|
||||||
add_filter('registration_errors', [$this, 'verify_register'], 10, 3);
|
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_init', [$this, 'register_settings']);
|
||||||
add_action('admin_menu', [$this, 'register_menu']);
|
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 ----------------------------------------------------------
|
// ---- Rendering ----------------------------------------------------------
|
||||||
@@ -149,6 +176,13 @@ class Simple_Math_Captcha {
|
|||||||
if (empty($_POST) || empty($_POST['log']) || empty($_POST['pwd'])) {
|
if (empty($_POST) || empty($_POST['log']) || empty($_POST['pwd'])) {
|
||||||
return $user;
|
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()) {
|
if (!$this->check()) {
|
||||||
return new WP_Error(
|
return new WP_Error(
|
||||||
'captcha_failed',
|
'captcha_failed',
|
||||||
@@ -221,6 +255,13 @@ class Simple_Math_Captcha {
|
|||||||
return in_array((string) $v, self::POSITIONS, true) ? (string) $v : self::DEFAULT_POSITION;
|
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(
|
add_settings_section(
|
||||||
'smc_main',
|
'smc_main',
|
||||||
@@ -285,6 +326,33 @@ class Simple_Math_Captcha {
|
|||||||
'smc_settings',
|
'smc_settings',
|
||||||
'smc_main'
|
'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 {
|
public function register_menu(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user