use std::time::SystemTime; use axum::{ debug_handler, extract::State, response::{IntoResponse, Response}, }; use http::{HeaderMap, StatusCode}; use crate::{ models::{ApiResponse, AppError, Session}, requests::AppState, services::{ auth_token::{self, generate_session_token, get_if_auth_token_exists, verify_token}, user_session, }, }; use super::models::AuthSessionResponse; #[debug_handler] pub async fn auth_session_get_handler( State(state): State, headers: HeaderMap, ) -> Result { let cache_pool = state.cache_pool(); let token_key = state.env().token_key(); let auth_token_str = auth_token::extract_token_string_from_http_headers(&headers)?; let auth_token = verify_token(token_key, auth_token_str, None)?; let user_id = auth_token .payload_claims() .and_then(|claims| claims.get_claim("sub")) .and_then(|user_id| user_id.as_str()) .ok_or(AppError::invalid_token()) .and_then(|user_id| { user_id .parse::() .map_err(|_| AppError::invalid_token()) }) .unwrap(); let auth_token_exists = get_if_auth_token_exists(cache_pool, user_id, auth_token_str.to_string().as_str()).await?; if !auth_token_exists { return Err(AppError::no_session_found()); } let (session_token, session_token_id, session_token_expiration) = generate_session_token(token_key, user_id); let expiration = session_token_expiration .duration_since(SystemTime::now()) .unwrap(); let new_session = Session { user_id, created_at: SystemTime::now(), expires_at: session_token_expiration, }; user_session::store_user_session(cache_pool, session_token_id, new_session, Some(expiration)) .await?; Ok(( StatusCode::CREATED, ApiResponse::new(AuthSessionResponse { token: session_token, expiration: session_token_expiration, }) .into_json_response(), ) .into_response()) }