feat: add Central API clients, bot rate limiting, and admin API UI
- Add ITK_HP_API and ITK_Bot_API static classes with queue/flush/cron - Add WP-Cron (5 min) + shutdown flush for both API queues - Bot Blocker and Honeypot now queue events to their respective APIs - Admin: Bot Blocker tab gains Central Bot API settings panel (enable, URL, token, test connection, flush queue, historical sync) - Admin: Honeypot tab gains Central Honeypot API settings panel - Admin JS: AJAX handlers for Test Connection and Flush Now buttons - Admin CSS: API card styles (status badge, notices, footer controls) - Add .gitignore (excludes bot-api/ which lives in CloudHost/bot-api) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -308,3 +308,60 @@ input:checked + .itk-slider:before { transform: translateX(20px); }
|
||||
.itk-toggle-saving { opacity: .6; pointer-events: none; }
|
||||
.itk-toggle-saved { color: #00a32a; font-size: 11px; }
|
||||
.itk-toggle-error { color: #b32d2e; font-size: 11px; }
|
||||
|
||||
/* ── Central API card ─────────────────────────────────────── */
|
||||
.itk-api-card { grid-column: 1 / -1; }
|
||||
.itk-api-desc { margin: -8px 0 14px; color: #646970; }
|
||||
|
||||
.itk-api-status-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 14px;
|
||||
padding: 8px 12px;
|
||||
background: #f6f7f7;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.itk-api-badge {
|
||||
display: inline-block;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.itk-api-ok { background: #d7f7e0; color: #1a7a3a; border: 1px solid #9de0b4; }
|
||||
.itk-api-err { background: #ffecec; color: #b32d2e; border: 1px solid #f7c5c5; }
|
||||
.itk-api-unknown { background: #f0f0f1; color: #646970; border: 1px solid #c3c4c7; }
|
||||
.itk-api-time { font-size: 11px; color: #646970; }
|
||||
.itk-api-err-msg { font-size: 11px; color: #b32d2e; font-style: italic; }
|
||||
|
||||
.itk-api-notice {
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.itk-api-notice-ok { background: #d7f7e0; border: 1px solid #9de0b4; color: #1a7a3a; }
|
||||
.itk-api-notice-err { background: #ffecec; border: 1px solid #f7c5c5; color: #b32d2e; }
|
||||
|
||||
.itk-api-table { margin-top: 0 !important; }
|
||||
.itk-api-table th { width: 130px; }
|
||||
|
||||
.itk-api-form-actions { margin-top: 4px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
|
||||
|
||||
.itk-api-footer {
|
||||
margin-top: 16px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px 30px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.itk-api-queue-row,
|
||||
.itk-api-history-row { font-size: 13px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
|
||||
.itk-api-rem { color: #646970; font-size: 12px; }
|
||||
|
||||
@@ -43,6 +43,64 @@
|
||||
setTimeout(function () { $fb.fadeOut(400, function () { $(this).remove(); }); }, 2000);
|
||||
}
|
||||
|
||||
/* ── 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');
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Config file editor (AJAX) ────────────────────────────── */
|
||||
$('#itk-save-config').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user