const REASONS = {
'honeypot': 'Антиспам-поле заполнено',
'login-bruteforce': 'Подбор пароля (10 неудачных входов)',
'share-password-bruteforce': 'Подбор пароля ссылки',
'manual': 'Вручную',
};
function reasonLabel(r) {
return REASONS[r] || r || '—';
}
async function loadBans() {
const tbody = document.getElementById('bansBody');
const info = document.getElementById('bansInfo');
const res = await fetch(`${API}/api/bans`, { headers: hdr() });
if (!res.ok) {
tbody.innerHTML = `
| Ошибка загрузки (${res.status}) |
`;
info.textContent = '';
return;
}
const bans = await res.json();
info.textContent = `Активных блокировок: ${bans.length}`;
if (!bans.length) {
tbody.innerHTML = '| Активных блокировок нет |
';
return;
}
tbody.innerHTML = bans.map(b => `
| ${esc(b.ip)} |
${esc(reasonLabel(b.reason))} |
${new Date(b.created_at).toLocaleString('ru')} |
${new Date(b.banned_until).toLocaleString('ru')} |
|
`).join('');
renderIcons();
}
document.getElementById('bansBody').addEventListener('click', async e => {
const ip = e.target.closest('[data-unban]')?.dataset.unban;
if (!ip) return;
const btn = e.target.closest('[data-unban]');
btn.disabled = true;
const res = await fetch(`${API}/api/bans/${encodeURIComponent(ip)}`, { method: 'DELETE', headers: hdr() });
if (res.ok) showToast('IP разблокирован: ' + ip);
else showToast('Ошибка разблокировки');
btn.disabled = false;
loadBans();
});
document.getElementById('refreshBtn').addEventListener('click', loadBans);
(async () => {
if (await requireAdminPage()) {
buildSidebar(document.body.dataset.page);
loadBans();
}
})();