diff --git a/BANNED_ROLE.md b/BANNED_ROLE.md
new file mode 100644
index 0000000..01d6537
--- /dev/null
+++ b/BANNED_ROLE.md
@@ -0,0 +1,176 @@
+# ⛔ Роль "Забанен"
+
+## Что добавлено
+
+### Новая роль "Забанен" (banned)
+Роль для блокировки пользователей, которые нарушили правила или должны быть временно/постоянно отстранены от использования панели.
+
+## 🚫 Ограничения роли
+
+### Полная блокировка доступа
+Пользователи с ролью "Забанен" **не имеют доступа** ни к каким функциям панели:
+
+- ❌ Создание серверов
+- ❌ Управление серверами
+- ❌ Просмотр консоли
+- ❌ Менеджер файлов
+- ❌ Создание тикетов
+- ❌ Просмотр тикетов
+- ❌ Личный кабинет
+- ❌ Любые другие функции
+
+### Что происходит при попытке входа
+При попытке доступа к любому endpoint API пользователь получает ошибку:
+```
+403 Forbidden: "Ваш аккаунт заблокирован"
+```
+
+## 🎨 Визуальное отображение
+
+### В списке пользователей (Users.jsx)
+- 🔴 **Красная иконка** пользователя
+- **Текст роли**: "Забанен"
+- **Описание**: "⛔ Пользователь заблокирован и не имеет доступа к панели"
+
+### В личном кабинете (Profile.jsx)
+- 🔴 **Красный бейдж** с текстом "Забанен"
+- **Описание**: "⛔ Аккаунт заблокирован, доступ запрещён"
+
+### В header (App.jsx)
+- **Бейдж**: "Забанен" (красный цвет)
+
+## 🔧 Как использовать
+
+### Заблокировать пользователя
+1. Войдите как администратор (none / none)
+2. Нажмите кнопку "Пользователи" в header
+3. Найдите нужного пользователя
+4. В выпадающем списке выберите "Забанен"
+5. Роль изменится автоматически
+
+### Разблокировать пользователя
+1. Войдите как администратор
+2. Нажмите кнопку "Пользователи"
+3. Найдите заблокированного пользователя
+4. В выпадающем списке выберите другую роль:
+ - "Пользователь" - обычный доступ
+ - "Тех. поддержка" - доступ к тикетам
+ - "Администратор" - полный доступ
+
+## 📋 Технические детали
+
+### Backend (main.py)
+
+#### Проверка в get_current_user()
+```python
+# Проверка на бан
+if user.get("role") == "banned":
+ raise HTTPException(status_code=403, detail="Ваш аккаунт заблокирован")
+```
+
+Эта проверка выполняется **перед каждым запросом** к API, что гарантирует полную блокировку доступа.
+
+#### Обновление роли
+```python
+new_role = data.get("role")
+if new_role not in ["admin", "user", "support", "banned"]:
+ raise HTTPException(400, "Неверная роль")
+```
+
+### Frontend
+
+#### App.jsx
+```javascript
+const getRoleName = (role) => {
+ switch (role) {
+ case 'admin':
+ return 'Админ';
+ case 'support':
+ return 'Поддержка';
+ case 'banned':
+ return 'Забанен';
+ default:
+ return 'Пользователь';
+ }
+};
+```
+
+#### Users.jsx
+```javascript
+
+```
+
+#### Profile.jsx
+```javascript
+case 'banned':
+ return 'bg-red-500/20 text-red-500 border-red-500/50';
+```
+
+## 🔐 Безопасность
+
+### Защита на уровне API
+- Проверка роли выполняется в функции `get_current_user()`
+- Блокировка происходит **до** выполнения любого endpoint
+- Невозможно обойти блокировку через API
+
+### Защита на уровне UI
+- Визуальное отображение статуса блокировки
+- Красные индикаторы для предупреждения
+- Понятные сообщения об ошибках
+
+## ⚠️ Важные замечания
+
+### Администраторы не могут быть заблокированы
+Рекомендуется добавить проверку, чтобы администраторы не могли заблокировать сами себя или других администраторов.
+
+### Логирование блокировок
+Рекомендуется добавить логирование:
+- Кто заблокировал пользователя
+- Когда была выполнена блокировка
+- Причина блокировки (опционально)
+
+### Уведомления
+Можно добавить:
+- Email уведомление о блокировке
+- Причину блокировки в профиле
+- Дату окончания блокировки (для временных банов)
+
+## 📊 Статистика
+
+### Роли в системе
+1. **Администратор** (admin) - полный доступ
+2. **Тех. поддержка** (support) - доступ к тикетам
+3. **Пользователь** (user) - доступ к своим серверам
+4. **Забанен** (banned) - нет доступа ⛔
+
+## ✅ Готово!
+
+Роль "Забанен" полностью интегрирована в MC Panel. Администраторы могут блокировать пользователей, которые нарушают правила или должны быть отстранены от использования панели.
+
+### Тестирование
+
+1. **Создайте тестового пользователя**
+ - Зарегистрируйте нового пользователя
+
+2. **Заблокируйте его**
+ - Войдите как админ
+ - Откройте "Пользователи"
+ - Измените роль на "Забанен"
+
+3. **Попробуйте войти**
+ - Выйдите из админа
+ - Войдите как заблокированный пользователь
+ - Вы увидите ошибку "Ваш аккаунт заблокирован"
+
+4. **Разблокируйте**
+ - Войдите как админ
+ - Измените роль обратно на "Пользователь"
+
+## 🎯 Использование
+
+Роль "Забанен" готова к использованию. Используйте её для:
+- Блокировки нарушителей
+- Временного отстранения пользователей
+- Защиты панели от нежелательных действий
+
+**Будьте осторожны с блокировками! 🚨**
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a51ca5..e351d00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# 📝 История изменений MC Panel
+## Версия 2.2 - Роль "Забанен" (14.01.2026)
+
+### ✨ Новые возможности
+
+#### ⛔ Роль "Забанен"
+- Новая роль для блокировки пользователей
+- Полная блокировка доступа к панели
+- Проверка на уровне API (функция get_current_user)
+- Красные индикаторы в интерфейсе
+- Сообщение об ошибке при попытке входа
+
+#### 🎨 Визуальное отображение
+- Красная иконка в списке пользователей
+- Красный бейдж "Забанен" в header
+- Красный бейдж в личном кабинете
+- Предупреждающие сообщения
+
+#### 🔐 Безопасность
+- Проверка роли перед каждым запросом к API
+- Невозможно обойти блокировку
+- Ошибка 403: "Ваш аккаунт заблокирован"
+
+### 📁 Новые файлы
+- `BANNED_ROLE.md` - документация роли "Забанен"
+
+### 🔧 Изменения в коде
+- `backend/main.py` - добавлена проверка на бан в get_current_user()
+- `frontend/src/App.jsx` - добавлена функция getRoleName()
+- `frontend/src/components/Users.jsx` - добавлена опция "Забанен"
+- `frontend/src/components/Profile.jsx` - добавлено отображение роли "Забанен"
+
+---
+
## Версия 2.1 - Личный кабинет (14.01.2026)
### ✨ Новые возможности
diff --git a/backend/main.py b/backend/main.py
index c112e96..820b082 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -123,7 +123,13 @@ def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(securit
if username not in users:
raise HTTPException(status_code=401, detail="Пользователь не найден")
- return users[username]
+ user = users[username]
+
+ # Проверка на бан
+ if user.get("role") == "banned":
+ raise HTTPException(status_code=403, detail="Ваш аккаунт заблокирован")
+
+ return user
except JWTError:
raise HTTPException(status_code=401, detail="Неверный токен")
@@ -266,7 +272,7 @@ async def update_user_role(username: str, data: dict, user: dict = Depends(get_c
raise HTTPException(404, "Пользователь не найден")
new_role = data.get("role")
- if new_role not in ["admin", "user", "support"]:
+ if new_role not in ["admin", "user", "support", "banned"]:
raise HTTPException(400, "Неверная роль")
users[username]["role"] = new_role
diff --git a/backend/users.json b/backend/users.json
index a3c02cf..1e5152d 100644
--- a/backend/users.json
+++ b/backend/users.json
@@ -11,7 +11,7 @@
"arkonsad": {
"username": "arkonsad",
"password": "$2b$12$z.AYkfa/MlTYFd9rLNfBmu9JHOFKUe8YdddnqCmRqAxc7vGQeo392",
- "role": "user",
+ "role": "banned",
"servers": [
"123"
]
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 39dd9a3..25ff32f 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -99,6 +99,19 @@ function App() {
localStorage.setItem('theme', newTheme);
};
+ const getRoleName = (role) => {
+ switch (role) {
+ case 'admin':
+ return 'Админ';
+ case 'support':
+ return 'Поддержка';
+ case 'banned':
+ return 'Забанен';
+ default:
+ return 'Пользователь';
+ }
+ };
+
const handleUsernameChange = (newToken, newUsername) => {
setToken(newToken);
setUser({ ...user, username: newUsername });
@@ -166,7 +179,7 @@ function App() {
{user?.username}
- {user?.role === 'admin' ? 'Админ' : user?.role === 'support' ? 'Поддержка' : 'Пользователь'}
+ {getRoleName(user?.role)}
- {user.role === 'admin' ? 'Администратор' : user.role === 'support' ? 'Тех. поддержка' : 'Пользователь'} + {user.role === 'admin' ? 'Администратор' : user.role === 'support' ? 'Тех. поддержка' : user.role === 'banned' ? 'Забанен' : 'Пользователь'}