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