// Passkey HTTP handlers extracted from passkey.rs use crate::core::shared::state::AppState; use crate::security::passkey_types::*; use crate::security::passkey_service::PasskeyService; use axum::{ extract::{Path, State}, http::StatusCode, response::IntoResponse, Json, }; use std::sync::Arc; use uuid::Uuid; /// Start WebAuthn registration for passkey pub async fn start_registration( State(state): State>, Json(request): Json, ) -> Result, PasskeyError> { let user_id = request.user_id; let service = PasskeyService::new(Arc::clone(&state.conn)); let options = service.generate_registration_options(&state, &request).await?; Ok(Json(options)) } /// Verify passkey registration authentication pub async fn verify_registration( State(state): State>, Json(request): Json, ) -> Result, PasskeyError> { let user_id = request.user_id; let service = PasskeyService::new(Arc::clone(&state.conn)); let verified = service.verify_registration(&request).await?; Ok(Json(AuthenticationResponse { status: "verified".to_string(), user_id: user_id.to_string(), display_name: request.display_name.unwrap_or_default(), new_credential_id: verified.new_credential_id, })) } /// Get all passkey credentials for user pub async fn get_credentials( State(state): State>, Path(user_id): Path, ) -> Result>, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); let credentials = service.get_user_credentials(user_id).await?; Ok(Json(credentials)) } /// Sign in with passkey pub async fn sign_in( State(state): State>, Json(request): Json, ) -> Result, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); let response = service.sign_in(&request).await?; Ok(Json(response)) } /// Get fallback configuration pub async fn get_fallback_config( State(state): State>, ) -> Result, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); let config = service.get_fallback_config().await?; Ok(Json(config)) } /// Update fallback configuration pub async fn set_fallback_config( State(state): State>, Json(config): Json, ) -> Result, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); service.set_fallback_config(&config).await?; Ok(Json(serde_json::json!({"success": true}))) } /// Clear fallback attempts pub async fn clear_fallback( State(state): State>, Json(request): Json, ) -> Result, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); service.clear_fallback_attempts(&request.username).await?; Ok(Json(serde_json::json!({"success": true}))) } /// Get passkey challenges pub async fn get_challenges( State(state): State>, Json(request): Json, ) -> Result>, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); let challenges = service.get_challenges(&request).await?; Ok(Json(challenges)) } /// Answer passkey challenge pub async fn answer_challenge( State(state): State>, Path((user_id, challenge_id)): Path<(Uuid, String)>, Json(request): Json, ) -> Result, PasskeyError> { let service = PasskeyService::new(Arc::clone(&state.conn)); let response = service.answer_challenge(&user_id, &challenge_id, &request).await?; Ok(Json(response)) }