From 829af9e4ff377bfde6be60f4009e6d91dd021846 Mon Sep 17 00:00:00 2001 From: Timshel Date: Tue, 25 Aug 2026 16:45:41 +0200 Subject: [PATCH] Fix 2FA Yubikeys --- src/api/core/two_factor/yubikey.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/api/core/two_factor/yubikey.rs b/src/api/core/two_factor/yubikey.rs index bd36de2a..bcf43349 100644 --- a/src/api/core/two_factor/yubikey.rs +++ b/src/api/core/two_factor/yubikey.rs @@ -152,21 +152,23 @@ async fn activate_yubikey(data: Json, headers: Headers, conn: let yubikeys = parse_yubikeys(&data); let mut user = headers.user; - two_factor::validate_yubikey(&data.user_verification_token, &user.uuid, &yubikeys, yubikeys.is_empty())?; - - // Check if we already have some data - let mut yubikey_data = - match TwoFactor::find_by_user_and_type(&user.uuid, TwoFactorType::YubiKey as i32, &conn).await { - Some(data) => data, - None => TwoFactor::new(user.uuid.clone(), TwoFactorType::YubiKey, String::new()), - }; - if yubikeys.is_empty() { // Return an error to prevent saving empty keys which would cause users not being able to login anymore. // To remove all keys users should click the `Deactivate all keys` button err!("A key is required."); } + // Check if we already have some data + let mut yubikey_data = + if let Some(yd) = TwoFactor::find_by_user_and_type(&user.uuid, TwoFactorType::YubiKey as i32, &conn).await { + let ym: YubikeyMetadata = serde_json::from_str(&yd.data)?; + two_factor::validate_yubikey(&data.user_verification_token, &user.uuid, &ym.keys, !ym.keys.is_empty())?; + yd + } else { + two_factor::validate_yubikey(&data.user_verification_token, &user.uuid, &Vec::new(), false)?; + TwoFactor::new(user.uuid.clone(), TwoFactorType::YubiKey, String::new()) + }; + // Ensure they are valid OTPs for yubikey in &yubikeys { if yubikey.is_empty() || yubikey.len() == 12 {