=== Web-Art Login Shield with reCAPTCHA ===
Contributors: webartdesigning
Donate link: https://www.paypal.me/webartcreativedesign
Tags: security, login, recaptcha, elementor, brute-force
Requires at least: 5.8
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.2.3
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Protect WordPress logins and Elementor Login/Forms using Google reCAPTCHA v2/v3 and optional IP-based lockouts.

== Description ==

Web-Art Login Shield with reCAPTCHA protects WordPress authentication, Elementor Login widgets and Elementor Forms.

It provides optional Google reCAPTCHA v2/v3, IP lockouts, Advanced login URL protection, IP blocking and REST/XML-RPC protection. It preserves WordPress core authentication logic.

No ads, author telemetry or external dashboard. All modules are opt-in and disabled by default.

== Key Features ==

= reCAPTCHA v2/v3 =

* selectable v2 checkbox or v3 score-based verification
* protection for wp-login.php, Elementor Login and Elementor Forms
* server-side token, action, score and hostname validation where applicable
* configurable v3 score threshold
* one active type at a time
* configuration verification before activation

= Elementor support =

* protection for Elementor Login, classic Elementor Pro Forms and Atomic Forms
* classic forms containing native Elementor reCAPTCHA fields are skipped to avoid duplication
* v2 alignment controls
* login errors and lockouts remain inside the Login widget
* dynamic content and Elementor popup support

= Login Protect =

* per-IP failed-attempt counting and temporary lockouts
* safe concurrent-request handling
* active-lockout countdown
* local security event log with bounded retention
* optional REST API, Application Password and XML-RPC protection
* independent operation with or without reCAPTCHA

= Advanced login URL =

* optional custom login endpoint
* protection of default login routes while preserving required public actions
* logout and password-link compatibility
* emergency wp-config.php recovery constant

= IP allowlists and blocking =

* separate reCAPTCHA allowlist and Login Protect trusted IP list
* permanent IP blocking for public site requests with HTTP 403
* optional IP | reason notes

= XML-RPC hardening =
Optional blocking of:

* pingback.ping
* pingback.extensions.getPingbacks
* system.multicall

== Security Model ==

Compatibility scope: the Elementor Forms integration supports the classic Elementor Pro Form widget and Atomic Forms with reCAPTCHA v2 and v3. Atomic submissions are verified server-side before form actions run, and internal CAPTCHA fields are removed from submission data. Native WooCommerce My Account/checkout login, registration and password reset forms do not currently have a dedicated reCAPTCHA integration. Login Protect's interactive attempt detection covers WordPress login and this plugin's Elementor Login AJAX flow, not native WooCommerce login. REST protection refers to WordPress authentication (including Application Passwords), not a dedicated WooCommerce consumer-key authentication integration.

Protected flows use fail-closed handling. If an enabled check cannot be completed safely, the request is rejected instead of bypassing protection.

Login Protect preserves active lockouts and safely handles concurrent requests. Setting Maximum login attempts or Lockout duration to 0 disables lockout enforcement.

All modules remain disabled until enabled. Recovery constants are available in wp-config.php for selected modules.

== External Services ==

This plugin integrates with Google reCAPTCHA v2 and v3, services provided by Google LLC.

reCAPTCHA is disabled by default. Google scripts or verification requests are used only after an administrator enables reCAPTCHA or runs a settings-page verification test.

Google's reCAPTCHA JavaScript (https://www.google.com/recaptcha/api.js) may load on protected wp-login.php requests, pages containing protected Elementor widgets or forms, and the settings page during a verification test. Allowlisted visitors bypass frontend loading where applicable.

When reCAPTCHA runs, the visitor's browser connects directly to Google. Google may process browser, device and interaction information and may set the necessary _GRECAPTCHA cookie under its policies.

For server-side verification, the plugin sends the token, configured Secret Key and visitor IP address when available to Google's siteverify endpoint. It does not include usernames, passwords, email addresses or form contents in that request.

The plugin sends no telemetry, analytics or usage data to its author.

Google policies:

* https://policies.google.com/privacy
* https://policies.google.com/terms

== Privacy ==

Locally stored security data may include:

* IP addresses, failed-attempt counts and lockout timestamps
* a username or email associated with an IP lockout
* recent events containing an IP address, username or email, source, type and timestamp
* the latest reCAPTCHA configuration or transport error used for diagnostics
* permanent IP blocklist entries and optional notes

Inactive Login Protect entries become eligible for deletion after seven days. Active lockouts remain until expiry. The event log is limited to 30 entries and 30 days.

WordPress privacy tools export or erase records matched to the requested email address or associated account. Unmatched IP-only records remain subject to retention and administrator cleanup. Permanent blocklist entries remain until removed by an administrator.

Plugin data can be removed during uninstall when uninstall cleanup is enabled.

== Installation ==

