Skip to content

Commit 7cc4dfa

Browse files
authored
Fix 2fa recovery endpoint (#6240)
The newer web-vaults handle the 2fa recovery code differently. This commit fixes this by adding this new flow. Fixes #6200 Fixes #6203 Signed-off-by: BlackDex <[email protected]>
1 parent 5a8736e commit 7cc4dfa

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

src/api/identity.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ async fn _sso_login(
267267
}
268268
Some((mut user, sso_user)) => {
269269
let mut device = get_device(&data, conn, &user).await?;
270-
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, conn).await?;
270+
let twofactor_token = twofactor_auth(&mut user, &data, &mut device, ip, client_version, conn).await?;
271271

272272
if user.private_key.is_none() {
273273
// User was invited a stub was created
@@ -431,7 +431,7 @@ async fn _password_login(
431431

432432
let mut device = get_device(&data, conn, &user).await?;
433433

434-
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, client_version, conn).await?;
434+
let twofactor_token = twofactor_auth(&mut user, &data, &mut device, ip, client_version, conn).await?;
435435

436436
let auth_tokens = auth::AuthTokens::new(&device, &user, AuthMethod::Password, data.client_id);
437437

@@ -658,7 +658,7 @@ async fn get_device(data: &ConnectData, conn: &mut DbConn, user: &User) -> ApiRe
658658
}
659659

660660
async fn twofactor_auth(
661-
user: &User,
661+
user: &mut User,
662662
data: &ConnectData,
663663
device: &mut Device,
664664
ip: &ClientIp,
@@ -723,7 +723,6 @@ async fn twofactor_auth(
723723
Some(TwoFactorType::Email) => {
724724
email::validate_email_code_str(&user.uuid, twofactor_code, &selected_data?, &ip.ip, conn).await?
725725
}
726-
727726
Some(TwoFactorType::Remember) => {
728727
match device.twofactor_remember {
729728
Some(ref code) if !CONFIG.disable_2fa_remember() && ct_eq(code, twofactor_code) => {
@@ -737,6 +736,22 @@ async fn twofactor_auth(
737736
}
738737
}
739738
}
739+
Some(TwoFactorType::RecoveryCode) => {
740+
// Check if recovery code is correct
741+
if !user.check_valid_recovery_code(twofactor_code) {
742+
err!("Recovery code is incorrect. Try again.")
743+
}
744+
745+
// Remove all twofactors from the user
746+
TwoFactor::delete_all_by_user(&user.uuid, conn).await?;
747+
enforce_2fa_policy(user, &user.uuid, device.atype, &ip.ip, conn).await?;
748+
749+
log_user_event(EventType::UserRecovered2fa as i32, &user.uuid, device.atype, &ip.ip, conn).await;
750+
751+
// Remove the recovery code, not needed without twofactors
752+
user.totp_recover = None;
753+
user.save(conn).await?;
754+
}
740755
_ => err!(
741756
"Invalid two factor provider",
742757
ErrorEvent {

src/db/models/two_factor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub enum TwoFactorType {
3131
Remember = 5,
3232
OrganizationDuo = 6,
3333
Webauthn = 7,
34+
RecoveryCode = 8,
3435

3536
// These are implementation details
3637
U2fRegisterChallenge = 1000,

0 commit comments

Comments
 (0)