Skip to content

Clear expired tokens from JS-driven forms, send visitor IP to siteverify (1.23.0) - #65

Merged
forgetso merged 1 commit into
mainfrom
feat/token-lifecycle-and-verify-ip
Oct 29, 2026
Merged

forgetso merged 1 commit into
mainfrom
feat/token-lifecycle-and-verify-ip

Conversation

@forgetso

Copy link
Copy Markdown
Member

Brings the plugin in line with the current Procaptcha widget's callbacks and verify API.

Changes

  • Expired, errored or reset tokens are now cleared. The plugin connected only callback. When a token expired, the widget removed its own procaptcha-response input, but the custom .prosopo-procaptcha-input used by JS-driven forms kept the stale token. Client validation passed, then the server rejected the submission.
    • expired-callback, error-callback and reset-callback now empty that input and dispatch _prosopo-procaptcha__cleared.
    • WooCommerce block checkout falls back to its stub value, and Beaver Builder drops its cached token. Ninja Forms reads the input when it validates, so it picks up the change automatically.
  • Each widget gets its own options. The plugin used to change the shared window.procaptchaWpAttributes object and pass that same object to every widget. The widget stores the options and reuses them on reset(), so on a page with several widgets a reset would send the token to the last widget's form.
  • User callbacks from the filter are kept. A callback set through prosopo/procaptcha/captcha_attributes was overwritten; it is now called after the plugin's own. Function names work with or without a window. prefix.
  • The visitor IP is sent to /siteverify. It comes from REMOTE_ADDR. A new prosopo/procaptcha/visitor_ip filter lets sites behind a proxy pass the real IP; anything that isn't a valid IP is dropped.
  • Version bumped to 1.23.0, with a changelog entry.

Testing

  • tools/check-code-quality.sh passes: ESLint, Prettier, PHPStan, Pest and PHPCS. tsc and yarn build also pass.
  • I ran a happy-dom check against the bundled component with two widgets on one page:
    • each render gets a separate options object, and the global object is left unchanged;
    • tokens land in the right form, and user callbacks given as strings still fire;
    • expiry, error and reset each clear only their own form and fire the cleared event;
    • a missing user function logs a warning instead of throwing.
  • Not done: manual testing of each captcha type against the portal, which the release checklist asks for.

Follow-up: the docs at https://docs.prosopo.io/en/wordpress-plugin/hooks/ give $attributes['lang'] as an example, but the option is called language. The docs should also cover the new visitor_ip filter.

🤖 Generated with Claude Code

…siteverify

- Wire expired-callback, error-callback and reset-callback to empty the
  custom token input and dispatch _prosopo-procaptcha__cleared, so Ninja
  Forms, WooCommerce block checkout and Beaver Builder stop submitting a
  token the server will reject.
- Give each widget its own copy of the render options instead of mutating
  the shared procaptchaWpAttributes object, which the widget reuses on reset.
- Chain user callbacks from the captcha_attributes filter rather than
  overwriting `callback`.
- Send `ip` to /siteverify, with a prosopo/procaptcha/visitor_ip filter for
  sites behind a proxy.
- Bump to 1.23.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@forgetso
forgetso merged commit fb52163 into main Oct 29, 2026
8 checks passed
@forgetso forgetso mentioned this pull request Oct 29, 2026
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.

1 participant