1. Install and activate the plugin.
2. Open the plugin settings page.
3. Select reCAPTCHA v2 or v3 if required.
4. Enter the matching Site Key and Secret Key.
5. Save the keys and run the verification test.
6. Enable the required protection modules.
7. If using Advanced login URL, securely store the generated login URL.

== Frequently Asked Questions ==

= What is the reCAPTCHA v3 score threshold? =
A request is accepted only when its score meets the configured threshold and its action is valid.

= What if an Elementor Form already uses native reCAPTCHA? =
For the classic Elementor Pro Form widget, the plugin skips its own handling when a native Elementor reCAPTCHA v2 or v3 field is present. Atomic Forms use a separate integration and do not use this native-field bypass.

= What happens if Google reCAPTCHA is unreachable? =
The affected protected request is rejected instead of bypassing enabled protection.

= Does REST API protection include Application Passwords? =
Yes. It covers native WordPress Application Password authentication without storing or logging application passwords.

= What if I lose access after enabling Advanced login URL or IP Blocking? =
Use LGRE_DISABLE_ADVANCED_LOGIN or LGRE_DISABLE_IP_BLOCKING in wp-config.php, then remove the constant after restoring access.

= Does the plugin trust proxy headers? =
No. It uses validated REMOTE_ADDR by default. Trusted code may enable sanitized proxy headers through lgre_trust_proxy_headers.

= Can custom authentication add credential error codes? =
Yes. Trusted code may use lgre_login_protect_credential_error_codes; added values are validated.

= Should the custom login URL be cached? =
No. The plugin marks the custom login endpoint as non-cacheable using WordPress no-cache handling and explicit no-store headers. When LiteSpeed Cache is active, it additionally sends a request-local no-cache signal and performs targeted purging only for the custom login URL when cache-sensitive settings or plugin lifecycle state change. It does not modify LiteSpeed's persistent Do Not Cache settings or other cache configuration. Existing persistent exclusions created by version 1.2.1 may remain and can be left in place or removed manually. External CDN rules such as Cache Everything may still require manually excluding the custom login URL.

== Screenshots ==

1. reCAPTCHA settings panel
2. Login Protect settings panel
3. Security event log and blocked IP list
4. WordPress login screen
5. Elementor Login widget
6. Elementor Form

== Changelog ==

= 1.2.3 =

* Documentation: Update the implemented Atomic Forms support scope and clarify that native CAPTCHA field detection applies to classic Elementor Pro Forms.
* Security: Compare reCAPTCHA v3 actions exactly without case folding or character removal in login, form and admin verification.
* Security: Require a boolean true success value in both reCAPTCHA v2 server-side validators; reject non-boolean verification responses.
* Security: Match login action exclusions exactly so noncanonical action values cannot bypass reCAPTCHA or Login Protect on WordPress login requests.
* Fix: Match equivalent IPv6 spellings in the global IP blocklist, including compressed, expanded and mixed-case forms, while keeping IPv4 and IPv6 address families distinct.
* Fix: Count in-flight Login Protect requests toward the attempt limit and preserve active blocks during concurrent authentication.
* Fix: Count failed logins within a fixed window starting at the first failure, without extending the window on subsequent failures.
* Fix: Match equivalent IPv6 addresses in the Login Protect allowlist.
* Fix: Bound Elementor Login lockout-status requests, allow retries after timeouts, and ignore late responses.
* Fix: Recover reCAPTCHA v3 admin verification after empty or invalid tokens and deferred API errors, bound server requests, and ignore late token callbacks.
* Security: Require a boolean success response and a finite numeric score from 0 to 1 for reCAPTCHA v3 verification, including when the configured threshold is zero.
* Fix: Refresh Elementor Login v3 session nonces before authentication, recognize sessions opened in another tab, and bound API loading and login requests while ignoring late responses.
* Fix: Prevent overlapping WP Login v3 token requests, bound Google API waits, handle deferred API exceptions, and preserve server-side rejection when token acquisition fails.
* Fix: Respect the Elementor Login CAPTCHA setting independently of Login Protect so disabling CAPTCHA does not block logins while attempt limiting remains active.
* Compatibility: Add reCAPTCHA v2/v3 integration for Elementor Atomic Forms, including Atomic field serialization, server-side verification before form actions, and removal of internal CAPTCHA fields from submission data.
* Reliability: Reset Atomic Forms CAPTCHA tokens after submissions and validation failures, and prevent overlapping submissions while a request is pending.
* Fix: Bound classic Elementor Forms v3 token requests, ignore late callbacks, isolate concurrent forms, and recover from API errors or browser validation failures without reusing stale tokens.
* Fix: Refresh the Elementor Login v2 session nonce before submitting credentials and reload stale login forms when another tab is already signed in.
* Reliability: Bound Elementor Login v2 session and authentication requests, recover the form after timeouts, and ignore late responses without automatically replaying credentials.
* Fix: Reset classic Elementor Forms reCAPTCHA v2 after successful submissions and submission errors so retries obtain a fresh token while preserving entered fields and other forms.
* Maintenance: Correct input-handling warnings in the Atomic Forms integration, keep essential code comments in English, and invalidate cached frontend assets when their files change.
* Maintenance: Synchronize version 1.2.3 across the plugin header, runtime constant, readme stable tag, admin fallback and translation metadata.

