feat: initial InformatiQ Toolkit plugin
Merges informatiq-wp-secure + informatiq-utils + HoneypotFields into
a single unified plugin with the following improvements:
- Fixed deactivation bug: all protection methods now guard themselves
with their own option check so toggling off via AJAX takes effect
immediately without any hook re-registration.
- Added rate-limiting for good/legitimate bots (Googlebot, Bingbot,
DuckDuckBot, Yandex, etc.) via transient sliding-window counters;
configurable per-bot limits in goodbots.conf (BotName|req/min);
returns HTTP 429 with Retry-After: 60 when over limit.
- Unified MySQL-backed logging (itk_bot_log + itk_honeypot_log tables)
replaces the old wp_options-based 100-entry cap.
- New Dashboard tab with terminal-style bot activity monitor: total
blocked, today's count, rate-limited hits, top threat sources
(bar chart), top IPs, top honeypot form types, active-module
status panel.
- All optimizations from utils.php merged into Optimization tab as
toggleable settings (was always-on before).
- Single admin page (Settings → InformatiQ Toolkit) with 8 tabs:
Dashboard | Bot Blocker | Protection | Optimization | Honeypot |
Bot Logs | Honeypot Logs | Config Files.
- Config file editor for badbots.conf, goodbots.conf, referrers.conf,
networks.conf, allowed-ips.conf with AJAX save and transient flush.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 11:45:26 +02:00
|
|
|
|
/* InformatiQ Toolkit – Admin JS */
|
|
|
|
|
|
(function ($) {
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
/* ── Toggle switches (AJAX) ───────────────────────────────── */
|
|
|
|
|
|
$(document).on('change', '.itk-toggle-input', function () {
|
|
|
|
|
|
var $input = $(this);
|
|
|
|
|
|
var $row = $input.closest('.itk-toggle-row');
|
|
|
|
|
|
var option = $input.data('option');
|
|
|
|
|
|
var setting = $input.data('setting');
|
|
|
|
|
|
var value = $input.is(':checked') ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
|
|
$row.addClass('itk-toggle-saving');
|
|
|
|
|
|
|
|
|
|
|
|
$.post(itkAdmin.ajaxUrl, {
|
|
|
|
|
|
action: 'itk_save_setting',
|
|
|
|
|
|
nonce: itkAdmin.nonce,
|
|
|
|
|
|
option: option,
|
|
|
|
|
|
setting: setting,
|
|
|
|
|
|
value: value
|
|
|
|
|
|
})
|
|
|
|
|
|
.done(function (res) {
|
|
|
|
|
|
if (res.success) {
|
|
|
|
|
|
showFeedback($row, 'itk-toggle-saved', 'Saved');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$input.prop('checked', !$input.is(':checked')); // revert
|
|
|
|
|
|
showFeedback($row, 'itk-toggle-error', 'Error saving');
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.fail(function () {
|
|
|
|
|
|
$input.prop('checked', !$input.is(':checked'));
|
|
|
|
|
|
showFeedback($row, 'itk-toggle-error', 'Request failed');
|
|
|
|
|
|
})
|
|
|
|
|
|
.always(function () {
|
|
|
|
|
|
$row.removeClass('itk-toggle-saving');
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function showFeedback($row, cls, msg) {
|
|
|
|
|
|
$row.find('.itk-feedback').remove();
|
|
|
|
|
|
var $fb = $('<span class="itk-feedback ' + cls + '">' + msg + '</span>');
|
|
|
|
|
|
$row.append($fb);
|
|
|
|
|
|
setTimeout(function () { $fb.fadeOut(400, function () { $(this).remove(); }); }, 2000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-09 18:32:27 +02:00
|
|
|
|
/* ── API: Test connection ─────────────────────────────────── */
|
|
|
|
|
|
$(document).on('click', '.itk-btn-test-api', function () {
|
|
|
|
|
|
var $btn = $(this);
|
|
|
|
|
|
var api = $btn.data('api');
|
|
|
|
|
|
var $result = $btn.closest('form').find('.itk-api-ajax-result');
|
|
|
|
|
|
|
|
|
|
|
|
$btn.prop('disabled', true).text('Testing…');
|
|
|
|
|
|
$result.hide();
|
|
|
|
|
|
|
|
|
|
|
|
$.post(itkAdmin.ajaxUrl, {
|
|
|
|
|
|
action: 'itk_test_api',
|
|
|
|
|
|
nonce: itkAdmin.nonce,
|
|
|
|
|
|
api: api
|
|
|
|
|
|
})
|
|
|
|
|
|
.done(function (res) {
|
|
|
|
|
|
var ok = res && res.ok;
|
|
|
|
|
|
var msg = (res && res.message) ? res.message : (ok ? 'Connected.' : 'Test failed.');
|
|
|
|
|
|
$result.text(msg).css('color', ok ? '#00a32a' : '#b32d2e').show();
|
|
|
|
|
|
setTimeout(function () { $result.fadeOut(); }, 5000);
|
|
|
|
|
|
})
|
|
|
|
|
|
.fail(function () {
|
|
|
|
|
|
$result.text('Request failed.').css('color', '#b32d2e').show();
|
|
|
|
|
|
setTimeout(function () { $result.fadeOut(); }, 4000);
|
|
|
|
|
|
})
|
|
|
|
|
|
.always(function () {
|
|
|
|
|
|
$btn.prop('disabled', false).text('Test Connection');
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/* ── API: Flush queue ─────────────────────────────────────── */
|
|
|
|
|
|
$(document).on('click', '.itk-btn-flush-api', function () {
|
|
|
|
|
|
var $btn = $(this);
|
|
|
|
|
|
var api = $btn.data('api');
|
|
|
|
|
|
var $result = $btn.siblings('.itk-api-flush-result');
|
|
|
|
|
|
|
|
|
|
|
|
$btn.prop('disabled', true).text('Flushing…');
|
|
|
|
|
|
$result.hide();
|
|
|
|
|
|
|
|
|
|
|
|
$.post(itkAdmin.ajaxUrl, {
|
|
|
|
|
|
action: 'itk_flush_api_queue',
|
|
|
|
|
|
nonce: itkAdmin.nonce,
|
|
|
|
|
|
api: api
|
|
|
|
|
|
})
|
|
|
|
|
|
.done(function (res) {
|
|
|
|
|
|
var ok = res && res.success;
|
|
|
|
|
|
var msg = ok ? 'Queue flushed.' : 'Flush failed.';
|
|
|
|
|
|
$result.text(msg).css('color', ok ? '#00a32a' : '#b32d2e').show();
|
|
|
|
|
|
setTimeout(function () { $result.fadeOut(); }, 3000);
|
|
|
|
|
|
})
|
|
|
|
|
|
.fail(function () {
|
|
|
|
|
|
$result.text('Request failed.').css('color', '#b32d2e').show();
|
|
|
|
|
|
setTimeout(function () { $result.fadeOut(); }, 3000);
|
|
|
|
|
|
})
|
|
|
|
|
|
.always(function () {
|
|
|
|
|
|
$btn.prop('disabled', false).text('Flush Now');
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
feat: initial InformatiQ Toolkit plugin
Merges informatiq-wp-secure + informatiq-utils + HoneypotFields into
a single unified plugin with the following improvements:
- Fixed deactivation bug: all protection methods now guard themselves
with their own option check so toggling off via AJAX takes effect
immediately without any hook re-registration.
- Added rate-limiting for good/legitimate bots (Googlebot, Bingbot,
DuckDuckBot, Yandex, etc.) via transient sliding-window counters;
configurable per-bot limits in goodbots.conf (BotName|req/min);
returns HTTP 429 with Retry-After: 60 when over limit.
- Unified MySQL-backed logging (itk_bot_log + itk_honeypot_log tables)
replaces the old wp_options-based 100-entry cap.
- New Dashboard tab with terminal-style bot activity monitor: total
blocked, today's count, rate-limited hits, top threat sources
(bar chart), top IPs, top honeypot form types, active-module
status panel.
- All optimizations from utils.php merged into Optimization tab as
toggleable settings (was always-on before).
- Single admin page (Settings → InformatiQ Toolkit) with 8 tabs:
Dashboard | Bot Blocker | Protection | Optimization | Honeypot |
Bot Logs | Honeypot Logs | Config Files.
- Config file editor for badbots.conf, goodbots.conf, referrers.conf,
networks.conf, allowed-ips.conf with AJAX save and transient flush.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 11:45:26 +02:00
|
|
|
|
/* ── Config file editor (AJAX) ────────────────────────────── */
|
|
|
|
|
|
$('#itk-save-config').on('click', function (e) {
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
var $btn = $(this);
|
|
|
|
|
|
var file = $btn.data('file');
|
|
|
|
|
|
var content = $('#itk-config-content').val();
|
|
|
|
|
|
var $status = $('#itk-config-status');
|
|
|
|
|
|
|
|
|
|
|
|
$btn.prop('disabled', true).text('Saving…');
|
|
|
|
|
|
$status.hide();
|
|
|
|
|
|
|
|
|
|
|
|
$.post(itkAdmin.ajaxUrl, {
|
|
|
|
|
|
action: 'itk_save_config_file',
|
|
|
|
|
|
nonce: itkAdmin.nonce,
|
|
|
|
|
|
file: file,
|
|
|
|
|
|
content: content
|
|
|
|
|
|
})
|
|
|
|
|
|
.done(function (res) {
|
|
|
|
|
|
if (res.success) {
|
|
|
|
|
|
$status.text('Saved!').css('color', '#00a32a').show();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$status.text('Error: ' + (res.data || 'unknown')).css('color', '#b32d2e').show();
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.fail(function () {
|
|
|
|
|
|
$status.text('Request failed.').css('color', '#b32d2e').show();
|
|
|
|
|
|
})
|
|
|
|
|
|
.always(function () {
|
|
|
|
|
|
$btn.prop('disabled', false).text('Save File');
|
|
|
|
|
|
setTimeout(function () { $status.fadeOut(); }, 3000);
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
})(jQuery);
|