=== TINXDK Captcha Lite ===
Contributors: tinxdk
Tags: captcha, spam, altcha, antispam, forms
Requires at least: 6.3
Tested up to: 7.1
Requires PHP: 8.2.35
Stable tag: 2.1.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Self-hosted ALTCHA captcha for login, registration, comments, WooCommerce and 12 form plugins. No external service, no cookies.

== Description ==

TINXDK Captcha Lite protects your forms against bots with ALTCHA, a proof-of-work captcha. The visitor's browser solves a small calculation in the background (no images, no puzzles to click), and your own server creates and verifies the challenge. No data is sent to a third party and no cookies are set.

**Protected forms** (each one can be switched on or off under Settings > TINXDK Captcha Lite, and is on by default when its plugin is active):

* WordPress: login (also `wp_login_form()`), registration, lost password, reset password and comments.
* WooCommerce: my account login, registration, lost password and the classic checkout.
* Contact Form 7
* Fluent Forms
* Elementor Pro Forms
* WPForms (Lite and Pro)
* Gravity Forms
* Formidable Forms
* Ninja Forms
* Forminator
* Jetpack Forms (the Contact Form block)
* Divi contact form module (Divi theme and Divi Builder)
* Kadence Blocks forms (the Form block and the Advanced Form block)
* Mailchimp for WordPress sign-up forms

**How it works**

* The widget asks your site for a signed challenge (REST route `tinxdk-captcha/v1/challenge`, rate limited per IP) and the browser finds the answer.
* The form submission carries the solved proof. Your server checks the signature (HMAC with a secret that only your site knows), the expiry (5 minutes) and that the proof has not been used before (replay protection).
* A form without a valid proof is refused with a clear message, or marked as spam in Contact Form 7.
* Overview on the settings page: verified, failed and missing proofs today and the last 7 days. Only counts are stored (30 days). No IP addresses, no form content.
* Difficulty setting (low, normal, high) for how much work the browser does.
* Logged-in users who can moderate comments skip the check on the comment form.
* Emergency switch: add `define( 'TINXDK_CAPTCHA_DISABLE', true );` to wp-config.php to switch all checks off.

**For developers**

* Filter `tinxdk_captcha_required( $required, $form_id )`: return false to leave a form unprotected. Form ids: `wp-login`, `wp_login_form()`, `wp-register`, `wp-lostpassword`, `wp-resetpass`, `wp-comment`, `woocommerce-login`, `woocommerce-register`, `woocommerce-lost`, `woocommerce-checkout`, and `contact-form-7:<id>`, `fluentform:<id>`, `wpforms:<id>`, `gravityforms:<id>`, `formidable:<id>`, `elementor-form`, `ninja-forms:<id>`, `forminator:<id>`, `jetpack-forms:<id>`, `divi-contact-form`, `kadence-form:<id>`, `kadence-advanced-form:<id>` and `mc4wp:<id>`.
* Actions `tinxdk_captcha_verified( $form_id, $reason )` and `tinxdk_captcha_failed( $form_id, $reason )`. The reason of a failure is `missing` (no proof: the widget did not run, typically a bot), `invalid` or `blocked`. Filter `tinxdk_captcha_reject( $reject, $form_id )`: return true to refuse a submission even with a valid proof.
* Filter `tinxdk_captcha_widget_attributes( $attributes, $form_id )` for the attributes of the widget element.
* Filter `tinxdk_captcha_challenge_options( $options )` (`maxnumber`) to change the difficulty of the challenges.
* Filter `tinxdk_captcha_skip_moderators( $skip )` and `tinxdk_captcha_client_ip( $ip )`.
* Action `tinxdk_captcha_loaded` after the plugin has booted, and the settings extension points `tinxdk_captcha_settings_defaults`, `tinxdk_captcha_sanitize_settings` and `tinxdk_captcha_admin_sections`.

The plugin does not contact any external service.

Works together with TINXDK Login Limit Lite: when both are active, TINXDK Captcha Lite takes care of ALTCHA so your visitors never see two widgets.

