use actix_web::{HttpResponse, Result, web}; use serde::Serialize; use session::SessionUser; use utoipa::ToSchema; use crate::ApiResponse; use crate::error::ApiError; use service::AppService; use service::ws_token::WS_TOKEN_TTL_SECONDS; #[derive(Debug, Serialize, ToSchema)] pub struct WsTokenResponse { pub token: String, pub expires_in_seconds: i64, } /// Returns a short-lived token that can be used to authenticate WebSocket connections /// by passing it as a query parameter: `ws://host/ws?token=xxx` #[utoipa::path( post, path = "/api/ws/token", responses( (status = 200, description = "Token generated successfully", body = ApiResponse), (status = 401, description = "Unauthorized - not logged in", body = ApiResponse), ), tag = "WebSocket" )] pub async fn ws_token_generate( service: web::Data, session_user: SessionUser, ) -> Result { let SessionUser(user_id) = session_user; let token = service .ws_token .generate_token(user_id) .await .map_err(ApiError::from)?; let response = WsTokenResponse { token, expires_in_seconds: WS_TOKEN_TTL_SECONDS, }; Ok(ApiResponse::ok(response).to_response()) }