use serde::{Deserialize, Serialize}; use session::Session; use session::share::session::session_token_key; use utoipa::{IntoParams, ToSchema}; use uuid::Uuid; use crate::errors::AuthError; use crate::services::AuthService; #[derive(Debug, Clone, Serialize, Deserialize, ToSchema, IntoParams)] #[into_params(parameter_in = Query)] pub struct JwtRequestQuery { pub appid: String, } #[derive(Debug, Clone, Serialize, ToSchema)] pub struct JwtRequestResp { pub jwt: String, pub expires_in_secs: u64, } impl AuthService { pub fn jwt_request( &self, uid: Uuid, session: &Session, appid: &str, ) -> Result { let (secret, ttl_secs) = match appid { "chat" => { let secret = self .config() .auth .chat_jwt_sec .clone() .filter(|value| !value.is_empty()) .ok_or_else(|| { AuthError::Internal("chat jwt secret is not configured".to_string()) })?; (secret, self.config().chat.ws.ticket_ttl_secs) } other => { return Err(AuthError::BadRequest(format!( "unsupported appid {other:?}" ))); } }; let token_hash = session .get::(&session_token_key(uid)) .ok_or(AuthError::Unauthorized)?; let jwt = export::jwt::issue_app_jwt(&secret, appid, uid, &token_hash, ttl_secs) .map_err(|error| AuthError::Internal(error.to_string()))?; Ok(JwtRequestResp { jwt, expires_in_secs: ttl_secs, }) } }