use axum::{ Json, extract::{Extension, State}, http::{HeaderMap, StatusCode}, response::IntoResponse, }; use module_auth::{PasswordEntryError, PasswordEntryInput}; use serde_json::json; use shared_contracts::auth::{PasswordEntryRequest, PasswordEntryResponse}; use crate::{ api_response::json_success_body, auth_payload::map_auth_user_payload, auth_session::{ attach_set_cookie_header, build_refresh_session_cookie_header, create_password_auth_session, }, http_error::AppError, request_context::RequestContext, session_client::resolve_session_client_context, state::AppState, }; pub async fn password_entry( State(state): State, Extension(request_context): Extension, headers: HeaderMap, Json(payload): Json, ) -> Result { let input = PasswordEntryInput { phone_number: payload.phone, password: payload.password, }; let result = if state.config.dev_password_entry_auto_register_enabled { state .password_entry_service() .execute_with_dev_registration(input) .await } else { state.password_entry_service().execute(input).await } .map_err(map_password_entry_error)?; let session_client = resolve_session_client_context(&headers); let signed_session = create_password_auth_session(&state, &result.user, &session_client)?; state .sync_auth_store_snapshot_to_spacetime() .await .map_err(|error| { AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR) .with_message(format!("同步认证快照失败:{error}")) })?; let mut headers = HeaderMap::new(); attach_set_cookie_header( &mut headers, build_refresh_session_cookie_header(&state, &signed_session.refresh_token)?, ); Ok(( headers, json_success_body( Some(&request_context), PasswordEntryResponse { token: signed_session.access_token, user: map_auth_user_payload(result.user), }, ), )) } fn map_password_entry_error(error: PasswordEntryError) -> AppError { match error { PasswordEntryError::InvalidPhoneNumber => AppError::from_status(StatusCode::BAD_REQUEST) .with_message("手机号格式不正确") .with_details(json!({ "field": "phone", })), PasswordEntryError::InvalidPasswordLength => AppError::from_status(StatusCode::BAD_REQUEST) .with_message("密码长度需要在 6 到 128 位之间") .with_details(json!({ "field": "password", })), PasswordEntryError::InvalidPublicUserCode => AppError::from_status(StatusCode::BAD_REQUEST) .with_message("叙世号格式不正确") .with_details(json!({ "field": "phone", })), PasswordEntryError::InvalidCredentials => { AppError::from_status(StatusCode::UNAUTHORIZED).with_message("手机号或密码错误") } PasswordEntryError::UserNotFound => { AppError::from_status(StatusCode::UNAUTHORIZED).with_message("手机号或密码错误") } PasswordEntryError::Store(_) | PasswordEntryError::PasswordHash(_) => { AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR).with_message(error.to_string()) } } }