vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit 445680fb84d238aa432fdec271235933043410e4
parent 04a17dcdef5063892933d501447fb29eaaa38b39
Author: Mathijs van Veluw <black.dex@gmail.com>
Date:   Fri, 26 May 2023 18:03:45 +0200

Merge pull request #3546 from BlackDex/GH-3534

Fix collection change ws notifications
Diffstat:
Msrc/api/core/ciphers.rs | 29++++++++++++++++++++++++-----
Msrc/api/notifications.rs | 19+++++++++++++++----
2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs @@ -512,7 +512,7 @@ pub async fn update_cipher_from_data( .await; } - nt.send_cipher_update(ut, cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid).await; + nt.send_cipher_update(ut, cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid, None).await; } Ok(()) @@ -702,8 +702,9 @@ async fn put_collections_update( data: JsonUpcase<CollectionsAdminData>, headers: Headers, conn: DbConn, + nt: Notify<'_>, ) -> EmptyResult { - post_collections_admin(uuid, data, headers, conn).await + post_collections_admin(uuid, data, headers, conn, nt).await } #[post("/ciphers/<uuid>/collections", data = "<data>")] @@ -712,8 +713,9 @@ async fn post_collections_update( data: JsonUpcase<CollectionsAdminData>, headers: Headers, conn: DbConn, + nt: Notify<'_>, ) -> EmptyResult { - post_collections_admin(uuid, data, headers, conn).await + post_collections_admin(uuid, data, headers, conn, nt).await } #[put("/ciphers/<uuid>/collections-admin", data = "<data>")] @@ -722,8 +724,9 @@ async fn put_collections_admin( data: JsonUpcase<CollectionsAdminData>, headers: Headers, conn: DbConn, + nt: Notify<'_>, ) -> EmptyResult { - post_collections_admin(uuid, data, headers, conn).await + post_collections_admin(uuid, data, headers, conn, nt).await } #[post("/ciphers/<uuid>/collections-admin", data = "<data>")] @@ -732,6 +735,7 @@ async fn post_collections_admin( data: JsonUpcase<CollectionsAdminData>, headers: Headers, mut conn: DbConn, + nt: Notify<'_>, ) -> EmptyResult { let data: CollectionsAdminData = data.into_inner().data; @@ -767,6 +771,15 @@ async fn post_collections_admin( } } + nt.send_cipher_update( + UpdateType::SyncCipherUpdate, + &cipher, + &cipher.update_users_revision(&mut conn).await, + &headers.device.uuid, + Some(Vec::from_iter(posted_collections)), + ) + .await; + log_event( EventType::CipherUpdatedCollections as i32, &cipher.uuid, @@ -1108,6 +1121,7 @@ async fn save_attachment( &cipher, &cipher.update_users_revision(&mut conn).await, &headers.device.uuid, + None, ) .await; @@ -1393,7 +1407,8 @@ async fn move_cipher_selected( // Move cipher cipher.move_to_folder(data.FolderId.clone(), &user_uuid, &mut conn).await?; - nt.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &[user_uuid.clone()], &headers.device.uuid).await; + nt.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &[user_uuid.clone()], &headers.device.uuid, None) + .await; } Ok(()) @@ -1503,6 +1518,7 @@ async fn _delete_cipher_by_uuid( &cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid, + None, ) .await; } else { @@ -1512,6 +1528,7 @@ async fn _delete_cipher_by_uuid( &cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid, + None, ) .await; } @@ -1581,6 +1598,7 @@ async fn _restore_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &mut DbCon &cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid, + None, ) .await; if let Some(org_uuid) = &cipher.organization_uuid { @@ -1662,6 +1680,7 @@ async fn _delete_cipher_attachment_by_id( &cipher, &cipher.update_users_revision(conn).await, &headers.device.uuid, + None, ) .await; if let Some(org_uuid) = cipher.organization_uuid { diff --git a/src/api/notifications.rs b/src/api/notifications.rs @@ -4,7 +4,7 @@ use std::{ time::Duration, }; -use chrono::NaiveDateTime; +use chrono::{NaiveDateTime, Utc}; use rmpv::Value; use rocket::{ futures::{SinkExt, StreamExt}, @@ -265,17 +265,28 @@ impl WebSocketUsers { cipher: &Cipher, user_uuids: &[String], acting_device_uuid: &String, + collection_uuids: Option<Vec<String>>, ) { - let user_uuid = convert_option(cipher.user_uuid.clone()); let org_uuid = convert_option(cipher.organization_uuid.clone()); + // Depending if there are collections provided or not, we need to have different values for the following variables. + // The user_uuid should be `null`, and the revision date should be set to now, else the clients won't sync the collection change. + let (user_uuid, collection_uuids, revision_date) = if let Some(collection_uuids) = collection_uuids { + ( + Value::Nil, + Value::Array(collection_uuids.into_iter().map(|v| v.into()).collect::<Vec<rmpv::Value>>()), + serialize_date(Utc::now().naive_utc()), + ) + } else { + (convert_option(cipher.user_uuid.clone()), Value::Nil, serialize_date(cipher.updated_at)) + }; let data = create_update( vec![ ("Id".into(), cipher.uuid.clone().into()), ("UserId".into(), user_uuid), ("OrganizationId".into(), org_uuid), - ("CollectionIds".into(), Value::Nil), - ("RevisionDate".into(), serialize_date(cipher.updated_at)), + ("CollectionIds".into(), collection_uuids), + ("RevisionDate".into(), revision_date), ], ut, Some(acting_device_uuid.into()),