=== SK Spamshield ===
Contributors: svenkersten
Tags: spam, antispam, honeypot, proof-of-work, contact form 7
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.2.3
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Stops form spam on your own website, without third parties and without cookies.

== Description ==

SK Spamshield protects Elementor Pro forms, Contact Form 7, Fluent Forms, SureForms and WordPress comments in three layers:

1. A honeypot field with a name that changes on every visit, plus a signed timestamp.
2. ALTCHA proof-of-work: the visitor's browser does a small calculation in the background. Visible checkbox and simple sum are available as alternatives.
3. Temporary rate limiting per IP address for forms only; the rest of the site stays reachable.

Everything runs on your own website. No form data is sent to other services, no cookies are set, and no scripts are loaded from a CDN. Pages stay fully cacheable: the changing values are fetched from an uncached endpoint.

Includes a test mode (log only), a log of rejected submissions without form content, a health check for the endpoint, and a notice when another anti-spam plugin has become redundant.

== Installation ==

1. Upload the plugin and activate it.
2. Go to Sven Kersten > Spamshield. Start in test mode for a week on a live site, then switch test mode off.

== Frequently Asked Questions ==

= Does it work without JavaScript? =

No. Without JavaScript the plugin rejects the submission with a clear message. The proof-of-work needs JavaScript.

= What happens when a new form plugin is detected? =

Protection for Fluent Forms and SureForms is on by default. The first seven days after it becomes active on a site, it only logs what it would reject (a run-in period), so an update never silently closes a form. After that it blocks. You can end the run-in early, extend it by a week at a time (up to 30 days), or switch the integration off. Check status with `wp sk-spamshield inloop`.

= Which forms can it not protect? =

Fluent Forms conversational forms are protected too: the check is added to their submission. Only with the "simple sum" mode they cannot be protected (there is no field for the answer) and are rejected once the run-in ends. SureForms forms with a payment block: a visitor who pays and is then rejected keeps an open payment. The settings screen lists both.

= Do API integrations that post to the Fluent Forms REST route still work? =

The route `/wp-json/fluentform/v1/form-submit` is checked like the public form. An integration that submits through it with an application password is rejected, unless that user can edit posts (`edit_posts`).

= What data is stored? =

For rejected submissions: time, reason, form type, IP address and a shortened browser string. No form content. Rows are deleted automatically after 14 days (configurable up to 30). Counters for rate limiting use a keyed hash of the IP address.

= Can I set the key myself? =

Yes. Put a constant in wp-config.php; it takes precedence over the stored key. Generate a random value of 32 bytes, for example with WP-CLI:

`wp eval 'echo base64_encode(random_bytes(32));'`

and add `define( 'SK_SPAMSHIELD_KEY', '<the value>' );`. The value must be at least 32 characters. Never reuse it on another site.

== Third-party libraries ==

* ALTCHA widget 3.2.3 (MIT), https://github.com/altcha-org/altcha
* ALTCHA PHP library 2.1.0 (MIT), https://github.com/altcha-org/altcha-lib-php

Both are bundled; nothing is loaded from external servers.

== Changelog ==

= 0.2.3 =
* Security: updates are only installed when they carry a valid signature from the publisher. A tampered or unsigned update is refused and nothing is installed.

= 0.2.2 =
* New: the SureForms payment routes (Stripe, PayPal) refuse blocked IP addresses and more than 10 attempts per IP per hour, against card testing. Refusals are logged.
* New: the overlap notice also mentions the honeypot, token check and CleanTalk of Fluent Forms.
* Fix: the script for conversational forms only loads when Fluent Forms is installed.

= 0.2.1 =
* Fix: forms on sites that minify scripts into a cache folder (for example Perfmatters) were rejected in 0.2.0, because the proof-of-work library could not be found. The library address now comes from the plugin's own settings again, with a strict check that it points to the plugin's own folder.

= 0.2.0 =
* New: protection for Fluent Forms, including conversational forms and the Pro features (steps, save and resume, payments).
* New: protection for SureForms and SureForms Business, including multi-step and conversational forms.
* New: a newly detected form plugin first logs for seven days (run-in period) before it blocks. Status via the settings screen and `wp sk-spamshield inloop`.
* Security: the front-end script only reads its settings from its own configuration block, and only loads files from its own folder.
* Fix: buttons that do not submit (next, previous, save and resume) are no longer intercepted.

= 0.1.0 =
* First version.
