feat(admin): журнал событий безопасности (Tier 1-2) + аудит чувствительных действий (Tier 3)
- security_events (миграция 047) + utils/securityLog.js (defensive, lazy stmt) - Tier 1: login.success/fail, register, password.change в authController - Tier 2: 403 (роль/разрешение) в middleware/auth, rate_limited в rateLimit - Tier 3: audit() на выдачу доступа (access), начисление/сброс XP (gam), модерацию аватаров - API GET/DELETE /api/admin/security-log (фильтр по категории + поиск, прунинг по дням) - Frontend: вкладка «Безопасность» в admin.html + loadSecurityLog, расширены ACTION_LABELS Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
-- 047_security_events.sql
|
||||
-- Журнал событий безопасности и входа (Tier 1 + Tier 2 плана логирования).
|
||||
--
|
||||
-- Отдельная таблица, НЕ admin_audit_log, потому что:
|
||||
-- • автор часто аноним (у неудачного логина ещё нет user_id);
|
||||
-- • объём может быть большим (боты долбят логин / rate-limit);
|
||||
-- • свой ретеншн (чистится агрессивнее, чем осознанные админ-действия).
|
||||
-- admin_audit_log остаётся домом для привилегированных действий (Tier 3).
|
||||
--
|
||||
-- category:
|
||||
-- auth — login.success | login.fail | register | password.change
|
||||
-- access_denied — forbidden (роль) | perm_denied (разрешение)
|
||||
-- rate_limit — rate_limited (превышение лимита запросов)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS security_events (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
category TEXT NOT NULL CHECK (category IN ('auth','access_denied','rate_limit')),
|
||||
event TEXT NOT NULL,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
||||
email TEXT, -- email из попытки/связанный (для анонимных)
|
||||
ip TEXT,
|
||||
user_agent TEXT,
|
||||
method TEXT,
|
||||
route TEXT,
|
||||
detail TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_sec_events_date ON security_events (created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_sec_events_category ON security_events (category, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_sec_events_email ON security_events (email);
|
||||
CREATE INDEX IF NOT EXISTS idx_sec_events_ip ON security_events (ip);
|
||||
CREATE INDEX IF NOT EXISTS idx_sec_events_user ON security_events (user_id);
|
||||
Reference in New Issue
Block a user