Files
sfera-new/2025-09-19/CABINET_SECTIONS_SECURITY_ANALYSIS.md
Veronika Smirnova fe24b73634 fix: исправить критические ошибки системы партнерских заявок
КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ:
- Исправлено отображение входящих заявок (неправильное извлечение данных)
- Устранен ApolloError при принятии заявок (неправильная структура мутаций)
- Исправлено отображение контрагентов после принятия заявки
- Обновлены типы возврата GraphQL мутаций для соответствия резолверам

UI/UX УЛУЧШЕНИЯ:
- Обновлены все компоненты на темную glass-morphism тему
- Компактные карточки контрагентов (удалена избыточная информация)
- Удален дублирующий блок поиска новых партнеров

ЗАТРОНУТЫЕ ФАЙЛЫ:
- useCounterpartyData.ts: исправлено извлечение данных
- useCounterpartyActions.ts: исправлены структуры мутаций
- IncomingRequestsBlock.tsx: темная тема + исправления UI
- OutgoingRequestsBlock.tsx: темная тема
- CounterpartiesListBlock.tsx: компактные карточки + темная тема
- typedefs.ts: исправлены типы возврата мутаций

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-19 23:23:03 +03:00

259 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🔍 АНАЛИЗ БЕЗОПАСНОСТИ РАЗДЕЛОВ С ОДИНАКОВЫМИ НАЗВАНИЯМИ В КАБИНЕТАХ
> **Дата:** 2025-09-19
> **Контекст:** 4 типа кабинетов (SELLER, FULFILLMENT, WHOLESALE, LOGIST) с одинаковыми названиями разделов
---
## 🚨 КЛЮЧЕВЫЕ ПРОБЛЕМЫ
### 1. ДУБЛИРОВАНИЕ МАРШРУТОВ БЕЗ ЗАЩИТЫ
**Текущая структура:**
```
ГЛОБАЛЬНЫЕ (БЕЗ ЗАЩИТЫ) КАБИНЕТНЫЕ (С ЗАЩИТОЙ)
/economics/ → /seller/economics/
/partners/ → /fulfillment/partners/
/messenger/ → /wholesale/messenger/
/market/ → /logistics/market/
```
**Проблема:** Глобальные маршруты доступны ВСЕМ авторизованным пользователям независимо от их роли.
### 2. WRAPPER-КОМПОНЕНТЫ С ДИНАМИЧЕСКИМ РЕНДЕРИНГОМ
**Пример: EconomicsPageWrapper**
```typescript
export function EconomicsPageWrapper() {
const { user } = useAuthContext()
// Роутинг по типу организации
switch (user.organization.type) {
case 'SELLER': return <SellerEconomicsPage />
case 'FULFILLMENT': return <FulfillmentEconomicsPage />
case 'WHOLESALE': return <WholesaleEconomicsPage />
case 'LOGIST': return <LogistEconomicsPage />
}
}
```
**Риски:**
- ❌ Пользователь может получить доступ к чужим компонентам через глобальный маршрут `/economics/`
- ❌ Нет проверки прав доступа на уровне маршрута
- ❌ Логика безопасности размазана между маршрутами и компонентами
### 3. ОБЩИЕ КОМПОНЕНТЫ ДЛЯ ВСЕХ РОЛЕЙ
**Примеры проблемных компонентов:**
- `PartnersDashboard` - используется всеми ролями без дифференциации
- `MessengerDashboard` - единый компонент для всех типов организаций
- `MarketDashboard` - общий маркет для всех
**Что происходит внутри:**
```typescript
// MessengerDashboard использует GET_MY_COUNTERPARTIES
const counterparties = counterpartiesData?.myCounterparties || []
```
**Проблема:** Один компонент пытается обслужить разные бизнес-логики для разных типов организаций.
### 4. ИЗОЛЯЦИЯ ДАННЫХ НА УРОВНЕ API
**Хорошо:** API возвращает только `myCounterparties` - контрагентов текущей организации
**Плохо:** Но доступ к компонентам не ограничен по ролям на уровне UI
---
## ⚠️ КОНКРЕТНЫЕ РИСКИ
### СЦЕНАРИЙ АТАКИ 1: Обход защиты через глобальные маршруты
```
1. Пользователь SELLER авторизован
2. Заходит на /economics/ (вместо /seller/economics/)
3. EconomicsPageWrapper показывает SellerEconomicsPage
4. Но через манипуляции может получить доступ к данным других ролей
```
### СЦЕНАРИЙ АТАКИ 2: Доступ к функционалу других ролей
```
1. Логист заходит на /partners/
2. Видит PartnersDashboard со своими данными
3. Но интерфейс может содержать функции для других ролей
4. Потенциальная утечка бизнес-логики
```
### СЦЕНАРИЙ АТАКИ 3: Путаница в данных
```
1. Пользователь с несколькими ролями (если такое возможно)
2. Заходит на глобальный маршрут
3. Непредсказуемое поведение wrapper-компонентов
4. Отображение некорректных данных
```
---
## ✅ ПРАВИЛЬНОЕ РЕШЕНИЕ
### ВАРИАНТ 1: УДАЛИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ
**Преимущества:**
- ✅ Невозможно обойти защиту
- ✅ Четкая изоляция кабинетов
- ✅ Простота понимания структуры
**Недостатки:**
- ❌ Нужно обновить все ссылки в приложении
- ❌ Может сломать закладки пользователей
### ВАРИАНТ 2: ЗАЩИТИТЬ ГЛОБАЛЬНЫЕ МАРШРУТЫ
```typescript
// /app/economics/page.tsx
export default function EconomicsPage() {
const { user } = useAuthContext()
// Автоматический редирект на правильный кабинет
if (user?.organization?.type) {
redirect(`/${user.organization.type.toLowerCase()}/economics/`)
}
return <div>Загрузка...</div>
}
```
**Преимущества:**
- ✅ Обратная совместимость
- ✅ Автоматическая навигация
- ✅ Защита от неавторизованного доступа
### ВАРИАНТ 3: РОЛЬ-СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ
Вместо общих компонентов создать специфичные для каждой роли:
```
PartnersDashboard → SellerPartnersDashboard
→ FulfillmentPartnersDashboard
→ WholesalePartnersDashboard
→ LogistPartnersDashboard
```
**Преимущества:**
- ✅ Четкая бизнес-логика для каждой роли
- ✅ Невозможно показать чужой функционал
- ✅ Легче тестировать и поддерживать
---
## 🛡️ РЕКОМЕНДУЕМАЯ АРХИТЕКТУРА
### 1. СТРУКТУРА МАРШРУТОВ
```
/seller/
├── home/ (✅ protected with useRoleGuard)
├── economics/ (✅ protected with useRoleGuard)
├── partners/ (✅ protected with useRoleGuard)
└── messenger/ (✅ protected with useRoleGuard)
/fulfillment/
├── home/ (✅ protected with useRoleGuard)
├── economics/ (✅ protected with useRoleGuard)
├── partners/ (✅ protected with useRoleGuard)
└── messenger/ (✅ protected with useRoleGuard)
❌ УДАЛИТЬ ИЛИ ЗАЩИТИТЬ:
/economics/
/partners/
/messenger/
/market/
```
### 2. ЗАЩИТА НА УРОВНЕ LAYOUT
```typescript
// /app/seller/layout.tsx
export default function SellerLayout({ children }) {
useRoleGuard('SELLER') // Защита всего кабинета
return (
<AuthGuard>
{children}
</AuthGuard>
)
}
```
### 3. СПЕЦИФИЧНЫЕ КОМПОНЕНТЫ
```typescript
// Вместо общего PartnersDashboard
export function SellerPartnersDashboard() {
// Логика только для селлеров
}
export function FulfillmentPartnersDashboard() {
// Логика только для фулфилмента
}
```
---
## 📋 ПЛАН ДЕЙСТВИЙ
### ЭТАП 1: НЕМЕДЛЕННО (Сегодня)
1. **Добавить редиректы в глобальные страницы:**
```typescript
// /app/economics/page.tsx
if (user?.organization?.type) {
redirect(`/${user.organization.type.toLowerCase()}/economics/`)
}
```
2. **Добавить useRoleGuard в wrapper-компоненты:**
```typescript
export function EconomicsPageWrapper() {
// Добавить проверку перед switch
if (!user?.organization?.type) {
redirect('/login')
}
}
```
### ЭТАП 2: КРАТКОСРОЧНО (1-3 дня)
1. **Создать layout-защиту для каждого кабинета**
2. **Провести аудит всех ссылок на глобальные маршруты**
3. **Создать карту редиректов для обратной совместимости**
### ЭТАП 3: ДОЛГОСРОЧНО (1-2 недели)
1. **Разделить общие компоненты на роль-специфичные**
2. **Удалить глобальные маршруты после миграции**
3. **Создать автоматические тесты для проверки доступа**
---
## 🎯 ИТОГ
**Текущая ситуация:** Опасная архитектура с возможностью обхода защиты через глобальные маршруты.
**Решение:** Либо полностью удалить глобальные маршруты, либо добавить автоматические редиректы на роль-специфичные страницы.
**Приоритет:** 🔴 КРИТИЧЕСКИЙ - исправить в течение 1-2 дней