Rene Leonhardt
2 weeks ago
No known key found for this signature in database
GPG Key ID: 8C95C84F75AB1E8E
10 changed files with
130 additions and
136 deletions
-
src/api/admin.rs
-
src/api/core/accounts.rs
-
src/api/core/ciphers.rs
-
src/api/core/emergency_access.rs
-
src/api/core/events.rs
-
src/api/core/sends.rs
-
src/api/core/two_factor/duo_oidc.rs
-
src/auth.rs
-
src/db/models/sso_nonce.rs
-
src/util.rs
|
|
|
@ -731,13 +731,14 @@ async fn diagnostics(_token: AdminToken, ip_header: IpHeader, conn: DbConn) -> A |
|
|
|
let web_vault_version = get_web_vault_version(); |
|
|
|
|
|
|
|
// Check if the running version is newer than the latest stable released version
|
|
|
|
let web_vault_pre_release = if let Ok(web_ver_match) = semver::VersionReq::parse(&format!(">{latest_web_build}")) { |
|
|
|
web_ver_match.matches( |
|
|
|
let web_vault_pre_release = match semver::VersionReq::parse(&format!(">{latest_web_build}")) { |
|
|
|
Ok(web_ver_match) => web_ver_match.matches( |
|
|
|
&semver::Version::parse(&web_vault_version).unwrap_or_else(|_| semver::Version::parse("2025.1.1").unwrap()), |
|
|
|
) |
|
|
|
} else { |
|
|
|
), |
|
|
|
Err(_) => { |
|
|
|
error!("Unable to parse latest_web_build: '{latest_web_build}'"); |
|
|
|
false |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
let diagnostics_json = json!({ |
|
|
|
|
|
|
|
@ -324,8 +324,11 @@ pub async fn _register(data: Json<RegisterData>, email_verification: bool, conn: |
|
|
|
error!("Error sending welcome email: {e:#?}"); |
|
|
|
} |
|
|
|
user.last_verifying_at = Some(user.created_at); |
|
|
|
} else if let Err(e) = mail::send_welcome(&user.email).await { |
|
|
|
error!("Error sending welcome email: {e:#?}"); |
|
|
|
} else { |
|
|
|
match mail::send_welcome(&user.email).await { |
|
|
|
Err(e) => error!("Error sending welcome email: {e:#?}"), |
|
|
|
Ok(_) => (), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if email_verified && is_email_2fa_required(data.organization_user_id, &conn).await { |
|
|
|
@ -1692,9 +1695,8 @@ async fn get_auth_requests_pending(headers: Headers, conn: DbConn) -> JsonResult |
|
|
|
|
|
|
|
pub async fn purge_auth_requests(pool: DbPool) { |
|
|
|
debug!("Purging auth requests"); |
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
AuthRequest::purge_expired_auth_requests(&conn).await; |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while purging trashed ciphers") |
|
|
|
match pool.get().await { |
|
|
|
Ok(conn) => AuthRequest::purge_expired_auth_requests(&conn).await, |
|
|
|
Err(_) => error!("Failed to get DB connection while purging trashed ciphers"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -100,10 +100,9 @@ pub fn routes() -> Vec<Route> { |
|
|
|
|
|
|
|
pub async fn purge_trashed_ciphers(pool: DbPool) { |
|
|
|
debug!("Purging trashed ciphers"); |
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
Cipher::purge_trash(&conn).await; |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while purging trashed ciphers") |
|
|
|
match pool.get().await { |
|
|
|
Ok(conn) => Cipher::purge_trash(&conn).await, |
|
|
|
Err(_) => error!("Failed to get DB connection while purging trashed ciphers"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -721,7 +721,11 @@ pub async fn emergency_request_timeout_job(pool: DbPool) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
let Ok(conn) = pool.get().await else { |
|
|
|
error!("Failed to get DB connection while searching emergency request timed out"); |
|
|
|
return; |
|
|
|
}; |
|
|
|
|
|
|
|
let emergency_access_list = EmergencyAccess::find_all_recoveries_initiated(&conn).await; |
|
|
|
|
|
|
|
if emergency_access_list.is_empty() { |
|
|
|
@ -765,9 +769,6 @@ pub async fn emergency_request_timeout_job(pool: DbPool) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while searching emergency request timed out") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub async fn emergency_notification_reminder_job(pool: DbPool) { |
|
|
|
@ -776,7 +777,11 @@ pub async fn emergency_notification_reminder_job(pool: DbPool) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
let Ok(conn) = pool.get().await else { |
|
|
|
error!("Failed to get DB connection while searching emergency request timed out"); |
|
|
|
return; |
|
|
|
}; |
|
|
|
|
|
|
|
let emergency_access_list = EmergencyAccess::find_all_recoveries_initiated(&conn).await; |
|
|
|
|
|
|
|
if emergency_access_list.is_empty() { |
|
|
|
@ -824,7 +829,4 @@ pub async fn emergency_notification_reminder_job(pool: DbPool) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while searching emergency notification reminder") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -335,9 +335,8 @@ pub async fn event_cleanup_job(pool: DbPool) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
Event::clean_events(&conn).await.ok(); |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while trying to cleanup the events table") |
|
|
|
match pool.get().await { |
|
|
|
Ok(conn) => Event::clean_events(&conn).await.ok().unwrap_or(()), |
|
|
|
Err(_) => error!("Failed to get DB connection while trying to cleanup the events table"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -60,10 +60,9 @@ pub fn routes() -> Vec<rocket::Route> { |
|
|
|
|
|
|
|
pub async fn purge_sends(pool: DbPool) { |
|
|
|
debug!("Purging sends"); |
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
Send::purge(&conn).await; |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while purging sends") |
|
|
|
match pool.get().await { |
|
|
|
Ok(conn) => Send::purge(&conn).await, |
|
|
|
Err(_) => error!("Failed to get DB connection while purging sends"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -344,10 +344,9 @@ async fn extract_context(state: &str, conn: &DbConn) -> Option<DuoAuthContext> { |
|
|
|
// Task to clean up expired Duo authentication contexts that may have accumulated in the database.
|
|
|
|
pub async fn purge_duo_contexts(pool: DbPool) { |
|
|
|
debug!("Purging Duo authentication contexts"); |
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
TwoFactorDuoContext::purge_expired_duo_contexts(&conn).await; |
|
|
|
} else { |
|
|
|
error!("Failed to get DB connection while purging expired Duo authentications") |
|
|
|
match pool.get().await { |
|
|
|
Ok(conn) => TwoFactorDuoContext::purge_expired_duo_contexts(&conn).await, |
|
|
|
Err(_) => error!("Failed to get DB connection while purging expired Duo authentications"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -700,15 +700,10 @@ impl<'r> FromRequest<'r> for OrgHeaders { |
|
|
|
// org_id is usually the second path param ("/organizations/<org_id>"),
|
|
|
|
// but there are cases where it is a query value.
|
|
|
|
// First check the path, if this is not a valid uuid, try the query values.
|
|
|
|
let url_org_id: Option<OrganizationId> = { |
|
|
|
if let Some(Ok(org_id)) = request.param::<OrganizationId>(1) { |
|
|
|
Some(org_id) |
|
|
|
} else if let Some(Ok(org_id)) = request.query_value::<OrganizationId>("organizationId") { |
|
|
|
Some(org_id) |
|
|
|
} else { |
|
|
|
None |
|
|
|
} |
|
|
|
}; |
|
|
|
let url_org_id: Option<OrganizationId> = request |
|
|
|
.param::<OrganizationId>(1) |
|
|
|
.and_then(|r| r.ok()) |
|
|
|
.or_else(|| request.query_value("organizationId").and_then(|r| r.ok())); |
|
|
|
|
|
|
|
match url_org_id { |
|
|
|
Some(org_id) if uuid::Uuid::parse_str(&org_id).is_ok() => { |
|
|
|
|
|
|
|
@ -73,15 +73,14 @@ impl SsoNonce { |
|
|
|
|
|
|
|
pub async fn delete_expired(pool: DbPool) -> EmptyResult { |
|
|
|
debug!("Purging expired sso_nonce"); |
|
|
|
if let Ok(conn) = pool.get().await { |
|
|
|
let Ok(conn) = pool.get().await else { |
|
|
|
err!("Failed to get DB connection while purging expired sso_nonce"); |
|
|
|
}; |
|
|
|
let oldest = Utc::now().naive_utc() - *NONCE_EXPIRATION; |
|
|
|
db_run! { conn: { |
|
|
|
diesel::delete(sso_nonce::table.filter(sso_nonce::created_at.lt(oldest))) |
|
|
|
.execute(conn) |
|
|
|
.map_res("Error deleting expired SSO nonce") |
|
|
|
}} |
|
|
|
} else { |
|
|
|
err!("Failed to get DB connection while purging expired sso_nonce") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -375,10 +375,9 @@ where |
|
|
|
S: AsRef<str>, |
|
|
|
T: FromStr, |
|
|
|
{ |
|
|
|
if let Some(Ok(value)) = string.map(|s| s.as_ref().parse::<T>()) { |
|
|
|
Some(value) |
|
|
|
} else { |
|
|
|
None |
|
|
|
match string.map(|s| s.as_ref().parse::<T>()) { |
|
|
|
Some(Ok(value)) => Some(value), |
|
|
|
_ => None, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|