Skip to main content

systemprompt_api/services/static_content/
session.rs

1use std::sync::Arc;
2
3use anyhow::Result;
4use axum::http::HeaderMap;
5use systemprompt_identifiers::{ClientId, SessionId, SessionSource, UserId};
6use systemprompt_oauth::{validate_jwt_token, CreateAnonymousSessionInput, SessionCreationService};
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 jwt_secret = systemprompt_models::SecretsBootstrap::jwt_secret()?;
25    let config = systemprompt_models::Config::get()?;
26
27    if let Ok(token) = TokenExtractor::browser_only().extract(headers) {
28        if let Ok(claims) = validate_jwt_token(
29            &token,
30            jwt_secret,
31            &config.jwt_issuer,
32            &config.jwt_audiences,
33        ) {
34            if let Some(session_id) = claims.session_id {
35                return Ok(SessionInfo {
36                    session_id: SessionId::new(session_id),
37                    user_id: UserId::new(claims.sub),
38                    is_new: false,
39                    jwt_token: Some(token),
40                });
41            }
42        }
43    }
44
45    let user_service = UserService::new(ctx.db_pool())?;
46    let session_service = SessionCreationService::new(
47        ctx.analytics_service().clone(),
48        Arc::new(UserProviderImpl::new(user_service)),
49    );
50
51    let client_id = ClientId::new("sp_web".to_string());
52    let session_info = session_service
53        .create_anonymous_session(CreateAnonymousSessionInput {
54            headers,
55            uri,
56            client_id: &client_id,
57            jwt_secret,
58            session_source: SessionSource::Web,
59        })
60        .await?;
61
62    Ok(SessionInfo {
63        session_id: session_info.session_id,
64        user_id: session_info.user_id,
65        is_new: session_info.is_new,
66        jwt_token: Some(session_info.jwt_token),
67    })
68}