**TINXDK Captcha Pro** is a separate plugin that extends this one with an invisible mode and an "Under Attack" mode with higher difficulty. Read more at https://tinxdkcloud.dk/wordpress-plugins/tinxdk-captcha/#pro

== Installation ==

1. Install the plugin from the WordPress plugin directory, or upload the folder to `/wp-content/plugins/`, and activate it.
2. Configure it under Settings > TINXDK Captcha Lite. The forms of the active plugins are protected right away.

== Frequently Asked Questions ==

= Does ALTCHA send data to a third party? =

No. The challenge is created and verified on your own server. The widget script is bundled with the plugin.

= Does it set cookies? =

No.

= Does it work with the WooCommerce block checkout? =

Not yet. The block checkout is rendered in the browser by React and has no server-side place for the widget, so the classic checkout (shortcode) is protected, but the block checkout is not. The my account forms work with both.

= Which form plugins are supported? =

Contact Form 7, Fluent Forms, Elementor Pro Forms, WPForms, Gravity Forms, Formidable Forms, Ninja Forms, Forminator, Jetpack Forms, the Divi contact form, Kadence Blocks forms and Mailchimp for WordPress sign-up forms, plus WordPress itself and WooCommerce. Switch an integration off under Settings > TINXDK Captcha Lite if you use another captcha there.

= The widget does not show in my Divi contact form. =

The Divi integration is written for the Divi 4 contact form module (Divi theme and Divi Builder) and is off by default: switch on "Divi Contact Form" under Settings > TINXDK Captcha Lite and send a test message. If your Divi version renders the module differently and the widget does not appear, switch it off again, or tell us on the support forum.

= Does it work with Ninja Forms, Jetpack Forms and Kadence Blocks when the form is sent without a page reload? =

Yes. These forms are sent with JavaScript: the plugin hands the solved proof to the form and solves a fresh one after every submission, because a proof can be used once.

= A visitor says the form does not send. =

The proof expires after 5 minutes and can be used once. If the page has been open for a long time, reload it. Behind a reverse proxy all visitors may share one IP address and hit the rate limit of the challenge route: use the filter `tinxdk_captcha_client_ip` to supply the real client IP.

= I locked myself out of the login. =

Add `define( 'TINXDK_CAPTCHA_DISABLE', true );` to wp-config.php, log in, and remove the line again.

= Is there a Pro version? =

Yes, TINXDK Captcha Pro adds an invisible mode and an "Under Attack" mode. See https://tinxdkcloud.dk/wordpress-plugins/tinxdk-captcha/#pro

== Changelog ==

= 2.1.1 =
* Changed: Renamed to TINXDK Captcha Lite (no functional change). Slug, settings and data are unchanged.

= 2.1.0 =
* New: ALTCHA on Ninja Forms, Forminator, Jetpack Forms (Contact Form block), the Divi contact form, Kadence Blocks forms (Form and Advanced Form blocks) and Mailchimp for WordPress sign-up forms. Each has its own switch under Settings > TINXDK Captcha Lite, on by default when the plugin is active (Divi: off by default, switch it on after a test message).
* New: the widget is reset and solves a new challenge after an AJAX submission of Ninja Forms, Forminator, Jetpack Forms and Kadence Blocks forms.
* New: Danish translation of the new settings.

= 2.0.0 =
* First release of TINXDK Captcha Lite: self-hosted ALTCHA proof-of-work captcha for WordPress (login, registration, lost and reset password, comments), WooCommerce (my account forms and classic checkout), Contact Form 7, Fluent Forms, Elementor Pro Forms, WPForms, Gravity Forms and Formidable Forms.
* New: Settings page with a switch per integration, difficulty and an overview of verified, failed and missing proofs.
* New: Developer hooks prefixed `tinxdk_captcha_` and extension points for TINXDK Captcha Pro.

== Upgrade Notice ==

= 2.1.1 =
Renamed to TINXDK Captcha Lite (no functional change).

= 2.1.0 =
Adds Ninja Forms, Forminator, Jetpack Forms, Divi, Kadence Blocks and Mailchimp for WordPress forms. The new switches are on by default when those plugins are active (Divi: off by default).

= 2.0.0 =
First release.
