systemprompt_api/services/static_content/
session.rs1use std::sync::Arc;
8
9use anyhow::Result;
10use axum::http::HeaderMap;
11use systemprompt_identifiers::{ClientId, SessionId, SessionSource, UserId};
12use systemprompt_oauth::{CreateAnonymousSessionInput, SessionCreationService, validate_jwt_token};
13use systemprompt_runtime::AppContext;
14use systemprompt_security::TokenExtractor;
15use systemprompt_users::UserService;
16
17#[derive(Debug, Clone)]
18pub struct SessionInfo {
19 pub session_id: SessionId,
20 pub user_id: UserId,
21 pub is_new: bool,
22 pub jwt_token: Option<String>,
23}
24
25pub async fn ensure_session(
26 headers: &HeaderMap,
27 uri: Option<&http::Uri>,
28 ctx: &AppContext,
29) -> Result<SessionInfo> {
30 let config = systemprompt_models::Config::get()?;
31
32 if let Ok(token) = TokenExtractor::browser_only().extract(headers)
33 && let Ok(claims) = validate_jwt_token(&token, &config.jwt_issuer, &config.jwt_audiences)
34 && let Some(session_id) = claims.session_id
35 {
36 return Ok(SessionInfo {
37 session_id: SessionId::new(session_id),
38 user_id: UserId::new(claims.sub),
39 is_new: false,
40 jwt_token: Some(token),
41 });
42 }
43
44 let user_service = UserService::new(ctx.db_pool())?;
45 let concrete = Arc::clone(ctx.analytics_service());
46 let analytics: Arc<dyn systemprompt_traits::AnalyticsProvider> = concrete;
47 let session_service = SessionCreationService::new(analytics, Arc::new(user_service));
48
49 let client_id = ClientId::new("sp_web");
50 let session_info = session_service
51 .create_anonymous_session(CreateAnonymousSessionInput {
52 headers,
53 uri,
54 client_id: &client_id,
55 session_source: SessionSource::Web,
56 })
57 .await?;
58
59 Ok(SessionInfo {
60 session_id: session_info.session_id,
61 user_id: session_info.user_id,
62 is_new: session_info.is_new,
63 jwt_token: Some(session_info.jwt_token),
64 })
65}