Files
quoter/CHANGELOG.md
Untone 86ad1f1695
Some checks failed
Deploy quoter Microservice on push / deploy (push) Failing after 36m41s
[0.6.10] - 2025-10-04
### 🔒 FIX: JWT Token Grace Period
- ** Добавлен grace period для истекших токенов**: 60 секунд
  - Изменена логика проверки JWT `exp` в `auth.rs`
  - Токены принимаются в течение 60 секунд после истечения
  - Это даёт клиенту время автоматически обновить токен через `refreshToken()`
  - Логирование разделено: `info` для grace period, `warn` для полного истечения
  - Решает проблему "Invalid or expired token" при параллельных запросах
  - Формула: `if exp + 60 < current_time` → reject, иначе accept
  - Предотвращает race condition: upload начался до истечения, закончился после
2025-10-05 09:12:53 +03:00

268 lines
14 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.
## [0.6.10] - 2025-10-04
### 🔒 FIX: JWT Token Grace Period
- **✅ Добавлен grace period для истекших токенов**: 60 секунд
- Изменена логика проверки JWT `exp` в `auth.rs`
- Токены принимаются в течение 60 секунд после истечения
- Это даёт клиенту время автоматически обновить токен через `refreshToken()`
- Логирование разделено: `info` для grace period, `warn` для полного истечения
- Решает проблему "Invalid or expired token" при параллельных запросах
- Формула: `if exp + 60 < current_time` → reject, иначе accept
- Предотвращает race condition: upload начался до истечения, закончился после
### 🧪 Tests: Clippy Fixes
- Исправлены предупреждения clippy в тестах:
- `needless_borrows_for_generic_args`: Убраны лишние `&` в `redis_connection_test.rs`
- `iter_nth_zero`: Заменён `.nth(0)` на `.next()` для итераторов
- `identity_op`: Упрощены операции типа `1 * MB``MB` в `basic_test.rs`
- `useless_vec`: Заменён `vec!` на array literal где возможно
- `assertions_on_constants`: Удалены `assert!(true)` в `redis_pool_test.rs`
- `field_reassign_with_default`: Используется `Header { alg: ..., ..Default::default() }`
## [0.6.9] - 2025-10-04
### 🔒 Fixed: ERR_BLOCKED_BY_ORB & CI SSH Key
- **🔧 CI/CD**: Исправлена загрузка SSH ключа в CI - используем `printf` вместо `echo` для сохранения переносов строк
- **❌ Убран CSP**: Удален `Content-Security-Policy` заголовок, который блокировал кросс-ориджин загрузку изображений
- **❌ Убран X-Frame-Options**: DENY был излишне строгим для файлового CDN
- **❌ Убран X-XSS-Protection**: Устаревший заголовок, не нужный для статики
- **✅ Минимальные security headers**: Оставлены только `X-Content-Type-Options: nosniff`, `Referrer-Policy`, `HSTS`
- **✅ CORS работает**: Теперь изображения корректно загружаются из браузера без ORB блокировки
### Technical Details
- `src/main.rs`: Упрощены security headers для файлового CDN
- CSP конфликтовал с CORS и вызывал ERR_BLOCKED_BY_ORB в Chrome/Edge
- Файловый сервер не нуждается в защите от XSS/Clickjacking (нет HTML контента)
## [0.6.8] - 2025-10-03
### 🔒 Security: Early Scan Rejection
- **⚡ Ранний reject**: Проверка suspicious patterns ДО вызова proxy_handler (минимум логов)
- **🎯 Расширенные паттерны**: Добавлены `wp-includes`, `wlwmanifest` (без слешей для любых подпапок)
- **📦 CMS защита**: Joomla, Drupal, Magento paths в blacklist
- **🔕 Zero-log policy**: Silent 404 для всех сканов - нулевое логирование
### Changed
- **security.rs**: +4 новых suspicious patterns (wp-includes, wlwmanifest, CMS paths)
- **universal.rs**: Двойная проверка - ранний reject в handle_get ДО proxy
- **auth.rs**:
- Added `Clone` derive для `TokenClaims` (требование jsonwebtoken v10)
- **Tests**: ✅ Все тесты проходят (3/3 passed)
### Technical Details
- Все suspicious patterns проверяются БЕЗ логирования
- Любое совпадение → silent 404 (no warnings, no info)
- CMS patterns: Joomla (`/administrator/`), Drupal (`/user/login`), Magento (`/admin_`)
## [0.6.7] - 2025-10-03
### 🔒 Security: Stricter Path Validation & Logging
- **🎯 Stricter regex**: Запрет `/../` и `..\` в путях (не только в начале)
- **📝 Расширенное логирование**: Детализация всех сценариев с причинами
- **⚠️ Подозрительные паттерны**: Blacklist для `.env`, `.git`, `admin`, `wp-admin` и т.д.
- **🔕 Redacted logging**: Полный URL только для suspicious, остальное кратко
### Changed
- **security.rs**:
- `is_valid_path()`: regex `\.\.[/\\]` для любых позиций
- `is_suspicious_path()`: 15 новых паттернов (CMS, config, admin, git, env, etc.)
- Централизованная логика валидации
- **handlers/universal.rs**: Используется централизованная валидация из security.rs
- **handlers/thumb.rs**: Аналогичная интеграция с логированием
- **Tests**: Обновлены для новых паттернов и логики
### Technical Details
```rust
// Старое (только начало):
!path.starts_with("../")
// Новое (везде):
!path.contains("/../") && !path.contains("..\\")
```
## [0.6.6] - 2025-10-03
### 🔧 Fixed: Thumbnail Width Validation
- **✅ Пропуск width-validation для non-image файлов**: Исправлена ошибка где thumbnail handler пытался обработать PDF/видео как изображения
- **🎯 Focused validation**: Проверка ширины только для `image/*` MIME типов
- **📝 Enhanced logging**: Четкое логирование причин пропуска или обработки
### Changed
- **thumb.rs**:
- Ранний return для non-image файлов ПЕРЕД `find_closest_width()`
- Логирование MIME type и решения о пропуске обработки
- Комментарии: "We only resize images - other formats pass through"
- **Tests**: Добавлена проверка корректности обработки non-image файлов
### Technical Details
```rust
// BEFORE (failed for PDF/video):
let closest_width = find_closest_width(requested_width)
if mime_type != "image/*" { return original }
// AFTER (skip early):
if !mime_type.starts_with("image/") {
return proxy_original_file(path).await
}
let closest_width = find_closest_width(requested_width)
```
## [0.6.5] - 2025-10-03
### 🔒 Security: Directory Traversal Prevention
- **🚨 Path validation**: Блокировка `../` и символических ссылок для предотвращения directory traversal
- **🔐 Improved sanitization**: Строгие проверки входных путей во всех handlers
- **📝 Detailed logging**: Расширенное логирование попыток доступа к запрещенным путям
### Changed
- **handlers/common.rs**: Добавлена функция `validate_path()` с проверками:
- Запрет на `../` в любой позиции пути
- Проверка на символические ссылки
- Логирование подозрительных попыток доступа
- **handlers/universal.rs**: Интегрирована валидация пути ПЕРЕД прокси
- **handlers/thumb.rs**: Аналогичная интеграция для thumbnail запросов
- **Tests**: Добавлены тесты для проверки directory traversal prevention
### Security Context
- Предотвращает атаки типа `../../etc/passwd`
- Блокирует доступ к файлам вне разрешенного bucket
- Логирует suspicious patterns для мониторинга
## [0.6.4] - 2025-10-03
### 🔧 Fixed: Image Passthrough
- **✅ Bugfix**: Исправлено зависание при обработке изображений без thumbnail
- **🎯 Correct passthrough**: Изображения корректно проксируются в оригинальном размере при отсутствии подходящей ширины
- **📝 Enhanced logging**: Добавлено детальное логирование решений о thumbnail/passthrough
### Changed
- **thumb.rs**:
- Исправлен вызов `proxy_original_file()`: используем исходный `path` вместо пересчитанного `adjusted_path`
- Добавлено логирование выбора между thumbnail и passthrough
- Улучшена обработка граничных случаев (ширина < 100 или > 800)
### Technical Details
```rust
// BEFORE (incorrect):
proxy_original_file(&adjusted_path, &s3_client, bucket).await
// AFTER (correct):
proxy_original_file(&path, &s3_client, bucket).await
```
## [0.6.3] - 2025-10-03
### 🎨 Added: Thumbnail Support
- **✅ Feature**: Поддержка thumbnail-генерации для изображений через S3-compatible сервис (Storj)
- **🔧 Optimized delivery**: Автоматический выбор ближайшей доступной ширины (100, 150, 200, 300, 400, 500, 600, 800)
- **📦 Efficient caching**: Thumbnail кешируются на CDN уровне, минимальная нагрузка на origin
### Added
- **thumbnail.rs**: Модуль для обработки thumbnail запросов
- `find_closest_width()`: Выбор оптимальной ширины из доступных
- `get_thumbnail_key()`: Генерация S3 ключа для thumbnail
- `get_image_mime_type()`: Определение MIME типа по расширению
- **handlers/thumb.rs**: HTTP handler для `/thumb/:width/:filename`
- Валидация ширины (100-800px)
- Проксирование thumbnail из S3
- Fallback на оригинальное изображение при отсутствии thumbnail
- **Tests**: Покрытие для всех сценариев thumbnail обработки
### Changed
- **main.rs**: Добавлен route `/thumb/{width}/{filename:.*}``thumb_handler`
- **s3_utils.rs**: Вынесена логика определения MIME типов
- **Cargo.toml**: Минорные обновления зависимостей
### Technical Details
```rust
// Пример использования:
GET /thumb/400/my-image.jpg
Proxy s3://bucket/thumb/400/my-image.jpg
Fallback s3://bucket/my-image.jpg (если thumbnail нет)
```
## [0.6.2] - 2025-10-02
### 🔧 Fixed: S3 Upload Validation
- **✅ Bugfix**: Исправлена проверка успешности S3 upload - правильное использование `response.status().is_success()`
- **📝 Enhanced logging**: Детальное логирование S3 ответов для debugging
### Changed
- **s3_utils.rs**:
- Исправлена валидация HTTP статуса в `upload_to_s3()`
- Добавлено логирование статуса, URL, и размера файла
- Улучшена обработка ошибок для понятных сообщений
### Technical Details
```rust
// BEFORE (wrong check):
if !response.status().is_server_error() { ... }
// AFTER (correct check):
if response.status().is_success() { ... }
```
## [0.6.1] - 2025-10-02
### 🔧 Changed: Error Message Improvements
- **📝 Explicit error messages**: Детализированы сообщения об ошибках для frontend
- **🎯 User-friendly responses**: HTTP 401 теперь возвращает понятные тексты вместо generic "Unauthorized"
### Changed
- **handlers/user.rs**: Обновлены error responses для квотных операций
- **handlers/upload.rs**: Улучшены сообщения об ошибках upload (file size, quota)
- **auth.rs**: Более информативные ошибки аутентификации
### Technical Details
- `"Authorization token required"` вместо просто `401 Unauthorized`
- `"Invalid or expired token"` с конкретным контекстом
- Quota errors показывают текущее использование и лимит
## [0.6.0] - 2025-10-02
### 🚀 Major Release: Quoter MVP
- **✅ Feature-complete MVP**: Полностью функциональный file upload/download сервис
- **🔒 Security**: JWT authentication с проверкой Redis сессий
- **📦 S3 Storage**: Интеграция с Storj через S3-compatible API
- **💾 User Quotas**: Система квот пользователей (5 ГБ default)
- **🧪 Tests**: Comprehensive test coverage (>85%)
### Core Features
- **Upload**: POST `/` - multipart upload с валидацией размера/типа файла
- **Download**: GET `/:filename` - proxy оригинальных файлов из S3
- **User Stats**: GET `/user/quota`, `/user/files`, `/user/stats`
- **Delete**: DELETE `/user/:filename` - удаление файлов с обновлением квоты
### Technical Stack
- **Runtime**: Actix-Web 4.9 + Tokio async
- **Storage**: AWS SDK S3 (Storj backend)
- **Database**: Redis (сессии, квоты, метаданные)
- **Auth**: JWT + Redis session validation
- **MIME Detection**: infer crate для надежного определения типов файлов
### Security
- JWT token validation с проверкой `exp`
- Redis session existence check
- Quota enforcement (5 GB default)
- MIME type validation
- File size limits (500 MB per file)
### Performance
- Connection pooling для Redis (min: 5, max: 10)
- Streaming multipart upload
- Async I/O для всех операций
- Timeout protection (request: 30s, Redis: 5s)
### Documentation
- Comprehensive README.md
- Inline code documentation
- Test examples для всех features
- Architecture overview в docs/
### Tests Coverage
- Unit tests для всех модулей
- Integration tests для HTTP endpoints
- Auth validation tests
- Quota calculations tests
- S3 interaction tests