diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 71417097..d70dd906 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -104,7 +104,7 @@ async fn sync(data: SyncData, headers: Headers, conn: DbConn) -> Json { // Get all ciphers which are visible by the user let ciphers = Cipher::find_by_user_visible(&headers.user.uuid, &conn).await; - let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, &conn).await; + let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, CipherSyncType::User, &conn).await; // Lets generate the ciphers_json using all the gathered info let ciphers_json: Vec = stream::iter(ciphers) @@ -154,7 +154,7 @@ async fn sync(data: SyncData, headers: Headers, conn: DbConn) -> Json { #[get("/ciphers")] async fn get_ciphers(headers: Headers, conn: DbConn) -> Json { let ciphers = Cipher::find_by_user_visible(&headers.user.uuid, &conn).await; - let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, &conn).await; + let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, CipherSyncType::User, &conn).await; let ciphers_json = stream::iter(ciphers) .then(|c| async { @@ -1486,25 +1486,39 @@ pub struct CipherSyncData { pub user_collections: HashMap, } +pub enum CipherSyncType { + User, + Organization, +} + impl CipherSyncData { - pub async fn new(user_uuid: &str, ciphers: &Vec, conn: &DbConn) -> Self { + pub async fn new(user_uuid: &str, ciphers: &Vec, sync_type: CipherSyncType, conn: &DbConn) -> Self { // Generate a list of Cipher UUID's to be used during a query filter with an eq_any. let cipher_uuids = stream::iter(ciphers).map(|c| c.uuid.to_string()).collect::>().await; + let mut cipher_folders: HashMap = HashMap::new(); + let mut cipher_favorites: HashSet = HashSet::new(); + match sync_type { + // User Sync supports Folders and Favorits + CipherSyncType::User => { + // Generate a HashMap with the Cipher UUID as key and the Folder UUID as value + cipher_folders = stream::iter(FolderCipher::find_by_user(user_uuid, conn).await).collect().await; + + // Generate a HashSet of all the Cipher UUID's which are marked as favorite + cipher_favorites = + stream::iter(Favorite::get_all_cipher_uuid_by_user(user_uuid, conn).await).collect().await; + } + // Organization Sync does not support Folders and Favorits. + // If these are set, it will cause issues in the web-vault. + CipherSyncType::Organization => {} + } + // Generate a list of Cipher UUID's containing a Vec with one or more Attachment records let mut cipher_attachments: HashMap> = HashMap::new(); for attachment in Attachment::find_all_by_ciphers(&cipher_uuids, conn).await { cipher_attachments.entry(attachment.cipher_uuid.to_string()).or_default().push(attachment); } - // Generate a HashMap with the Cipher UUID as key and the Folder UUID as value - let cipher_folders: HashMap = - stream::iter(FolderCipher::find_by_user(user_uuid, conn).await).collect().await; - - // Generate a HashSet of all the Cipher UUID's which are marked as favorite - let cipher_favorites: HashSet = - stream::iter(Favorite::get_all_cipher_uuid_by_user(user_uuid, conn).await).collect().await; - // Generate a HashMap with the Cipher UUID as key and one or more Collection UUID's let mut cipher_collections: HashMap> = HashMap::new(); for (cipher, collection) in Cipher::get_collections_with_cipher_by_user(user_uuid, conn).await { diff --git a/src/api/core/emergency_access.rs b/src/api/core/emergency_access.rs index 7ca501cb..74197020 100644 --- a/src/api/core/emergency_access.rs +++ b/src/api/core/emergency_access.rs @@ -5,7 +5,10 @@ use serde_json::Value; use std::borrow::Borrow; use crate::{ - api::{core::CipherSyncData, EmptyResult, JsonResult, JsonUpcase, NumberOrString}, + api::{ + core::{CipherSyncData, CipherSyncType}, + EmptyResult, JsonResult, JsonUpcase, NumberOrString, + }, auth::{decode_emergency_access_invite, Headers}, db::{models::*, DbConn, DbPool}, mail, CONFIG, @@ -596,7 +599,8 @@ async fn view_emergency_access(emer_id: String, headers: Headers, conn: DbConn) } let ciphers = Cipher::find_owned_by_user(&emergency_access.grantor_uuid, &conn).await; - let cipher_sync_data = CipherSyncData::new(&emergency_access.grantor_uuid, &ciphers, &conn).await; + let cipher_sync_data = + CipherSyncData::new(&emergency_access.grantor_uuid, &ciphers, CipherSyncType::User, &conn).await; let ciphers_json = stream::iter(ciphers) .then(|c| async { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 3a6208dd..c54ebeb7 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -7,7 +7,7 @@ mod sends; pub mod two_factor; pub use ciphers::purge_trashed_ciphers; -pub use ciphers::CipherSyncData; +pub use ciphers::{CipherSyncData, CipherSyncType}; pub use emergency_access::{emergency_notification_reminder_job, emergency_request_timeout_job}; pub use sends::purge_sends; pub use two_factor::send_incomplete_2fa_notifications; diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index c4ae909c..7064f221 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -5,8 +5,8 @@ use serde_json::Value; use crate::{ api::{ - core::CipherSyncData, EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, - UpdateType, + core::{CipherSyncData, CipherSyncType}, + EmptyResult, JsonResult, JsonUpcase, JsonUpcaseVec, Notify, NumberOrString, PasswordData, UpdateType, }, auth::{decode_invite, AdminHeaders, Headers, ManagerHeaders, ManagerHeadersLoose, OwnerHeaders}, db::{models::*, DbConn}, @@ -487,7 +487,7 @@ struct OrgIdData { #[get("/ciphers/organization-details?")] async fn get_org_details(data: OrgIdData, headers: Headers, conn: DbConn) -> Json { let ciphers = Cipher::find_by_org(&data.organization_id, &conn).await; - let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, &conn).await; + let cipher_sync_data = CipherSyncData::new(&headers.user.uuid, &ciphers, CipherSyncType::Organization, &conn).await; let ciphers_json = stream::iter(ciphers) .then(|c| async {