core/docs/security.md

213 lines
6.6 KiB
Markdown
Raw Normal View History

# Security System
## Overview
Система безопасности обеспечивает управление паролями и email адресами пользователей через специализированные GraphQL мутации с использованием Redis для хранения токенов.
## GraphQL API
### Мутации
#### updateSecurity
Универсальная мутация для смены пароля и/или email пользователя с полной валидацией и безопасностью.
**Parameters:**
- `email: String` - Новый email (опционально)
- `old_password: String` - Текущий пароль (обязательно для любых изменений)
- `new_password: String` - Новый пароль (опционально)
**Returns:**
```typescript
type SecurityUpdateResult {
success: Boolean!
error: String
author: Author
}
```
**Примеры использования:**
```graphql
# Смена пароля
mutation {
updateSecurity(
old_password: "current123"
new_password: "newPassword456"
) {
success
error
author {
id
name
email
}
}
}
# Смена email
mutation {
updateSecurity(
email: "newemail@example.com"
old_password: "current123"
) {
success
error
author {
id
name
email
}
}
}
# Одновременная смена пароля и email
mutation {
updateSecurity(
email: "newemail@example.com"
old_password: "current123"
new_password: "newPassword456"
) {
success
error
author {
id
name
email
}
}
}
```
#### confirmEmailChange
Подтверждение смены email по токену, полученному на новый email адрес.
**Parameters:**
- `token: String!` - Токен подтверждения
**Returns:** `SecurityUpdateResult`
#### cancelEmailChange
Отмена процесса смены email.
**Returns:** `SecurityUpdateResult`
### Валидация и Ошибки
```typescript
const ERRORS = {
NOT_AUTHENTICATED: "User not authenticated",
INCORRECT_OLD_PASSWORD: "incorrect old password",
PASSWORDS_NOT_MATCH: "New passwords do not match",
EMAIL_ALREADY_EXISTS: "email already exists",
INVALID_EMAIL: "Invalid email format",
WEAK_PASSWORD: "Password too weak",
SAME_PASSWORD: "New password must be different from current",
VALIDATION_ERROR: "Validation failed",
INVALID_TOKEN: "Invalid token",
TOKEN_EXPIRED: "Token expired",
NO_PENDING_EMAIL: "No pending email change"
}
```
## Логика смены email
1. **Инициация смены:**
- Пользователь вызывает `updateSecurity` с новым email
- Генерируется токен подтверждения `token_urlsafe(32)`
- Данные смены email сохраняются в Redis с ключом `email_change:{user_id}`
- Устанавливается автоматическое истечение токена (1 час)
- Отправляется письмо на новый email с токеном
2. **Подтверждение:**
- Пользователь получает письмо с токеном
- Вызывает `confirmEmailChange` с токеном
- Система проверяет токен и срок действия в Redis
- Если токен валиден, email обновляется в базе данных
- Данные смены email удаляются из Redis
3. **Отмена:**
- Пользователь может отменить смену через `cancelEmailChange`
- Данные смены email удаляются из Redis
## Redis Storage
### Хранение токенов смены email
```json
{
"key": "email_change:{user_id}",
"value": {
"user_id": 123,
"old_email": "old@example.com",
"new_email": "new@example.com",
"token": "random_token_32_chars",
"expires_at": 1640995200
},
"ttl": 3600 // 1 час
}
```
### Хранение OAuth токенов
```json
{
"key": "oauth_access:{user_id}:{provider}",
"value": {
"token": "oauth_access_token",
"provider": "google",
"user_id": 123,
"created_at": 1640995200,
"expires_in": 3600,
"scope": "profile email"
},
"ttl": 3600 // время из expires_in или 1 час по умолчанию
}
```
```json
{
"key": "oauth_refresh:{user_id}:{provider}",
"value": {
"token": "oauth_refresh_token",
"provider": "google",
"user_id": 123,
"created_at": 1640995200
},
"ttl": 2592000 // 30 дней по умолчанию
}
```
### Преимущества Redis хранения
- **Автоматическое истечение**: TTL в Redis автоматически удаляет истекшие токены
- **Производительность**: Быстрый доступ к данным токенов
- **Масштабируемость**: Не нагружает основную базу данных
- **Безопасность**: Токены не хранятся в основной БД
- **Простота**: Не требует миграции схемы базы данных
- **OAuth токены**: Централизованное управление токенами всех OAuth провайдеров
## Безопасность
### Требования к паролю
- Минимум 8 символов
- Не может совпадать с текущим паролем
### Аутентификация
- Все операции требуют валидного токена аутентификации
- Старый пароль обязателен для подтверждения личности
### Валидация email
- Проверка формата email через регулярное выражение
- Проверка уникальности email в системе
- Защита от race conditions при смене email
### Токены безопасности
- Генерация токенов через `secrets.token_urlsafe(32)`
- Автоматическое истечение через 1 час
- Удаление токенов после использования или отмены
## Database Schema
Система не требует изменений в схеме базы данных. Все токены и временные данные хранятся в Redis.
### Защищенные поля
Следующие поля показываются только владельцу аккаунта:
- `email`
- `password`