[0.6.1] - 2025-09-02
Some checks failed
Deploy / deploy (push) Has been skipped
CI / lint (push) Failing after 8s
CI / test (push) Failing after 10m26s

### 🚀 Изменено - Упрощение архитектуры
- **Генерация миниатюр**: Полностью удалена из Quoter, теперь управляется Vercel Edge API
- **Очистка legacy кода**: Удалены все функции генерации миниатюр и сложность
- **Документация**: Сокращена с 17 файлов до 7, следуя принципам KISS/DRY
- **Смена фокуса**: Quoter теперь сосредоточен на upload + storage, Vercel обрабатывает миниатюры
- **Логирование запросов**: Добавлена аналитика источников для оптимизации CORS whitelist
- **Реализация таймаутов**: Добавлены настраиваемые таймауты для S3, Redis и внешних операций
- **Упрощенная безопасность**: Удален сложный rate limiting, оставлена только необходимая защита upload

### 📝 Обновлено
- Консолидирована документация в практическую структуру:
  - Основной README.md с быстрым стартом
  - docs/SETUP.md для конфигурации и развертывания
  - Упрощенный features.md с фокусом на основную функциональность
- Добавлен акцент на Vercel по всему коду и документации

### 🗑️ Удалено
- Избыточные файлы документации (api-reference, deployment, development, и т.д.)
- Дублирующийся контент в нескольких документах
- Излишне детальная документация для простого файлового прокси

💋 **Упрощение**: KISS принцип применен - убрали избыточность, оставили суть.
This commit is contained in:
2025-09-02 14:00:54 +03:00
parent b876564f4a
commit 7973ba0027
32 changed files with 1168 additions and 3855 deletions

View File

@@ -2,11 +2,8 @@ use actix_web::error::ErrorInternalServerError;
use jsonwebtoken::{Algorithm, DecodingKey, Validation, decode};
use log::{info, warn};
use redis::{AsyncCommands, aio::MultiplexedConnection};
use reqwest::Client as HTTPClient;
use reqwest::header::{CONTENT_TYPE, HeaderMap, HeaderValue};
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::{collections::HashMap, env, error::Error};
use std::{error::Error, time::Duration};
// Структуры для JWT токенов
#[derive(Debug, Deserialize)]
@@ -87,10 +84,11 @@ pub fn validate_token(token: &str) -> Result<bool, Box<dyn Error>> {
}
}
/// Получает user_id из JWT токена и базовые данные пользователя
/// Получает user_id из JWT токена и базовые данные пользователя с таймаутом
pub async fn get_user_by_token(
token: &str,
redis: &mut MultiplexedConnection,
timeout: Duration,
) -> Result<Author, Box<dyn Error>> {
// Декодируем JWT токен для получения user_id
let claims = decode_jwt_token(token)?;
@@ -98,11 +96,15 @@ pub async fn get_user_by_token(
info!("Extracted user_id from JWT token: {}", user_id);
// Проверяем валидность токена через сессию в Redis (опционально)
// Проверяем валидность токена через сессию в Redis (опционально) с таймаутом
let token_key = format!("session:{}:{}", user_id, token);
let session_exists: bool = redis
.exists(&token_key)
let session_exists: bool = tokio::time::timeout(timeout, redis.exists(&token_key))
.await
.map_err(|_| {
warn!("Redis timeout checking session existence");
// Не критичная ошибка, продолжаем с базовыми данными
})
.unwrap_or(Ok(false))
.map_err(|e| {
warn!("Failed to check session existence in Redis: {}", e);
// Не критичная ошибка, продолжаем с базовыми данными
@@ -116,13 +118,19 @@ pub async fn get_user_by_token(
.unwrap()
.as_secs();
let _: () = redis
.hset(&token_key, "last_activity", current_time.to_string())
.await
.map_err(|e| {
warn!("Failed to update last_activity: {}", e);
})
.unwrap_or(());
let _: () = tokio::time::timeout(
timeout,
redis.hset(&token_key, "last_activity", current_time.to_string()),
)
.await
.map_err(|_| {
warn!("Redis timeout updating last_activity");
})
.unwrap_or(Ok(()))
.map_err(|e| {
warn!("Failed to update last_activity: {}", e);
})
.unwrap_or(());
info!("Updated last_activity for session: {}", token_key);
} else {