Skip to content

Add AJAX support for form submissions#302

Open
ilyautkin wants to merge 12 commits into3.xfrom
feature/ajax-submit
Open

Add AJAX support for form submissions#302
ilyautkin wants to merge 12 commits into3.xfrom
feature/ajax-submit

Conversation

@ilyautkin
Copy link
Copy Markdown

@ilyautkin ilyautkin commented Feb 20, 2026

What does it do?

Add JS script and backend handler to enable AJAX-based form submission and processing. Documentation: https://github.com/ilyautkin/Docs-1/blob/fix-formit-docs/en/extras/formit/formit.ajax.md

Why is it needed?

AjaxForm can not handle correctly FormIt errors, so we need to add Ajax supporting in FormIt

Related issue(s)/PR(s)

Fixing #260

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds AJAX support for FormIt form submissions to address limitations with AjaxForm's error handling. The implementation includes a new frontend JavaScript library that intercepts form submissions, a backend PHP endpoint to process AJAX requests, and fixes a bug with the reCAPTCHA instanceof check (issue #260).

Changes:

  • Added AJAX form submission support with client-side JavaScript and server-side endpoint
  • Fixed reCAPTCHA service instanceof check and improved error handling
  • Added lexicon entries for AJAX-related error messages across multiple languages

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
assets/components/formit/js/web/formit.js New frontend JavaScript for AJAX form handling with event system and callbacks
assets/components/formit/action.php New backend endpoint that processes AJAX submissions via MODX API mode
core/components/formit/src/FormIt/Request.php Fixed reCAPTCHA instanceof bug, added AJAX token generation and JS registration
core/components/formit/src/FormIt/Service/RecaptchaService.php Improved error handling by consistently returning RecaptchaResponse objects
core/components/formit/src/FormIt/Hook/Recaptcha.php Added null coalescing operators for safer POST data access
core/components/formit/src/FormIt.php Removed unused processForm method
core/components/formit/lexicon/*/default.inc.php Added error messages for missing/expired configuration in 11 languages
_build/gpm.yml Added frontend_js system setting configuration
.gitignore Added build-related directories to ignore list

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread assets/components/formit/js/web/formit.js Outdated
Comment thread assets/components/formit/js/web/formit.js Outdated
Comment thread assets/components/formit/js/web/formit.js Outdated
Comment thread assets/components/formit/js/web/formit.js
Comment thread assets/components/formit/js/web/formit.js
Comment thread core/components/formit/src/FormIt/Request.php Outdated
Comment thread assets/components/formit/js/web/formit.js Outdated
Comment thread core/components/formit/src/FormIt/Request.php
Comment thread assets/components/formit/js/web/formit.js
Comment thread core/components/formit/src/FormIt/Request.php Outdated
@MateiDev
Copy link
Copy Markdown

http://endless.horse/

@svrhovac
Copy link
Copy Markdown

svrhovac commented Apr 6, 2026

Hi @ilya
I have few remarks (brought by Claude and Gemini) which looks reasonable, however most of them are aroind this one issue:

Predictable AJAX token + full config exposure — Request.php:147-153

$ajaxToken = md5(serialize($properties));
$_SESSION['formit'][$ajaxToken] = $properties;
$this->modx->cacheManager->set('formit/props_' . $ajaxToken, $properties, $cacheTtl);

Three compounding problems:

  • Deterministic token: Same form config always produces the same token. An attacker who knows the snippet properties can compute it.
  • Full config stored: $properties contains everything — emailTo, hook names, reCAPTCHA keys, validation rules.
  • Leaked to client: action.php:91-102 returns ALL fi.-prefixed placeholders to the JSON response without filtering.

Fix: Use bin2hex(random_bytes(16)) for the token. Whitelist which placeholders are returned (only error.*, successMessage, validation_error_message, error_message).

@svrhovac
Copy link
Copy Markdown

svrhovac commented Apr 6, 2026

@ilyautkin other then previous comment, I am OK with these changes.

Tested on local environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants