101 lines
4.7 KiB
PHP
101 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Plugin\fp_altcha_spamschutz;
|
|
|
|
use JTL\Events\Dispatcher;
|
|
use JTL\Plugin\Bootstrapper;
|
|
use JTL\Plugin\PluginInterface;
|
|
use JTL\Shop;
|
|
use Plugin\fp_altcha_spamschutz\src\Handler\TemplateHandler;
|
|
use Plugin\fp_altcha_spamschutz\src\Handler\ValidationHandler;
|
|
use Plugin\fp_altcha_spamschutz\src\Service\AltchaService;
|
|
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Hasher/HasherInterface.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Hasher/Algorithm.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Hasher/Hasher.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/BaseChallengeOptions.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/ChallengeOptions.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/CheckChallengeOptions.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Challenge.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Payload.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Solution.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Obfuscator.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/ServerSignaturePayload.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/ServerSignatureVerificationData.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/ServerSignatureVerification.php';
|
|
require_once __DIR__ . '/src/Vendor/AltchaOrg/Altcha/V1/Altcha.php';
|
|
require_once __DIR__ . '/src/Service/AltchaService.php';
|
|
require_once __DIR__ . '/src/Handler/TemplateHandler.php';
|
|
require_once __DIR__ . '/src/Handler/ValidationHandler.php';
|
|
|
|
/**
|
|
* Bootstrap-Klasse für das Plugin fp_altcha_spamschutz.
|
|
*
|
|
* Setzt einen selbst gehosteten, quelloffenen Proof-of-Work-Spamschutz (ALTCHA, MIT-Lizenz) für
|
|
* die Kundenregistrierung, die Newsletter-Anmeldung und das Kontaktformular ein. Keine Daten
|
|
* verlassen den eigenen Server. Bewusst ohne Google reCAPTCHA und ohne Umleitung über Cloudflare
|
|
* oder ähnliche Dienste.
|
|
*
|
|
* Hintergrund/Anlass: ein Bot-Problem bei einem Kunden (Fake-Anmeldungen im Shop). Andere
|
|
* getestete Ansätze konnten das dort verwendete Muster
|
|
* ("Test"/"Test User" in Vorname/Nachname/Ort/Straße, aber echte Drittanbieter-E-Mail-Adressen)
|
|
* strukturell nicht erkennen, weil deren Wortlisten-Prüfung nur auf Kommentar-/
|
|
* Nachrichtenfelder wirkt, die das Registrierungsformular gar nicht besitzt.
|
|
*/
|
|
class Bootstrap extends Bootstrapper
|
|
{
|
|
public function boot(Dispatcher $dispatcher): void
|
|
{
|
|
parent::boot($dispatcher);
|
|
|
|
if (!Shop::isFrontend()) {
|
|
return;
|
|
}
|
|
|
|
// Die komplette Einrichtung ist defensiv umschlossen: boot() läuft bei JEDEM
|
|
// Frontend-Aufruf, noch bevor irgendeine Seite gerendert wird. Ein Fehler hier (z. B.
|
|
// weil das Plugin gerade erst installiert und noch nicht konfiguriert wurde) darf
|
|
// niemals den gesamten Shop lahmlegen.
|
|
try {
|
|
/** @var PluginInterface $plugin */
|
|
$plugin = $this->getPlugin();
|
|
|
|
$altchaService = new AltchaService($plugin, __DIR__);
|
|
$templateHandler = new TemplateHandler($plugin, $altchaService);
|
|
$validationHandler = new ValidationHandler($altchaService);
|
|
|
|
// Früheste mögliche Prüfung der Newsletter-Anmeldung: läuft direkt hier, noch
|
|
// bevor JTL-Shop das $_POST verarbeitet. Siehe ValidationHandler::guardNewsletterSubmission().
|
|
$validationHandler->guardNewsletterSubmission();
|
|
|
|
// Dieselbe frühe Prüfung für das Kontaktformular. Siehe
|
|
// ValidationHandler::guardContactSubmission().
|
|
$validationHandler->guardContactSubmission();
|
|
|
|
// Widget (Container + Skript) in Registrierungs- und Newsletter-Formular einfügen.
|
|
$dispatcher->listen(
|
|
'shop.hook.' . \HOOK_SMARTY_OUTPUTFILTER,
|
|
[$templateHandler, 'generalTemplateIntegration']
|
|
);
|
|
|
|
// Registrierung: Plausibilitätsprüfung nach Formularabsendung.
|
|
$dispatcher->listen(
|
|
'shop.hook.' . \HOOK_REGISTRIEREN_PAGE_REGISTRIEREN_PLAUSI,
|
|
[$validationHandler, 'checkRegistrationPlausibility']
|
|
);
|
|
|
|
// Newsletter: zusätzliche Absicherung kurz vor dem Speichern des Empfängers.
|
|
if (\defined('HOOK_NEWSLETTER_PAGE_EMPFAENGEREINTRAGEN')) {
|
|
$dispatcher->listen(
|
|
'shop.hook.' . \HOOK_NEWSLETTER_PAGE_EMPFAENGEREINTRAGEN,
|
|
[$validationHandler, 'checkNewsletterRecipient']
|
|
);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
error_log('[fp_altcha_spamschutz] Fehler beim Initialisieren des Plugins: ' . $e->getMessage());
|
|
}
|
|
}
|
|
}
|