Browse Source

fix email as 2fa with auth requests

pull/6736/head
Stefan Melmuk 6 days ago
parent
commit
258336bb4b
No known key found for this signature in database GPG Key ID: 817020C608FE9C09
  1. 45
      src/api/core/two_factor/email.rs

45
src/api/core/two_factor/email.rs

@ -7,10 +7,10 @@ use crate::{
core::{log_user_event, two_factor::_generate_recover_code}, core::{log_user_event, two_factor::_generate_recover_code},
EmptyResult, JsonResult, PasswordOrOtpData, EmptyResult, JsonResult, PasswordOrOtpData,
}, },
auth::Headers, auth::{ClientHeaders, Headers},
crypto, crypto,
db::{ db::{
models::{DeviceId, EventType, TwoFactor, TwoFactorType, User, UserId}, models::{AuthRequest, AuthRequestId, DeviceId, EventType, TwoFactor, TwoFactorType, User, UserId},
DbConn, DbConn,
}, },
error::{Error, MapResult}, error::{Error, MapResult},
@ -30,12 +30,14 @@ struct SendEmailLoginData {
email: Option<String>, email: Option<String>,
#[serde(alias = "MasterPasswordHash")] #[serde(alias = "MasterPasswordHash")]
master_password_hash: Option<String>, master_password_hash: Option<String>,
auth_request_id: Option<AuthRequestId>,
auth_request_access_code: Option<String>,
} }
/// User is trying to login and wants to use email 2FA. /// User is trying to login and wants to use email 2FA.
/// Does not require Bearer token /// Does not require Bearer token
#[post("/two-factor/send-email-login", data = "<data>")] // JsonResult #[post("/two-factor/send-email-login", data = "<data>")] // JsonResult
async fn send_email_login(data: Json<SendEmailLoginData>, conn: DbConn) -> EmptyResult { async fn send_email_login(data: Json<SendEmailLoginData>, client_headers: ClientHeaders, conn: DbConn) -> EmptyResult {
let data: SendEmailLoginData = data.into_inner(); let data: SendEmailLoginData = data.into_inner();
if !CONFIG._enable_email_2fa() { if !CONFIG._enable_email_2fa() {
@ -47,18 +49,41 @@ async fn send_email_login(data: Json<SendEmailLoginData>, conn: DbConn) -> Empty
Some(email) if !email.is_empty() => Some(email), Some(email) if !email.is_empty() => Some(email),
_ => None, _ => None,
}; };
let user = if let Some(email) = email { let master_password_hash = match &data.master_password_hash {
let Some(master_password_hash) = &data.master_password_hash else { Some(password_hash) if !password_hash.is_empty() => Some(password_hash),
err!("No password hash has been submitted.") _ => None,
}; };
let auth_request_id = match &data.auth_request_id {
Some(auth_request_id) if !auth_request_id.is_empty() => Some(auth_request_id),
_ => None,
};
let user = if let Some(email) = email {
let Some(user) = User::find_by_mail(email, &conn).await else { let Some(user) = User::find_by_mail(email, &conn).await else {
err!("Username or password is incorrect. Try again.") err!("Username or password is incorrect. Try again.")
}; };
// Check password if let Some(master_password_hash) = master_password_hash {
if !user.check_valid_password(master_password_hash) { // Check password
err!("Username or password is incorrect. Try again.") if !user.check_valid_password(master_password_hash) {
err!("Username or password is incorrect. Try again.")
}
} else if let Some(auth_request_id) = auth_request_id {
let Some(auth_request) = AuthRequest::find_by_uuid(auth_request_id, &conn).await else {
err!("AuthRequest doesn't exist", "User not found")
};
let Some(code) = &data.auth_request_access_code else {
err!("no auth request access code")
};
if auth_request.device_type != client_headers.device_type
|| auth_request.request_ip != client_headers.ip.ip.to_string()
|| !auth_request.check_access_code(code)
{
err!("AuthRequest doesn't exist", "Invalid device, IP or code")
}
} else {
err!("No password hash has been submitted.")
} }
user user

Loading…
Cancel
Save