authkestra_engine/auth/
session.rs1use crate::auth::error::AuthError;
2use crate::auth::state::Identity;
3use crate::auth::SameSite;
4use async_trait::async_trait;
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug)]
9pub struct SessionConfig {
10 pub cookie_name: String,
12 pub secure: bool,
14 pub http_only: bool,
16 pub same_site: SameSite,
18 pub path: String,
20 pub max_age: Option<chrono::Duration>,
22 pub state_encryption_key: [u8; 32],
25}
26
27impl Default for SessionConfig {
28 fn default() -> Self {
29 let mut key = [0u8; 32];
30 key.copy_from_slice(b"static_key_change_in_production!");
34
35 Self {
36 cookie_name: "authkestra_session".to_string(),
37 secure: true,
38 http_only: true,
39 same_site: SameSite::Lax,
40 path: "/".to_string(),
41 max_age: Some(chrono::Duration::hours(24)),
42 state_encryption_key: key,
43 }
44 }
45}
46
47#[derive(Clone, Debug, Serialize, Deserialize)]
49pub struct Session {
50 pub id: String,
52 pub identity: Identity,
54 pub expires_at: chrono::DateTime<chrono::Utc>,
56}
57
58#[async_trait]
60pub trait SessionStore: Send + Sync + 'static {
61 async fn load_session(&self, id: &str) -> Result<Option<Session>, AuthError>;
63 async fn save_session(&self, session: &Session) -> Result<(), AuthError>;
65 async fn delete_session(&self, id: &str) -> Result<(), AuthError>;
67}
68
69#[async_trait]
70impl<S: crate::store::KvStore<Session>> SessionStore for S {
71 async fn load_session(&self, id: &str) -> Result<Option<Session>, AuthError> {
72 self.get(id)
73 .await
74 .map_err(|e| AuthError::Session(e.to_string()))
75 }
76
77 async fn save_session(&self, session: &Session) -> Result<(), AuthError> {
78 let ttl_secs = (session.expires_at - chrono::Utc::now()).num_seconds();
79 let ttl = std::time::Duration::from_secs(if ttl_secs > 0 { ttl_secs as u64 } else { 0 });
80 self.set(&session.id, session.clone(), ttl)
81 .await
82 .map_err(|e| AuthError::Session(e.to_string()))
83 }
84
85 async fn delete_session(&self, id: &str) -> Result<(), AuthError> {
86 self.delete(id)
87 .await
88 .map_err(|e| AuthError::Session(e.to_string()))
89 }
90}