use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
pub id: String,
pub user_id: String,
pub ip_address: String,
pub user_agent: String,
pub device_name: String,
pub device_type: String,
pub fingerprint: String,
pub data: serde_json::Value,
pub created_at: DateTime<Utc>,
pub last_active_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
use super::store::SessionData;
impl From<SessionData> for Session {
fn from(raw: SessionData) -> Self {
Self {
id: raw.id,
user_id: raw.user_id,
ip_address: raw.ip_address,
user_agent: raw.user_agent,
device_name: raw.device_name,
device_type: raw.device_type,
fingerprint: raw.fingerprint,
data: raw.data,
created_at: raw.created_at,
last_active_at: raw.last_active_at,
expires_at: raw.expires_at,
}
}
}
use axum::extract::{FromRequestParts, OptionalFromRequestParts};
use http::request::Parts;
use crate::Error;
impl<S: Send + Sync> FromRequestParts<S> for Session {
type Rejection = Error;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
parts
.extensions
.get::<Session>()
.cloned()
.ok_or_else(|| Error::unauthorized("unauthorized").with_code("auth:session_not_found"))
}
}
impl<S: Send + Sync> OptionalFromRequestParts<S> for Session {
type Rejection = Error;
async fn from_request_parts(
parts: &mut Parts,
_state: &S,
) -> Result<Option<Self>, Self::Rejection> {
Ok(parts.extensions.get::<Session>().cloned())
}
}