use crate::actors::users_actor; use crate::actors::users_actor::UsersActor; use crate::data::action_logger::{Action, ActionLogger}; use actix::Addr; use actix_identity::Identity; use actix_remote_ip::RemoteIP; use actix_web::{web, HttpRequest, HttpResponse, Responder}; use webauthn_rs::prelude::PublicKeyCredential; use crate::data::session_identity::{SessionIdentity, SessionStatus}; use crate::data::webauthn_manager::WebAuthManagerReq; #[derive(serde::Deserialize)] pub struct AuthWebauthnRequest { opaque_state: String, credential: PublicKeyCredential, } pub async fn auth_webauthn( id: Identity, req: web::Json, manager: WebAuthManagerReq, http_req: HttpRequest, remote_ip: RemoteIP, users: web::Data>, logger: ActionLogger, ) -> impl Responder { let user_id = SessionIdentity(Some(&id)).user_id(); match manager.finish_authentication(&user_id, &req.opaque_state, &req.credential) { Ok(_) => { users .send(users_actor::AddSuccessful2FALogin( user_id.clone(), remote_ip.0, )) .await .unwrap(); let session = SessionIdentity(Some(&id)); session.record_2fa_auth(&http_req); session.set_status(&http_req, SessionStatus::SignedIn); logger.log(Action::LoginWebauthnAttempt { success: true, user_id, }); HttpResponse::Ok().body("You are authenticated!") } Err(e) => { log::error!("Failed to authenticate user using webauthn! {:?}", e); logger.log(Action::LoginWebauthnAttempt { success: false, user_id, }); HttpResponse::InternalServerError().body("Failed to validate security key!") } } }