=== TINXDK WP - Login Limit ===
Contributors: tinxdk
Tags: login, security, brute force, limit login attempts, altcha
Requires at least: 6.3
Tested up to: 6.8
Requires PHP: 8.2.35
Stable tag: 1.1.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Allow X failed login attempts per IP address, then block login from that IP for Y hours.

== Description ==

A small, focused alternative to "Limit Login Attempts Reloaded". One rule: after X failed logins from an IP address, login from that IP is blocked for Y hours.

**Free edition** (no licence needed, fully usable):

* Counts failed logins on wp-login.php: X attempts, then the IP is blocked for Y hours; remaining-attempts message and reset window.
* Existing lockouts are enforced everywhere (wp-login.php, XML-RPC, REST application passwords, WooCommerce): a locked IP is refused even when the password is correct, and the password check is not even run.
* Admin page with the active lockouts and one-click unlock.
* ALTCHA (self-hosted proof of work, no third party) on the wp-login.php login, lost password, reset password and registration forms and on the WooCommerce account forms (login, registration, lost password).

**Licensed edition** (licence key from https://tinxdkcloud.dk/wordpress-plugins/tinxdk-wp-login-limit/#licens):

* Counts failures from XML-RPC (every failed call of system.multicall), REST application passwords and WooCommerce my-account logins.
* Allowlist and blocklist of IP addresses (IPv4/IPv6, CIDR) and usernames.
* Real client IP behind a reverse proxy: X-Forwarded-For, X-Real-IP or CF-Connecting-IP are honoured only when the request comes from a trusted proxy (the free edition uses REMOTE_ADDR only).
* Lockout log and statistics, GDPR option to anonymise IP addresses, configurable log retention.
* One email to the administrator per lockout (optionally only every N-th lockout).
* WP-CLI: `wp login-limit list`, `wp login-limit unlock <ip>|--all`, `wp login-limit log`.
* Automatic plugin updates through the TINXDK licence server.

Licensed settings stay visible but disabled in the free edition; the stored values are kept and apply again when a licence is activated. Without contact to the licence server the licence keeps working for 7 days.

Licence activation: Settings > Login Limit > License, enter the key (TINX-XXXX-XXXX-XXXX-XXXX) and click Activate. The site URL, plugin/WordPress/PHP versions and the key are sent to the licence server (licens.tinxdkcloud.dk) when activating, twice daily when validating and when checking for updates. Nothing else is sent.

Emergency access: add `define( 'TINXDK_LL_DISABLE', true );` to wp-config.php to switch enforcement and ALTCHA off. The filter `tinxdk_ll_client_ip` can override the resolved IP.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/` and activate it.
2. Configure it under Settings > Login Limit.

== Changelog ==

= 1.1.1 =
* Changed: ALTCHA on the WooCommerce account forms is now part of the free edition. Every public form is protected by ALTCHA in both editions.

= 1.1.0 =
* New: Free edition and licensed edition. The free edition counts failed logins on wp-login.php, enforces lockouts everywhere, lists and unlocks lockouts and protects the wp-login forms with ALTCHA.
* New: Licensed edition: counting via XML-RPC, REST application passwords and WooCommerce, allowlist/blocklist, trusted proxy headers, log and statistics with GDPR option, email notifications, WP-CLI commands, ALTCHA on the WooCommerce forms and automatic updates.
* New: License section under Settings > Login Limit (activate/deactivate, status, expiry, sites used, 7-day grace period without contact to the licence server).
* Changed: Licensed settings are shown disabled with a "Requires license" label in the free edition; stored values are kept.

= 1.0.0 =
* First release.
