commit 83376544d86d333974e6c7a15cf8818bdf832927
parent 04a17dcdef5063892933d501447fb29eaaa38b39
Author: BlackDex <black.dex@gmail.com>
Date: Thu, 25 May 2023 20:57:31 +0200
Fix collection change ws notifications
When chaning a collection this did not got notified via WebSockets.
This PR adds this feature and resolves #3534
Diffstat:
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()),