diff --git a/src/api/core/two_factor/email.rs b/src/api/core/two_factor/email.rs index fe1b9a8d..b8724cf1 100644 --- a/src/api/core/two_factor/email.rs +++ b/src/api/core/two_factor/email.rs @@ -64,7 +64,7 @@ async fn send_email_login(data: Json, conn: DbConn) -> Empty user } else { // SSO login only sends device id, so we get the user by the most recently used device - let Some(user) = User::find_by_device(&data.device_identifier, &conn).await else { + let Some(user) = User::find_by_device_for_email2fa(&data.device_identifier, &conn).await else { err!("Username or password is incorrect. Try again.") }; diff --git a/src/db/models/user.rs b/src/db/models/user.rs index d2de7a21..c96e0fe7 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -1,4 +1,4 @@ -use crate::db::schema::{devices, invitations, sso_users, users}; +use crate::db::schema::{invitations, sso_users, twofactor_incomplete, users}; use chrono::{NaiveDateTime, TimeDelta, Utc}; use derive_more::{AsRef, Deref, Display, From}; use diesel::prelude::*; @@ -386,16 +386,18 @@ impl User { }} } - pub async fn find_by_device(device_uuid: &DeviceId, conn: &DbConn) -> Option { - db_run! { conn: { - users::table - .inner_join(devices::table.on(devices::user_uuid.eq(users::uuid))) - .filter(devices::uuid.eq(device_uuid)) - .select(users::all_columns) - .order_by(devices::updated_at.desc()) - .first::(conn) + pub async fn find_by_device_for_email2fa(device_uuid: &DeviceId, conn: &DbConn) -> Option { + if let Some(user_uuid) = db_run! ( conn: { + twofactor_incomplete::table + .filter(twofactor_incomplete::device_uuid.eq(device_uuid)) + .order_by(twofactor_incomplete::login_time.desc()) + .select(twofactor_incomplete::user_uuid) + .first::(conn) .ok() - }} + }) { + return Self::find_by_uuid(&user_uuid, conn).await; + } + None } pub async fn get_all(conn: &DbConn) -> Vec<(Self, Option)> {