@@ -310,7 +310,8 @@ async fn post_ciphers(
310
310
data. LastKnownRevisionDate = None ;
311
311
312
312
let mut cipher = Cipher :: new ( data. Type , data. Name . clone ( ) ) ;
313
- update_cipher_from_data ( & mut cipher, data, & headers, false , & mut conn, & ip, & nt, UpdateType :: CipherCreate ) . await ?;
313
+ update_cipher_from_data ( & mut cipher, data, & headers, false , & mut conn, & ip, & nt, UpdateType :: SyncCipherCreate )
314
+ . await ?;
314
315
315
316
Ok ( Json ( cipher. to_json ( & headers. host , & headers. user . uuid , None , & mut conn) . await ) )
316
317
}
@@ -415,7 +416,14 @@ pub async fn update_cipher_from_data(
415
416
for ( id, attachment) in attachments {
416
417
let mut saved_att = match Attachment :: find_by_id ( & id, conn) . await {
417
418
Some ( att) => att,
418
- None => err ! ( "Attachment doesn't exist" ) ,
419
+ None => {
420
+ // Warn and continue here.
421
+ // A missing attachment means it was removed via an other client.
422
+ // Also the Desktop Client supports removing attachments and save an update afterwards.
423
+ // Bitwarden it self ignores these mismatches server side.
424
+ warn ! ( "Attachment {id} doesn't exist" ) ;
425
+ continue ;
426
+ }
419
427
} ;
420
428
421
429
if saved_att. cipher_uuid != cipher. uuid {
@@ -482,8 +490,8 @@ pub async fn update_cipher_from_data(
482
490
// Only log events for organizational ciphers
483
491
if let Some ( org_uuid) = & cipher. organization_uuid {
484
492
let event_type = match ( & ut, transfer_cipher) {
485
- ( UpdateType :: CipherCreate , true ) => EventType :: CipherCreated ,
486
- ( UpdateType :: CipherUpdate , true ) => EventType :: CipherShared ,
493
+ ( UpdateType :: SyncCipherCreate , true ) => EventType :: CipherCreated ,
494
+ ( UpdateType :: SyncCipherUpdate , true ) => EventType :: CipherShared ,
487
495
( _, _) => EventType :: CipherUpdated ,
488
496
} ;
489
497
@@ -499,7 +507,7 @@ pub async fn update_cipher_from_data(
499
507
. await ;
500
508
}
501
509
502
- nt. send_cipher_update ( ut, cipher, & cipher. update_users_revision ( conn) . await ) . await ;
510
+ nt. send_cipher_update ( ut, cipher, & cipher. update_users_revision ( conn) . await , & headers . device . uuid ) . await ;
503
511
}
504
512
505
513
Ok ( ( ) )
@@ -562,7 +570,7 @@ async fn post_ciphers_import(
562
570
563
571
let mut user = headers. user ;
564
572
user. update_revision ( & mut conn) . await ?;
565
- nt. send_user_update ( UpdateType :: Vault , & user) . await ;
573
+ nt. send_user_update ( UpdateType :: SyncVault , & user) . await ;
566
574
Ok ( ( ) )
567
575
}
568
576
@@ -628,7 +636,8 @@ async fn put_cipher(
628
636
err ! ( "Cipher is not write accessible" )
629
637
}
630
638
631
- update_cipher_from_data ( & mut cipher, data, & headers, false , & mut conn, & ip, & nt, UpdateType :: CipherUpdate ) . await ?;
639
+ update_cipher_from_data ( & mut cipher, data, & headers, false , & mut conn, & ip, & nt, UpdateType :: SyncCipherUpdate )
640
+ . await ?;
632
641
633
642
Ok ( Json ( cipher. to_json ( & headers. host , & headers. user . uuid , None , & mut conn) . await ) )
634
643
}
@@ -850,9 +859,9 @@ async fn share_cipher_by_uuid(
850
859
851
860
// When LastKnownRevisionDate is None, it is a new cipher, so send CipherCreate.
852
861
let ut = if data. Cipher . LastKnownRevisionDate . is_some ( ) {
853
- UpdateType :: CipherUpdate
862
+ UpdateType :: SyncCipherUpdate
854
863
} else {
855
- UpdateType :: CipherCreate
864
+ UpdateType :: SyncCipherCreate
856
865
} ;
857
866
858
867
update_cipher_from_data ( & mut cipher, data. Cipher , headers, shared_to_collection, conn, ip, nt, ut) . await ?;
@@ -1054,7 +1063,13 @@ async fn save_attachment(
1054
1063
data. data . move_copy_to ( file_path) . await ?
1055
1064
}
1056
1065
1057
- nt. send_cipher_update ( UpdateType :: CipherUpdate , & cipher, & cipher. update_users_revision ( & mut conn) . await ) . await ;
1066
+ nt. send_cipher_update (
1067
+ UpdateType :: SyncCipherUpdate ,
1068
+ & cipher,
1069
+ & cipher. update_users_revision ( & mut conn) . await ,
1070
+ & headers. device . uuid ,
1071
+ )
1072
+ . await ;
1058
1073
1059
1074
if let Some ( org_uuid) = & cipher. organization_uuid {
1060
1075
log_event (
@@ -1390,7 +1405,7 @@ async fn move_cipher_selected(
1390
1405
// Move cipher
1391
1406
cipher. move_to_folder ( data. FolderId . clone ( ) , & user_uuid, & mut conn) . await ?;
1392
1407
1393
- nt. send_cipher_update ( UpdateType :: CipherUpdate , & cipher, & [ user_uuid. clone ( ) ] ) . await ;
1408
+ nt. send_cipher_update ( UpdateType :: SyncCipherUpdate , & cipher, & [ user_uuid. clone ( ) ] , & headers . device . uuid ) . await ;
1394
1409
}
1395
1410
1396
1411
Ok ( ( ) )
@@ -1438,7 +1453,7 @@ async fn delete_all(
1438
1453
Some ( user_org) => {
1439
1454
if user_org. atype == UserOrgType :: Owner {
1440
1455
Cipher :: delete_all_by_organization ( & org_data. org_id , & mut conn) . await ?;
1441
- nt. send_user_update ( UpdateType :: Vault , & user) . await ;
1456
+ nt. send_user_update ( UpdateType :: SyncVault , & user) . await ;
1442
1457
1443
1458
log_event (
1444
1459
EventType :: OrganizationPurgedVault as i32 ,
@@ -1471,7 +1486,7 @@ async fn delete_all(
1471
1486
}
1472
1487
1473
1488
user. update_revision ( & mut conn) . await ?;
1474
- nt. send_user_update ( UpdateType :: Vault , & user) . await ;
1489
+ nt. send_user_update ( UpdateType :: SyncVault , & user) . await ;
1475
1490
Ok ( ( ) )
1476
1491
}
1477
1492
}
@@ -1497,10 +1512,22 @@ async fn _delete_cipher_by_uuid(
1497
1512
if soft_delete {
1498
1513
cipher. deleted_at = Some ( Utc :: now ( ) . naive_utc ( ) ) ;
1499
1514
cipher. save ( conn) . await ?;
1500
- nt. send_cipher_update ( UpdateType :: CipherUpdate , & cipher, & cipher. update_users_revision ( conn) . await ) . await ;
1515
+ nt. send_cipher_update (
1516
+ UpdateType :: SyncCipherUpdate ,
1517
+ & cipher,
1518
+ & cipher. update_users_revision ( conn) . await ,
1519
+ & headers. device . uuid ,
1520
+ )
1521
+ . await ;
1501
1522
} else {
1502
1523
cipher. delete ( conn) . await ?;
1503
- nt. send_cipher_update ( UpdateType :: CipherDelete , & cipher, & cipher. update_users_revision ( conn) . await ) . await ;
1524
+ nt. send_cipher_update (
1525
+ UpdateType :: SyncCipherDelete ,
1526
+ & cipher,
1527
+ & cipher. update_users_revision ( conn) . await ,
1528
+ & headers. device . uuid ,
1529
+ )
1530
+ . await ;
1504
1531
}
1505
1532
1506
1533
if let Some ( org_uuid) = cipher. organization_uuid {
@@ -1562,7 +1589,13 @@ async fn _restore_cipher_by_uuid(
1562
1589
cipher. deleted_at = None ;
1563
1590
cipher. save ( conn) . await ?;
1564
1591
1565
- nt. send_cipher_update ( UpdateType :: CipherUpdate , & cipher, & cipher. update_users_revision ( conn) . await ) . await ;
1592
+ nt. send_cipher_update (
1593
+ UpdateType :: SyncCipherUpdate ,
1594
+ & cipher,
1595
+ & cipher. update_users_revision ( conn) . await ,
1596
+ & headers. device . uuid ,
1597
+ )
1598
+ . await ;
1566
1599
if let Some ( org_uuid) = & cipher. organization_uuid {
1567
1600
log_event (
1568
1601
EventType :: CipherRestored as i32 ,
@@ -1639,7 +1672,13 @@ async fn _delete_cipher_attachment_by_id(
1639
1672
1640
1673
// Delete attachment
1641
1674
attachment. delete ( conn) . await ?;
1642
- nt. send_cipher_update ( UpdateType :: CipherUpdate , & cipher, & cipher. update_users_revision ( conn) . await ) . await ;
1675
+ nt. send_cipher_update (
1676
+ UpdateType :: SyncCipherUpdate ,
1677
+ & cipher,
1678
+ & cipher. update_users_revision ( conn) . await ,
1679
+ & headers. device . uuid ,
1680
+ )
1681
+ . await ;
1643
1682
if let Some ( org_uuid) = cipher. organization_uuid {
1644
1683
log_event (
1645
1684
EventType :: CipherAttachmentDeleted as i32 ,
0 commit comments