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::{UserProviderImpl, 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 if let Ok(claims) = validate_jwt_token(&token, &config.jwt_issuer, &config.jwt_audiences) {
28 if let Some(session_id) = claims.session_id {
29 return Ok(SessionInfo {
30 session_id: SessionId::new(session_id),
31 user_id: UserId::new(claims.sub),
32 is_new: false,
33 jwt_token: Some(token),
34 });
35 }
36 }
37 }
38
39 let user_service = UserService::new(ctx.db_pool())?;
40 let concrete = Arc::clone(ctx.analytics_service());
41 let analytics: Arc<dyn systemprompt_traits::AnalyticsProvider> = concrete;
42 let session_service =
43 SessionCreationService::new(analytics, Arc::new(UserProviderImpl::new(user_service)));
44
45 let client_id = ClientId::new("sp_web");
46 let session_info = session_service
47 .create_anonymous_session(CreateAnonymousSessionInput {
48 headers,
49 uri,
50 client_id: &client_id,
51 session_source: SessionSource::Web,
52 })
53 .await?;
54
55 Ok(SessionInfo {
56 session_id: session_info.session_id,
57 user_id: session_info.user_id,
58 is_new: session_info.is_new,
59 jwt_token: Some(session_info.jwt_token),
60 })
61}