= 1.2.2 =

* Compatibility: Removed automatic reading, writing and synchronization of LiteSpeed Cache persistent exclusion settings.
* Compatibility: Kept only request-local no-cache signaling and targeted purging of the custom login URL; the plugin does not perform global cache, Object Cache/Redis or CSS/JS purges.
* Reliability: Deactivation and uninstall no longer modify LiteSpeed Cache configuration; persistent exclusions created by version 1.2.1 are left untouched.
* Regression safety: Kept reCAPTCHA v2/v3, IP allowlist, Login Protect and Elementor authentication/form flows unchanged from version 1.2.1.
* Fix: Kept the successful lost-password confirmation on the custom login endpoint instead of resolving the default wp-login.php redirect to a 404 route.
* Fix: Preserved complete password-reset links on the custom login endpoint, including safe URL encoding of usernames with spaces so the reset key and action are not truncated by email clients.

= 1.2.1 =

* Fix: Prevented full-page caching of the custom login endpoint so reCAPTCHA and IP allowlist decisions remain consistent with the current request.
* Compatibility: Added lifecycle-managed LiteSpeed Cache exclusions for the custom login endpoint, runtime no-cache signaling, targeted URL purging, and cleanup after slug changes, disabling masking, deactivation, or deletion.

= 1.2.0 =

* Feature: Added Google reCAPTCHA v3 with selectable v2/v3 configuration, action and score validation for wp-login.php, Elementor Login and Elementor Forms; existing installations remain configured for v2 by default.
* Feature: Added scoped frontend loading for protected Elementor widgets and forms, including dynamically inserted content and Elementor popups.
* Feature: Extended optional REST API Login Protect coverage to native WordPress Application Password authentication.
* Security: Strengthened reCAPTCHA hostname validation and fail-closed handling across protected authentication and form submission flows.
* Security: Hardened Login Protect state management, concurrent authentication handling and lockout enforcement.
* Security: Improved Advanced Login routing and request validation across multisite, subdirectory and non-standard WordPress configurations.
* Compatibility: Improved independent reCAPTCHA rendering scopes for Elementor Login and Elementor Forms and skipped forms containing native Elementor reCAPTCHA fields.
* Compatibility: Kept authentication errors, remaining attempts and active lockouts inside Elementor Login widgets and ensured configured logout redirects remain in the current browser tab.
* Reliability: Added multisite network activation support, automatic initialization for newly created sites, lifecycle cleanup and configuration recovery.
* Privacy: Added scheduled retention cleanup, privacy export and erasure integration, and expanded documentation for external services and locally stored data.
* Performance: Moved large plugin options out of autoload where supported.
* Tweak: Updated the admin interface, diagnostics and translations.

= 1.1.1 =

* Compatibility: Tested with WordPress 7.0.
* Tweak: Updated plugin metadata for WordPress 7.0 compatibility.

= 1.1.0 =

* Feature: Added IP Blocking (Site-wide) with a permanent IP blocklist and HTTP 403 responses across the site.
* UX: Separated and standardized admin status labels for permanent and temporary IP blocks.
* UX: Documented optional IP | reason note support for the reCAPTCHA allowlist and Login Protect trusted IPs.
* Security: Login Protect lockouts on wp-login.php now return HTTP 429 with a Retry-After header for active lockouts on login attempts.
* UX: Added a wp-login.php lockout countdown notice and temporary submit blocking during an active lockout.
* Fix: Improved login-screen messaging when a new lockout is triggered.
* Hardening: Reduced unnecessary request inspection by limiting wp-login.php POST attempt detection to relevant contexts.
* Recovery: Added wp-config.php kill-switch constants for Advanced login URL and IP Blocking.

= 1.0.1 =

* Feature: Added left, center and right reCAPTCHA alignment options for Elementor Login and Elementor Forms.
* Security: Improved input sanitization for FastCGI and Nginx environments.
* Performance: Disabled reCAPTCHA rendering in the Elementor editor.
* Fix: Stabilized Elementor Forms reCAPTCHA alignment in multi-column layouts with column gaps.
* UX: Simplified and unified configuration status labels in the admin settings.
* Tweak: General code hardening and stricter type handling.

= 1.0.0 =

* Initial release.

== Legal ==
reCAPTCHA is a trademark of Google LLC.
Elementor is a trademark of Elementor Ltd.
This plugin is not affiliated with, endorsed by, or sponsored by Google LLC or Elementor Ltd.
