1
0
Fork 0
mirror of https://github.com/dani-garcia/vaultwarden.git synced 2025-06-17 00:00:09 +00:00

implement webauthn login deletion (untested)

This commit is contained in:
zUnixorn 2025-06-04 04:03:06 +02:00
parent 9d4b94bb95
commit a4b480dc9f
No known key found for this signature in database
GPG key ID: 0BE3A9CAE3E8D0DA
3 changed files with 27 additions and 6 deletions

View file

@ -10,7 +10,7 @@ pub mod two_factor;
use std::collections::HashMap;
use std::sync::{Mutex, OnceLock};
use crate::db::models::WebAuthnCredential;
use crate::db::models::{WebAuthnCredential, WebAuthnCredentialId};
pub use accounts::purge_auth_requests;
pub use ciphers::{purge_trashed_ciphers, CipherData, CipherSyncData, CipherSyncType};
pub use emergency_access::{emergency_notification_reminder_job, emergency_request_timeout_job};
@ -21,7 +21,7 @@ pub use sends::purge_sends;
pub fn routes() -> Vec<Route> {
let mut eq_domains_routes = routes![get_eq_domains, post_eq_domains, put_eq_domains];
let mut hibp_routes = routes![hibp_breach];
let mut meta_routes = routes![alive, now, version, config, get_api_webauthn, post_api_webauthn, post_api_webauthn_attestation_options];
let mut meta_routes = routes![alive, now, version, config, get_api_webauthn, post_api_webauthn, post_api_webauthn_attestation_options, post_api_webauthn_delete];
let mut routes = Vec::new();
routes.append(&mut accounts::routes());
@ -192,14 +192,25 @@ fn version() -> Json<&'static str> {
Json(crate::VERSION.unwrap_or_default())
}
#[post("/webauthn/<uuid>/delete", data = "<data>")]
async fn post_api_webauthn_delete(data: Json<PasswordOrOtpData>, uuid: String, headers: Headers, mut conn: DbConn) -> ApiResult<Status> {
let data: PasswordOrOtpData = data.into_inner();
let user = headers.user;
data.validate(&user, false, &mut conn).await?;
WebAuthnCredential::delete_by_uuid_and_user(&WebAuthnCredentialId(uuid), &user.uuid, &mut conn).await?;
Ok(Status::Ok)
}
static WEBAUTHN_STATES: OnceLock<Mutex<HashMap<UserId, RegistrationState>>> = OnceLock::new();
#[post("/webauthn/attestation-options", data = "<data>")]
async fn post_api_webauthn_attestation_options(data: Json<PasswordOrOtpData>, headers: Headers, mut conn: DbConn) -> JsonResult {
let data: PasswordOrOtpData = data.into_inner();
let user = headers.user;
// TODO what does delete_if_valid do?
data.validate(&user, false, &mut conn).await?;
// C# does this check as well

View file

@ -40,4 +40,4 @@ pub use self::two_factor::{TwoFactor, TwoFactorType};
pub use self::two_factor_duo_context::TwoFactorDuoContext;
pub use self::two_factor_incomplete::TwoFactorIncomplete;
pub use self::user::{Invitation, User, UserId, UserKdfType, UserStampException};
pub use self::web_authn_credential::WebAuthnCredential;
pub use self::web_authn_credential::{WebAuthnCredential, WebAuthnCredentialId};

View file

@ -2,6 +2,7 @@ use derive_more::{AsRef, Deref, Display, From};
use macros::UuidFromParam;
use crate::api::EmptyResult;
use crate::db::DbConn;
use crate::MapResult;
use super::UserId;
db_object! {
@ -68,6 +69,15 @@ impl WebAuthnCredential {
// TODO do not unwrap
}}.unwrap()
}
pub async fn delete_by_uuid_and_user(uuid: &WebAuthnCredentialId, user_uuid: &UserId, conn: &mut DbConn) -> EmptyResult {
db_run! { conn: {
diesel::delete(web_authn_credentials::table
.filter(web_authn_credentials::uuid.eq(uuid))
.filter(web_authn_credentials::user_uuid.eq(user_uuid))
).execute(conn).map_res("Error removing web_authn_credential for user")
}}
}
}
#[derive(
@ -86,4 +96,4 @@ impl WebAuthnCredential {
Deserialize,
UuidFromParam,
)]
pub struct WebAuthnCredentialId(String);
pub struct WebAuthnCredentialId(pub String);