2025-10-05 09:12:53 +03:00
|
|
|
|
## [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() }`
|
|
|
|
|
|
|
2025-10-04 08:55:39 +03:00
|
|
|
|
## [0.6.9] - 2025-10-04
|
|
|
|
|
|
|
2025-10-04 08:58:01 +03:00
|
|
|
|
### 🔒 Fixed: ERR_BLOCKED_BY_ORB & CI SSH Key
|
|
|
|
|
|
- **🔧 CI/CD**: Исправлена загрузка SSH ключа в CI - используем `printf` вместо `echo` для сохранения переносов строк
|
2025-10-04 08:55:39 +03:00
|
|
|
|
- **❌ Убран 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 контента)
|
|
|
|
|
|
|
2025-10-03 19:58:43 +03:00
|
|
|
|
## [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)
|
|
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### Technical Details
|
|
|
|
|
|
- Все suspicious patterns проверяются БЕЗ логирования
|
|
|
|
|
|
- Любое совпадение → silent 404 (no warnings, no info)
|
|
|
|
|
|
- CMS patterns: Joomla (`/administrator/`), Drupal (`/user/login`), Magento (`/admin_`)
|
2025-10-03 14:19:12 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.7] - 2025-10-03
|
2025-10-03 14:19:12 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🔒 Security: Stricter Path Validation & Logging
|
|
|
|
|
|
- **🎯 Stricter regex**: Запрет `/../` и `..\` в путях (не только в начале)
|
|
|
|
|
|
- **📝 Расширенное логирование**: Детализация всех сценариев с причинами
|
|
|
|
|
|
- **⚠️ Подозрительные паттерны**: Blacklist для `.env`, `.git`, `admin`, `wp-admin` и т.д.
|
|
|
|
|
|
- **🔕 Redacted logging**: Полный URL только для suspicious, остальное кратко
|
2025-09-30 20:08:31 +03:00
|
|
|
|
|
2025-09-30 21:46:47 +03:00
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **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**: Обновлены для новых паттернов и логики
|
2025-09-30 20:08:31 +03:00
|
|
|
|
|
|
|
|
|
|
### Technical Details
|
2025-10-05 09:12:53 +03:00
|
|
|
|
```rust
|
|
|
|
|
|
// Старое (только начало):
|
|
|
|
|
|
!path.starts_with("../")
|
2025-09-01 22:52:33 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
// Новое (везде):
|
|
|
|
|
|
!path.contains("/../") && !path.contains("..\\")
|
|
|
|
|
|
```
|
2025-09-01 22:52:33 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.6] - 2025-10-03
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🔧 Fixed: Thumbnail Width Validation
|
|
|
|
|
|
- **✅ Пропуск width-validation для non-image файлов**: Исправлена ошибка где thumbnail handler пытался обработать PDF/видео как изображения
|
|
|
|
|
|
- **🎯 Focused validation**: Проверка ширины только для `image/*` MIME типов
|
|
|
|
|
|
- **📝 Enhanced logging**: Четкое логирование причин пропуска или обработки
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **thumb.rs**:
|
|
|
|
|
|
- Ранний return для non-image файлов ПЕРЕД `find_closest_width()`
|
|
|
|
|
|
- Логирование MIME type и решения о пропуске обработки
|
|
|
|
|
|
- Комментарии: "We only resize images - other formats pass through"
|
|
|
|
|
|
- **Tests**: Добавлена проверка корректности обработки non-image файлов
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
### Technical Details
|
2025-10-05 09:12:53 +03:00
|
|
|
|
```rust
|
|
|
|
|
|
// BEFORE (failed for PDF/video):
|
|
|
|
|
|
let closest_width = find_closest_width(requested_width)
|
|
|
|
|
|
if mime_type != "image/*" { return original }
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
// AFTER (skip early):
|
|
|
|
|
|
if !mime_type.starts_with("image/") {
|
|
|
|
|
|
return proxy_original_file(path).await
|
|
|
|
|
|
}
|
|
|
|
|
|
let closest_width = find_closest_width(requested_width)
|
|
|
|
|
|
```
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.5] - 2025-10-03
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🔒 Security: Directory Traversal Prevention
|
|
|
|
|
|
- **🚨 Path validation**: Блокировка `../` и символических ссылок для предотвращения directory traversal
|
|
|
|
|
|
- **🔐 Improved sanitization**: Строгие проверки входных путей во всех handlers
|
|
|
|
|
|
- **📝 Detailed logging**: Расширенное логирование попыток доступа к запрещенным путям
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **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
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **thumb.rs**:
|
|
|
|
|
|
- Исправлен вызов `proxy_original_file()`: используем исходный `path` вместо пересчитанного `adjusted_path`
|
|
|
|
|
|
- Добавлено логирование выбора между thumbnail и passthrough
|
|
|
|
|
|
- Улучшена обработка граничных случаев (ширина < 100 или > 800)
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### Technical Details
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// BEFORE (incorrect):
|
|
|
|
|
|
proxy_original_file(&adjusted_path, &s3_client, bucket).await
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
// AFTER (correct):
|
|
|
|
|
|
proxy_original_file(&path, &s3_client, bucket).await
|
|
|
|
|
|
```
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.3] - 2025-10-03
|
2025-09-01 20:36:15 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🎨 Added: Thumbnail Support
|
|
|
|
|
|
- **✅ Feature**: Поддержка thumbnail-генерации для изображений через S3-compatible сервис (Storj)
|
|
|
|
|
|
- **🔧 Optimized delivery**: Автоматический выбор ближайшей доступной ширины (100, 150, 200, 300, 400, 500, 600, 800)
|
|
|
|
|
|
- **📦 Efficient caching**: Thumbnail кешируются на CDN уровне, минимальная нагрузка на origin
|
2025-08-12 15:59:51 +03:00
|
|
|
|
|
|
|
|
|
|
### Added
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **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 обработки
|
2025-08-12 15:59:51 +03:00
|
|
|
|
|
|
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **main.rs**: Добавлен route `/thumb/{width}/{filename:.*}` → `thumb_handler`
|
|
|
|
|
|
- **s3_utils.rs**: Вынесена логика определения MIME типов
|
|
|
|
|
|
- **Cargo.toml**: Минорные обновления зависимостей
|
2025-08-12 15:59:51 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### Technical Details
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// Пример использования:
|
|
|
|
|
|
GET /thumb/400/my-image.jpg
|
|
|
|
|
|
→ Proxy → s3://bucket/thumb/400/my-image.jpg
|
|
|
|
|
|
→ Fallback → s3://bucket/my-image.jpg (если thumbnail нет)
|
|
|
|
|
|
```
|
2025-08-12 14:48:59 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.2] - 2025-10-02
|
2025-08-02 00:18:09 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🔧 Fixed: S3 Upload Validation
|
|
|
|
|
|
- **✅ Bugfix**: Исправлена проверка успешности S3 upload - правильное использование `response.status().is_success()`
|
|
|
|
|
|
- **📝 Enhanced logging**: Детальное логирование S3 ответов для debugging
|
2025-08-02 00:18:09 +03:00
|
|
|
|
|
|
|
|
|
|
### Changed
|
2025-10-05 09:12:53 +03:00
|
|
|
|
- **s3_utils.rs**:
|
|
|
|
|
|
- Исправлена валидация HTTP статуса в `upload_to_s3()`
|
|
|
|
|
|
- Добавлено логирование статуса, URL, и размера файла
|
|
|
|
|
|
- Улучшена обработка ошибок для понятных сообщений
|
2025-08-02 00:18:09 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### Technical Details
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// BEFORE (wrong check):
|
|
|
|
|
|
if !response.status().is_server_error() { ... }
|
2025-08-02 00:18:09 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
// AFTER (correct check):
|
|
|
|
|
|
if response.status().is_success() { ... }
|
|
|
|
|
|
```
|
2025-08-02 00:18:09 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
## [0.6.1] - 2025-10-02
|
2025-06-02 22:20:37 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 🔧 Changed: Error Message Improvements
|
|
|
|
|
|
- **📝 Explicit error messages**: Детализированы сообщения об ошибках для frontend
|
|
|
|
|
|
- **🎯 User-friendly responses**: HTTP 401 теперь возвращает понятные тексты вместо generic "Unauthorized"
|
2025-06-02 22:20:37 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### Changed
|
|
|
|
|
|
- **handlers/user.rs**: Обновлены error responses для квотных операций
|
|
|
|
|
|
- **handlers/upload.rs**: Улучшены сообщения об ошибках upload (file size, quota)
|
|
|
|
|
|
- **auth.rs**: Более информативные ошибки аутентификации
|
2025-06-02 22:20:37 +03:00
|
|
|
|
|
2025-10-05 09:12:53 +03:00
|
|
|
|
### 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
|