-
Notifications
You must be signed in to change notification settings - Fork 2
Altcha integration #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Implemented AltchaIntegration class for plugin configuration - Added AltchaClient service for challenge generation and validation - Created AltchaType form type with configurable options - Implemented AltchaFormSubscriber for event handling - Added Altcha widget template with invisible mode support - Registered all services and event listeners - Added English and German translations - Implemented comprehensive test suite (19 tests, 23 assertions) - All property-based tests passing (8 properties validated) - GDPR-compliant: no external API calls, local validation only
- Run PHPUnit tests on PHP 8.1 - Create production ZIP package (excludes dev files) - Upload package to GitLab Package Registry - Trigger on main, tags, and develop branches
- Install bcmath, gd, imap, sockets, and zip extensions - Configure gd with freetype and jpeg support - Configure imap with kerberos and ssl support - Resolves composer dependency installation errors
- Remove libc-client-dev and libkrb5-dev (not available in Debian 13) - Skip IMAP extension as it's only needed by Mautic core, not our tests - Use --ignore-platform-req=ext-imap for composer install - Keep bcmath, gd, sockets, and zip extensions for actual test requirements
- Add 'docker' tag to test job - Add 'docker' tag to package job - Ensures jobs run on Docker executor instead of shell executor
- Remove LoggerInterface parameter from AltchaClient constructor to match other captcha clients - Add challenge generation in AltchaFormSubscriber.onFormBuild() - Update altcha.html.twig template to handle challenge data correctly - Update AltchaClientTest to reflect constructor changes - All tests passing (19/19)
…Mautic form validation error
…rdPress - Add event propagation stopping to prevent jQuery infinite loops - Add detailed logging for debugging validation issues - Improve base64 payload decoding - Add UTC timezone for challenge creation - Isolate widget in container to prevent event bubbling
- Add expires parameter to createChallenge() method to properly encode expiration time in salt - Fix verify() method to handle both base64-encoded and JSON payloads - Fix test to use base64-encoded payload as required by Altcha library - All 20 tests now pass successfully
- Extract inline JavaScript to separate altcha-handler.js file - Prevent 'Unexpected end of input' error when Mautic embeds forms - Improve event handling and jQuery conflict prevention - Add proper script loading management for embedded forms - Maintain backward compatibility with existing functionality
- Add retry logic for widget initialization - Improve script loading with proper timing - Add comprehensive logging for debugging - Ensure DOM readiness before widget initialization - Fix widget visibility issues in embedded forms
- Remove overly complex altcha-handler.js - Use simple script tag loading approach - Let web developers handle multiple forms themselves - Fix original JavaScript parsing error with minimal changes
- Use JavaScript to create script tag with type='module' - Prevents Mautic from stripping the module type attribute - Fixes 'unexpected export' error in browser
- Add AltchaExtension Twig extension for runtime challenge generation - Add AltchaController with AJAX endpoint for dynamic challenge loading - Update altcha.html.twig to use Twig function instead of cached challenge - Remove challenge generation from AltchaFormSubscriber onFormBuild - Register new services and routes in config.php This fixes the issue where cached forms would fail after challenge expiration by generating fresh challenges on every form render.
Use imported class name instead of fully qualified class name to avoid autoload issues.
- Remove AltchaExtension.php that caused cache:clear issues - Update altcha.html.twig to use AJAX challenge loading - Remove Twig extension registration from config.php - Keep AltchaController for dynamic challenge generation This approach avoids Mautic service container issues while still solving the caching problem.
Replace path() function with hardcoded URL to avoid routing issues. The route is defined but Mautic may not recognize it immediately after deployment.
- Add AltchaApiController with secure /altcha/api/challenge endpoint - Use ALTCHA native challengeurl attribute instead of custom JavaScript - Fixed security issue: no user-controllable parameters in API - Update templates to use challengeurl with refetchonexpire - Add comprehensive documentation for API endpoint - Update deployment configuration to include Controller directory - Remove complex JavaScript in favor of native ALTCHA features - Version bump to 1.1.1 Fixes caching issues where ALTCHA challenges were cached with forms, causing expired challenges. Now each form load gets a fresh challenge via the secure API endpoint.
- Fix controller route: use service reference instead of bundle syntax - Fix challengeurl: make absolute URL to work with embedded forms - Controller now properly registered as 'mautic.altcha.controller.api:generateChallengeAction' - challengeurl now uses absolute_url() to work from external domains Fixes 500 error when calling API endpoint and relative URL issues when forms are embedded in external websites.
- Move controller from 'others' to 'controllers' service section - Remove constructor injection, use container->get() instead - Use direct class reference in route: AltchaApiController::class - Follow Mautic controller patterns for proper DI container access Fixes 'no container set' error when calling API endpoint.
- Change from CommonController to AbstractController to avoid complex dependencies - Restore constructor injection with AltchaClient parameter - Add arguments back to controller service registration - Use Symfony's AbstractController for simpler API controller pattern Fixes ArgumentCountError with CommonController constructor.
- Remove controller inheritance completely (no extends) - Use plain PHP class with constructor injection - Reference controller as service in route configuration - Avoid Symfony/Mautic container conflicts with simple approach This should resolve the 'no container set' service subscriber error.
- Update endpoint path from /altcha/challenge to /altcha/api/challenge - Add X-Altcha-Spam-Filter header to allowed CORS headers - Remove unnecessary form/submit and general API locations - Focus on essential ALTCHA-specific CORS configuration Fixes CORS error: 'Request header field x-altcha-spam-filter is not allowed'
NGINX improvements: - Add exact location match for /altcha/api/challenge - Add broader regex location as fallback - Include Cache-Control header for ALTCHA compatibility - Add debug endpoint for testing - Use 'always' directive to ensure headers are set PHP Controller improvements: - Handle OPTIONS preflight requests in controller - Add CORS headers to all responses (success and error) - Ensure CORS works even if nginx config is not applied - Dual-layer CORS protection (nginx + PHP) This should resolve persistent CORS issues with cross-origin requests.
|
Hey @brafreider, Thank you for your PR! I noticed you also translated the strings of the original bundle to German in This has got to be one of the cleanest PRs I have ever seen. I'm very impressed. Even if it was with help of an LLM. I took the liberty of cleaning up a little before merging. |
|
@fmm-rwalraven wait a minute, there is a little issue with mautic form caching. I had to change some code after creating this PR. |
|
@brafreider Marked as draft again. Let me know when you have it resolved! :) |
|
the issue was that I did not find a way to prevent Mautic from caching the challenge token. After adding Altcha, to a form the tests succeeded, but after the challenge lifetime had passed, the form could not be submitted any more, until the cache was invalidated. I solved this, by adding an API endpoint to retrieve the challenge. This works, but currently the configuration value for challenge expiration has no effect, as the endpoint does not know which form it is called from. This means, that the value is hard coded at the moment, it could be changed in a global configuration value and of course the field level configuration should be removed. |
- Removed maxNumber and expires fields from individual field configuration (AltchaType) - Added maxNumber and expires as optional fields to global ALTCHA integration settings - Updated AltchaClient with getConfiguration() method to retrieve global settings - Modified API endpoint to use global configuration values with fallback defaults (50000/120) - Added comprehensive tests for configuration retrieval and API endpoint behavior - All 28 tests passing with 106 assertions
- Changed from getAvailableFields() to appendToForm() method - Added NumberType and Range constraint imports - Fields maxNumber and expires now properly display in plugin configuration - Maintained validation constraints (1000-1000000 for maxNumber, 10-300 for expires) - Default values: maxNumber=50000, expires=120
|
@fmm-rwalraven I have now removed the configuration of max-number and lifetime from field configuration and added both to the plugin configuration dialog. Additionally, I have added unit tests and validated functionality in our Mautic5 sandbox. |
This PR includes Altcha as an additional Captcha option. See https://altcha.org for details. Altcha uses PoW to check if the user is real. PoW is not a 100% proof, but it will need javascript to pass and waste spammer's ressources, depending on the complexity level you choose.
The main advantage, why we use Altcha in several projects is, that it can be used without external dependencies, which is perfect for GDPR compliance.
you can find a form, that uses this integration on https://visual4.de/kontakt/
I have taken the help of Kiro, so the PR is partly vibe coded, without, it would have taken much longer.
I have added: