1- use bitwarden_api_api:: models:: CipherDetailsResponseModel ;
1+ use bitwarden_api_api:: models:: { CipherDetailsResponseModel , CipherResponseModel } ;
22use bitwarden_collections:: collection:: CollectionId ;
33use bitwarden_core:: {
44 MissingFieldError , OrganizationId , UserId ,
@@ -30,8 +30,8 @@ use super::{
3030 secure_note, ssh_key,
3131} ;
3232use crate :: {
33- EncryptError , Fido2CredentialFullView , Fido2CredentialView , FolderId , Login , LoginView ,
34- VaultParseError , password_history,
33+ AttachmentView , EncryptError , Fido2CredentialFullView , Fido2CredentialView , FolderId , Login ,
34+ LoginView , VaultParseError , password_history,
3535} ;
3636
3737uuid_newtype ! ( pub CipherId ) ;
@@ -79,11 +79,12 @@ pub enum CipherType {
7979}
8080
8181#[ allow( missing_docs) ]
82- #[ derive( Clone , Copy , Serialize_repr , Deserialize_repr , Debug , PartialEq ) ]
82+ #[ derive( Clone , Copy , Default , Serialize_repr , Deserialize_repr , Debug , PartialEq ) ]
8383#[ repr( u8 ) ]
8484#[ cfg_attr( feature = "uniffi" , derive( uniffi:: Enum ) ) ]
8585#[ cfg_attr( feature = "wasm" , wasm_bindgen) ]
8686pub enum CipherRepromptType {
87+ #[ default]
8788 None = 0 ,
8889 Password = 1 ,
8990}
@@ -472,10 +473,8 @@ impl CipherView {
472473
473474 #[ allow( missing_docs) ]
474475 pub fn generate_checksums ( & mut self ) {
475- if let Some ( uris) = self . login . as_mut ( ) . and_then ( |l| l. uris . as_mut ( ) ) {
476- for uri in uris {
477- uri. generate_checksum ( ) ;
478- }
476+ if let Some ( l) = self . login . as_mut ( ) {
477+ l. generate_checksums ( ) ;
479478 }
480479 }
481480
@@ -493,13 +492,7 @@ impl CipherView {
493492 new_key : SymmetricKeyId ,
494493 ) -> Result < ( ) , CryptoError > {
495494 if let Some ( attachments) = & mut self . attachments {
496- for attachment in attachments {
497- if let Some ( attachment_key) = & mut attachment. key {
498- let tmp_attachment_key_id = SymmetricKeyId :: Local ( "attachment_key" ) ;
499- ctx. unwrap_symmetric_key ( old_key, tmp_attachment_key_id, attachment_key) ?;
500- * attachment_key = ctx. wrap_symmetric_key ( new_key, tmp_attachment_key_id) ?;
501- }
502- }
495+ AttachmentView :: reencrypt_keys ( attachments, ctx, old_key, new_key) ?;
503496 }
504497 Ok ( ( ) )
505498 }
@@ -528,11 +521,7 @@ impl CipherView {
528521 new_key : SymmetricKeyId ,
529522 ) -> Result < ( ) , CryptoError > {
530523 if let Some ( login) = self . login . as_mut ( ) {
531- if let Some ( fido2_credentials) = & mut login. fido2_credentials {
532- let dec_fido2_credentials: Vec < Fido2CredentialFullView > =
533- fido2_credentials. decrypt ( ctx, old_key) ?;
534- * fido2_credentials = dec_fido2_credentials. encrypt_composite ( ctx, new_key) ?;
535- }
524+ login. reencrypt_fido2_credentials ( ctx, old_key, new_key) ?;
536525 }
537526 Ok ( ( ) )
538527 }
@@ -695,6 +684,15 @@ impl Decryptable<KeyIds, SymmetricKeyId, CipherListView> for Cipher {
695684 }
696685}
697686
687+ #[ cfg( feature = "wasm" ) ]
688+ impl wasm_bindgen:: __rt:: VectorIntoJsValue for CipherView {
689+ fn vector_into_jsvalue (
690+ vector : wasm_bindgen:: __rt:: std:: boxed:: Box < [ Self ] > ,
691+ ) -> wasm_bindgen:: JsValue {
692+ wasm_bindgen:: __rt:: js_value_vector_into_jsvalue ( vector)
693+ }
694+ }
695+
698696impl IdentifyKey < SymmetricKeyId > for Cipher {
699697 fn key_identifier ( & self ) -> SymmetricKeyId {
700698 match self . organization_id {
@@ -796,6 +794,75 @@ impl From<bitwarden_api_api::models::CipherRepromptType> for CipherRepromptType
796794 }
797795}
798796
797+ impl From < CipherType > for bitwarden_api_api:: models:: CipherType {
798+ fn from ( t : CipherType ) -> Self {
799+ match t {
800+ CipherType :: Login => bitwarden_api_api:: models:: CipherType :: Login ,
801+ CipherType :: SecureNote => bitwarden_api_api:: models:: CipherType :: SecureNote ,
802+ CipherType :: Card => bitwarden_api_api:: models:: CipherType :: Card ,
803+ CipherType :: Identity => bitwarden_api_api:: models:: CipherType :: Identity ,
804+ CipherType :: SshKey => bitwarden_api_api:: models:: CipherType :: SSHKey ,
805+ }
806+ }
807+ }
808+
809+ impl From < CipherRepromptType > for bitwarden_api_api:: models:: CipherRepromptType {
810+ fn from ( t : CipherRepromptType ) -> Self {
811+ match t {
812+ CipherRepromptType :: None => bitwarden_api_api:: models:: CipherRepromptType :: None ,
813+ CipherRepromptType :: Password => bitwarden_api_api:: models:: CipherRepromptType :: Password ,
814+ }
815+ }
816+ }
817+
818+ impl TryFrom < CipherResponseModel > for Cipher {
819+ type Error = VaultParseError ;
820+
821+ fn try_from ( cipher : CipherResponseModel ) -> Result < Self , Self :: Error > {
822+ Ok ( Self {
823+ id : cipher. id . map ( CipherId :: new) ,
824+ organization_id : cipher. organization_id . map ( OrganizationId :: new) ,
825+ folder_id : cipher. folder_id . map ( FolderId :: new) ,
826+ collection_ids : vec ! [ ] , // CipherResponseModel doesn't include collection_ids
827+ name : require ! ( cipher. name) . parse ( ) ?,
828+ notes : EncString :: try_from_optional ( cipher. notes ) ?,
829+ r#type : require ! ( cipher. r#type) . into ( ) ,
830+ login : cipher. login . map ( |l| ( * l) . try_into ( ) ) . transpose ( ) ?,
831+ identity : cipher. identity . map ( |i| ( * i) . try_into ( ) ) . transpose ( ) ?,
832+ card : cipher. card . map ( |c| ( * c) . try_into ( ) ) . transpose ( ) ?,
833+ secure_note : cipher. secure_note . map ( |s| ( * s) . try_into ( ) ) . transpose ( ) ?,
834+ ssh_key : cipher. ssh_key . map ( |s| ( * s) . try_into ( ) ) . transpose ( ) ?,
835+ favorite : cipher. favorite . unwrap_or ( false ) ,
836+ reprompt : cipher
837+ . reprompt
838+ . map ( |r| r. into ( ) )
839+ . unwrap_or ( CipherRepromptType :: None ) ,
840+ organization_use_totp : cipher. organization_use_totp . unwrap_or ( false ) ,
841+ edit : cipher. edit . unwrap_or ( false ) ,
842+ permissions : cipher. permissions . map ( |p| ( * p) . try_into ( ) ) . transpose ( ) ?,
843+ view_password : cipher. view_password . unwrap_or ( true ) ,
844+ local_data : None , // Not sent from server
845+ attachments : cipher
846+ . attachments
847+ . map ( |a| a. into_iter ( ) . map ( |a| a. try_into ( ) ) . collect ( ) )
848+ . transpose ( ) ?,
849+ fields : cipher
850+ . fields
851+ . map ( |f| f. into_iter ( ) . map ( |f| f. try_into ( ) ) . collect ( ) )
852+ . transpose ( ) ?,
853+ password_history : cipher
854+ . password_history
855+ . map ( |p| p. into_iter ( ) . map ( |p| p. try_into ( ) ) . collect ( ) )
856+ . transpose ( ) ?,
857+ creation_date : require ! ( cipher. creation_date) . parse ( ) ?,
858+ deleted_date : cipher. deleted_date . map ( |d| d. parse ( ) ) . transpose ( ) ?,
859+ revision_date : require ! ( cipher. revision_date) . parse ( ) ?,
860+ key : EncString :: try_from_optional ( cipher. key ) ?,
861+ archived_date : cipher. archived_date . map ( |d| d. parse ( ) ) . transpose ( ) ?,
862+ } )
863+ }
864+ }
865+
799866#[ cfg( test) ]
800867mod tests {
801868
0 commit comments