feat(api): внешний API и API-ключи для интеграций
Отдельный префикс /api/v1 со своей авторификацией по API-ключам,
чтобы внешние системы могли забирать и менять данные, не получая
доступа к админке.
Что добавлено:
- таблица api_keys (db/init.sql, db/migration.sql, ensureApiKeysTable)
- CRUD ключей: GET/POST /api/api-keys, PUT/DELETE /:id, POST /:id/rotate
- requireApiKey: X-Api-Key или Authorization: Bearer, только для /api/v1/*
- 21 эндпоинт /api/v1: branches, groups, students, modules, entries,
lesson-reports, stats, me; списки в формате {items,total,limit,offset}
- страница управления ключами public/apikeys.html + пункт в меню
Безопасность:
- в БД только sha256(ключ) и префикс, секрет отдаётся один раз
- скоупы read/write: без write мутации дают 403
- branch_ids ключа сужают права и понижают роль до tutor
- per-key rate limit на cache.rateLimitStore, подбор ключей -> бан IP
- аудит мутаций с меткой via_api_key
- ключи не входят в бэкап и удаляются при restore
Проверено: api-keys.selftest.js (45 проверок), api.smoketest.js без
регрессий, работа без Redis через in-memory fallback.
This commit is contained in:
+3
-1
@@ -63,6 +63,7 @@ function buildSidebar(active) {
|
||||
{ page: 'modules', label: 'Темы модулей', icon: 'layers' },
|
||||
{ page: 'branches', label: 'Филиалы', icon: 'building-2' },
|
||||
{ page: 'users', label: 'Пользователи', icon: 'user-cog' },
|
||||
{ page: 'apikeys', label: 'API-ключи', icon: 'key-round' },
|
||||
{ page: 'worker', label: 'Воркер ИИ', icon: 'bot' },
|
||||
{ page: 'audit', label: 'Аудит', icon: 'scroll-text' },
|
||||
{ page: 'bans', label: 'Блокировки', icon: 'shield-off' },
|
||||
@@ -399,10 +400,11 @@ function renderIcons() {
|
||||
}
|
||||
}
|
||||
|
||||
function showToast(msg) {
|
||||
function showToast(msg, isError) {
|
||||
const t = document.getElementById('toast');
|
||||
if (!t) return;
|
||||
t.textContent = msg;
|
||||
t.classList.toggle('error', !!isError);
|
||||
t.classList.add('show');
|
||||
setTimeout(() => t.classList.remove('show'), 3000);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user