Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions admin/partials/settings-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,17 @@
<h2><?php esc_html_e('Blocking Settings', 'webdecoy'); ?></h2>

<table class="form-table">
<tr>
<th scope="row">
<label for="webdecoy_ip_allowlist"><?php esc_html_e('IP Allowlist', 'webdecoy'); ?></label>
</th>
<td>
<textarea id="webdecoy_ip_allowlist" name="webdecoy_options[ip_allowlist]"
rows="3" class="large-text code"
placeholder="203.0.113.10&#10;198.51.100.0/24"><?php echo esc_textarea(is_array($options['ip_allowlist'] ?? '') ? implode("\n", $options['ip_allowlist']) : ($options['ip_allowlist'] ?? '')); ?></textarea>
<p class="description"><?php esc_html_e('IPs or CIDR ranges that bypass all detection and blocking (e.g. your office, an uptime monitor). One per line. Invalid entries are discarded on save.', 'webdecoy'); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="webdecoy_block_action"><?php esc_html_e('Block Action', 'webdecoy'); ?></label>
Expand Down
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
*** WebDecoy Bot Detection Changelog ***

= 2.2.0 - Unreleased =
* Added: IP allowlist — IPs or CIDR ranges that bypass all detection and blocking (Settings → Blocking). Previously the check existed internally but had no way to configure it.
* Changed: Consolidated onto a single detector path (SDK detector + WordPress-signal wrapper) across front-end, forms, and WooCommerce; removed the unused legacy forms class and a dead scheduled task. No behavior change to detection.
* Added: Filter rules — write expression-based rules (e.g. `ip.tor or ip.abuse_score > 50`, `ip.country in ["CN","RU"] and req.path matches "^/wp-login"`) evaluated before scoring; block or throttle, with dry-run. New Settings → Rules tab with a rule builder and parse-on-save validation. Expression language is byte-for-byte compatible with @webdecoy/node.
* Added: IP enrichment — VPN/proxy/Tor, geo, ASN, and abuse-score data (WebDecoy Cloud) powering the ip.* filter-rule fields, cached 1 hour, fetched only when a rule needs it, fail-open.
* Improved: Rate limiting now runs as a rule in the engine — over-limit requests get a proper 429 with Retry-After and X-RateLimit-* headers (previously it only nudged the bot score). Adds a sliding-window algorithm (exact via a persistent object cache, falling back to the fixed-window database counter), per-IP / per-IP+route / per-user keying, and dry-run.
Expand Down
11 changes: 6 additions & 5 deletions includes/class-webdecoy-activator.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,16 @@ private static function schedule_cleanup(): void
wp_schedule_event(time(), 'hourly', 'webdecoy_cleanup_expired');
}

// Schedule blocked IP sync (every 15 minutes)
if (!wp_next_scheduled('webdecoy_sync_blocked_ips')) {
wp_schedule_event(time(), 'fifteen_minutes', 'webdecoy_sync_blocked_ips');
}

// Safety-net drain of the violation-report spool (every 15 minutes).
// The primary delivery path is the per-request shutdown flush; this
// catches anything left behind after an ingest outage.
if (!wp_next_scheduled('webdecoy_flush_violations')) {
wp_schedule_event(time(), 'fifteen_minutes', 'webdecoy_flush_violations');
}

// Note: webdecoy_sync_blocked_ips is intentionally NOT scheduled — it
// never had a handler. Any leftover schedule from an older install is
// cleared in activate()/deactivate().
}

/**
Expand All @@ -230,6 +229,8 @@ public static function maybe_upgrade(): void
if (version_compare($current_version, self::DB_VERSION, '<')) {
self::create_tables();
update_option('webdecoy_db_version', self::DB_VERSION);
// Clear the dead sync-blocked-ips schedule left by older installs.
wp_clear_scheduled_hook('webdecoy_sync_blocked_ips');
}
}

Expand Down
Loading
Loading