From e375743a3f06719e66c2f7296eefc26fe46b00a0 Mon Sep 17 00:00:00 2001 From: Chris Portscheller Date: Mon, 17 Aug 2026 19:24:13 -0500 Subject: [PATCH] fix(connect): premium flips on at connect time; upsell links reach the connect tab (#71 #72) + 2.4.1 store_cloud_credentials() now marks the API status active instead of only clearing the cache: its only caller is the connect flow, right after a successful token exchange, so the key is known-good and is_premium() should not wait for a lazy revalidation while the user is watching their freshly connected site do nothing. Dashboard widget deep link used a #tab-cloud hash the settings page ignores (it only reads ?tab=cloud); the Statistics upsell sent people off-site to /pricing instead of the in-admin connect CTA. --- admin/partials/dashboard-widget.php | 2 +- admin/partials/statistics-page.php | 4 ++-- changelog.txt | 5 +++++ readme.txt | 7 ++++++- webdecoy.php | 16 ++++++++++++---- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/admin/partials/dashboard-widget.php b/admin/partials/dashboard-widget.php index b9d4b3a..fc463ff 100644 --- a/admin/partials/dashboard-widget.php +++ b/admin/partials/dashboard-widget.php @@ -75,7 +75,7 @@

- +

diff --git a/admin/partials/statistics-page.php b/admin/partials/statistics-page.php index bb062fe..1d16ace 100644 --- a/admin/partials/statistics-page.php +++ b/admin/partials/statistics-page.php @@ -246,8 +246,8 @@

- - + +
diff --git a/changelog.txt b/changelog.txt index 6de81fc..8dee742 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,10 @@ *** WebDecoy Bot Detection Changelog *** += 2.4.1 - 2026-08-17 = +* Fixed: cloud features switch on immediately after one-click connect. The connection itself succeeded, but the premium status stayed off until a later background revalidation, so the JS verification token and cloud reporting were silently inactive at the exact moment you had just connected. +* Fixed: the dashboard widget's "Learn more" link landed on the Protection tab instead of the WebDecoy Cloud tab. +* Changed: the Statistics page upsell now opens the in-admin Cloud connect tab instead of leaving your site for the pricing page. + = 2.4.0 - 2026-07-30 = * Added: filter rules can read the WebDecoy edge validator's verdict through new edge.* fields — edge.class, edge.clearance, edge.present, plus the shorthands edge.verified / edge.crawler / edge.script / edge.browser. edge.class is one of: verified (an identity Cloudflare attested, such as Googlebot — never degrade these), crawler (says it is a crawler, unproven), script (an HTTP client library, not a browser), or browser (nothing non-human fired). Matching this was already possible as req.header("x-wd-class") because the plugin forwards every request header into the rule context, but nothing told you the header existed or what its values meant, so nobody used it. The Rules screen now lists the fields and explains them. Absence is deliberately not a class: if the validator is not in front of a request, edge.present is false and every edge.* condition is false, which means "no information" rather than "human" — a rule using these decides whether to serve someone less, so guessing would be the wrong default. A value we do not recognise is ignored rather than passed through. Safe to use for blocking, throttling, logging and metering; not safe for serving different page content on a cacheable URL, because Cloudflare's cache key ignores this header outside Enterprise plans, so the first cached version would be served to everyone including Googlebot — the Rules screen says so too. diff --git a/readme.txt b/readme.txt index 1067adf..7c6fff5 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Donate link: https://webdecoy.com Tags: bot detection, security, spam protection, woocommerce, ai bots Requires at least: 6.1 Tested up to: 7.0 -Stable tag: 2.4.0 +Stable tag: 2.4.1 Requires PHP: 7.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html @@ -222,6 +222,11 @@ The bundled good-bot list (sdk/src/GoodBotList.php) stores a documentation URL f == Changelog == += 2.4.1 = +* Fixed: cloud features switch on immediately after one-click connect. The connection itself succeeded, but the premium status stayed off until a later background revalidation, so the JS verification token and cloud reporting were silently inactive at the exact moment you had just connected. +* Fixed: the dashboard widget's "Learn more" link landed on the Protection tab instead of the WebDecoy Cloud tab. +* Changed: the Statistics page upsell now opens the in-admin Cloud connect tab instead of leaving your site for the pricing page. + = 2.4.0 = * Added: filter rules can read what the WebDecoy edge validator concluded about a request, using new edge.* fields: edge.class, edge.clearance, edge.present, and the shorthands edge.verified / edge.crawler / edge.script / edge.browser. edge.class is one of: verified (an identity Cloudflare attested, such as Googlebot, never degrade these), crawler (says it is a crawler, unproven), script (an HTTP client library, not a browser), or browser (nothing non-human fired). This was always matchable as req.header("x-wd-class"), but nothing said so; the Rules screen now documents the fields and what each value means. If the validator is not in front of a request, edge.present is false and every edge.* condition is false. That means "no information", not "human". Safe for blocking, throttling, logging and metering; the Rules screen also explains why you should not use it to serve different page content on a cacheable URL. diff --git a/webdecoy.php b/webdecoy.php index 474c956..dbceb0c 100644 --- a/webdecoy.php +++ b/webdecoy.php @@ -3,7 +3,7 @@ * Plugin Name: WebDecoy Bot Detection * Plugin URI: https://webdecoy.com/wordpress * Description: Protect your WordPress site from bots, spam, and carding attacks with WebDecoy's advanced threat detection. - * Version: 2.4.0 + * Version: 2.4.1 * Requires at least: 6.1 * Requires PHP: 7.4 * Author: WebDecoy @@ -41,7 +41,7 @@ function str_starts_with(string $haystack, string $needle): bool } // Plugin constants -define('WEBDECOY_VERSION', '2.4.0'); +define('WEBDECOY_VERSION', '2.4.1'); define('WEBDECOY_PLUGIN_FILE', __FILE__); define('WEBDECOY_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('WEBDECOY_PLUGIN_URL', plugin_dir_url(__FILE__)); @@ -3300,8 +3300,16 @@ public function store_cloud_credentials(string $api_key, string $site_key, strin $this->options['api_key'] = $this->is_encrypted($api_key) ? $this->decrypt_value($api_key) : $api_key; } - // Force a fresh API status check on next use now that creds changed. - $this->clear_api_status_cache(); + // The only caller is the connect flow, which reaches here immediately + // after a successful token exchange against the API — the key is + // known-good right now. Mark the status active instead of merely + // clearing the cache: with only a clear, is_premium() stays false + // until something happens to trigger a revalidation, which keeps the + // JS verification token and violation reporting off at the exact + // moment the user just connected and is watching. (update_options_raw + // above already fired the option hook that clears the cache, so this + // set is what survives.) + $this->set_api_status_cache('active'); } /**