use crate::envelope::{Envelope, NoData}; use crate::session::{RequestId, Session}; use actix_web::web; use crate::server::AuthSvc; use crate::server::errors::AuthError; use crate::server::http::token::types::{TokenRequest, TokenResponse}; #[utoipa::path( post, path = "/api/v1/oauth/session/token", tag = "auth", operation_id = "auth_token_issue", summary = "用会话换取平台访问令牌", description = "认证中心用 Ed25519 私钥签发 JWT(`alg=EdDSA`),`aud` 固定为 `gitdata.ai`,`azp`(`app_id`)可选。服务通过内部 gRPC authority 验签。`ttl_seconds` 取值 1 ~ 3600,不填或填 0 用默认 900。", request_body = TokenRequest, responses( (status = 200, description = "令牌已签发", body = Envelope), (status = 400, description = "ttl 超出上限(`invalid_expiry`)", body = Envelope), (status = 401, description = "会话未绑定账号(`unauthenticated`)", body = Envelope), (status = 404, description = "app_id 不在清单里(`app_not_found`)", body = Envelope) ) )] pub async fn token_issue( svc: web::Data, session: Session, request_id: RequestId, body: web::Json, ) -> Result, AuthError> { let user_id = svc .require_session(&session, Some(request_id.as_str())) .await?; let response = svc .issue_user_token( &session, user_id, body.into_inner(), Some(request_id.as_str()), ) .await?; Ok(Envelope::ok(response)) }