deploy change, update token system, fix abuses and add admin verify

This commit is contained in:
2026-05-26 12:50:25 +07:00
parent 1ef93c2025
commit 26d6f2db8a
25 changed files with 416 additions and 557 deletions
+9
View File
@@ -1,4 +1,6 @@
use crate::{api::ApiState, error::AppError};
use axum::http::header::SET_COOKIE;
use axum::http::HeaderMap;
use axum::response::IntoResponse;
use axum::{extract::State, routing::post, Json, Router};
use serde::Deserialize;
@@ -56,6 +58,13 @@ async fn auth_telegram_api(
.auth_service
.generate_auth_token(user.id, user.tg_id, &state.jwt_secret)?;
let mut headers = HeaderMap::new();
let cookie = format!(
"nrxp_token={}; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=600",
token
);
headers.insert(SET_COOKIE, cookie.parse().unwrap());
Ok(Json(json!({ "status": "success", "token": token })))
}
+18 -8
View File
@@ -16,23 +16,32 @@ pub async fn auth_guard(
let auth_header = req
.headers()
.get("Authorization")
.and_then(|h| h.to_str().ok())
.filter(|h| h.starts_with("Bearer "))
.map(|h| &h[7..])
.ok_or_else(|| AppError::Unauthorized("Access token required".into()))?;
.and_then(|h| h.to_str().ok());
// 1. Получаем чистый токен (String)
let token = if let Some(h) = auth_header {
h.replace("Bearer ", "")
} else {
req.headers()
.get("Cookie")
.and_then(|c| c.to_str().ok())
.and_then(|c| c.split("; ").find(|part| part.starts_with("nrxp_token=")))
.map(|part| part.replace("nrxp_token=", ""))
.ok_or_else(|| AppError::Unauthorized("Access token required".into()))?
};
// 2. Декодируем токен, используя полученную выше переменную `token`
// Передаем ссылку &token, так как jsonwebtoken ожидает &str
let token_data = jsonwebtoken::decode::<super::service::Claims>(
auth_header,
&token,
&jsonwebtoken::DecodingKey::from_secret(state.jwt_secret.as_bytes()),
&jsonwebtoken::Validation::default(),
)
.map_err(|_| AppError::Unauthorized("Invalid session signature".into()))?;
// Парсим внутренний UUID из поля sub токена
let user_id = uuid::Uuid::parse_str(&token_data.claims.sub)
.map_err(|_| AppError::Unauthorized("Invalid token payload structure".into()))?;
// Ищем оперативника в сети по его системному UUID
let user = state
.repo
.get_user_by_id(user_id)
@@ -51,7 +60,8 @@ pub async fn admin_guard(req: Request, next: Next) -> Result<Response, AppError>
.get::<User>()
.ok_or_else(|| AppError::Unauthorized("Context lost: Auth required".into()))?;
if user.role != "admin" {
let admin_id: i64 = std::env::var("ADMIN_TG_ID").unwrap().parse().unwrap();
if user.tg_id == Some(admin_id) || user.role == "admin" {
warn!(
"SECURITY_ALERT: Unauthorized admin access attempt by @{:?}",
user.tg_username
+2 -1
View File
@@ -41,7 +41,8 @@ impl AuthService {
let claims = Claims {
sub: user_id.to_string(),
tg_id,
exp: (Utc::now() + chrono::Duration::hours(24)).timestamp() as usize,
// Время жизни токена сокращено до 10 минут
exp: (Utc::now() + chrono::Duration::minutes(10)).timestamp() as usize,
};
encode(