From e2bb9c1c608db1eb831e0305436177f7d11b00bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 12 May 2025 12:36:12 +0200 Subject: [PATCH 01/19] Make context local Ids autogenerated --- .../bitwarden-core/src/key_management/mod.rs | 4 +- crates/bitwarden-crypto/src/store/context.rs | 26 ++++--- crates/bitwarden-crypto/src/traits/key_id.rs | 17 ++++- crates/bitwarden-crypto/src/traits/mod.rs | 4 +- crates/bitwarden-send/src/send.rs | 4 +- .../bitwarden-vault/src/cipher/attachment.rs | 6 +- crates/bitwarden-vault/src/cipher/cipher.rs | 22 ++---- .../src/pure_crypto.rs | 76 ++++++------------- 8 files changed, 67 insertions(+), 92 deletions(-) diff --git a/crates/bitwarden-core/src/key_management/mod.rs b/crates/bitwarden-core/src/key_management/mod.rs index dd13ab21c..b2190bd8d 100644 --- a/crates/bitwarden-core/src/key_management/mod.rs +++ b/crates/bitwarden-core/src/key_management/mod.rs @@ -16,14 +16,14 @@ key_ids! { User, Organization(uuid::Uuid), #[local] - Local(&'static str), + Local(uuid::Uuid), } #[asymmetric] pub enum AsymmetricKeyId { UserPrivateKey, #[local] - Local(&'static str), + Local(uuid::Uuid), } pub KeyIds => SymmetricKeyId, AsymmetricKeyId; diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 261067af8..19be9005c 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -133,15 +133,13 @@ impl KeyStoreContext<'_, Ids> { /// /// * `encryption_key` - The key id used to decrypt the `encrypted_key`. It must already exist /// in the context - /// * `new_key_id` - The key id where the decrypted key will be stored. If it already exists, it - /// will be overwritten /// * `encrypted_key` - The key to decrypt pub fn unwrap_symmetric_key( &mut self, encryption_key: Ids::Symmetric, - new_key_id: Ids::Symmetric, encrypted_key: &EncString, ) -> Result { + let new_key_id = Ids::Symmetric::new_local(); let mut new_key_material = self.decrypt_data_with_symmetric_key(encryption_key, encrypted_key)?; @@ -245,7 +243,8 @@ impl KeyStoreContext<'_, Ids> { } /// Generate a new random symmetric key and store it in the context - pub fn generate_symmetric_key(&mut self, key_id: Ids::Symmetric) -> Result { + pub fn generate_symmetric_key(&mut self) -> Result { + let key_id = Ids::Symmetric::new_local(); let key = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); #[allow(deprecated)] self.set_symmetric_key(key_id, key)?; @@ -258,11 +257,11 @@ impl KeyStoreContext<'_, Ids> { /// Bitwarden `clients` repository. pub fn derive_shareable_key( &mut self, - key_id: Ids::Symmetric, secret: Zeroizing<[u8; 16]>, name: &str, info: Option<&str>, ) -> Result { + let key_id = Ids::Symmetric::new_local(); #[allow(deprecated)] self.set_symmetric_key( key_id, @@ -322,6 +321,12 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + pub fn add_local_symmetric_key(&mut self, key: SymmetricCryptoKey) -> Result { + let key_id = Ids::Symmetric::new_local(); + self.local_symmetric_keys.upsert(key_id, key); + Ok(key_id) + } + #[deprecated(note = "This function should ideally never be used outside this crate")] pub fn set_asymmetric_key( &mut self, @@ -379,6 +384,8 @@ impl KeyStoreContext<'_, Ids> { #[cfg(test)] #[allow(deprecated)] mod tests { + use uuid::Uuid; + use crate::{ store::{tests::DataView, KeyStore}, traits::tests::{TestIds, TestSymmKey}, @@ -412,7 +419,7 @@ mod tests { let mut ctx = store.context(); // Generate and insert a key - let key_1_id = TestSymmKey::C(1); + let key_1_id = TestSymmKey::C(Uuid::new_v4()); let key_1 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_1_id, key_1.clone()).unwrap(); @@ -420,7 +427,7 @@ mod tests { assert!(ctx.has_symmetric_key(key_1_id)); // Generate and insert a new key - let key_2_id = TestSymmKey::C(2); + let key_2_id = TestSymmKey::C(Uuid::new_v4()); let key_2 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_2_id, key_2.clone()).unwrap(); @@ -431,10 +438,7 @@ mod tests { let key_2_enc = ctx.wrap_symmetric_key(key_1_id, key_2_id).unwrap(); // Decrypt the new key with the old key in a different identifier - let new_key_id = TestSymmKey::C(3); - - ctx.unwrap_symmetric_key(key_1_id, new_key_id, &key_2_enc) - .unwrap(); + let new_key_id = ctx.unwrap_symmetric_key(key_1_id, &key_2_enc).unwrap(); // Now `key_2_id` and `new_key_id` contain the same key, so we should be able to encrypt // with one and decrypt with the other diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index ba997a5b0..e81396805 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -23,6 +23,8 @@ pub trait KeyId: /// Returns whether the key is local to the current context or shared globally by the /// key store. See [crate::store::KeyStoreContext] for more information. fn is_local(&self) -> bool; + + fn new_local() -> Self; } /// Represents a set of all the key identifiers that need to be defined to use a key store. @@ -81,6 +83,12 @@ macro_rules! key_ids { key_ids!(@variant_value $( $variant_tag )? ), )* } } + + fn new_local() -> Self { + $( + { key_ids!(@new_local $variant $( $variant_tag )? ) } + )* + } } )+ @@ -99,10 +107,15 @@ macro_rules! key_ids { ( @variant_value local ) => { true }; ( @variant_value ) => { false }; + + ( @new_local $variant:ident local ) => { Self::$variant(uuid::Uuid::new_v4()) }; + ( @new_local $variant:ident ) => {{}}; } #[cfg(test)] pub(crate) mod tests { + use uuid::Uuid; + use crate::{ traits::tests::{TestAsymmKey, TestSymmKey}, KeyId, @@ -112,10 +125,10 @@ pub(crate) mod tests { fn test_local() { assert!(!TestSymmKey::A(0).is_local()); assert!(!TestSymmKey::B((4, 10)).is_local()); - assert!(TestSymmKey::C(8).is_local()); + assert!(TestSymmKey::C(Uuid::new_v4()).is_local()); assert!(!TestAsymmKey::A(0).is_local()); assert!(!TestAsymmKey::B.is_local()); - assert!(TestAsymmKey::C("test").is_local()); + assert!(TestAsymmKey::C(Uuid::new_v4()).is_local()); } } diff --git a/crates/bitwarden-crypto/src/traits/mod.rs b/crates/bitwarden-crypto/src/traits/mod.rs index 28b811e36..5def73101 100644 --- a/crates/bitwarden-crypto/src/traits/mod.rs +++ b/crates/bitwarden-crypto/src/traits/mod.rs @@ -25,7 +25,7 @@ pub(crate) mod tests { B((u8, u8)), #[local] - C(u8), + C(uuid::Uuid), } #[asymmetric] @@ -33,7 +33,7 @@ pub(crate) mod tests { A(u8), B, #[local] - C(&'static str), + C(uuid::Uuid), } pub TestIds => TestSymmKey, TestAsymmKey; diff --git a/crates/bitwarden-send/src/send.rs b/crates/bitwarden-send/src/send.rs index a9f54ed4c..67b6c6d2a 100644 --- a/crates/bitwarden-send/src/send.rs +++ b/crates/bitwarden-send/src/send.rs @@ -143,8 +143,6 @@ pub struct SendListView { pub expiration_date: Option>, } -const SEND_KEY: SymmetricKeyId = SymmetricKeyId::Local("send_key"); - impl Send { pub fn get_key( ctx: &mut KeyStoreContext, @@ -160,7 +158,7 @@ impl Send { key: &[u8], ) -> Result { let key = Zeroizing::new(key.try_into().map_err(|_| CryptoError::InvalidKeyLen)?); - ctx.derive_shareable_key(SEND_KEY, key, "send", Some("send")) + ctx.derive_shareable_key(key, "send", Some("send")) } } diff --git a/crates/bitwarden-vault/src/cipher/attachment.rs b/crates/bitwarden-vault/src/cipher/attachment.rs index 5d997f631..e75239899 100644 --- a/crates/bitwarden-vault/src/cipher/attachment.rs +++ b/crates/bitwarden-vault/src/cipher/attachment.rs @@ -60,7 +60,6 @@ pub struct AttachmentFileView<'a> { pub attachment: AttachmentView, pub contents: &'a [u8], } -const ATTACHMENT_KEY: SymmetricKeyId = SymmetricKeyId::Local("attachment_key"); impl IdentifyKey for AttachmentFileView<'_> { fn key_identifier(&self) -> SymmetricKeyId { @@ -85,7 +84,7 @@ impl Encryptable for Attachment // Because this is a new attachment, we have to generate a key for it, encrypt the contents // with it, and then encrypt the key with the cipher key - let attachment_key = ctx.generate_symmetric_key(ATTACHMENT_KEY)?; + let attachment_key = ctx.generate_symmetric_key()?; let encrypted_contents = self.contents.encrypt(ctx, attachment_key)?; attachment.key = Some(ctx.wrap_symmetric_key(ciphers_key, attachment_key)?); @@ -122,8 +121,7 @@ impl Decryptable> for AttachmentFile { // Version 2 or 3, `AttachmentKey` or `CipherKey(AttachmentKey)` if let Some(attachment_key) = &self.attachment.key { - let content_key = - ctx.unwrap_symmetric_key(ciphers_key, ATTACHMENT_KEY, attachment_key)?; + let content_key = ctx.unwrap_symmetric_key(ciphers_key, attachment_key)?; self.contents.decrypt(ctx, content_key) } else { // Legacy attachment version 1, use user/org key diff --git a/crates/bitwarden-vault/src/cipher/cipher.rs b/crates/bitwarden-vault/src/cipher/cipher.rs index 36a1b011b..e77af2666 100644 --- a/crates/bitwarden-vault/src/cipher/cipher.rs +++ b/crates/bitwarden-vault/src/cipher/cipher.rs @@ -322,9 +322,8 @@ impl Cipher { key: SymmetricKeyId, ciphers_key: &Option, ) -> Result { - const CIPHER_KEY: SymmetricKeyId = SymmetricKeyId::Local("cipher_key"); match ciphers_key { - Some(ciphers_key) => ctx.unwrap_symmetric_key(key, CIPHER_KEY, ciphers_key), + Some(ciphers_key) => ctx.unwrap_symmetric_key(key, ciphers_key), None => Ok(key), } } @@ -455,9 +454,7 @@ impl CipherView { ) -> Result<(), CryptoError> { let old_ciphers_key = Cipher::decrypt_cipher_key(ctx, key, &self.key)?; - const NEW_KEY: SymmetricKeyId = SymmetricKeyId::Local("new_cipher_key"); - - let new_key = ctx.generate_symmetric_key(NEW_KEY)?; + let new_key = ctx.generate_symmetric_key()?; self.reencrypt_attachment_keys(ctx, old_ciphers_key, new_key)?; self.reencrypt_fido2_credentials(ctx, old_ciphers_key, new_key)?; @@ -929,9 +926,8 @@ mod tests { let mut original_cipher = generate_cipher(); { - const CIPHER_KEY: SymmetricKeyId = SymmetricKeyId::Local("test_cipher_key"); let mut ctx = key_store.context(); - let cipher_key = ctx.generate_symmetric_key(CIPHER_KEY).unwrap(); + let cipher_key = ctx.generate_symmetric_key().unwrap(); original_cipher.key = Some( ctx.wrap_symmetric_key(SymmetricKeyId::User, cipher_key) @@ -1053,9 +1049,7 @@ mod tests { // Attachment has a key that is encrypted with the user key, as the cipher has no key itself let (attachment_key_enc, attachment_key_val) = { let mut ctx = key_store.context(); - let attachment_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) - .unwrap(); + let attachment_key = ctx.generate_symmetric_key().unwrap(); let attachment_key_enc = ctx .wrap_symmetric_key(SymmetricKeyId::User, attachment_key) .unwrap(); @@ -1120,17 +1114,13 @@ mod tests { let mut ctx = key_store.context(); - let cipher_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_cipher_key")) - .unwrap(); + let cipher_key = ctx.generate_symmetric_key().unwrap(); let cipher_key_enc = ctx .wrap_symmetric_key(SymmetricKeyId::User, cipher_key) .unwrap(); // Attachment has a key that is encrypted with the cipher key - let attachment_key = ctx - .generate_symmetric_key(SymmetricKeyId::Local("test_attachment_key")) - .unwrap(); + let attachment_key = ctx.generate_symmetric_key().unwrap(); let attachment_key_enc = ctx.wrap_symmetric_key(cipher_key, attachment_key).unwrap(); let mut cipher = generate_cipher(); diff --git a/crates/bitwarden-wasm-internal/src/pure_crypto.rs b/crates/bitwarden-wasm-internal/src/pure_crypto.rs index 85a34b49b..7df7abe7c 100644 --- a/crates/bitwarden-wasm-internal/src/pure_crypto.rs +++ b/crates/bitwarden-wasm-internal/src/pure_crypto.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use bitwarden_core::key_management::{KeyIds, SymmetricKeyId}; +use bitwarden_core::key_management::KeyIds; use bitwarden_crypto::{ AsymmetricCryptoKey, AsymmetricPublicCryptoKey, CryptoError, Decryptable, EncString, Encryptable, Kdf, KeyDecryptable, KeyEncryptable, KeyStore, MasterKey, SymmetricCryptoKey, @@ -117,22 +117,13 @@ impl PureCrypto { ) -> Result { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("key_to_wrap"), - SymmetricCryptoKey::try_from(key_to_be_wrapped)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; + let key_to_wrap = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(key_to_be_wrapped)?)?; // Note: The order of arguments is different here, and should probably be refactored Ok(context - .wrap_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricKeyId::Local("key_to_wrap"), - )? + .wrap_symmetric_key(wrapping_key, key_to_wrap)? .to_string()) } @@ -144,19 +135,14 @@ impl PureCrypto { ) -> Result, CryptoError> { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; + // Note: The order of arguments is different here, and should probably be refactored - context.unwrap_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricKeyId::Local("wrapped_key"), - &EncString::from_str(wrapped_key.as_str())?, - )?; + let unwrapped = context + .unwrap_symmetric_key(wrapping_key, &EncString::from_str(wrapped_key.as_str())?)?; #[allow(deprecated)] - let key = context.dangerous_get_symmetric_key(SymmetricKeyId::Local("wrapped_key"))?; + let key = context.dangerous_get_symmetric_key(unwrapped)?; Ok(key.to_encoded()) } @@ -171,14 +157,11 @@ impl PureCrypto { ) -> Result { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; // Note: The order of arguments is different here, and should probably be refactored Ok(encapsulation_key - .encrypt(&mut context, SymmetricKeyId::Local("wrapping_key"))? + .encrypt(&mut context, wrapping_key)? .to_string()) } @@ -190,14 +173,10 @@ impl PureCrypto { ) -> Result, CryptoError> { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; // Note: The order of arguments is different here, and should probably be refactored - EncString::from_str(wrapped_key.as_str())? - .decrypt(&mut context, SymmetricKeyId::Local("wrapping_key")) + EncString::from_str(wrapped_key.as_str())?.decrypt(&mut context, wrapping_key) } /// Wraps (encrypts) a PKCS8 DER encoded decapsulation (private) key using a symmetric wrapping @@ -208,14 +187,11 @@ impl PureCrypto { ) -> Result { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; // Note: The order of arguments is different here, and should probably be refactored Ok(decapsulation_key - .encrypt(&mut context, SymmetricKeyId::Local("wrapping_key"))? + .encrypt(&mut context, wrapping_key)? .to_string()) } @@ -227,14 +203,10 @@ impl PureCrypto { ) -> Result, CryptoError> { let tmp_store: KeyStore = KeyStore::default(); let mut context = tmp_store.context(); - #[allow(deprecated)] - context.set_symmetric_key( - SymmetricKeyId::Local("wrapping_key"), - SymmetricCryptoKey::try_from(wrapping_key)?, - )?; + let wrapping_key = + context.add_local_symmetric_key(SymmetricCryptoKey::try_from(wrapping_key)?)?; // Note: The order of arguments is different here, and should probably be refactored - EncString::from_str(wrapped_key.as_str())? - .decrypt(&mut context, SymmetricKeyId::Local("wrapping_key")) + EncString::from_str(wrapped_key.as_str())?.decrypt(&mut context, wrapping_key) } /// Encapsulates (encrypts) a symmetric key using an asymmetric encapsulation key (public key) From 7218aba67686bf3163eb7eb0a0f2b8d6dbaa110b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 12 May 2025 12:52:00 +0200 Subject: [PATCH 02/19] Update docs --- crates/bitwarden-crypto/src/store/context.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 19be9005c..2a685642e 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -51,11 +51,10 @@ use crate::{ /// # } /// # } /// -/// const LOCAL_KEY: SymmKeyId = SymmKeyId::Local("local_key_id"); /// /// impl Encryptable for Data { /// fn encrypt(&self, ctx: &mut KeyStoreContext, key: SymmKeyId) -> Result { -/// let local_key_id = ctx.unwrap_symmetric_key(key, LOCAL_KEY, &self.key)?; +/// let local_key_id = ctx.unwrap_symmetric_key(key, &self.key)?; /// self.name.encrypt(ctx, local_key_id) /// } /// } From ab25b955571d75d685e5c1204affd2b093eb2f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Thu, 12 Jun 2025 18:39:05 +0200 Subject: [PATCH 03/19] Add comments --- crates/bitwarden-crypto/src/store/context.rs | 1 + crates/bitwarden-crypto/src/traits/key_id.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 92d853266..4982cf7bd 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -323,6 +323,7 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + /// Add a new symmetric key to the local context, returning a new unique identifier for it. pub fn add_local_symmetric_key(&mut self, key: SymmetricCryptoKey) -> Result { let key_id = Ids::Symmetric::new_local(); self.local_symmetric_keys.upsert(key_id, key); diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index 0396fb37d..b6a091736 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -25,6 +25,7 @@ pub trait KeyId: /// key store. See [crate::store::KeyStoreContext] for more information. fn is_local(&self) -> bool; + /// Creates a new unique local key identifier. fn new_local() -> Self; } From d9707e03b5c561874b5702623fd8e106906f0b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Thu, 12 Jun 2025 18:50:49 +0200 Subject: [PATCH 04/19] Fix tests --- crates/bitwarden-crypto/src/store/context.rs | 5 ++++- crates/bitwarden-crypto/src/store/mod.rs | 4 +++- crates/bitwarden-crypto/src/traits/key_id.rs | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 4982cf7bd..6e38f89c6 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -33,11 +33,14 @@ use crate::{ /// # #[symmetric] /// # pub enum SymmKeyId { /// # User, -/// # Local(&'static str), +/// # #[local] +/// # Local(uuid::Uuid), /// # } /// # #[asymmetric] /// # pub enum AsymmKeyId { /// # UserPrivate, +/// # #[local] +/// # Local(uuid::Uuid), /// # } /// # pub Ids => SymmKeyId, AsymmKeyId; /// # } diff --git a/crates/bitwarden-crypto/src/store/mod.rs b/crates/bitwarden-crypto/src/store/mod.rs index f447f58b2..06169f587 100644 --- a/crates/bitwarden-crypto/src/store/mod.rs +++ b/crates/bitwarden-crypto/src/store/mod.rs @@ -52,11 +52,13 @@ pub use context::KeyStoreContext; /// pub enum SymmKeyId { /// User, /// #[local] -/// Local(&'static str) +/// Local(uuid::Uuid), /// } /// #[asymmetric] /// pub enum AsymmKeyId { /// UserPrivate, +/// #[local] +/// Local(uuid::Uuid), /// } /// pub Ids => SymmKeyId, AsymmKeyId; /// } diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index b6a091736..aca111d07 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -48,12 +48,14 @@ pub trait KeyIds { /// User, /// Org(uuid::Uuid), /// #[local] -/// Local(&'static str), +/// Local(uuid::Uuid), /// } /// /// #[asymmetric] /// pub enum AsymmKeyId { /// PrivateKey, +/// #[local] +/// Local(uuid::Uuid), /// } /// pub Ids => SymmKeyId, AsymmKeyId; /// } From 237cb200025221a827c7a7d6d3560612a32b3bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Thu, 26 Jun 2025 19:04:08 +0200 Subject: [PATCH 05/19] Add signing keys --- .../src/key_management/crypto.rs | 7 +++---- crates/bitwarden-crypto/src/store/context.rs | 20 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/crates/bitwarden-core/src/key_management/crypto.rs b/crates/bitwarden-core/src/key_management/crypto.rs index 3a1cd66a4..05a015720 100644 --- a/crates/bitwarden-core/src/key_management/crypto.rs +++ b/crates/bitwarden-core/src/key_management/crypto.rs @@ -20,7 +20,7 @@ use {tsify_next::Tsify, wasm_bindgen::prelude::*}; use crate::{ client::{encryption_settings::EncryptionSettingsError, LoginMethod, UserLoginMethod}, - key_management::{AsymmetricKeyId, SigningKeyId, SymmetricKeyId}, + key_management::{AsymmetricKeyId, SymmetricKeyId}, Client, NotAuthenticatedError, VaultLockedError, WrongPasswordError, }; @@ -595,9 +595,8 @@ pub fn make_user_signing_keys_for_enrollment( // Make new keypair and sign the public key with it let signature_keypair = SigningKey::make(SignatureAlgorithm::Ed25519); - let temporary_signature_keypair_id = SigningKeyId::Local("temporary_key_for_rotation"); - #[allow(deprecated)] - ctx.set_signing_key(temporary_signature_keypair_id, signature_keypair.clone())?; + let temporary_signature_keypair_id = ctx.add_local_signing_key(signature_keypair.clone())?; + let signed_public_key = ctx.make_signed_public_key( AsymmetricKeyId::UserPrivateKey, temporary_signature_keypair_id, diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 3a42e866b..97598dbfc 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -259,20 +259,13 @@ impl KeyStoreContext<'_, Ids> { /// Generate a new random symmetric key and store it in the context pub fn generate_symmetric_key(&mut self) -> Result { - let key_id = Ids::Symmetric::new_local(); - let key = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); - #[allow(deprecated)] - self.set_symmetric_key(key_id, key)?; - Ok(key_id) + self.add_local_symmetric_key(SymmetricCryptoKey::make_aes256_cbc_hmac_key()) } /// Generate a new signature key using the current default algorithm, and store it in the /// context - pub fn make_signing_key(&mut self, key_id: Ids::Signing) -> Result { - let key = SigningKey::make(SignatureAlgorithm::default_algorithm()); - #[allow(deprecated)] - self.set_signing_key(key_id, key)?; - Ok(key_id) + pub fn make_signing_key(&mut self) -> Result { + self.add_local_signing_key(SigningKey::make(SignatureAlgorithm::default_algorithm())) } /// Derive a shareable key using hkdf from secret and name and store it in the context. @@ -397,6 +390,13 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + /// Add a new signing key to the local context, returning a new unique identifier for it. + pub fn add_local_signing_key(&mut self, key: SigningKey) -> Result { + let key_id = Ids::Signing::new_local(); + self.local_signing_keys.upsert(key_id, key); + Ok(key_id) + } + /// Sets a signing key in the context #[deprecated(note = "This function should ideally never be used outside this crate")] pub fn set_signing_key(&mut self, key_id: Ids::Signing, key: SigningKey) -> Result<()> { From 7b2b49fdca193ce77bc020fedea8ea707557cdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 30 Jun 2025 15:54:36 +0200 Subject: [PATCH 06/19] Introduce opaque local ids --- .../bitwarden-core/src/key_management/mod.rs | 6 +-- crates/bitwarden-crypto/src/lib.rs | 2 +- crates/bitwarden-crypto/src/store/context.rs | 22 +++++------ crates/bitwarden-crypto/src/store/mod.rs | 4 +- crates/bitwarden-crypto/src/traits/key_id.rs | 39 +++++++++++++------ crates/bitwarden-crypto/src/traits/mod.rs | 8 ++-- 6 files changed, 48 insertions(+), 33 deletions(-) diff --git a/crates/bitwarden-core/src/key_management/mod.rs b/crates/bitwarden-core/src/key_management/mod.rs index 5d90aadcd..57eed5b9e 100644 --- a/crates/bitwarden-core/src/key_management/mod.rs +++ b/crates/bitwarden-core/src/key_management/mod.rs @@ -25,21 +25,21 @@ key_ids! { User, Organization(uuid::Uuid), #[local] - Local(uuid::Uuid), + Local(LocalId), } #[asymmetric] pub enum AsymmetricKeyId { UserPrivateKey, #[local] - Local(uuid::Uuid), + Local(LocalId), } #[signing] pub enum SigningKeyId { UserSigningKey, #[local] - Local(uuid::Uuid), + Local(LocalId), } pub KeyIds => SymmetricKeyId, AsymmetricKeyId, SigningKeyId; diff --git a/crates/bitwarden-crypto/src/lib.rs b/crates/bitwarden-crypto/src/lib.rs index 60428d8a4..b6009efd0 100644 --- a/crates/bitwarden-crypto/src/lib.rs +++ b/crates/bitwarden-crypto/src/lib.rs @@ -39,7 +39,7 @@ pub use signing::*; mod traits; mod xchacha20; pub use traits::{ - CompositeEncryptable, Decryptable, IdentifyKey, KeyId, KeyIds, PrimitiveEncryptable, + CompositeEncryptable, Decryptable, IdentifyKey, KeyId, KeyIds, LocalId, PrimitiveEncryptable, }; pub use zeroizing_alloc::ZeroAlloc as ZeroizingAllocator; diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index ed2c41582..4e32f87f1 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -10,7 +10,7 @@ use super::KeyStoreInner; use crate::{ derive_shareable_key, error::UnsupportedOperation, signing, store::backend::StoreBackend, AsymmetricCryptoKey, BitwardenLegacyKeyBytes, ContentFormat, CryptoError, EncString, KeyId, - KeyIds, Result, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, + KeyIds, LocalId, Result, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, SignedPublicKeyMessage, SigningKey, SymmetricCryptoKey, UnsignedSharedKey, }; @@ -38,13 +38,13 @@ use crate::{ /// # pub enum SymmKeyId { /// # User, /// # #[local] -/// # Local(uuid::Uuid), +/// # Local(LocalId), /// # } /// # #[asymmetric] /// # pub enum AsymmKeyId { /// # UserPrivate, /// # #[local] -/// # Local(uuid::Uuid), +/// # Local(LocalId), /// # } /// # #[signing] /// # pub enum SigningKeyId { @@ -184,7 +184,7 @@ impl KeyStoreContext<'_, Ids> { _ => return Err(CryptoError::InvalidKey), }; - let new_key_id = Ids::Symmetric::new_local(); + let new_key_id = Ids::Symmetric::new_local(LocalId::new()); #[allow(deprecated)] self.set_symmetric_key(new_key_id, key)?; @@ -324,7 +324,7 @@ impl KeyStoreContext<'_, Ids> { name: &str, info: Option<&str>, ) -> Result { - let key_id = Ids::Symmetric::new_local(); + let key_id = Ids::Symmetric::new_local(LocalId::new()); #[allow(deprecated)] self.set_symmetric_key( key_id, @@ -413,7 +413,7 @@ impl KeyStoreContext<'_, Ids> { /// Add a new symmetric key to the local context, returning a new unique identifier for it. pub fn add_local_symmetric_key(&mut self, key: SymmetricCryptoKey) -> Result { - let key_id = Ids::Symmetric::new_local(); + let key_id = Ids::Symmetric::new_local(LocalId::new()); self.local_symmetric_keys.upsert(key_id, key); Ok(key_id) } @@ -438,7 +438,7 @@ impl KeyStoreContext<'_, Ids> { /// Add a new signing key to the local context, returning a new unique identifier for it. pub fn add_local_signing_key(&mut self, key: SigningKey) -> Result { - let key_id = Ids::Signing::new_local(); + let key_id = Ids::Signing::new_local(LocalId::new()); self.local_signing_keys.upsert(key_id, key); Ok(key_id) } @@ -529,7 +529,6 @@ impl KeyStoreContext<'_, Ids> { #[allow(deprecated)] mod tests { use serde::{Deserialize, Serialize}; - use uuid::Uuid; use crate::{ store::{ @@ -537,7 +536,7 @@ mod tests { KeyStore, }, traits::tests::{TestIds, TestSigningKey, TestSymmKey}, - CompositeEncryptable, CryptoError, Decryptable, SignatureAlgorithm, SigningKey, + CompositeEncryptable, CryptoError, Decryptable, LocalId, SignatureAlgorithm, SigningKey, SigningNamespace, SymmetricCryptoKey, }; @@ -579,11 +578,12 @@ mod tests { #[test] fn test_key_encryption() { let store: KeyStore = KeyStore::default(); + let local = LocalId::new(); let mut ctx = store.context(); // Generate and insert a key - let key_1_id = TestSymmKey::C(Uuid::new_v4()); + let key_1_id = TestSymmKey::C(local); let key_1 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_1_id, key_1.clone()).unwrap(); @@ -591,7 +591,7 @@ mod tests { assert!(ctx.has_symmetric_key(key_1_id)); // Generate and insert a new key - let key_2_id = TestSymmKey::C(Uuid::new_v4()); + let key_2_id = TestSymmKey::C(local); let key_2 = SymmetricCryptoKey::make_aes256_cbc_hmac_key(); ctx.set_symmetric_key(key_2_id, key_2.clone()).unwrap(); diff --git a/crates/bitwarden-crypto/src/store/mod.rs b/crates/bitwarden-crypto/src/store/mod.rs index 9a07cf5e3..fe802dfd9 100644 --- a/crates/bitwarden-crypto/src/store/mod.rs +++ b/crates/bitwarden-crypto/src/store/mod.rs @@ -52,13 +52,13 @@ pub use context::KeyStoreContext; /// pub enum SymmKeyId { /// User, /// #[local] -/// Local(uuid::Uuid), +/// Local(LocalId), /// } /// #[asymmetric] /// pub enum AsymmKeyId { /// UserPrivate, /// #[local] -/// Local(uuid::Uuid), +/// Local(LocalId), /// } /// #[signing] /// pub enum SigningKeyId { diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index 5f6bcd540..87d54c102 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -26,7 +26,7 @@ pub trait KeyId: fn is_local(&self) -> bool; /// Creates a new unique local key identifier. - fn new_local() -> Self; + fn new_local(id: LocalId) -> Self; } /// Represents a set of all the key identifiers that need to be defined to use a key store. @@ -40,6 +40,17 @@ pub trait KeyIds { type Signing: KeyId; } +/// An opaque identifier for a local key. Currently only contains a unique ID, but it can be +/// extended to contain scope information to allow cleanup on scope exit. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)] +pub struct LocalId(pub(crate) uuid::Uuid); + +impl LocalId { + pub(crate) fn new() -> Self { + LocalId(uuid::Uuid::new_v4()) + } +} + /// Just a small derive_like macro that can be used to generate the key identifier enums. /// Example usage: /// ```rust @@ -50,14 +61,14 @@ pub trait KeyIds { /// User, /// Org(uuid::Uuid), /// #[local] -/// Local(uuid::Uuid), +/// Local(LocalId), /// } /// /// #[asymmetric] /// pub enum AsymmKeyId { /// PrivateKey, /// #[local] -/// Local(uuid::Uuid), +/// Local(LocalId), /// } /// /// #[signing] @@ -81,6 +92,9 @@ macro_rules! key_ids { )+ $ids_vis:vis $ids_name:ident => $symm_name:ident, $asymm_name:ident, $signing_name:ident; ) => { + + use $crate::LocalId; + $( #[derive(std::fmt::Debug, Clone, Copy, std::hash::Hash, Eq, PartialEq, Ord, PartialOrd)] #[allow(missing_docs)] @@ -99,9 +113,9 @@ macro_rules! key_ids { )* } } - fn new_local() -> Self { + fn new_local(id: LocalId) -> Self { $( - { key_ids!(@new_local $variant $( $variant_tag )? ) } + { key_ids!(@new_local $variant id $( $variant_tag )? ) } )* } } @@ -126,31 +140,32 @@ macro_rules! key_ids { ( @variant_value local ) => { true }; ( @variant_value ) => { false }; - ( @new_local $variant:ident local ) => { Self::$variant(uuid::Uuid::new_v4()) }; - ( @new_local $variant:ident ) => {{}}; + ( @new_local $variant:ident $id:ident local ) => { Self::$variant($id) }; + ( @new_local $variant:ident $id:ident ) => {{}}; } #[cfg(test)] pub(crate) mod tests { - use uuid::Uuid; use crate::{ traits::tests::{TestAsymmKey, TestSigningKey, TestSymmKey}, - KeyId, + KeyId, LocalId, }; #[test] fn test_local() { + let local = LocalId::new(); + assert!(!TestSymmKey::A(0).is_local()); assert!(!TestSymmKey::B((4, 10)).is_local()); - assert!(TestSymmKey::C(Uuid::new_v4()).is_local()); + assert!(TestSymmKey::C(local).is_local()); assert!(!TestAsymmKey::A(0).is_local()); assert!(!TestAsymmKey::B.is_local()); - assert!(TestAsymmKey::C(Uuid::new_v4()).is_local()); + assert!(TestAsymmKey::C(local).is_local()); assert!(!TestSigningKey::A(0).is_local()); assert!(!TestSigningKey::B.is_local()); - assert!(TestSigningKey::C(Uuid::new_v4()).is_local()); + assert!(TestSigningKey::C(local).is_local()); } } diff --git a/crates/bitwarden-crypto/src/traits/mod.rs b/crates/bitwarden-crypto/src/traits/mod.rs index 4ba00a197..54946075d 100644 --- a/crates/bitwarden-crypto/src/traits/mod.rs +++ b/crates/bitwarden-crypto/src/traits/mod.rs @@ -5,7 +5,7 @@ mod decryptable; pub use decryptable::Decryptable; pub(crate) mod key_id; -pub use key_id::{KeyId, KeyIds}; +pub use key_id::{KeyId, KeyIds, LocalId}; /// Types implementing [IdentifyKey] are capable of knowing which cryptographic key is /// needed to encrypt/decrypt them. @@ -27,7 +27,7 @@ pub(crate) mod tests { B((u8, u8)), #[local] - C(uuid::Uuid), + C(LocalId), } #[asymmetric] @@ -35,7 +35,7 @@ pub(crate) mod tests { A(u8), B, #[local] - C(uuid::Uuid), + C(LocalId), } #[signing] @@ -43,7 +43,7 @@ pub(crate) mod tests { A(u8), B, #[local] - C(uuid::Uuid), + C(LocalId), } pub TestIds => TestSymmKey, TestAsymmKey, TestSigningKey; From 817cf6e2c724106edb140804ce103ca3b814f5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 30 Jun 2025 15:55:53 +0200 Subject: [PATCH 07/19] Fmt --- crates/bitwarden-crypto/src/store/context.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 4e32f87f1..58371f7e3 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -436,13 +436,6 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } - /// Add a new signing key to the local context, returning a new unique identifier for it. - pub fn add_local_signing_key(&mut self, key: SigningKey) -> Result { - let key_id = Ids::Signing::new_local(LocalId::new()); - self.local_signing_keys.upsert(key_id, key); - Ok(key_id) - } - /// Sets a signing key in the context #[deprecated(note = "This function should ideally never be used outside this crate")] pub fn set_signing_key(&mut self, key_id: Ids::Signing, key: SigningKey) -> Result<()> { @@ -454,6 +447,13 @@ impl KeyStoreContext<'_, Ids> { Ok(()) } + /// Add a new signing key to the local context, returning a new unique identifier for it. + pub fn add_local_signing_key(&mut self, key: SigningKey) -> Result { + let key_id = Ids::Signing::new_local(LocalId::new()); + self.local_signing_keys.upsert(key_id, key); + Ok(key_id) + } + pub(crate) fn decrypt_data_with_symmetric_key( &self, key: Ids::Symmetric, From c4cf8ec1816f791f80aa246841c0502ade0e9312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garci=CC=81a?= Date: Mon, 30 Jun 2025 16:51:12 +0200 Subject: [PATCH 08/19] Missing docs --- crates/bitwarden-crypto/src/store/context.rs | 2 ++ crates/bitwarden-crypto/src/store/mod.rs | 2 ++ crates/bitwarden-crypto/src/traits/key_id.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 58371f7e3..63ec3784b 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -49,6 +49,8 @@ use crate::{ /// # #[signing] /// # pub enum SigningKeyId { /// # UserSigning, +/// # #[local] +/// # Local(LocalId), /// # } /// # pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; /// # } diff --git a/crates/bitwarden-crypto/src/store/mod.rs b/crates/bitwarden-crypto/src/store/mod.rs index fe802dfd9..55fd69d11 100644 --- a/crates/bitwarden-crypto/src/store/mod.rs +++ b/crates/bitwarden-crypto/src/store/mod.rs @@ -63,6 +63,8 @@ pub use context::KeyStoreContext; /// #[signing] /// pub enum SigningKeyId { /// UserSigning, +/// #[local] +/// Local(LocalId), /// } /// pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; /// } diff --git a/crates/bitwarden-crypto/src/traits/key_id.rs b/crates/bitwarden-crypto/src/traits/key_id.rs index 87d54c102..a1b756d0d 100644 --- a/crates/bitwarden-crypto/src/traits/key_id.rs +++ b/crates/bitwarden-crypto/src/traits/key_id.rs @@ -74,6 +74,8 @@ impl LocalId { /// #[signing] /// pub enum SigningKeyId { /// SigningKey, +/// #[local] +/// Local(LocalId), /// } /// /// pub Ids => SymmKeyId, AsymmKeyId, SigningKeyId; From 7963cdc27151cc82ab13ccbc5aeecfe48edd389d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Wed, 8 Oct 2025 12:18:26 +0200 Subject: [PATCH 09/19] [PM-22591] Unify client repository initialization (#484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## đŸŽŸī¸ Tracking https://bitwarden.atlassian.net/browse/PM-22591 ## 📔 Objective Currently, all app crates (wasm, uniffi) need to declare all the client managed repositories that they allow clients to implement. This means that all the crates need to be updated when adding more repositories, which adds more steps to implementations and can lead to things being out of sync. This PR unifies the declaration of client managed repositories so that there's only one place where they are defined. While I was at it, I've changed slightly the way we register the repositories. Rather than provide one function for each (`register_cipher_repository`/`register_folder_repository`) I provide a single function that takes an object that contains all the repos. This is easier to generate and should make it easier to know if any of the repos are missing (you should get a compile error). I left the previous ones for backwards-compat Sadly both wasm and uniffi have a lot of compile time type shenanigans and macros which don't make this easy, so this solution contains multiple parts: - In `bitwarden_wasm` and `bitwarden_uniffi` we already have a macro that creates the repository implementations based on a type. This has been expanded to take multiple types and also create the `Repositories` struct which is just a grouping of all of them. Now, instead of manually calling these macros manually for each type, they instead get passed to the `bitwarden_pm::create_client_managed_repositories!` macro. - The `bitwarden_pm::create_client_managed_repositories!` macro's only purpose is to call the passed macro repeatedly with all the types that need to be created. This is the only way I found to lazily define the types in `bitwarden-pm` so that they would be usable in macros in the other crates. The definition is fairly repetitive with the types, because we don't have easy ways to change the case of identifiers or merge them together. We could use the `paste` crate to avoid the repetition but didn't seem worth it at the moment Note that in the past we placed the sdk-managed definitions in a shared `bitwarden-state-migrations` crate, but now that we have the new `bitwarden-pm` crate as a shared crate focused on password manager functionality I don't think `bitwarden-state-migrations` is needed. Instead this PR moves the sdk-managed definitions to `bitwarden-pm` (next to the new client managed repositories macro) and deletes the `bitwarden-state-migrations` crate. ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## đŸĻŽ Reviewer guidelines - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or â„šī¸ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or âš ī¸ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or â™ģī¸ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --- Cargo.lock | 11 +- Cargo.toml | 1 - crates/bitwarden-pm/Cargo.toml | 3 + crates/bitwarden-pm/src/lib.rs | 7 + crates/bitwarden-pm/src/migrations.rs | 32 ++++ crates/bitwarden-state-migrations/Cargo.toml | 21 --- crates/bitwarden-state-migrations/README.md | 4 - crates/bitwarden-state-migrations/src/lib.rs | 15 -- crates/bitwarden-state/README.md | 58 +++---- crates/bitwarden-uniffi/Cargo.toml | 1 - crates/bitwarden-uniffi/src/platform/mod.rs | 16 +- .../src/platform/repository.rs | 120 +++++++++------ crates/bitwarden-wasm-internal/Cargo.toml | 1 - .../src/platform/mod.rs | 16 +- .../src/platform/repository.rs | 144 +++++++++++------- 15 files changed, 245 insertions(+), 205 deletions(-) create mode 100644 crates/bitwarden-pm/src/migrations.rs delete mode 100644 crates/bitwarden-state-migrations/Cargo.toml delete mode 100644 crates/bitwarden-state-migrations/README.md delete mode 100644 crates/bitwarden-state-migrations/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 727ea70ea..972fe3366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -734,6 +734,7 @@ dependencies = [ "bitwarden-fido", "bitwarden-generators", "bitwarden-send", + "bitwarden-state", "bitwarden-vault", "tsify", "uniffi", @@ -816,14 +817,6 @@ dependencies = [ "uniffi", ] -[[package]] -name = "bitwarden-state-migrations" -version = "1.0.0" -dependencies = [ - "bitwarden-state", - "bitwarden-vault", -] - [[package]] name = "bitwarden-test" version = "1.0.0" @@ -873,7 +866,6 @@ dependencies = [ "bitwarden-send", "bitwarden-ssh", "bitwarden-state", - "bitwarden-state-migrations", "bitwarden-uniffi-error", "bitwarden-vault", "chrono", @@ -960,7 +952,6 @@ dependencies = [ "bitwarden-pm", "bitwarden-ssh", "bitwarden-state", - "bitwarden-state-migrations", "bitwarden-threading", "bitwarden-vault", "console_error_panic_hook", diff --git a/Cargo.toml b/Cargo.toml index d7e9d3eb5..675ecfcdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,6 @@ bitwarden-send = { path = "crates/bitwarden-send", version = "=1.0.0" } bitwarden-sm = { path = "bitwarden_license/bitwarden-sm", version = "=1.0.0" } bitwarden-ssh = { path = "crates/bitwarden-ssh", version = "=1.0.0" } bitwarden-state = { path = "crates/bitwarden-state", version = "=1.0.0" } -bitwarden-state-migrations = { path = "crates/bitwarden-state-migrations", version = "=1.0.0" } bitwarden-test = { path = "crates/bitwarden-test", version = "=1.0.0" } bitwarden-threading = { path = "crates/bitwarden-threading", version = "=1.0.0" } bitwarden-uniffi-error = { path = "crates/bitwarden-uniffi-error", version = "=1.0.0" } diff --git a/crates/bitwarden-pm/Cargo.toml b/crates/bitwarden-pm/Cargo.toml index 7a90980a5..b084522ae 100644 --- a/crates/bitwarden-pm/Cargo.toml +++ b/crates/bitwarden-pm/Cargo.toml @@ -24,6 +24,7 @@ uniffi = [ "bitwarden-fido/uniffi", "bitwarden-generators/uniffi", "bitwarden-send/uniffi", + "bitwarden-state/uniffi", "bitwarden-vault/uniffi", "dep:uniffi" ] # Uniffi bindings @@ -33,6 +34,7 @@ wasm = [ "bitwarden-core/wasm", "bitwarden-exporters/wasm", "bitwarden-generators/wasm", + "bitwarden-state/wasm", "bitwarden-vault/wasm", "dep:wasm-bindgen", "dep:wasm-bindgen-futures", @@ -48,6 +50,7 @@ bitwarden-exporters = { workspace = true } bitwarden-fido = { workspace = true } bitwarden-generators = { workspace = true } bitwarden-send = { workspace = true } +bitwarden-state = { workspace = true } bitwarden-vault = { workspace = true } tsify = { workspace = true, optional = true } diff --git a/crates/bitwarden-pm/src/lib.rs b/crates/bitwarden-pm/src/lib.rs index aeb23a24d..81e282dd7 100644 --- a/crates/bitwarden-pm/src/lib.rs +++ b/crates/bitwarden-pm/src/lib.rs @@ -27,6 +27,8 @@ pub mod clients { #[cfg(feature = "bitwarden-license")] pub use commercial::CommercialPasswordManagerClient; +pub mod migrations; + /// The main entry point for the Bitwarden Password Manager SDK pub struct PasswordManagerClient(pub bitwarden_core::Client); @@ -46,6 +48,11 @@ impl PasswordManagerClient { )) } + /// Platform operations + pub fn platform(&self) -> bitwarden_core::platform::PlatformClient { + self.0.platform() + } + /// Auth operations pub fn auth(&self) -> bitwarden_auth::AuthClient { self.0.auth_new() diff --git a/crates/bitwarden-pm/src/migrations.rs b/crates/bitwarden-pm/src/migrations.rs new file mode 100644 index 000000000..242ae87e3 --- /dev/null +++ b/crates/bitwarden-pm/src/migrations.rs @@ -0,0 +1,32 @@ +//! Manages repository migrations for the Bitwarden SDK. + +use bitwarden_state::repository::{RepositoryItem, RepositoryMigrationStep, RepositoryMigrations}; +use bitwarden_vault::{Cipher, Folder}; + +/// Returns a list of all SDK-managed repository migrations. +pub fn get_sdk_managed_migrations() -> RepositoryMigrations { + use RepositoryMigrationStep::*; + RepositoryMigrations::new(vec![ + // Add any new migrations here. Note that order matters, and that removing a repository + // requires a separate migration step using `Remove(...)`. + Add(Cipher::data()), + Add(Folder::data()), + ]) +} + +/// Macro to create the client managed repositories for the SDK. +/// To add a new repository, add it to the list in the macro invocation. +/// This is meant to be used by the final application crates (e.g., bitwarden-uniffi, +/// bitwarden-wasm-internal, bw). +#[macro_export] +macro_rules! create_client_managed_repositories { + ($container_name:ident, $macro:ident) => { + $macro! { + $container_name; + // List any SDK-managed repositories here. The format is: + // , , , + ::bitwarden_vault::Cipher, Cipher, cipher, CipherRepository; + ::bitwarden_vault::Folder, Folder, folder, FolderRepository; + } + }; +} diff --git a/crates/bitwarden-state-migrations/Cargo.toml b/crates/bitwarden-state-migrations/Cargo.toml deleted file mode 100644 index f0cadc8d0..000000000 --- a/crates/bitwarden-state-migrations/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "bitwarden-state-migrations" -version.workspace = true -authors.workspace = true -edition.workspace = true -rust-version.workspace = true -homepage.workspace = true -repository.workspace = true -license-file.workspace = true -keywords.workspace = true - -[features] -uniffi = ["bitwarden-vault/uniffi"] -wasm = ["bitwarden-vault/wasm"] - -[dependencies] -bitwarden-state = { workspace = true } -bitwarden-vault = { workspace = true } - -[lints] -workspace = true diff --git a/crates/bitwarden-state-migrations/README.md b/crates/bitwarden-state-migrations/README.md deleted file mode 100644 index a0fa7635f..000000000 --- a/crates/bitwarden-state-migrations/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# bitwarden-state-migrations - -This crate contains migrations for the SDK-managed state framework. It should only be imported by -the final application crates (`bitwarden-wasm-internal` and `bitwarden-uniffi`) diff --git a/crates/bitwarden-state-migrations/src/lib.rs b/crates/bitwarden-state-migrations/src/lib.rs deleted file mode 100644 index b6585cac2..000000000 --- a/crates/bitwarden-state-migrations/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![doc = include_str!("../README.md")] - -use bitwarden_state::repository::{RepositoryItem, RepositoryMigrationStep, RepositoryMigrations}; -use bitwarden_vault::{Cipher, Folder}; - -/// Returns a list of all SDK-managed repository migrations. -pub fn get_sdk_managed_migrations() -> RepositoryMigrations { - use RepositoryMigrationStep::*; - RepositoryMigrations::new(vec![ - // Add any new migrations here. Note that order matters, and that removing a repository - // requires a separate migration step using `Remove(...)`. - Add(Cipher::data()), - Add(Folder::data()), - ]) -} diff --git a/crates/bitwarden-state/README.md b/crates/bitwarden-state/README.md index bda45c114..f3f72dfca 100644 --- a/crates/bitwarden-state/README.md +++ b/crates/bitwarden-state/README.md @@ -39,21 +39,20 @@ need to define some functions in `bitwarden-wasm-internal` and `bitwarden-uniffi applications to provide their `Repository` implementations. The implementations themselves will be very simple as we provide macros that take care of the brunt of the work. -### Client-Managed State in WASM +To add support for a new `Repository`, add it to the list defined at the end of +`crates/bitwarden-pm/src/migrations.rs`. -For WASM, we need to define a new `Repository` for our type and provide a function that will accept -it. This is done in the file `crates/bitwarden-wasm-internal/src/platform/mod.rs`, you can check the -provided example: - -```rust,ignore -repository::create_wasm_repository!(CipherRepository, Cipher, "Repository"); - -#[wasm_bindgen] -impl StateClient { - pub fn register_cipher_repository(&self, store: CipherRepository) { - let store = store.into_channel_impl(); - self.0.platform().state().register_client_managed(store) - } +```rust +macro_rules! create_client_managed_repositories { + ($container_name:ident, $macro:ident) => { + $macro! { + $container_name; + // List any SDK-managed repositories here. The format is: + // , , , + ::bitwarden_vault::Cipher, Cipher, cipher, CipherRepository; + ::bitwarden_vault::Folder, Folder, folder, FolderRepository; + } + }; } ``` @@ -90,30 +89,9 @@ export async function initializeState( stateClient: StateClient, stateProvider: StateProvider, ): Promise { - await stateClient.register_cipher_repository( - new RepositoryRecord(userId, stateProvider, new CipherRecordMapper()), - ); -} -``` - -### Client-Managed State in UniFFI - -For UniFFI, we need to define a new `Repository` for our type and provide a function that will -accept it. This is done in the file `crates/bitwarden-uniffi/src/platform/mod.rs`, you can check the -provided example: - -```rust,ignore -repository::create_uniffi_repository!(CipherRepository, Cipher); - -#[uniffi::export] -impl StateClient { - pub fn register_cipher_repository(&self, store: Arc) { - let store_internal = UniffiRepositoryBridge::new(store); - self.0 - .platform() - .state() - .register_client_managed(store_internal) - } + stateClient.register_client_managed_repositories({ + cipher: new RepositoryRecord(userId, stateProvider, new CipherRecordMapper()), + }); } ``` @@ -187,8 +165,8 @@ SDK. To add support for an SDK managed `Repository`, a new migration step needs ### How to initialize SDK-Managed State -Go to `crates/bitwarden-state-migrations/src/lib.rs` and add a line with your type, as shown below. -In this example we're registering `Cipher` and `Folder` as SDK managed. +Go to `crates/bitwarden-pm/src/migrations.rs` and add a line with your type, as shown below. In this +example we're registering `Cipher` and `Folder` as SDK managed. ```rust,ignore /// Returns a list of all SDK-managed repository migrations. diff --git a/crates/bitwarden-uniffi/Cargo.toml b/crates/bitwarden-uniffi/Cargo.toml index ab7b6c60a..82aa7a7bb 100644 --- a/crates/bitwarden-uniffi/Cargo.toml +++ b/crates/bitwarden-uniffi/Cargo.toml @@ -31,7 +31,6 @@ bitwarden-pm = { workspace = true, features = ["uniffi"] } bitwarden-send = { workspace = true, features = ["uniffi"] } bitwarden-ssh = { workspace = true, features = ["uniffi"] } bitwarden-state = { workspace = true, features = ["uniffi"] } -bitwarden-state-migrations = { workspace = true, features = ["uniffi"] } bitwarden-uniffi-error = { workspace = true } bitwarden-vault = { workspace = true, features = ["uniffi"] } chrono = { workspace = true, features = ["std"] } diff --git a/crates/bitwarden-uniffi/src/platform/mod.rs b/crates/bitwarden-uniffi/src/platform/mod.rs index 8f71c5775..8dcdaeb4e 100644 --- a/crates/bitwarden-uniffi/src/platform/mod.rs +++ b/crates/bitwarden-uniffi/src/platform/mod.rs @@ -1,10 +1,11 @@ +#![allow(deprecated)] + use std::sync::Arc; use bitwarden_core::{Client, platform::FingerprintRequest}; use bitwarden_fido::ClientFido2Ext; use bitwarden_state::DatabaseConfiguration; -use bitwarden_vault::Cipher; -use repository::UniffiRepositoryBridge; +use repository::{UniffiRepositoryBridge, create_uniffi_repositories}; use crate::error::Result; @@ -45,24 +46,29 @@ impl PlatformClient { #[derive(uniffi::Object)] pub struct StateClient(Client); -repository::create_uniffi_repository!(CipherRepository, Cipher); - #[derive(uniffi::Record)] pub struct SqliteConfiguration { db_name: String, folder_path: String, } +bitwarden_pm::create_client_managed_repositories!(Repositories, create_uniffi_repositories); + #[uniffi::export] impl StateClient { + #[deprecated(note = "Use `register_client_managed_repositories` instead")] pub fn register_cipher_repository(&self, repository: Arc) { let cipher = UniffiRepositoryBridge::new(repository); self.0.platform().state().register_client_managed(cipher); } + pub fn register_client_managed_repositories(&self, repositories: Repositories) { + repositories.register_all(&self.0.platform().state()); + } + /// Initialize the database for SDK managed repositories. pub async fn initialize_state(&self, configuration: SqliteConfiguration) -> Result<()> { - let migrations = bitwarden_state_migrations::get_sdk_managed_migrations(); + let migrations = bitwarden_pm::migrations::get_sdk_managed_migrations(); self.0 .platform() diff --git a/crates/bitwarden-uniffi/src/platform/repository.rs b/crates/bitwarden-uniffi/src/platform/repository.rs index 7cee81918..973afd3a0 100644 --- a/crates/bitwarden-uniffi/src/platform/repository.rs +++ b/crates/bitwarden-uniffi/src/platform/repository.rs @@ -39,60 +39,82 @@ impl From for bitwarden_state::repository::RepositoryError { /// This macro creates a Uniffi repository trait and its implementation for the /// [bitwarden_state::repository::Repository] trait -macro_rules! create_uniffi_repository { - ($name:ident, $ty:ty) => { - #[uniffi::export(with_foreign)] - #[async_trait::async_trait] - pub trait $name: Send + Sync { - async fn get( - &self, - id: String, - ) -> Result, $crate::platform::repository::RepositoryError>; - async fn list(&self) - -> Result, $crate::platform::repository::RepositoryError>; - async fn set( - &self, - id: String, - value: $ty, - ) -> Result<(), $crate::platform::repository::RepositoryError>; - async fn remove( - &self, - id: String, - ) -> Result<(), $crate::platform::repository::RepositoryError>; +macro_rules! create_uniffi_repositories { + ( $container_name:ident ; $( $qualified_type_name:ty, $type_name:ident, $field_name:ident, $repo_name:ident );+ $(;)? ) => { - async fn has( - &self, - id: String, - ) -> Result; + #[derive(::uniffi::Record)] + pub struct $container_name { + $( + pub $field_name: Option<::std::sync::Arc>, + )+ } - #[async_trait::async_trait] - impl bitwarden_state::repository::Repository<$ty> - for $crate::platform::repository::UniffiRepositoryBridge> - { - async fn get( - &self, - key: String, - ) -> Result, bitwarden_state::repository::RepositoryError> { - self.0.get(key).await.map_err(Into::into) + impl $container_name { + pub fn register_all(self, client: &bitwarden_core::platform::StateClient) { + $( + if let Some(repo) = self.$field_name { + let bridge = $crate::platform::repository::UniffiRepositoryBridge::new(repo); + client.register_client_managed(bridge); + } + )+ } - async fn list(&self) -> Result, bitwarden_state::repository::RepositoryError> { - self.0.list().await.map_err(Into::into) - } - async fn set( - &self, - key: String, - value: $ty, - ) -> Result<(), bitwarden_state::repository::RepositoryError> { - self.0.set(key, value).await.map_err(Into::into) + } + + $( + #[::uniffi::export(with_foreign)] + #[::async_trait::async_trait] + pub trait $repo_name: Send + Sync { + async fn get( + &self, + id: String, + ) -> Result, $crate::platform::repository::RepositoryError>; + async fn list(&self) + -> Result, $crate::platform::repository::RepositoryError>; + async fn set( + &self, + id: String, + value: $qualified_type_name, + ) -> Result<(), $crate::platform::repository::RepositoryError>; + async fn remove( + &self, + id: String, + ) -> Result<(), $crate::platform::repository::RepositoryError>; + + async fn has( + &self, + id: String, + ) -> Result; } - async fn remove( - &self, - key: String, - ) -> Result<(), bitwarden_state::repository::RepositoryError> { - self.0.remove(key).await.map_err(Into::into) + + #[async_trait::async_trait] + impl bitwarden_state::repository::Repository<$qualified_type_name> + for $crate::platform::repository::UniffiRepositoryBridge> + { + async fn get( + &self, + key: String, + ) -> Result, bitwarden_state::repository::RepositoryError> { + self.0.get(key).await.map_err(Into::into) + } + async fn list(&self) -> Result, bitwarden_state::repository::RepositoryError> { + self.0.list().await.map_err(Into::into) + } + async fn set( + &self, + key: String, + value: $qualified_type_name, + ) -> Result<(), bitwarden_state::repository::RepositoryError> { + self.0.set(key, value).await.map_err(Into::into) + } + async fn remove( + &self, + key: String, + ) -> Result<(), bitwarden_state::repository::RepositoryError> { + self.0.remove(key).await.map_err(Into::into) + } } - } + )+ }; } -pub(super) use create_uniffi_repository; + +pub(super) use create_uniffi_repositories; diff --git a/crates/bitwarden-wasm-internal/Cargo.toml b/crates/bitwarden-wasm-internal/Cargo.toml index e5b25ccdd..27cc102a0 100644 --- a/crates/bitwarden-wasm-internal/Cargo.toml +++ b/crates/bitwarden-wasm-internal/Cargo.toml @@ -30,7 +30,6 @@ bitwarden-ipc = { workspace = true, features = ["wasm"] } bitwarden-pm = { workspace = true, features = ["wasm"] } bitwarden-ssh = { workspace = true, features = ["wasm"] } bitwarden-state = { workspace = true, features = ["wasm"] } -bitwarden-state-migrations = { workspace = true, features = ["wasm"] } bitwarden-threading = { workspace = true } bitwarden-vault = { workspace = true, features = ["wasm"] } console_error_panic_hook = "0.1.7" diff --git a/crates/bitwarden-wasm-internal/src/platform/mod.rs b/crates/bitwarden-wasm-internal/src/platform/mod.rs index daf85ac65..6953557af 100644 --- a/crates/bitwarden-wasm-internal/src/platform/mod.rs +++ b/crates/bitwarden-wasm-internal/src/platform/mod.rs @@ -1,10 +1,11 @@ use bitwarden_core::Client; use bitwarden_state::DatabaseConfiguration; -use bitwarden_vault::{Cipher, Folder}; use serde::{Deserialize, Serialize}; use tsify::Tsify; use wasm_bindgen::{JsValue, prelude::wasm_bindgen}; +use crate::platform::repository::create_wasm_repositories; + mod repository; pub mod token_provider; @@ -48,8 +49,7 @@ impl StateClient { } } -repository::create_wasm_repository!(CipherRepository, Cipher, "Repository"); -repository::create_wasm_repository!(FolderRepository, Folder, "Repository"); +bitwarden_pm::create_client_managed_repositories!(Repositories, create_wasm_repositories); #[derive(Serialize, Deserialize, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] @@ -59,22 +59,30 @@ pub struct IndexedDbConfiguration { #[wasm_bindgen] impl StateClient { + #[allow(deprecated)] + #[deprecated(note = "Use `register_client_managed_repositories` instead")] pub fn register_cipher_repository(&self, cipher_repository: CipherRepository) { let cipher = cipher_repository.into_channel_impl(); self.0.platform().state().register_client_managed(cipher); } + #[allow(deprecated)] + #[deprecated(note = "Use `register_client_managed_repositories` instead")] pub fn register_folder_repository(&self, store: FolderRepository) { let store = store.into_channel_impl(); self.0.platform().state().register_client_managed(store) } + pub fn register_client_managed_repositories(&self, repositories: Repositories) { + repositories.register_all(&self.0.platform().state()); + } + /// Initialize the database for SDK managed repositories. pub async fn initialize_state( &self, configuration: IndexedDbConfiguration, ) -> Result<(), bitwarden_state::registry::StateRegistryError> { - let sdk_managed_repositories = bitwarden_state_migrations::get_sdk_managed_migrations(); + let sdk_managed_repositories = bitwarden_pm::migrations::get_sdk_managed_migrations(); self.0 .platform() diff --git a/crates/bitwarden-wasm-internal/src/platform/repository.rs b/crates/bitwarden-wasm-internal/src/platform/repository.rs index 3ec4033f5..faa4db8a0 100644 --- a/crates/bitwarden-wasm-internal/src/platform/repository.rs +++ b/crates/bitwarden-wasm-internal/src/platform/repository.rs @@ -29,7 +29,7 @@ * use the existing [Repository] trait. * - It runs the calls in a thread-bound manner, so we can safely call the [WasmRepository] * methods from any thread. - * - The [create_wasm_repository] macro, defines the [::wasm_bindgen] interface and implements + * - The [create_wasm_repositories] macro, defines the [::wasm_bindgen] interface and implements * the [WasmRepository] trait for you. */ @@ -95,70 +95,106 @@ export interface Repository { /// This macro generates a [::wasm_bindgen] interface for a repository type, and provides the /// implementation of [WasmRepository] and a way to convert it into something that implements /// the [Repository] trait. -macro_rules! create_wasm_repository { - ($name:ident, $ty:ty, $typescript_ty:literal) => { +macro_rules! create_wasm_repositories { + ( $container_name:ident ; $( $qualified_type_name:ty, $type_name:ident, $field_name:ident, $repo_name:ident );+ $(;)? ) => { + + const _: () = { + #[wasm_bindgen(typescript_custom_section)] + const REPOSITORIES_CUSTOM_TS_TYPE: &'static str = concat!( + "export interface ", + stringify!($container_name), + "{\n", + $( stringify!($field_name), ": Repository<", stringify!($type_name), "> | null;\n", )+ + "}\n" + ); + }; + #[wasm_bindgen] extern "C" { - #[wasm_bindgen(js_name = $name, typescript_type = $typescript_ty)] - pub type $name; - - #[wasm_bindgen(method, catch)] - async fn get( - this: &$name, - id: String, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; - #[wasm_bindgen(method, catch)] - async fn list(this: &$name) - -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; - #[wasm_bindgen(method, catch)] - async fn set( - this: &$name, - id: String, - value: $ty, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; - #[wasm_bindgen(method, catch)] - async fn remove( - this: &$name, - id: String, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; + #[wasm_bindgen(typescript_type = $container_name)] + pub type $container_name; + + $( + #[wasm_bindgen(method, getter)] + pub fn $field_name(this: &$container_name) -> Option<$repo_name>; + )+ } - impl $crate::platform::repository::WasmRepository<$ty> for $name { - async fn get( - &self, - id: String, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { - self.get(id).await + impl $container_name { + pub fn register_all(self, client: &bitwarden_core::platform::StateClient) { + $( + if let Some(repo) = self.$field_name() { + let repo = repo.into_channel_impl(); + client.register_client_managed(repo); + } + )+ } - async fn list(&self) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { - self.list().await - } - async fn set( - &self, - id: String, - value: $ty, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { - self.set(id, value).await + } + + $( + #[wasm_bindgen] + extern "C" { + #[wasm_bindgen] + pub type $repo_name; + + #[wasm_bindgen(method, catch)] + async fn get( + this: &$repo_name, + id: String, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; + #[wasm_bindgen(method, catch)] + async fn list(this: &$repo_name) + -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; + #[wasm_bindgen(method, catch)] + async fn set( + this: &$repo_name, + id: String, + value: $qualified_type_name, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; + #[wasm_bindgen(method, catch)] + async fn remove( + this: &$repo_name, + id: String, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue>; } - async fn remove( - &self, - id: String, - ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { - self.remove(id).await + + impl $crate::platform::repository::WasmRepository<$qualified_type_name> for $repo_name { + async fn get( + &self, + id: String, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { + self.get(id).await + } + async fn list(&self) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { + self.list().await + } + async fn set( + &self, + id: String, + value: $qualified_type_name, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { + self.set(id, value).await + } + async fn remove( + &self, + id: String, + ) -> Result<::wasm_bindgen::JsValue, ::wasm_bindgen::JsValue> { + self.remove(id).await + } } - } - impl $name { - pub fn into_channel_impl( - self, - ) -> ::std::sync::Arc> { - use $crate::platform::repository::WasmRepositoryChannel; - ::std::sync::Arc::new(WasmRepositoryChannel::new(self)) + impl $repo_name { + pub fn into_channel_impl( + self, + ) -> ::std::sync::Arc> { + use $crate::platform::repository::WasmRepositoryChannel; + ::std::sync::Arc::new(WasmRepositoryChannel::new(self)) + } } - } + )+ }; } -pub(crate) use create_wasm_repository; +pub(crate) use create_wasm_repositories; const UNIT: Result = Ok(JsValue::UNDEFINED); From 80fbec9e71bb065d86cfff0b32d9f2345d6bfb60 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Wed, 8 Oct 2025 12:45:09 +0200 Subject: [PATCH 10/19] fix: artifact name (#497) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## đŸŽŸī¸ Tracking ## 📔 Objective Accidentally renamed the artifact causing npm publishing to break ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## đŸĻŽ Reviewer guidelines - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or â„šī¸ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or âš ī¸ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or â™ģī¸ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --- .github/workflows/build-wasm-internal.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-wasm-internal.yml b/.github/workflows/build-wasm-internal.yml index 4b46b1bd9..daae58aa8 100644 --- a/.github/workflows/build-wasm-internal.yml +++ b/.github/workflows/build-wasm-internal.yml @@ -23,11 +23,11 @@ jobs: strategy: matrix: license_type: - - artifact_name: "wasm-internal" + - artifact_name: "sdk-internal" build_flags: "" npm_folder: "npm" readable: "open source license" - - artifact_name: "commercial-wasm-internal" + - artifact_name: "commercial-sdk-internal" build_flags: "-b" npm_folder: "bitwarden_license/npm" readable: "commercial license" From 090fc07c3ca8f0c0f615fba2c8058450b6bbdc1e Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 9 Oct 2025 10:24:45 +0200 Subject: [PATCH 11/19] Update key-management related CODEOWNERS (#498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## đŸŽŸī¸ Tracking ## 📔 Objective Updates the CODEOWNERS replace platform and architecture with @bitwarden/team-sdk-sme as the co-owner of @bitwarden/team-key-management-dev's code. Further, this moves the KM code in core, and PureCrypto into KM co-ownership. ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## đŸĻŽ Reviewer guidelines - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or â„šī¸ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or âš ī¸ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or â™ģī¸ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --- .github/CODEOWNERS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8cc4bb96c..3b553723c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,9 +15,13 @@ # Team-owned crates crates/bitwarden-auth/** @bitwarden/team-auth-dev @bitwarden/team-platform-dev -crates/bitwarden-crypto/** @bitwarden/team-key-management-dev @bitwarden/team-platform-dev @bitwarden/dept-architecture +crates/bitwarden-crypto/** @bitwarden/team-key-management-dev @bitwarden/team-sdk-sme crates/bitwarden-vault/** @bitwarden/team-vault-dev @bitwarden/team-sdk-sme +# KM Co-owned files +crates/bitwarden-core/src/key_management/** @bitwarden/team-key-management-dev @bitwarden/team-sdk-sme +crates/bitwarden-wasm-internal/src/pure_crypto.rs @bitwarden/team-key-management-dev @bitwarden/team-sdk-sme + # BW CLI crates/bw/src/admin_console/** @bitwarden/team-platform-dev crates/bw/src/auth/** @bitwarden/team-auth-dev @bitwarden/team-platform-dev From b505df094aaa1aed9cdae6d59597b29aef37da30 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 16:04:28 +0200 Subject: [PATCH 12/19] Update API to d2577f670e1cf9ca32791135d2197cff1fe12096 (#491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the API bindings to `d2577f670e1cf9ca32791135d2197cff1fe12096` --------- Co-authored-by: bw-ghapp[bot] <178206702+bw-ghapp[bot]@users.noreply.github.com> Co-authored-by: Daniel Garciˁa --- .../.openapi-generator/FILES | 23 +- crates/bitwarden-api-api/README.md | 36 +- .../src/apis/accounts_api.rs | 6 +- .../bitwarden-api-api/src/apis/ciphers_api.rs | 6 + .../bitwarden-api-api/src/apis/events_api.rs | 95 ++ .../src/apis/organization_billing_api.rs | 59 -- .../apis/organization_billing_v_next_api.rs | 415 ++++++++ .../src/apis/organizations_api.rs | 59 -- .../src/apis/slack_integration_api.rs | 15 +- crates/bitwarden-api-api/src/apis/tax_api.rs | 929 +++++++++++++++++- ...rs => checkout_billing_address_request.rs} | 10 +- .../src/models/event_response_model.rs | 6 + .../src/models/event_type.rs | 12 + .../src/models/kdf_request_model.rs | 55 +- ...sword_authentication_data_request_model.rs | 37 + ...d_unlock_and_authentication_data_model.rs} | 8 +- ...ster_password_unlock_data_request_model.rs | 37 + crates/bitwarden-api-api/src/models/mod.rs | 46 +- ...organization_integration_response_model.rs | 3 + .../models/organization_integration_status.rs | 47 + ...zation_subscription_plan_change_request.rs | 30 + ...anization_subscription_purchase_request.rs | 40 + ...rganization_subscription_update_request.rs | 30 + .../organization_verify_bank_request_model.rs | 27 - .../password_manager_purchase_selections.rs | 33 + .../password_manager_update_selections.rs | 30 + .../src/models/password_request_model.rs | 6 + .../{product_type.rs => plan_cadence_type.rs} | 18 +- .../src/models/policy_type.rs | 2 + ...on_subscription_plan_change_tax_request.rs | 33 + ...ation_subscription_purchase_tax_request.rs | 33 + ...ization_subscription_update_tax_request.rs | 29 + ...emium_subscription_purchase_tax_request.rs | 33 + ...unt_for_organization_trial_request_body.rs | 37 - .../models/provider_setup_request_model.rs | 15 +- .../models/restart_subscription_request.rs | 33 + .../secrets_manager_purchase_selections.rs | 33 + .../secrets_manager_update_selections.rs | 33 + .../src/models/unlock_data_request_model.rs | 4 +- crates/bitwarden-api-identity/README.md | 2 +- .../src/admin_console/policy.rs | 4 + 41 files changed, 2109 insertions(+), 300 deletions(-) rename crates/bitwarden-api-api/src/models/{tax_information_dto.rs => checkout_billing_address_request.rs} (71%) create mode 100644 crates/bitwarden-api-api/src/models/master_password_authentication_data_request_model.rs rename crates/bitwarden-api-api/src/models/{master_password_unlock_data_model.rs => master_password_unlock_and_authentication_data_model.rs} (87%) create mode 100644 crates/bitwarden-api-api/src/models/master_password_unlock_data_request_model.rs create mode 100644 crates/bitwarden-api-api/src/models/organization_integration_status.rs create mode 100644 crates/bitwarden-api-api/src/models/organization_subscription_plan_change_request.rs create mode 100644 crates/bitwarden-api-api/src/models/organization_subscription_purchase_request.rs create mode 100644 crates/bitwarden-api-api/src/models/organization_subscription_update_request.rs delete mode 100644 crates/bitwarden-api-api/src/models/organization_verify_bank_request_model.rs create mode 100644 crates/bitwarden-api-api/src/models/password_manager_purchase_selections.rs create mode 100644 crates/bitwarden-api-api/src/models/password_manager_update_selections.rs rename crates/bitwarden-api-api/src/models/{product_type.rs => plan_cadence_type.rs} (69%) create mode 100644 crates/bitwarden-api-api/src/models/preview_organization_subscription_plan_change_tax_request.rs create mode 100644 crates/bitwarden-api-api/src/models/preview_organization_subscription_purchase_tax_request.rs create mode 100644 crates/bitwarden-api-api/src/models/preview_organization_subscription_update_tax_request.rs create mode 100644 crates/bitwarden-api-api/src/models/preview_premium_subscription_purchase_tax_request.rs delete mode 100644 crates/bitwarden-api-api/src/models/preview_tax_amount_for_organization_trial_request_body.rs create mode 100644 crates/bitwarden-api-api/src/models/restart_subscription_request.rs create mode 100644 crates/bitwarden-api-api/src/models/secrets_manager_purchase_selections.rs create mode 100644 crates/bitwarden-api-api/src/models/secrets_manager_update_selections.rs diff --git a/crates/bitwarden-api-api/.openapi-generator/FILES b/crates/bitwarden-api-api/.openapi-generator/FILES index 48b67cc71..54548041c 100644 --- a/crates/bitwarden-api-api/.openapi-generator/FILES +++ b/crates/bitwarden-api-api/.openapi-generator/FILES @@ -118,6 +118,7 @@ src/models/bulk_delete_response_model.rs src/models/bulk_delete_response_model_list_response_model.rs src/models/bulk_deny_admin_auth_request_request_model.rs src/models/change_plan_frequency_request.rs +src/models/checkout_billing_address_request.rs src/models/cipher.rs src/models/cipher_attachment_model.rs src/models/cipher_bulk_archive_request_model.rs @@ -241,8 +242,10 @@ src/models/key_regeneration_request_model.rs src/models/keys_request_model.rs src/models/keys_response_model.rs src/models/license_type.rs +src/models/master_password_authentication_data_request_model.rs src/models/master_password_policy_response_model.rs -src/models/master_password_unlock_data_model.rs +src/models/master_password_unlock_and_authentication_data_model.rs +src/models/master_password_unlock_data_request_model.rs src/models/master_password_unlock_kdf_response_model.rs src/models/master_password_unlock_response_model.rs src/models/member_access_detail_report_response_model.rs @@ -276,6 +279,7 @@ src/models/organization_integration_configuration_request_model.rs src/models/organization_integration_configuration_response_model.rs src/models/organization_integration_request_model.rs src/models/organization_integration_response_model.rs +src/models/organization_integration_status.rs src/models/organization_keys_request_model.rs src/models/organization_keys_response_model.rs src/models/organization_license.rs @@ -295,7 +299,10 @@ src/models/organization_sponsorship_sync_response_model.rs src/models/organization_sso_request_model.rs src/models/organization_sso_response_model.rs src/models/organization_status_type.rs +src/models/organization_subscription_plan_change_request.rs +src/models/organization_subscription_purchase_request.rs src/models/organization_subscription_response_model.rs +src/models/organization_subscription_update_request.rs src/models/organization_subscription_update_request_model.rs src/models/organization_update_request_model.rs src/models/organization_upgrade_request_model.rs @@ -322,13 +329,14 @@ src/models/organization_user_user_details_response_model.rs src/models/organization_user_user_details_response_model_list_response_model.rs src/models/organization_user_user_mini_details_response_model.rs src/models/organization_user_user_mini_details_response_model_list_response_model.rs -src/models/organization_verify_bank_request_model.rs src/models/organization_verify_delete_recover_request_model.rs src/models/other_device_keys_update_request_model.rs src/models/password_health_report_application.rs src/models/password_health_report_application_model.rs src/models/password_hint_request_model.rs src/models/password_manager_plan_features_response_model.rs +src/models/password_manager_purchase_selections.rs +src/models/password_manager_update_selections.rs src/models/password_request_model.rs src/models/payment_method_type.rs src/models/payment_request_model.rs @@ -340,6 +348,7 @@ src/models/pending_organization_auth_request_response_model.rs src/models/pending_organization_auth_request_response_model_list_response_model.rs src/models/people_access_policies_request_model.rs src/models/permissions.rs +src/models/plan_cadence_type.rs src/models/plan_response_model.rs src/models/plan_response_model_list_response_model.rs src/models/plan_sponsorship_type.rs @@ -355,10 +364,12 @@ src/models/pre_validate_sponsorship_response_model.rs src/models/premium_cloud_hosted_subscription_request.rs src/models/preview_individual_invoice_request_body.rs src/models/preview_organization_invoice_request_body.rs -src/models/preview_tax_amount_for_organization_trial_request_body.rs +src/models/preview_organization_subscription_plan_change_tax_request.rs +src/models/preview_organization_subscription_purchase_tax_request.rs +src/models/preview_organization_subscription_update_tax_request.rs +src/models/preview_premium_subscription_purchase_tax_request.rs src/models/priority.rs src/models/product_tier_type.rs -src/models/product_type.rs src/models/profile_organization_response_model.rs src/models/profile_organization_response_model_list_response_model.rs src/models/profile_provider_organization_response_model.rs @@ -413,6 +424,7 @@ src/models/push_update_request_model.rs src/models/request_sm_access_request_model.rs src/models/reset_password_with_org_id_request_model.rs src/models/response_data.rs +src/models/restart_subscription_request.rs src/models/revoke_access_tokens_request.rs src/models/rotate_user_account_keys_and_data_request_model.rs src/models/saml2_binding_type.rs @@ -429,9 +441,11 @@ src/models/secret_verification_request_model.rs src/models/secret_with_projects_inner_project.rs src/models/secret_with_projects_list_response_model.rs src/models/secrets_manager_plan_features_response_model.rs +src/models/secrets_manager_purchase_selections.rs src/models/secrets_manager_request_model.rs src/models/secrets_manager_subscribe_request_model.rs src/models/secrets_manager_subscription_update_request_model.rs +src/models/secrets_manager_update_selections.rs src/models/secrets_sync_response_model.rs src/models/secrets_with_projects_inner_secret.rs src/models/secure_note_type.rs @@ -482,7 +496,6 @@ src/models/sync_response_model.rs src/models/tax_id_request.rs src/models/tax_info_response_model.rs src/models/tax_info_update_request_model.rs -src/models/tax_information_dto.rs src/models/tax_information_request_body.rs src/models/tax_information_request_model.rs src/models/tokenized_payment_method_request.rs diff --git a/crates/bitwarden-api-api/README.md b/crates/bitwarden-api-api/README.md index c7c196f1e..2d828cf5a 100644 --- a/crates/bitwarden-api-api/README.md +++ b/crates/bitwarden-api-api/README.md @@ -12,7 +12,7 @@ client. - API version: latest - Package version: 1.0.0 - Server Git commit: - [`d384c0cfe60ec02226479d3cde200e4d785a7e50`](https://github.com/bitwarden/server/commit/d384c0cfe60ec02226479d3cde200e4d785a7e50) + [`d2577f670e1cf9ca32791135d2197cff1fe12096`](https://github.com/bitwarden/server/commit/d2577f670e1cf9ca32791135d2197cff1fe12096) - Generator version: 7.15.0 - Build package: `org.openapitools.codegen.languages.RustClientCodegen` @@ -202,6 +202,7 @@ All URIs are relative to *https://api.bitwarden.com* | _EventsApi_ | [**get_provider**](docs/EventsApi.md#events_get_provider) | **GET** /providers/{providerId}/events | | _EventsApi_ | [**get_provider_user**](docs/EventsApi.md#events_get_provider_user) | **GET** /providers/{providerId}/users/{id}/events | | _EventsApi_ | [**get_secrets**](docs/EventsApi.md#events_get_secrets) | **GET** /organization/{orgId}/secrets/{id}/events | +| _EventsApi_ | [**get_service_accounts**](docs/EventsApi.md#events_get_service_accounts) | **GET** /organization/{orgId}/service-account/{id}/events | | _EventsApi_ | [**get_user**](docs/EventsApi.md#events_get_user) | **GET** /events | | _FoldersApi_ | [**delete**](docs/FoldersApi.md#folders_delete) | **DELETE** /folders/{id} | | _FoldersApi_ | [**delete_all**](docs/FoldersApi.md#folders_delete_all) | **DELETE** /folders/all | @@ -246,7 +247,6 @@ All URIs are relative to *https://api.bitwarden.com* | _OrganizationBillingApi_ | [**get_payment_method**](docs/OrganizationBillingApi.md#organization_billing_get_payment_method) | **GET** /organizations/{organizationId}/billing/payment-method | | _OrganizationBillingApi_ | [**get_tax_information**](docs/OrganizationBillingApi.md#organization_billing_get_tax_information) | **GET** /organizations/{organizationId}/billing/tax-information | | _OrganizationBillingApi_ | [**get_transactions**](docs/OrganizationBillingApi.md#organization_billing_get_transactions) | **GET** /organizations/{organizationId}/billing/transactions | -| _OrganizationBillingApi_ | [**restart_subscription**](docs/OrganizationBillingApi.md#organization_billing_restart_subscription) | **POST** /organizations/{organizationId}/billing/restart-subscription | | _OrganizationBillingApi_ | [**setup_business_unit**](docs/OrganizationBillingApi.md#organization_billing_setup_business_unit) | **POST** /organizations/{organizationId}/billing/setup-business-unit | | _OrganizationBillingApi_ | [**update_payment_method**](docs/OrganizationBillingApi.md#organization_billing_update_payment_method) | **PUT** /organizations/{organizationId}/billing/payment-method | | _OrganizationBillingApi_ | [**update_tax_information**](docs/OrganizationBillingApi.md#organization_billing_update_tax_information) | **PUT** /organizations/{organizationId}/billing/tax-information | @@ -256,6 +256,7 @@ All URIs are relative to *https://api.bitwarden.com* | _OrganizationBillingVNextApi_ | [**get_credit**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_get_credit) | **GET** /organizations/{organizationId}/billing/vnext/credit | | _OrganizationBillingVNextApi_ | [**get_payment_method**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_get_payment_method) | **GET** /organizations/{organizationId}/billing/vnext/payment-method | | _OrganizationBillingVNextApi_ | [**get_warnings**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_get_warnings) | **GET** /organizations/{organizationId}/billing/vnext/warnings | +| _OrganizationBillingVNextApi_ | [**restart_subscription**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_restart_subscription) | **POST** /organizations/{organizationId}/billing/vnext/subscription/restart | | _OrganizationBillingVNextApi_ | [**update_billing_address**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_update_billing_address) | **PUT** /organizations/{organizationId}/billing/vnext/address | | _OrganizationBillingVNextApi_ | [**update_payment_method**](docs/OrganizationBillingVNextApi.md#organization_billing_v_next_update_payment_method) | **PUT** /organizations/{organizationId}/billing/vnext/payment-method | | _OrganizationConnectionsApi_ | [**connections_enabled**](docs/OrganizationConnectionsApi.md#organization_connections_connections_enabled) | **GET** /organizations/connections/enabled | @@ -351,7 +352,6 @@ All URIs are relative to *https://api.bitwarden.com* | _OrganizationsApi_ | [**post_subscribe_secrets_manager**](docs/OrganizationsApi.md#organizations_post_subscribe_secrets_manager) | **POST** /organizations/{id}/subscribe-secrets-manager | | _OrganizationsApi_ | [**post_subscription**](docs/OrganizationsApi.md#organizations_post_subscription) | **POST** /organizations/{id}/subscription | | _OrganizationsApi_ | [**post_upgrade**](docs/OrganizationsApi.md#organizations_post_upgrade) | **POST** /organizations/{id}/upgrade | -| _OrganizationsApi_ | [**post_verify_bank**](docs/OrganizationsApi.md#organizations_post_verify_bank) | **POST** /organizations/{id}/verify-bank | | _OrganizationsApi_ | [**put**](docs/OrganizationsApi.md#organizations_put) | **PUT** /organizations/{id} | | _OrganizationsApi_ | [**put_collection_management**](docs/OrganizationsApi.md#organizations_put_collection_management) | **PUT** /organizations/{id}/collection-management | | _OrganizationsApi_ | [**put_tax_info**](docs/OrganizationsApi.md#organizations_put_tax_info) | **PUT** /organizations/{id}/tax | @@ -467,13 +467,16 @@ All URIs are relative to *https://api.bitwarden.com* | _ServiceAccountsApi_ | [**update**](docs/ServiceAccountsApi.md#service_accounts_update) | **PUT** /service-accounts/{id} | | _SettingsApi_ | [**get_domains**](docs/SettingsApi.md#settings_get_domains) | **GET** /settings/domains | | _SettingsApi_ | [**put_domains**](docs/SettingsApi.md#settings_put_domains) | **PUT** /settings/domains | -| _SlackIntegrationApi_ | [**create**](docs/SlackIntegrationApi.md#slack_integration_create) | **GET** /organizations/{organizationId}/integrations/slack/create | +| _SlackIntegrationApi_ | [**create**](docs/SlackIntegrationApi.md#slack_integration_create) | **GET** /organizations/integrations/slack/create | | _SlackIntegrationApi_ | [**redirect**](docs/SlackIntegrationApi.md#slack_integration_redirect) | **GET** /organizations/{organizationId}/integrations/slack/redirect | | _StripeApi_ | [**create_setup_intent_for_bank_account**](docs/StripeApi.md#stripe_create_setup_intent_for_bank_account) | **POST** /setup-intent/bank-account | | _StripeApi_ | [**create_setup_intent_for_card**](docs/StripeApi.md#stripe_create_setup_intent_for_card) | **POST** /setup-intent/card | | _StripeApi_ | [**is_country_supported**](docs/StripeApi.md#stripe_is_country_supported) | **GET** /tax/is-country-supported | | _SyncApi_ | [**get**](docs/SyncApi.md#sync_get) | **GET** /sync | -| _TaxApi_ | [**preview_tax_amount_for_organization_trial**](docs/TaxApi.md#tax_preview_tax_amount_for_organization_trial) | **POST** /tax/preview-amount/organization-trial | +| _TaxApi_ | [**preview_organization_subscription_plan_change_tax**](docs/TaxApi.md#tax_preview_organization_subscription_plan_change_tax) | **POST** /billing/tax/organizations/{organizationId}/subscription/plan-change | +| _TaxApi_ | [**preview_organization_subscription_purchase_tax**](docs/TaxApi.md#tax_preview_organization_subscription_purchase_tax) | **POST** /billing/tax/organizations/subscriptions/purchase | +| _TaxApi_ | [**preview_organization_subscription_update_tax**](docs/TaxApi.md#tax_preview_organization_subscription_update_tax) | **PUT** /billing/tax/organizations/{organizationId}/subscription/update | +| _TaxApi_ | [**preview_premium_subscription_purchase_tax**](docs/TaxApi.md#tax_preview_premium_subscription_purchase_tax) | **POST** /billing/tax/premium/subscriptions/purchase | | _TrashApi_ | [**empty_trash**](docs/TrashApi.md#trash_empty_trash) | **POST** /secrets/{organizationId}/trash/empty | | _TrashApi_ | [**list_by_organization**](docs/TrashApi.md#trash_list_by_organization) | **GET** /secrets/{organizationId}/trash | | _TrashApi_ | [**restore_trash**](docs/TrashApi.md#trash_restore_trash) | **POST** /secrets/{organizationId}/trash/restore | @@ -558,6 +561,7 @@ All URIs are relative to *https://api.bitwarden.com* - [BulkDeleteResponseModelListResponseModel](docs/BulkDeleteResponseModelListResponseModel.md) - [BulkDenyAdminAuthRequestRequestModel](docs/BulkDenyAdminAuthRequestRequestModel.md) - [ChangePlanFrequencyRequest](docs/ChangePlanFrequencyRequest.md) +- [CheckoutBillingAddressRequest](docs/CheckoutBillingAddressRequest.md) - [Cipher](docs/Cipher.md) - [CipherAttachmentModel](docs/CipherAttachmentModel.md) - [CipherBulkArchiveRequestModel](docs/CipherBulkArchiveRequestModel.md) @@ -681,8 +685,10 @@ All URIs are relative to *https://api.bitwarden.com* - [KeysRequestModel](docs/KeysRequestModel.md) - [KeysResponseModel](docs/KeysResponseModel.md) - [LicenseType](docs/LicenseType.md) +- [MasterPasswordAuthenticationDataRequestModel](docs/MasterPasswordAuthenticationDataRequestModel.md) - [MasterPasswordPolicyResponseModel](docs/MasterPasswordPolicyResponseModel.md) -- [MasterPasswordUnlockDataModel](docs/MasterPasswordUnlockDataModel.md) +- [MasterPasswordUnlockAndAuthenticationDataModel](docs/MasterPasswordUnlockAndAuthenticationDataModel.md) +- [MasterPasswordUnlockDataRequestModel](docs/MasterPasswordUnlockDataRequestModel.md) - [MasterPasswordUnlockKdfResponseModel](docs/MasterPasswordUnlockKdfResponseModel.md) - [MasterPasswordUnlockResponseModel](docs/MasterPasswordUnlockResponseModel.md) - [MemberAccessDetailReportResponseModel](docs/MemberAccessDetailReportResponseModel.md) @@ -715,6 +721,7 @@ All URIs are relative to *https://api.bitwarden.com* - [OrganizationIntegrationConfigurationResponseModel](docs/OrganizationIntegrationConfigurationResponseModel.md) - [OrganizationIntegrationRequestModel](docs/OrganizationIntegrationRequestModel.md) - [OrganizationIntegrationResponseModel](docs/OrganizationIntegrationResponseModel.md) +- [OrganizationIntegrationStatus](docs/OrganizationIntegrationStatus.md) - [OrganizationKeysRequestModel](docs/OrganizationKeysRequestModel.md) - [OrganizationKeysResponseModel](docs/OrganizationKeysResponseModel.md) - [OrganizationLicense](docs/OrganizationLicense.md) @@ -734,7 +741,10 @@ All URIs are relative to *https://api.bitwarden.com* - [OrganizationSsoRequestModel](docs/OrganizationSsoRequestModel.md) - [OrganizationSsoResponseModel](docs/OrganizationSsoResponseModel.md) - [OrganizationStatusType](docs/OrganizationStatusType.md) +- [OrganizationSubscriptionPlanChangeRequest](docs/OrganizationSubscriptionPlanChangeRequest.md) +- [OrganizationSubscriptionPurchaseRequest](docs/OrganizationSubscriptionPurchaseRequest.md) - [OrganizationSubscriptionResponseModel](docs/OrganizationSubscriptionResponseModel.md) +- [OrganizationSubscriptionUpdateRequest](docs/OrganizationSubscriptionUpdateRequest.md) - [OrganizationSubscriptionUpdateRequestModel](docs/OrganizationSubscriptionUpdateRequestModel.md) - [OrganizationUpdateRequestModel](docs/OrganizationUpdateRequestModel.md) - [OrganizationUpgradeRequestModel](docs/OrganizationUpgradeRequestModel.md) @@ -761,13 +771,14 @@ All URIs are relative to *https://api.bitwarden.com* - [OrganizationUserUserDetailsResponseModelListResponseModel](docs/OrganizationUserUserDetailsResponseModelListResponseModel.md) - [OrganizationUserUserMiniDetailsResponseModel](docs/OrganizationUserUserMiniDetailsResponseModel.md) - [OrganizationUserUserMiniDetailsResponseModelListResponseModel](docs/OrganizationUserUserMiniDetailsResponseModelListResponseModel.md) -- [OrganizationVerifyBankRequestModel](docs/OrganizationVerifyBankRequestModel.md) - [OrganizationVerifyDeleteRecoverRequestModel](docs/OrganizationVerifyDeleteRecoverRequestModel.md) - [OtherDeviceKeysUpdateRequestModel](docs/OtherDeviceKeysUpdateRequestModel.md) - [PasswordHealthReportApplication](docs/PasswordHealthReportApplication.md) - [PasswordHealthReportApplicationModel](docs/PasswordHealthReportApplicationModel.md) - [PasswordHintRequestModel](docs/PasswordHintRequestModel.md) - [PasswordManagerPlanFeaturesResponseModel](docs/PasswordManagerPlanFeaturesResponseModel.md) +- [PasswordManagerPurchaseSelections](docs/PasswordManagerPurchaseSelections.md) +- [PasswordManagerUpdateSelections](docs/PasswordManagerUpdateSelections.md) - [PasswordRequestModel](docs/PasswordRequestModel.md) - [PaymentMethodType](docs/PaymentMethodType.md) - [PaymentRequestModel](docs/PaymentRequestModel.md) @@ -779,6 +790,7 @@ All URIs are relative to *https://api.bitwarden.com* - [PendingOrganizationAuthRequestResponseModelListResponseModel](docs/PendingOrganizationAuthRequestResponseModelListResponseModel.md) - [PeopleAccessPoliciesRequestModel](docs/PeopleAccessPoliciesRequestModel.md) - [Permissions](docs/Permissions.md) +- [PlanCadenceType](docs/PlanCadenceType.md) - [PlanResponseModel](docs/PlanResponseModel.md) - [PlanResponseModelListResponseModel](docs/PlanResponseModelListResponseModel.md) - [PlanSponsorshipType](docs/PlanSponsorshipType.md) @@ -794,10 +806,12 @@ All URIs are relative to *https://api.bitwarden.com* - [PremiumCloudHostedSubscriptionRequest](docs/PremiumCloudHostedSubscriptionRequest.md) - [PreviewIndividualInvoiceRequestBody](docs/PreviewIndividualInvoiceRequestBody.md) - [PreviewOrganizationInvoiceRequestBody](docs/PreviewOrganizationInvoiceRequestBody.md) -- [PreviewTaxAmountForOrganizationTrialRequestBody](docs/PreviewTaxAmountForOrganizationTrialRequestBody.md) +- [PreviewOrganizationSubscriptionPlanChangeTaxRequest](docs/PreviewOrganizationSubscriptionPlanChangeTaxRequest.md) +- [PreviewOrganizationSubscriptionPurchaseTaxRequest](docs/PreviewOrganizationSubscriptionPurchaseTaxRequest.md) +- [PreviewOrganizationSubscriptionUpdateTaxRequest](docs/PreviewOrganizationSubscriptionUpdateTaxRequest.md) +- [PreviewPremiumSubscriptionPurchaseTaxRequest](docs/PreviewPremiumSubscriptionPurchaseTaxRequest.md) - [Priority](docs/Priority.md) - [ProductTierType](docs/ProductTierType.md) -- [ProductType](docs/ProductType.md) - [ProfileOrganizationResponseModel](docs/ProfileOrganizationResponseModel.md) - [ProfileOrganizationResponseModelListResponseModel](docs/ProfileOrganizationResponseModelListResponseModel.md) - [ProfileProviderOrganizationResponseModel](docs/ProfileProviderOrganizationResponseModel.md) @@ -852,6 +866,7 @@ All URIs are relative to *https://api.bitwarden.com* - [RequestSmAccessRequestModel](docs/RequestSmAccessRequestModel.md) - [ResetPasswordWithOrgIdRequestModel](docs/ResetPasswordWithOrgIdRequestModel.md) - [ResponseData](docs/ResponseData.md) +- [RestartSubscriptionRequest](docs/RestartSubscriptionRequest.md) - [RevokeAccessTokensRequest](docs/RevokeAccessTokensRequest.md) - [RotateUserAccountKeysAndDataRequestModel](docs/RotateUserAccountKeysAndDataRequestModel.md) - [Saml2BindingType](docs/Saml2BindingType.md) @@ -868,9 +883,11 @@ All URIs are relative to *https://api.bitwarden.com* - [SecretWithProjectsInnerProject](docs/SecretWithProjectsInnerProject.md) - [SecretWithProjectsListResponseModel](docs/SecretWithProjectsListResponseModel.md) - [SecretsManagerPlanFeaturesResponseModel](docs/SecretsManagerPlanFeaturesResponseModel.md) +- [SecretsManagerPurchaseSelections](docs/SecretsManagerPurchaseSelections.md) - [SecretsManagerRequestModel](docs/SecretsManagerRequestModel.md) - [SecretsManagerSubscribeRequestModel](docs/SecretsManagerSubscribeRequestModel.md) - [SecretsManagerSubscriptionUpdateRequestModel](docs/SecretsManagerSubscriptionUpdateRequestModel.md) +- [SecretsManagerUpdateSelections](docs/SecretsManagerUpdateSelections.md) - [SecretsSyncResponseModel](docs/SecretsSyncResponseModel.md) - [SecretsWithProjectsInnerSecret](docs/SecretsWithProjectsInnerSecret.md) - [SecureNoteType](docs/SecureNoteType.md) @@ -921,7 +938,6 @@ All URIs are relative to *https://api.bitwarden.com* - [TaxIdRequest](docs/TaxIdRequest.md) - [TaxInfoResponseModel](docs/TaxInfoResponseModel.md) - [TaxInfoUpdateRequestModel](docs/TaxInfoUpdateRequestModel.md) -- [TaxInformationDto](docs/TaxInformationDto.md) - [TaxInformationRequestBody](docs/TaxInformationRequestBody.md) - [TaxInformationRequestModel](docs/TaxInformationRequestModel.md) - [TokenizedPaymentMethodRequest](docs/TokenizedPaymentMethodRequest.md) diff --git a/crates/bitwarden-api-api/src/apis/accounts_api.rs b/crates/bitwarden-api-api/src/apis/accounts_api.rs index 54d9ba8d8..623f8bb6b 100644 --- a/crates/bitwarden-api-api/src/apis/accounts_api.rs +++ b/crates/bitwarden-api-api/src/apis/accounts_api.rs @@ -107,7 +107,7 @@ pub trait AccountsApi: Send + Sync { /// POST /accounts/kdf async fn post_kdf<'a>( &self, - kdf_request_model: Option, + password_request_model: Option, ) -> Result<(), Error>; /// POST /accounts/keys @@ -1023,7 +1023,7 @@ impl AccountsApi for AccountsApiClient { async fn post_kdf<'a>( &self, - kdf_request_model: Option, + password_request_model: Option, ) -> Result<(), Error> { let local_var_configuration = &self.configuration; @@ -1040,7 +1040,7 @@ impl AccountsApi for AccountsApiClient { if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); }; - local_var_req_builder = local_var_req_builder.json(&kdf_request_model); + local_var_req_builder = local_var_req_builder.json(&password_request_model); let local_var_req = local_var_req_builder.build()?; let local_var_resp = local_var_client.execute(local_var_req).await?; diff --git a/crates/bitwarden-api-api/src/apis/ciphers_api.rs b/crates/bitwarden-api-api/src/apis/ciphers_api.rs index 469f242bd..5e90968cb 100644 --- a/crates/bitwarden-api-api/src/apis/ciphers_api.rs +++ b/crates/bitwarden-api-api/src/apis/ciphers_api.rs @@ -109,6 +109,7 @@ pub trait CiphersApi: Send + Sync { async fn get_organization_ciphers<'a>( &self, organization_id: Option, + include_member_items: Option, ) -> Result< models::CipherMiniDetailsResponseModelListResponseModel, Error, @@ -1096,6 +1097,7 @@ impl CiphersApi for CiphersApiClient { async fn get_organization_ciphers<'a>( &self, organization_id: Option, + include_member_items: Option, ) -> Result< models::CipherMiniDetailsResponseModelListResponseModel, Error, @@ -1115,6 +1117,10 @@ impl CiphersApi for CiphersApiClient { local_var_req_builder = local_var_req_builder.query(&[("organizationId", ¶m_value.to_string())]); } + if let Some(ref param_value) = include_member_items { + local_var_req_builder = + local_var_req_builder.query(&[("includeMemberItems", ¶m_value.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); diff --git a/crates/bitwarden-api-api/src/apis/events_api.rs b/crates/bitwarden-api-api/src/apis/events_api.rs index ee1b252ec..340427e1b 100644 --- a/crates/bitwarden-api-api/src/apis/events_api.rs +++ b/crates/bitwarden-api-api/src/apis/events_api.rs @@ -93,6 +93,16 @@ pub trait EventsApi: Send + Sync { continuation_token: Option<&'a str>, ) -> Result>; + /// GET /organization/{orgId}/service-account/{id}/events + async fn get_service_accounts<'a>( + &self, + org_id: uuid::Uuid, + id: uuid::Uuid, + start: Option, + end: Option, + continuation_token: Option<&'a str>, + ) -> Result>; + /// GET /events async fn get_user<'a>( &self, @@ -662,6 +672,85 @@ impl EventsApi for EventsApiClient { } } + async fn get_service_accounts<'a>( + &self, + org_id: uuid::Uuid, + id: uuid::Uuid, + start: Option, + end: Option, + continuation_token: Option<&'a str>, + ) -> Result> { + let local_var_configuration = &self.configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/organization/{orgId}/service-account/{id}/events", + local_var_configuration.base_path, + orgId = org_id, + id = id + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref param_value) = start { + local_var_req_builder = + local_var_req_builder.query(&[("start", ¶m_value.to_string())]); + } + if let Some(ref param_value) = end { + local_var_req_builder = + local_var_req_builder.query(&[("end", ¶m_value.to_string())]); + } + if let Some(ref param_value) = continuation_token { + local_var_req_builder = + local_var_req_builder.query(&[("continuationToken", ¶m_value.to_string())]); + } + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder + .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content_type = local_var_resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let local_var_content_type = super::ContentType::from(local_var_content_type); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + match local_var_content_type { + ContentType::Json => serde_json::from_str(&local_var_content).map_err(Error::from), + ContentType::Text => { + return Err(Error::from(serde_json::Error::custom( + "Received `text/plain` content type response that cannot be converted to `models::EventResponseModelListResponseModel`", + ))); + } + ContentType::Unsupported(local_var_unknown_type) => { + return Err(Error::from(serde_json::Error::custom(format!( + "Received `{local_var_unknown_type}` content type response that cannot be converted to `models::EventResponseModelListResponseModel`" + )))); + } + } + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } + } + async fn get_user<'a>( &self, start: Option, @@ -777,6 +866,12 @@ pub enum GetProviderUserError { pub enum GetSecretsError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`EventsApi::get_service_accounts`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetServiceAccountsError { + UnknownValue(serde_json::Value), +} /// struct for typed errors of method [`EventsApi::get_user`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] diff --git a/crates/bitwarden-api-api/src/apis/organization_billing_api.rs b/crates/bitwarden-api-api/src/apis/organization_billing_api.rs index 30586b64c..28464bf0f 100644 --- a/crates/bitwarden-api-api/src/apis/organization_billing_api.rs +++ b/crates/bitwarden-api-api/src/apis/organization_billing_api.rs @@ -78,13 +78,6 @@ pub trait OrganizationBillingApi: Send + Sync { start_after: Option, ) -> Result<(), Error>; - /// POST /organizations/{organizationId}/billing/restart-subscription - async fn restart_subscription<'a>( - &self, - organization_id: uuid::Uuid, - organization_create_request_model: Option, - ) -> Result<(), Error>; - /// POST /organizations/{organizationId}/billing/setup-business-unit async fn setup_business_unit<'a>( &self, @@ -496,52 +489,6 @@ impl OrganizationBillingApi for OrganizationBillingApiClient { } } - async fn restart_subscription<'a>( - &self, - organization_id: uuid::Uuid, - organization_create_request_model: Option, - ) -> Result<(), Error> { - let local_var_configuration = &self.configuration; - - let local_var_client = &local_var_configuration.client; - - let local_var_uri_str = format!( - "{}/organizations/{organizationId}/billing/restart-subscription", - local_var_configuration.base_path, - organizationId = organization_id - ); - let mut local_var_req_builder = - local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); - - if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { - local_var_req_builder = local_var_req_builder - .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); - } - if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { - local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); - }; - local_var_req_builder = local_var_req_builder.json(&organization_create_request_model); - - let local_var_req = local_var_req_builder.build()?; - let local_var_resp = local_var_client.execute(local_var_req).await?; - - let local_var_status = local_var_resp.status(); - let local_var_content = local_var_resp.text().await?; - - if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - Ok(()) - } else { - let local_var_entity: Option = - serde_json::from_str(&local_var_content).ok(); - let local_var_error = ResponseContent { - status: local_var_status, - content: local_var_content, - entity: local_var_entity, - }; - Err(Error::ResponseError(local_var_error)) - } - } - async fn setup_business_unit<'a>( &self, organization_id: uuid::Uuid, @@ -775,12 +722,6 @@ pub enum GetTaxInformationError { pub enum GetTransactionsError { UnknownValue(serde_json::Value), } -/// struct for typed errors of method [`OrganizationBillingApi::restart_subscription`] -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum RestartSubscriptionError { - UnknownValue(serde_json::Value), -} /// struct for typed errors of method [`OrganizationBillingApi::setup_business_unit`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] diff --git a/crates/bitwarden-api-api/src/apis/organization_billing_v_next_api.rs b/crates/bitwarden-api-api/src/apis/organization_billing_v_next_api.rs index 413a6552f..172137c17 100644 --- a/crates/bitwarden-api-api/src/apis/organization_billing_v_next_api.rs +++ b/crates/bitwarden-api-api/src/apis/organization_billing_v_next_api.rs @@ -352,6 +352,72 @@ pub trait OrganizationBillingVNextApi: Send + Sync { sync_seats: Option, ) -> Result<(), Error>; + /// POST /organizations/{organizationId}/billing/vnext/subscription/restart + async fn restart_subscription<'a>( + &self, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + restart_subscription_request: Option, + ) -> Result<(), Error>; + /// PUT /organizations/{organizationId}/billing/vnext/address async fn update_billing_address<'a>( &self, @@ -2205,6 +2271,349 @@ impl OrganizationBillingVNextApi for OrganizationBillingVNextApiClient { } } + async fn restart_subscription<'a>( + &self, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + restart_subscription_request: Option, + ) -> Result<(), Error> { + let local_var_configuration = &self.configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/organizations/{organizationId}/billing/vnext/subscription/restart", + local_var_configuration.base_path, + organizationId = crate::apis::urlencode(organization_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref param_value) = id { + local_var_req_builder = + local_var_req_builder.query(&[("id", ¶m_value.to_string())]); + } + if let Some(ref param_value) = identifier { + local_var_req_builder = + local_var_req_builder.query(&[("identifier", ¶m_value.to_string())]); + } + if let Some(ref param_value) = name { + local_var_req_builder = + local_var_req_builder.query(&[("name", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_name { + local_var_req_builder = + local_var_req_builder.query(&[("businessName", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address1 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress1", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address2 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress2", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address3 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress3", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_country { + local_var_req_builder = + local_var_req_builder.query(&[("businessCountry", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_tax_number { + local_var_req_builder = + local_var_req_builder.query(&[("businessTaxNumber", ¶m_value.to_string())]); + } + if let Some(ref param_value) = billing_email { + local_var_req_builder = + local_var_req_builder.query(&[("billingEmail", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan { + local_var_req_builder = + local_var_req_builder.query(&[("plan", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan_type { + local_var_req_builder = + local_var_req_builder.query(&[("planType", ¶m_value.to_string())]); + } + if let Some(ref param_value) = seats { + local_var_req_builder = + local_var_req_builder.query(&[("seats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_collections { + local_var_req_builder = + local_var_req_builder.query(&[("maxCollections", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_policies { + local_var_req_builder = + local_var_req_builder.query(&[("usePolicies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_sso { + local_var_req_builder = + local_var_req_builder.query(&[("useSso", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_key_connector { + local_var_req_builder = + local_var_req_builder.query(&[("useKeyConnector", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_scim { + local_var_req_builder = + local_var_req_builder.query(&[("useScim", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_groups { + local_var_req_builder = + local_var_req_builder.query(&[("useGroups", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_directory { + local_var_req_builder = + local_var_req_builder.query(&[("useDirectory", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_events { + local_var_req_builder = + local_var_req_builder.query(&[("useEvents", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_totp { + local_var_req_builder = + local_var_req_builder.query(&[("useTotp", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use2fa { + local_var_req_builder = + local_var_req_builder.query(&[("use2fa", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_api { + local_var_req_builder = + local_var_req_builder.query(&[("useApi", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_reset_password { + local_var_req_builder = + local_var_req_builder.query(&[("useResetPassword", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_secrets_manager { + local_var_req_builder = + local_var_req_builder.query(&[("useSecretsManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = self_host { + local_var_req_builder = + local_var_req_builder.query(&[("selfHost", ¶m_value.to_string())]); + } + if let Some(ref param_value) = users_get_premium { + local_var_req_builder = + local_var_req_builder.query(&[("usersGetPremium", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_custom_permissions { + local_var_req_builder = + local_var_req_builder.query(&[("useCustomPermissions", ¶m_value.to_string())]); + } + if let Some(ref param_value) = storage { + local_var_req_builder = + local_var_req_builder.query(&[("storage", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_storage_gb { + local_var_req_builder = + local_var_req_builder.query(&[("maxStorageGb", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway { + local_var_req_builder = + local_var_req_builder.query(&[("gateway", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_customer_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewayCustomerId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_subscription_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewaySubscriptionId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = reference_data { + local_var_req_builder = + local_var_req_builder.query(&[("referenceData", ¶m_value.to_string())]); + } + if let Some(ref param_value) = enabled { + local_var_req_builder = + local_var_req_builder.query(&[("enabled", ¶m_value.to_string())]); + } + if let Some(ref param_value) = license_key { + local_var_req_builder = + local_var_req_builder.query(&[("licenseKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = public_key { + local_var_req_builder = + local_var_req_builder.query(&[("publicKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = private_key { + local_var_req_builder = + local_var_req_builder.query(&[("privateKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = two_factor_providers { + local_var_req_builder = + local_var_req_builder.query(&[("twoFactorProviders", ¶m_value.to_string())]); + } + if let Some(ref param_value) = expiration_date { + local_var_req_builder = + local_var_req_builder.query(&[("expirationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = creation_date { + local_var_req_builder = + local_var_req_builder.query(&[("creationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = revision_date { + local_var_req_builder = + local_var_req_builder.query(&[("revisionDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = owners_notified_of_autoscaling { + local_var_req_builder = local_var_req_builder + .query(&[("ownersNotifiedOfAutoscaling", ¶m_value.to_string())]); + } + if let Some(ref param_value) = status { + local_var_req_builder = + local_var_req_builder.query(&[("status", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_password_manager { + local_var_req_builder = + local_var_req_builder.query(&[("usePasswordManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("smSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_service_accounts { + local_var_req_builder = + local_var_req_builder.query(&[("smServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSmSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_service_accounts { + local_var_req_builder = local_var_req_builder + .query(&[("maxAutoscaleSmServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_creation { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionCreation", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_deletion { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = allow_admin_access_to_all_collection_items { + local_var_req_builder = local_var_req_builder.query(&[( + "allowAdminAccessToAllCollectionItems", + ¶m_value.to_string(), + )]); + } + if let Some(ref param_value) = limit_item_deletion { + local_var_req_builder = + local_var_req_builder.query(&[("limitItemDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_risk_insights { + local_var_req_builder = + local_var_req_builder.query(&[("useRiskInsights", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_organization_domains { + local_var_req_builder = local_var_req_builder + .query(&[("useOrganizationDomains", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_admin_sponsored_families { + local_var_req_builder = local_var_req_builder + .query(&[("useAdminSponsoredFamilies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sync_seats { + local_var_req_builder = + local_var_req_builder.query(&[("syncSeats", ¶m_value.to_string())]); + } + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder + .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.json(&restart_subscription_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } + } + async fn update_billing_address<'a>( &self, organization_id: &'a str, @@ -2922,6 +3331,12 @@ pub enum GetPaymentMethodError { pub enum GetWarningsError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`OrganizationBillingVNextApi::restart_subscription`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum RestartSubscriptionError { + UnknownValue(serde_json::Value), +} /// struct for typed errors of method [`OrganizationBillingVNextApi::update_billing_address`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] diff --git a/crates/bitwarden-api-api/src/apis/organizations_api.rs b/crates/bitwarden-api-api/src/apis/organizations_api.rs index 0ed2e165a..4ba86c00e 100644 --- a/crates/bitwarden-api-api/src/apis/organizations_api.rs +++ b/crates/bitwarden-api-api/src/apis/organizations_api.rs @@ -199,13 +199,6 @@ pub trait OrganizationsApi: Send + Sync { organization_upgrade_request_model: Option, ) -> Result>; - /// POST /organizations/{id}/verify-bank - async fn post_verify_bank<'a>( - &self, - id: uuid::Uuid, - organization_verify_bank_request_model: Option, - ) -> Result<(), Error>; - /// PUT /organizations/{id} async fn put<'a>( &self, @@ -1801,52 +1794,6 @@ impl OrganizationsApi for OrganizationsApiClient { } } - async fn post_verify_bank<'a>( - &self, - id: uuid::Uuid, - organization_verify_bank_request_model: Option, - ) -> Result<(), Error> { - let local_var_configuration = &self.configuration; - - let local_var_client = &local_var_configuration.client; - - let local_var_uri_str = format!( - "{}/organizations/{id}/verify-bank", - local_var_configuration.base_path, - id = id - ); - let mut local_var_req_builder = - local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); - - if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { - local_var_req_builder = local_var_req_builder - .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); - } - if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { - local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); - }; - local_var_req_builder = local_var_req_builder.json(&organization_verify_bank_request_model); - - let local_var_req = local_var_req_builder.build()?; - let local_var_resp = local_var_client.execute(local_var_req).await?; - - let local_var_status = local_var_resp.status(); - let local_var_content = local_var_resp.text().await?; - - if !local_var_status.is_client_error() && !local_var_status.is_server_error() { - Ok(()) - } else { - let local_var_entity: Option = - serde_json::from_str(&local_var_content).ok(); - let local_var_error = ResponseContent { - status: local_var_status, - content: local_var_content, - entity: local_var_entity, - }; - Err(Error::ResponseError(local_var_error)) - } - } - async fn put<'a>( &self, id: &'a str, @@ -2244,12 +2191,6 @@ pub enum PostSubscriptionError { pub enum PostUpgradeError { UnknownValue(serde_json::Value), } -/// struct for typed errors of method [`OrganizationsApi::post_verify_bank`] -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum PostVerifyBankError { - UnknownValue(serde_json::Value), -} /// struct for typed errors of method [`OrganizationsApi::put`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] diff --git a/crates/bitwarden-api-api/src/apis/slack_integration_api.rs b/crates/bitwarden-api-api/src/apis/slack_integration_api.rs index 9f69b39e2..39a218212 100644 --- a/crates/bitwarden-api-api/src/apis/slack_integration_api.rs +++ b/crates/bitwarden-api-api/src/apis/slack_integration_api.rs @@ -26,11 +26,11 @@ use crate::{ #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait SlackIntegrationApi: Send + Sync { - /// GET /organizations/{organizationId}/integrations/slack/create + /// GET /organizations/integrations/slack/create async fn create<'a>( &self, - organization_id: uuid::Uuid, code: Option<&'a str>, + state: Option<&'a str>, ) -> Result<(), Error>; /// GET /organizations/{organizationId}/integrations/slack/redirect @@ -52,17 +52,16 @@ impl SlackIntegrationApiClient { impl SlackIntegrationApi for SlackIntegrationApiClient { async fn create<'a>( &self, - organization_id: uuid::Uuid, code: Option<&'a str>, + state: Option<&'a str>, ) -> Result<(), Error> { let local_var_configuration = &self.configuration; let local_var_client = &local_var_configuration.client; let local_var_uri_str = format!( - "{}/organizations/{organizationId}/integrations/slack/create", - local_var_configuration.base_path, - organizationId = organization_id + "{}/organizations/integrations/slack/create", + local_var_configuration.base_path ); let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); @@ -71,6 +70,10 @@ impl SlackIntegrationApi for SlackIntegrationApiClient { local_var_req_builder = local_var_req_builder.query(&[("code", ¶m_value.to_string())]); } + if let Some(ref param_value) = state { + local_var_req_builder = + local_var_req_builder.query(&[("state", ¶m_value.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); diff --git a/crates/bitwarden-api-api/src/apis/tax_api.rs b/crates/bitwarden-api-api/src/apis/tax_api.rs index 74d1cac7b..06f606c0e 100644 --- a/crates/bitwarden-api-api/src/apis/tax_api.rs +++ b/crates/bitwarden-api-api/src/apis/tax_api.rs @@ -26,13 +26,157 @@ use crate::{ #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait TaxApi: Send + Sync { - /// POST /tax/preview-amount/organization-trial - async fn preview_tax_amount_for_organization_trial<'a>( + /// POST /billing/tax/organizations/{organizationId}/subscription/plan-change + async fn preview_organization_subscription_plan_change_tax<'a>( &self, - preview_tax_amount_for_organization_trial_request_body: Option< - models::PreviewTaxAmountForOrganizationTrialRequestBody, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + preview_organization_subscription_plan_change_tax_request: Option< + models::PreviewOrganizationSubscriptionPlanChangeTaxRequest, >, - ) -> Result<(), Error>; + ) -> Result<(), Error>; + + /// POST /billing/tax/organizations/subscriptions/purchase + async fn preview_organization_subscription_purchase_tax<'a>( + &self, + preview_organization_subscription_purchase_tax_request: Option< + models::PreviewOrganizationSubscriptionPurchaseTaxRequest, + >, + ) -> Result<(), Error>; + + /// PUT /billing/tax/organizations/{organizationId}/subscription/update + async fn preview_organization_subscription_update_tax<'a>( + &self, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + preview_organization_subscription_update_tax_request: Option< + models::PreviewOrganizationSubscriptionUpdateTaxRequest, + >, + ) -> Result<(), Error>; + + /// POST /billing/tax/premium/subscriptions/purchase + async fn preview_premium_subscription_purchase_tax<'a>( + &self, + preview_premium_subscription_purchase_tax_request: Option< + models::PreviewPremiumSubscriptionPurchaseTaxRequest, + >, + ) -> Result<(), Error>; } pub struct TaxApiClient { @@ -48,18 +192,757 @@ impl TaxApiClient { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl TaxApi for TaxApiClient { - async fn preview_tax_amount_for_organization_trial<'a>( + async fn preview_organization_subscription_plan_change_tax<'a>( + &self, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + preview_organization_subscription_plan_change_tax_request: Option< + models::PreviewOrganizationSubscriptionPlanChangeTaxRequest, + >, + ) -> Result<(), Error> { + let local_var_configuration = &self.configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/billing/tax/organizations/{organizationId}/subscription/plan-change", + local_var_configuration.base_path, + organizationId = crate::apis::urlencode(organization_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref param_value) = id { + local_var_req_builder = + local_var_req_builder.query(&[("id", ¶m_value.to_string())]); + } + if let Some(ref param_value) = identifier { + local_var_req_builder = + local_var_req_builder.query(&[("identifier", ¶m_value.to_string())]); + } + if let Some(ref param_value) = name { + local_var_req_builder = + local_var_req_builder.query(&[("name", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_name { + local_var_req_builder = + local_var_req_builder.query(&[("businessName", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address1 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress1", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address2 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress2", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address3 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress3", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_country { + local_var_req_builder = + local_var_req_builder.query(&[("businessCountry", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_tax_number { + local_var_req_builder = + local_var_req_builder.query(&[("businessTaxNumber", ¶m_value.to_string())]); + } + if let Some(ref param_value) = billing_email { + local_var_req_builder = + local_var_req_builder.query(&[("billingEmail", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan { + local_var_req_builder = + local_var_req_builder.query(&[("plan", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan_type { + local_var_req_builder = + local_var_req_builder.query(&[("planType", ¶m_value.to_string())]); + } + if let Some(ref param_value) = seats { + local_var_req_builder = + local_var_req_builder.query(&[("seats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_collections { + local_var_req_builder = + local_var_req_builder.query(&[("maxCollections", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_policies { + local_var_req_builder = + local_var_req_builder.query(&[("usePolicies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_sso { + local_var_req_builder = + local_var_req_builder.query(&[("useSso", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_key_connector { + local_var_req_builder = + local_var_req_builder.query(&[("useKeyConnector", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_scim { + local_var_req_builder = + local_var_req_builder.query(&[("useScim", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_groups { + local_var_req_builder = + local_var_req_builder.query(&[("useGroups", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_directory { + local_var_req_builder = + local_var_req_builder.query(&[("useDirectory", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_events { + local_var_req_builder = + local_var_req_builder.query(&[("useEvents", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_totp { + local_var_req_builder = + local_var_req_builder.query(&[("useTotp", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use2fa { + local_var_req_builder = + local_var_req_builder.query(&[("use2fa", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_api { + local_var_req_builder = + local_var_req_builder.query(&[("useApi", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_reset_password { + local_var_req_builder = + local_var_req_builder.query(&[("useResetPassword", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_secrets_manager { + local_var_req_builder = + local_var_req_builder.query(&[("useSecretsManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = self_host { + local_var_req_builder = + local_var_req_builder.query(&[("selfHost", ¶m_value.to_string())]); + } + if let Some(ref param_value) = users_get_premium { + local_var_req_builder = + local_var_req_builder.query(&[("usersGetPremium", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_custom_permissions { + local_var_req_builder = + local_var_req_builder.query(&[("useCustomPermissions", ¶m_value.to_string())]); + } + if let Some(ref param_value) = storage { + local_var_req_builder = + local_var_req_builder.query(&[("storage", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_storage_gb { + local_var_req_builder = + local_var_req_builder.query(&[("maxStorageGb", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway { + local_var_req_builder = + local_var_req_builder.query(&[("gateway", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_customer_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewayCustomerId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_subscription_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewaySubscriptionId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = reference_data { + local_var_req_builder = + local_var_req_builder.query(&[("referenceData", ¶m_value.to_string())]); + } + if let Some(ref param_value) = enabled { + local_var_req_builder = + local_var_req_builder.query(&[("enabled", ¶m_value.to_string())]); + } + if let Some(ref param_value) = license_key { + local_var_req_builder = + local_var_req_builder.query(&[("licenseKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = public_key { + local_var_req_builder = + local_var_req_builder.query(&[("publicKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = private_key { + local_var_req_builder = + local_var_req_builder.query(&[("privateKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = two_factor_providers { + local_var_req_builder = + local_var_req_builder.query(&[("twoFactorProviders", ¶m_value.to_string())]); + } + if let Some(ref param_value) = expiration_date { + local_var_req_builder = + local_var_req_builder.query(&[("expirationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = creation_date { + local_var_req_builder = + local_var_req_builder.query(&[("creationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = revision_date { + local_var_req_builder = + local_var_req_builder.query(&[("revisionDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = owners_notified_of_autoscaling { + local_var_req_builder = local_var_req_builder + .query(&[("ownersNotifiedOfAutoscaling", ¶m_value.to_string())]); + } + if let Some(ref param_value) = status { + local_var_req_builder = + local_var_req_builder.query(&[("status", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_password_manager { + local_var_req_builder = + local_var_req_builder.query(&[("usePasswordManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("smSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_service_accounts { + local_var_req_builder = + local_var_req_builder.query(&[("smServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSmSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_service_accounts { + local_var_req_builder = local_var_req_builder + .query(&[("maxAutoscaleSmServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_creation { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionCreation", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_deletion { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = allow_admin_access_to_all_collection_items { + local_var_req_builder = local_var_req_builder.query(&[( + "allowAdminAccessToAllCollectionItems", + ¶m_value.to_string(), + )]); + } + if let Some(ref param_value) = limit_item_deletion { + local_var_req_builder = + local_var_req_builder.query(&[("limitItemDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_risk_insights { + local_var_req_builder = + local_var_req_builder.query(&[("useRiskInsights", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_organization_domains { + local_var_req_builder = local_var_req_builder + .query(&[("useOrganizationDomains", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_admin_sponsored_families { + local_var_req_builder = local_var_req_builder + .query(&[("useAdminSponsoredFamilies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sync_seats { + local_var_req_builder = + local_var_req_builder.query(&[("syncSeats", ¶m_value.to_string())]); + } + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder + .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = + local_var_req_builder.json(&preview_organization_subscription_plan_change_tax_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } + } + + async fn preview_organization_subscription_purchase_tax<'a>( + &self, + preview_organization_subscription_purchase_tax_request: Option< + models::PreviewOrganizationSubscriptionPurchaseTaxRequest, + >, + ) -> Result<(), Error> { + let local_var_configuration = &self.configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/billing/tax/organizations/subscriptions/purchase", + local_var_configuration.base_path + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder + .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = + local_var_req_builder.json(&preview_organization_subscription_purchase_tax_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } + } + + async fn preview_organization_subscription_update_tax<'a>( + &self, + organization_id: &'a str, + id: Option, + identifier: Option<&'a str>, + name: Option<&'a str>, + business_name: Option<&'a str>, + business_address1: Option<&'a str>, + business_address2: Option<&'a str>, + business_address3: Option<&'a str>, + business_country: Option<&'a str>, + business_tax_number: Option<&'a str>, + billing_email: Option<&'a str>, + plan: Option<&'a str>, + plan_type: Option, + seats: Option, + max_collections: Option, + use_policies: Option, + use_sso: Option, + use_key_connector: Option, + use_scim: Option, + use_groups: Option, + use_directory: Option, + use_events: Option, + use_totp: Option, + use2fa: Option, + use_api: Option, + use_reset_password: Option, + use_secrets_manager: Option, + self_host: Option, + users_get_premium: Option, + use_custom_permissions: Option, + storage: Option, + max_storage_gb: Option, + gateway: Option, + gateway_customer_id: Option<&'a str>, + gateway_subscription_id: Option<&'a str>, + reference_data: Option<&'a str>, + enabled: Option, + license_key: Option<&'a str>, + public_key: Option<&'a str>, + private_key: Option<&'a str>, + two_factor_providers: Option<&'a str>, + expiration_date: Option, + creation_date: Option, + revision_date: Option, + max_autoscale_seats: Option, + owners_notified_of_autoscaling: Option, + status: Option, + use_password_manager: Option, + sm_seats: Option, + sm_service_accounts: Option, + max_autoscale_sm_seats: Option, + max_autoscale_sm_service_accounts: Option, + limit_collection_creation: Option, + limit_collection_deletion: Option, + allow_admin_access_to_all_collection_items: Option, + limit_item_deletion: Option, + use_risk_insights: Option, + use_organization_domains: Option, + use_admin_sponsored_families: Option, + sync_seats: Option, + preview_organization_subscription_update_tax_request: Option< + models::PreviewOrganizationSubscriptionUpdateTaxRequest, + >, + ) -> Result<(), Error> { + let local_var_configuration = &self.configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/billing/tax/organizations/{organizationId}/subscription/update", + local_var_configuration.base_path, + organizationId = crate::apis::urlencode(organization_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::PUT, local_var_uri_str.as_str()); + + if let Some(ref param_value) = id { + local_var_req_builder = + local_var_req_builder.query(&[("id", ¶m_value.to_string())]); + } + if let Some(ref param_value) = identifier { + local_var_req_builder = + local_var_req_builder.query(&[("identifier", ¶m_value.to_string())]); + } + if let Some(ref param_value) = name { + local_var_req_builder = + local_var_req_builder.query(&[("name", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_name { + local_var_req_builder = + local_var_req_builder.query(&[("businessName", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address1 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress1", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address2 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress2", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_address3 { + local_var_req_builder = + local_var_req_builder.query(&[("businessAddress3", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_country { + local_var_req_builder = + local_var_req_builder.query(&[("businessCountry", ¶m_value.to_string())]); + } + if let Some(ref param_value) = business_tax_number { + local_var_req_builder = + local_var_req_builder.query(&[("businessTaxNumber", ¶m_value.to_string())]); + } + if let Some(ref param_value) = billing_email { + local_var_req_builder = + local_var_req_builder.query(&[("billingEmail", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan { + local_var_req_builder = + local_var_req_builder.query(&[("plan", ¶m_value.to_string())]); + } + if let Some(ref param_value) = plan_type { + local_var_req_builder = + local_var_req_builder.query(&[("planType", ¶m_value.to_string())]); + } + if let Some(ref param_value) = seats { + local_var_req_builder = + local_var_req_builder.query(&[("seats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_collections { + local_var_req_builder = + local_var_req_builder.query(&[("maxCollections", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_policies { + local_var_req_builder = + local_var_req_builder.query(&[("usePolicies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_sso { + local_var_req_builder = + local_var_req_builder.query(&[("useSso", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_key_connector { + local_var_req_builder = + local_var_req_builder.query(&[("useKeyConnector", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_scim { + local_var_req_builder = + local_var_req_builder.query(&[("useScim", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_groups { + local_var_req_builder = + local_var_req_builder.query(&[("useGroups", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_directory { + local_var_req_builder = + local_var_req_builder.query(&[("useDirectory", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_events { + local_var_req_builder = + local_var_req_builder.query(&[("useEvents", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_totp { + local_var_req_builder = + local_var_req_builder.query(&[("useTotp", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use2fa { + local_var_req_builder = + local_var_req_builder.query(&[("use2fa", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_api { + local_var_req_builder = + local_var_req_builder.query(&[("useApi", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_reset_password { + local_var_req_builder = + local_var_req_builder.query(&[("useResetPassword", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_secrets_manager { + local_var_req_builder = + local_var_req_builder.query(&[("useSecretsManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = self_host { + local_var_req_builder = + local_var_req_builder.query(&[("selfHost", ¶m_value.to_string())]); + } + if let Some(ref param_value) = users_get_premium { + local_var_req_builder = + local_var_req_builder.query(&[("usersGetPremium", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_custom_permissions { + local_var_req_builder = + local_var_req_builder.query(&[("useCustomPermissions", ¶m_value.to_string())]); + } + if let Some(ref param_value) = storage { + local_var_req_builder = + local_var_req_builder.query(&[("storage", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_storage_gb { + local_var_req_builder = + local_var_req_builder.query(&[("maxStorageGb", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway { + local_var_req_builder = + local_var_req_builder.query(&[("gateway", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_customer_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewayCustomerId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = gateway_subscription_id { + local_var_req_builder = + local_var_req_builder.query(&[("gatewaySubscriptionId", ¶m_value.to_string())]); + } + if let Some(ref param_value) = reference_data { + local_var_req_builder = + local_var_req_builder.query(&[("referenceData", ¶m_value.to_string())]); + } + if let Some(ref param_value) = enabled { + local_var_req_builder = + local_var_req_builder.query(&[("enabled", ¶m_value.to_string())]); + } + if let Some(ref param_value) = license_key { + local_var_req_builder = + local_var_req_builder.query(&[("licenseKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = public_key { + local_var_req_builder = + local_var_req_builder.query(&[("publicKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = private_key { + local_var_req_builder = + local_var_req_builder.query(&[("privateKey", ¶m_value.to_string())]); + } + if let Some(ref param_value) = two_factor_providers { + local_var_req_builder = + local_var_req_builder.query(&[("twoFactorProviders", ¶m_value.to_string())]); + } + if let Some(ref param_value) = expiration_date { + local_var_req_builder = + local_var_req_builder.query(&[("expirationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = creation_date { + local_var_req_builder = + local_var_req_builder.query(&[("creationDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = revision_date { + local_var_req_builder = + local_var_req_builder.query(&[("revisionDate", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = owners_notified_of_autoscaling { + local_var_req_builder = local_var_req_builder + .query(&[("ownersNotifiedOfAutoscaling", ¶m_value.to_string())]); + } + if let Some(ref param_value) = status { + local_var_req_builder = + local_var_req_builder.query(&[("status", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_password_manager { + local_var_req_builder = + local_var_req_builder.query(&[("usePasswordManager", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("smSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sm_service_accounts { + local_var_req_builder = + local_var_req_builder.query(&[("smServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_seats { + local_var_req_builder = + local_var_req_builder.query(&[("maxAutoscaleSmSeats", ¶m_value.to_string())]); + } + if let Some(ref param_value) = max_autoscale_sm_service_accounts { + local_var_req_builder = local_var_req_builder + .query(&[("maxAutoscaleSmServiceAccounts", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_creation { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionCreation", ¶m_value.to_string())]); + } + if let Some(ref param_value) = limit_collection_deletion { + local_var_req_builder = local_var_req_builder + .query(&[("limitCollectionDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = allow_admin_access_to_all_collection_items { + local_var_req_builder = local_var_req_builder.query(&[( + "allowAdminAccessToAllCollectionItems", + ¶m_value.to_string(), + )]); + } + if let Some(ref param_value) = limit_item_deletion { + local_var_req_builder = + local_var_req_builder.query(&[("limitItemDeletion", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_risk_insights { + local_var_req_builder = + local_var_req_builder.query(&[("useRiskInsights", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_organization_domains { + local_var_req_builder = local_var_req_builder + .query(&[("useOrganizationDomains", ¶m_value.to_string())]); + } + if let Some(ref param_value) = use_admin_sponsored_families { + local_var_req_builder = local_var_req_builder + .query(&[("useAdminSponsoredFamilies", ¶m_value.to_string())]); + } + if let Some(ref param_value) = sync_seats { + local_var_req_builder = + local_var_req_builder.query(&[("syncSeats", ¶m_value.to_string())]); + } + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = local_var_req_builder + .header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.oauth_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = + local_var_req_builder.json(&preview_organization_subscription_update_tax_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + Ok(()) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } + } + + async fn preview_premium_subscription_purchase_tax<'a>( &self, - preview_tax_amount_for_organization_trial_request_body: Option< - models::PreviewTaxAmountForOrganizationTrialRequestBody, + preview_premium_subscription_purchase_tax_request: Option< + models::PreviewPremiumSubscriptionPurchaseTaxRequest, >, - ) -> Result<(), Error> { + ) -> Result<(), Error> { let local_var_configuration = &self.configuration; let local_var_client = &local_var_configuration.client; let local_var_uri_str = format!( - "{}/tax/preview-amount/organization-trial", + "{}/billing/tax/premium/subscriptions/purchase", local_var_configuration.base_path ); let mut local_var_req_builder = @@ -73,7 +956,7 @@ impl TaxApi for TaxApiClient { local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); }; local_var_req_builder = - local_var_req_builder.json(&preview_tax_amount_for_organization_trial_request_body); + local_var_req_builder.json(&preview_premium_subscription_purchase_tax_request); let local_var_req = local_var_req_builder.build()?; let local_var_resp = local_var_client.execute(local_var_req).await?; @@ -84,7 +967,7 @@ impl TaxApi for TaxApiClient { if !local_var_status.is_client_error() && !local_var_status.is_server_error() { Ok(()) } else { - let local_var_entity: Option = + let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); let local_var_error = ResponseContent { status: local_var_status, @@ -96,9 +979,27 @@ impl TaxApi for TaxApiClient { } } -/// struct for typed errors of method [`TaxApi::preview_tax_amount_for_organization_trial`] +/// struct for typed errors of method [`TaxApi::preview_organization_subscription_plan_change_tax`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum PreviewOrganizationSubscriptionPlanChangeTaxError { + UnknownValue(serde_json::Value), +} +/// struct for typed errors of method [`TaxApi::preview_organization_subscription_purchase_tax`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum PreviewOrganizationSubscriptionPurchaseTaxError { + UnknownValue(serde_json::Value), +} +/// struct for typed errors of method [`TaxApi::preview_organization_subscription_update_tax`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum PreviewOrganizationSubscriptionUpdateTaxError { + UnknownValue(serde_json::Value), +} +/// struct for typed errors of method [`TaxApi::preview_premium_subscription_purchase_tax`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] -pub enum PreviewTaxAmountForOrganizationTrialError { +pub enum PreviewPremiumSubscriptionPurchaseTaxError { UnknownValue(serde_json::Value), } diff --git a/crates/bitwarden-api-api/src/models/tax_information_dto.rs b/crates/bitwarden-api-api/src/models/checkout_billing_address_request.rs similarity index 71% rename from crates/bitwarden-api-api/src/models/tax_information_dto.rs rename to crates/bitwarden-api-api/src/models/checkout_billing_address_request.rs index c55ab888e..aae0cbd8c 100644 --- a/crates/bitwarden-api-api/src/models/tax_information_dto.rs +++ b/crates/bitwarden-api-api/src/models/checkout_billing_address_request.rs @@ -13,18 +13,18 @@ use serde::{Deserialize, Serialize}; use crate::models; #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] -pub struct TaxInformationDto { +pub struct CheckoutBillingAddressRequest { #[serde(rename = "country")] pub country: String, #[serde(rename = "postalCode")] pub postal_code: String, #[serde(rename = "taxId", skip_serializing_if = "Option::is_none")] - pub tax_id: Option, + pub tax_id: Option>, } -impl TaxInformationDto { - pub fn new(country: String, postal_code: String) -> TaxInformationDto { - TaxInformationDto { +impl CheckoutBillingAddressRequest { + pub fn new(country: String, postal_code: String) -> CheckoutBillingAddressRequest { + CheckoutBillingAddressRequest { country, postal_code, tax_id: None, diff --git a/crates/bitwarden-api-api/src/models/event_response_model.rs b/crates/bitwarden-api-api/src/models/event_response_model.rs index a8f1e7903..9ee03bb58 100644 --- a/crates/bitwarden-api-api/src/models/event_response_model.rs +++ b/crates/bitwarden-api-api/src/models/event_response_model.rs @@ -61,6 +61,11 @@ pub struct EventResponseModel { pub project_id: Option, #[serde(rename = "serviceAccountId", skip_serializing_if = "Option::is_none")] pub service_account_id: Option, + #[serde( + rename = "grantedServiceAccountId", + skip_serializing_if = "Option::is_none" + )] + pub granted_service_account_id: Option, } impl EventResponseModel { @@ -88,6 +93,7 @@ impl EventResponseModel { secret_id: None, project_id: None, service_account_id: None, + granted_service_account_id: None, } } } diff --git a/crates/bitwarden-api-api/src/models/event_type.rs b/crates/bitwarden-api-api/src/models/event_type.rs index c3cc0df66..603294c02 100644 --- a/crates/bitwarden-api-api/src/models/event_type.rs +++ b/crates/bitwarden-api-api/src/models/event_type.rs @@ -112,6 +112,12 @@ pub enum EventType { Project_Created = 2201, Project_Edited = 2202, Project_Deleted = 2203, + ServiceAccount_UserAdded = 2300, + ServiceAccount_UserRemoved = 2301, + ServiceAccount_GroupAdded = 2302, + ServiceAccount_GroupRemoved = 2303, + ServiceAccount_Created = 2304, + ServiceAccount_Deleted = 2305, } impl std::fmt::Display for EventType { @@ -211,6 +217,12 @@ impl std::fmt::Display for EventType { Self::Project_Created => "2201", Self::Project_Edited => "2202", Self::Project_Deleted => "2203", + Self::ServiceAccount_UserAdded => "2300", + Self::ServiceAccount_UserRemoved => "2301", + Self::ServiceAccount_GroupAdded => "2302", + Self::ServiceAccount_GroupRemoved => "2303", + Self::ServiceAccount_Created => "2304", + Self::ServiceAccount_Deleted => "2305", }) } } diff --git a/crates/bitwarden-api-api/src/models/kdf_request_model.rs b/crates/bitwarden-api-api/src/models/kdf_request_model.rs index 948a3e89e..5b070b806 100644 --- a/crates/bitwarden-api-api/src/models/kdf_request_model.rs +++ b/crates/bitwarden-api-api/src/models/kdf_request_model.rs @@ -14,52 +14,23 @@ use crate::models; #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct KdfRequestModel { - #[serde(rename = "masterPasswordHash", skip_serializing_if = "Option::is_none")] - pub master_password_hash: Option, - #[serde(rename = "otp", skip_serializing_if = "Option::is_none")] - pub otp: Option, - #[serde( - rename = "authRequestAccessCode", - skip_serializing_if = "Option::is_none" - )] - pub auth_request_access_code: Option, - #[serde(rename = "secret", skip_serializing_if = "Option::is_none")] - pub secret: Option, - #[serde(rename = "newMasterPasswordHash")] - pub new_master_password_hash: String, - #[serde(rename = "masterPasswordHint", skip_serializing_if = "Option::is_none")] - pub master_password_hint: Option, - #[serde(rename = "key")] - pub key: String, - #[serde(rename = "kdf")] - pub kdf: models::KdfType, - #[serde(rename = "kdfIterations")] - pub kdf_iterations: i32, - #[serde(rename = "kdfMemory", skip_serializing_if = "Option::is_none")] - pub kdf_memory: Option, - #[serde(rename = "kdfParallelism", skip_serializing_if = "Option::is_none")] - pub kdf_parallelism: Option, + #[serde(rename = "kdfType")] + pub kdf_type: models::KdfType, + #[serde(rename = "iterations")] + pub iterations: i32, + #[serde(rename = "memory", skip_serializing_if = "Option::is_none")] + pub memory: Option, + #[serde(rename = "parallelism", skip_serializing_if = "Option::is_none")] + pub parallelism: Option, } impl KdfRequestModel { - pub fn new( - new_master_password_hash: String, - key: String, - kdf: models::KdfType, - kdf_iterations: i32, - ) -> KdfRequestModel { + pub fn new(kdf_type: models::KdfType, iterations: i32) -> KdfRequestModel { KdfRequestModel { - master_password_hash: None, - otp: None, - auth_request_access_code: None, - secret: None, - new_master_password_hash, - master_password_hint: None, - key, - kdf, - kdf_iterations, - kdf_memory: None, - kdf_parallelism: None, + kdf_type, + iterations, + memory: None, + parallelism: None, } } } diff --git a/crates/bitwarden-api-api/src/models/master_password_authentication_data_request_model.rs b/crates/bitwarden-api-api/src/models/master_password_authentication_data_request_model.rs new file mode 100644 index 000000000..3b860667b --- /dev/null +++ b/crates/bitwarden-api-api/src/models/master_password_authentication_data_request_model.rs @@ -0,0 +1,37 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct MasterPasswordAuthenticationDataRequestModel { + #[serde(rename = "kdf")] + pub kdf: Box, + #[serde(rename = "masterPasswordAuthenticationHash")] + pub master_password_authentication_hash: Option, + #[serde(rename = "salt")] + pub salt: Option, +} + +impl MasterPasswordAuthenticationDataRequestModel { + pub fn new( + kdf: models::KdfRequestModel, + master_password_authentication_hash: Option, + salt: Option, + ) -> MasterPasswordAuthenticationDataRequestModel { + MasterPasswordAuthenticationDataRequestModel { + kdf: Box::new(kdf), + master_password_authentication_hash, + salt, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/master_password_unlock_data_model.rs b/crates/bitwarden-api-api/src/models/master_password_unlock_and_authentication_data_model.rs similarity index 87% rename from crates/bitwarden-api-api/src/models/master_password_unlock_data_model.rs rename to crates/bitwarden-api-api/src/models/master_password_unlock_and_authentication_data_model.rs index 073b833fd..41acaab53 100644 --- a/crates/bitwarden-api-api/src/models/master_password_unlock_data_model.rs +++ b/crates/bitwarden-api-api/src/models/master_password_unlock_and_authentication_data_model.rs @@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize}; use crate::models; #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] -pub struct MasterPasswordUnlockDataModel { +pub struct MasterPasswordUnlockAndAuthenticationDataModel { #[serde(rename = "kdfType")] pub kdf_type: models::KdfType, #[serde(rename = "kdfIterations")] @@ -32,15 +32,15 @@ pub struct MasterPasswordUnlockDataModel { pub master_password_hint: Option, } -impl MasterPasswordUnlockDataModel { +impl MasterPasswordUnlockAndAuthenticationDataModel { pub fn new( kdf_type: models::KdfType, kdf_iterations: i32, email: Option, master_key_authentication_hash: Option, master_key_encrypted_user_key: Option, - ) -> MasterPasswordUnlockDataModel { - MasterPasswordUnlockDataModel { + ) -> MasterPasswordUnlockAndAuthenticationDataModel { + MasterPasswordUnlockAndAuthenticationDataModel { kdf_type, kdf_iterations, kdf_memory: None, diff --git a/crates/bitwarden-api-api/src/models/master_password_unlock_data_request_model.rs b/crates/bitwarden-api-api/src/models/master_password_unlock_data_request_model.rs new file mode 100644 index 000000000..702d13434 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/master_password_unlock_data_request_model.rs @@ -0,0 +1,37 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct MasterPasswordUnlockDataRequestModel { + #[serde(rename = "kdf")] + pub kdf: Box, + #[serde(rename = "masterKeyWrappedUserKey")] + pub master_key_wrapped_user_key: Option, + #[serde(rename = "salt")] + pub salt: Option, +} + +impl MasterPasswordUnlockDataRequestModel { + pub fn new( + kdf: models::KdfRequestModel, + master_key_wrapped_user_key: Option, + salt: Option, + ) -> MasterPasswordUnlockDataRequestModel { + MasterPasswordUnlockDataRequestModel { + kdf: Box::new(kdf), + master_key_wrapped_user_key, + salt, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/mod.rs b/crates/bitwarden-api-api/src/models/mod.rs index f2f4f527a..5c429e616 100644 --- a/crates/bitwarden-api-api/src/models/mod.rs +++ b/crates/bitwarden-api-api/src/models/mod.rs @@ -98,6 +98,8 @@ pub mod bulk_deny_admin_auth_request_request_model; pub use self::bulk_deny_admin_auth_request_request_model::BulkDenyAdminAuthRequestRequestModel; pub mod change_plan_frequency_request; pub use self::change_plan_frequency_request::ChangePlanFrequencyRequest; +pub mod checkout_billing_address_request; +pub use self::checkout_billing_address_request::CheckoutBillingAddressRequest; pub mod cipher; pub use self::cipher::Cipher; pub mod cipher_attachment_model; @@ -344,10 +346,14 @@ pub mod keys_response_model; pub use self::keys_response_model::KeysResponseModel; pub mod license_type; pub use self::license_type::LicenseType; +pub mod master_password_authentication_data_request_model; +pub use self::master_password_authentication_data_request_model::MasterPasswordAuthenticationDataRequestModel; pub mod master_password_policy_response_model; pub use self::master_password_policy_response_model::MasterPasswordPolicyResponseModel; -pub mod master_password_unlock_data_model; -pub use self::master_password_unlock_data_model::MasterPasswordUnlockDataModel; +pub mod master_password_unlock_and_authentication_data_model; +pub use self::master_password_unlock_and_authentication_data_model::MasterPasswordUnlockAndAuthenticationDataModel; +pub mod master_password_unlock_data_request_model; +pub use self::master_password_unlock_data_request_model::MasterPasswordUnlockDataRequestModel; pub mod master_password_unlock_kdf_response_model; pub use self::master_password_unlock_kdf_response_model::MasterPasswordUnlockKdfResponseModel; pub mod master_password_unlock_response_model; @@ -412,6 +418,8 @@ pub mod organization_integration_request_model; pub use self::organization_integration_request_model::OrganizationIntegrationRequestModel; pub mod organization_integration_response_model; pub use self::organization_integration_response_model::OrganizationIntegrationResponseModel; +pub mod organization_integration_status; +pub use self::organization_integration_status::OrganizationIntegrationStatus; pub mod organization_keys_request_model; pub use self::organization_keys_request_model::OrganizationKeysRequestModel; pub mod organization_keys_response_model; @@ -450,8 +458,14 @@ pub mod organization_sso_response_model; pub use self::organization_sso_response_model::OrganizationSsoResponseModel; pub mod organization_status_type; pub use self::organization_status_type::OrganizationStatusType; +pub mod organization_subscription_plan_change_request; +pub use self::organization_subscription_plan_change_request::OrganizationSubscriptionPlanChangeRequest; +pub mod organization_subscription_purchase_request; +pub use self::organization_subscription_purchase_request::OrganizationSubscriptionPurchaseRequest; pub mod organization_subscription_response_model; pub use self::organization_subscription_response_model::OrganizationSubscriptionResponseModel; +pub mod organization_subscription_update_request; +pub use self::organization_subscription_update_request::OrganizationSubscriptionUpdateRequest; pub mod organization_subscription_update_request_model; pub use self::organization_subscription_update_request_model::OrganizationSubscriptionUpdateRequestModel; pub mod organization_update_request_model; @@ -504,8 +518,6 @@ pub mod organization_user_user_mini_details_response_model; pub use self::organization_user_user_mini_details_response_model::OrganizationUserUserMiniDetailsResponseModel; pub mod organization_user_user_mini_details_response_model_list_response_model; pub use self::organization_user_user_mini_details_response_model_list_response_model::OrganizationUserUserMiniDetailsResponseModelListResponseModel; -pub mod organization_verify_bank_request_model; -pub use self::organization_verify_bank_request_model::OrganizationVerifyBankRequestModel; pub mod organization_verify_delete_recover_request_model; pub use self::organization_verify_delete_recover_request_model::OrganizationVerifyDeleteRecoverRequestModel; pub mod other_device_keys_update_request_model; @@ -518,6 +530,10 @@ pub mod password_hint_request_model; pub use self::password_hint_request_model::PasswordHintRequestModel; pub mod password_manager_plan_features_response_model; pub use self::password_manager_plan_features_response_model::PasswordManagerPlanFeaturesResponseModel; +pub mod password_manager_purchase_selections; +pub use self::password_manager_purchase_selections::PasswordManagerPurchaseSelections; +pub mod password_manager_update_selections; +pub use self::password_manager_update_selections::PasswordManagerUpdateSelections; pub mod password_request_model; pub use self::password_request_model::PasswordRequestModel; pub mod payment_method_type; @@ -540,6 +556,8 @@ pub mod people_access_policies_request_model; pub use self::people_access_policies_request_model::PeopleAccessPoliciesRequestModel; pub mod permissions; pub use self::permissions::Permissions; +pub mod plan_cadence_type; +pub use self::plan_cadence_type::PlanCadenceType; pub mod plan_response_model; pub use self::plan_response_model::PlanResponseModel; pub mod plan_response_model_list_response_model; @@ -570,14 +588,18 @@ pub mod preview_individual_invoice_request_body; pub use self::preview_individual_invoice_request_body::PreviewIndividualInvoiceRequestBody; pub mod preview_organization_invoice_request_body; pub use self::preview_organization_invoice_request_body::PreviewOrganizationInvoiceRequestBody; -pub mod preview_tax_amount_for_organization_trial_request_body; -pub use self::preview_tax_amount_for_organization_trial_request_body::PreviewTaxAmountForOrganizationTrialRequestBody; +pub mod preview_organization_subscription_plan_change_tax_request; +pub use self::preview_organization_subscription_plan_change_tax_request::PreviewOrganizationSubscriptionPlanChangeTaxRequest; +pub mod preview_organization_subscription_purchase_tax_request; +pub use self::preview_organization_subscription_purchase_tax_request::PreviewOrganizationSubscriptionPurchaseTaxRequest; +pub mod preview_organization_subscription_update_tax_request; +pub use self::preview_organization_subscription_update_tax_request::PreviewOrganizationSubscriptionUpdateTaxRequest; +pub mod preview_premium_subscription_purchase_tax_request; +pub use self::preview_premium_subscription_purchase_tax_request::PreviewPremiumSubscriptionPurchaseTaxRequest; pub mod priority; pub use self::priority::Priority; pub mod product_tier_type; pub use self::product_tier_type::ProductTierType; -pub mod product_type; -pub use self::product_type::ProductType; pub mod profile_organization_response_model; pub use self::profile_organization_response_model::ProfileOrganizationResponseModel; pub mod profile_organization_response_model_list_response_model; @@ -686,6 +708,8 @@ pub mod reset_password_with_org_id_request_model; pub use self::reset_password_with_org_id_request_model::ResetPasswordWithOrgIdRequestModel; pub mod response_data; pub use self::response_data::ResponseData; +pub mod restart_subscription_request; +pub use self::restart_subscription_request::RestartSubscriptionRequest; pub mod revoke_access_tokens_request; pub use self::revoke_access_tokens_request::RevokeAccessTokensRequest; pub mod rotate_user_account_keys_and_data_request_model; @@ -718,12 +742,16 @@ pub mod secret_with_projects_list_response_model; pub use self::secret_with_projects_list_response_model::SecretWithProjectsListResponseModel; pub mod secrets_manager_plan_features_response_model; pub use self::secrets_manager_plan_features_response_model::SecretsManagerPlanFeaturesResponseModel; +pub mod secrets_manager_purchase_selections; +pub use self::secrets_manager_purchase_selections::SecretsManagerPurchaseSelections; pub mod secrets_manager_request_model; pub use self::secrets_manager_request_model::SecretsManagerRequestModel; pub mod secrets_manager_subscribe_request_model; pub use self::secrets_manager_subscribe_request_model::SecretsManagerSubscribeRequestModel; pub mod secrets_manager_subscription_update_request_model; pub use self::secrets_manager_subscription_update_request_model::SecretsManagerSubscriptionUpdateRequestModel; +pub mod secrets_manager_update_selections; +pub use self::secrets_manager_update_selections::SecretsManagerUpdateSelections; pub mod secrets_sync_response_model; pub use self::secrets_sync_response_model::SecretsSyncResponseModel; pub mod secrets_with_projects_inner_secret; @@ -824,8 +852,6 @@ pub mod tax_info_response_model; pub use self::tax_info_response_model::TaxInfoResponseModel; pub mod tax_info_update_request_model; pub use self::tax_info_update_request_model::TaxInfoUpdateRequestModel; -pub mod tax_information_dto; -pub use self::tax_information_dto::TaxInformationDto; pub mod tax_information_request_body; pub use self::tax_information_request_body::TaxInformationRequestBody; pub mod tax_information_request_model; diff --git a/crates/bitwarden-api-api/src/models/organization_integration_response_model.rs b/crates/bitwarden-api-api/src/models/organization_integration_response_model.rs index 7a7f0ea97..26819baff 100644 --- a/crates/bitwarden-api-api/src/models/organization_integration_response_model.rs +++ b/crates/bitwarden-api-api/src/models/organization_integration_response_model.rs @@ -22,6 +22,8 @@ pub struct OrganizationIntegrationResponseModel { pub r#type: Option, #[serde(rename = "configuration", skip_serializing_if = "Option::is_none")] pub configuration: Option, + #[serde(rename = "status", skip_serializing_if = "Option::is_none")] + pub status: Option, } impl OrganizationIntegrationResponseModel { @@ -31,6 +33,7 @@ impl OrganizationIntegrationResponseModel { id: None, r#type: None, configuration: None, + status: None, } } } diff --git a/crates/bitwarden-api-api/src/models/organization_integration_status.rs b/crates/bitwarden-api-api/src/models/organization_integration_status.rs new file mode 100644 index 000000000..24fd3b682 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/organization_integration_status.rs @@ -0,0 +1,47 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; +use serde_repr::{Deserialize_repr, Serialize_repr}; + +use crate::models; +/// +#[repr(i64)] +#[derive( + Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize_repr, Deserialize_repr, +)] +pub enum OrganizationIntegrationStatus { + NotApplicable = 0, + Invalid = 1, + Initiated = 2, + InProgress = 3, + Completed = 4, +} + +impl std::fmt::Display for OrganizationIntegrationStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::NotApplicable => "0", + Self::Invalid => "1", + Self::Initiated => "2", + Self::InProgress => "3", + Self::Completed => "4", + } + ) + } +} +impl Default for OrganizationIntegrationStatus { + fn default() -> OrganizationIntegrationStatus { + Self::NotApplicable + } +} diff --git a/crates/bitwarden-api-api/src/models/organization_subscription_plan_change_request.rs b/crates/bitwarden-api-api/src/models/organization_subscription_plan_change_request.rs new file mode 100644 index 000000000..fb085df12 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/organization_subscription_plan_change_request.rs @@ -0,0 +1,30 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct OrganizationSubscriptionPlanChangeRequest { + #[serde(rename = "tier")] + pub tier: models::ProductTierType, + #[serde(rename = "cadence")] + pub cadence: models::PlanCadenceType, +} + +impl OrganizationSubscriptionPlanChangeRequest { + pub fn new( + tier: models::ProductTierType, + cadence: models::PlanCadenceType, + ) -> OrganizationSubscriptionPlanChangeRequest { + OrganizationSubscriptionPlanChangeRequest { tier, cadence } + } +} diff --git a/crates/bitwarden-api-api/src/models/organization_subscription_purchase_request.rs b/crates/bitwarden-api-api/src/models/organization_subscription_purchase_request.rs new file mode 100644 index 000000000..0a97f6dd3 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/organization_subscription_purchase_request.rs @@ -0,0 +1,40 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct OrganizationSubscriptionPurchaseRequest { + #[serde(rename = "tier")] + pub tier: models::ProductTierType, + #[serde(rename = "cadence")] + pub cadence: models::PlanCadenceType, + #[serde(rename = "passwordManager")] + pub password_manager: Box, + #[serde(rename = "secretsManager", skip_serializing_if = "Option::is_none")] + pub secrets_manager: Option>, +} + +impl OrganizationSubscriptionPurchaseRequest { + pub fn new( + tier: models::ProductTierType, + cadence: models::PlanCadenceType, + password_manager: models::PasswordManagerPurchaseSelections, + ) -> OrganizationSubscriptionPurchaseRequest { + OrganizationSubscriptionPurchaseRequest { + tier, + cadence, + password_manager: Box::new(password_manager), + secrets_manager: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/organization_subscription_update_request.rs b/crates/bitwarden-api-api/src/models/organization_subscription_update_request.rs new file mode 100644 index 000000000..3e9045092 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/organization_subscription_update_request.rs @@ -0,0 +1,30 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct OrganizationSubscriptionUpdateRequest { + #[serde(rename = "passwordManager", skip_serializing_if = "Option::is_none")] + pub password_manager: Option>, + #[serde(rename = "secretsManager", skip_serializing_if = "Option::is_none")] + pub secrets_manager: Option>, +} + +impl OrganizationSubscriptionUpdateRequest { + pub fn new() -> OrganizationSubscriptionUpdateRequest { + OrganizationSubscriptionUpdateRequest { + password_manager: None, + secrets_manager: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/organization_verify_bank_request_model.rs b/crates/bitwarden-api-api/src/models/organization_verify_bank_request_model.rs deleted file mode 100644 index 58515ccc5..000000000 --- a/crates/bitwarden-api-api/src/models/organization_verify_bank_request_model.rs +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Bitwarden Internal API - * - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - * - * The version of the OpenAPI document: latest - * - * Generated by: https://openapi-generator.tech - */ - -use serde::{Deserialize, Serialize}; - -use crate::models; - -#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] -pub struct OrganizationVerifyBankRequestModel { - #[serde(rename = "amount1")] - pub amount1: i32, - #[serde(rename = "amount2")] - pub amount2: i32, -} - -impl OrganizationVerifyBankRequestModel { - pub fn new(amount1: i32, amount2: i32) -> OrganizationVerifyBankRequestModel { - OrganizationVerifyBankRequestModel { amount1, amount2 } - } -} diff --git a/crates/bitwarden-api-api/src/models/password_manager_purchase_selections.rs b/crates/bitwarden-api-api/src/models/password_manager_purchase_selections.rs new file mode 100644 index 000000000..1328592d9 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/password_manager_purchase_selections.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PasswordManagerPurchaseSelections { + #[serde(rename = "seats")] + pub seats: i32, + #[serde(rename = "additionalStorage")] + pub additional_storage: i32, + #[serde(rename = "sponsored", skip_serializing_if = "Option::is_none")] + pub sponsored: Option, +} + +impl PasswordManagerPurchaseSelections { + pub fn new(seats: i32, additional_storage: i32) -> PasswordManagerPurchaseSelections { + PasswordManagerPurchaseSelections { + seats, + additional_storage, + sponsored: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/password_manager_update_selections.rs b/crates/bitwarden-api-api/src/models/password_manager_update_selections.rs new file mode 100644 index 000000000..89cbccbbf --- /dev/null +++ b/crates/bitwarden-api-api/src/models/password_manager_update_selections.rs @@ -0,0 +1,30 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PasswordManagerUpdateSelections { + #[serde(rename = "seats", skip_serializing_if = "Option::is_none")] + pub seats: Option, + #[serde(rename = "additionalStorage", skip_serializing_if = "Option::is_none")] + pub additional_storage: Option, +} + +impl PasswordManagerUpdateSelections { + pub fn new() -> PasswordManagerUpdateSelections { + PasswordManagerUpdateSelections { + seats: None, + additional_storage: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/password_request_model.rs b/crates/bitwarden-api-api/src/models/password_request_model.rs index a48f87284..eac260d58 100644 --- a/crates/bitwarden-api-api/src/models/password_request_model.rs +++ b/crates/bitwarden-api-api/src/models/password_request_model.rs @@ -31,6 +31,10 @@ pub struct PasswordRequestModel { pub master_password_hint: Option, #[serde(rename = "key")] pub key: String, + #[serde(rename = "authenticationData", skip_serializing_if = "Option::is_none")] + pub authentication_data: Option>, + #[serde(rename = "unlockData", skip_serializing_if = "Option::is_none")] + pub unlock_data: Option>, } impl PasswordRequestModel { @@ -43,6 +47,8 @@ impl PasswordRequestModel { new_master_password_hash, master_password_hint: None, key, + authentication_data: None, + unlock_data: None, } } } diff --git a/crates/bitwarden-api-api/src/models/product_type.rs b/crates/bitwarden-api-api/src/models/plan_cadence_type.rs similarity index 69% rename from crates/bitwarden-api-api/src/models/product_type.rs rename to crates/bitwarden-api-api/src/models/plan_cadence_type.rs index 7dbf8f8c5..1f28a4b12 100644 --- a/crates/bitwarden-api-api/src/models/product_type.rs +++ b/crates/bitwarden-api-api/src/models/plan_cadence_type.rs @@ -17,25 +17,25 @@ use crate::models; #[derive( Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize_repr, Deserialize_repr, )] -pub enum ProductType { - PasswordManager = 0, - SecretsManager = 1, +pub enum PlanCadenceType { + Annually = 0, + Monthly = 1, } -impl std::fmt::Display for ProductType { +impl std::fmt::Display for PlanCadenceType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{}", match self { - Self::PasswordManager => "0", - Self::SecretsManager => "1", + Self::Annually => "0", + Self::Monthly => "1", } ) } } -impl Default for ProductType { - fn default() -> ProductType { - Self::PasswordManager +impl Default for PlanCadenceType { + fn default() -> PlanCadenceType { + Self::Annually } } diff --git a/crates/bitwarden-api-api/src/models/policy_type.rs b/crates/bitwarden-api-api/src/models/policy_type.rs index 8b8b548f9..cacc6d2e6 100644 --- a/crates/bitwarden-api-api/src/models/policy_type.rs +++ b/crates/bitwarden-api-api/src/models/policy_type.rs @@ -35,6 +35,7 @@ pub enum PolicyType { RemoveUnlockWithPin = 14, RestrictedItemTypesPolicy = 15, UriMatchDefaults = 16, + AutotypeDefaultSetting = 17, } impl std::fmt::Display for PolicyType { @@ -60,6 +61,7 @@ impl std::fmt::Display for PolicyType { Self::RemoveUnlockWithPin => "14", Self::RestrictedItemTypesPolicy => "15", Self::UriMatchDefaults => "16", + Self::AutotypeDefaultSetting => "17", } ) } diff --git a/crates/bitwarden-api-api/src/models/preview_organization_subscription_plan_change_tax_request.rs b/crates/bitwarden-api-api/src/models/preview_organization_subscription_plan_change_tax_request.rs new file mode 100644 index 000000000..668400efc --- /dev/null +++ b/crates/bitwarden-api-api/src/models/preview_organization_subscription_plan_change_tax_request.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PreviewOrganizationSubscriptionPlanChangeTaxRequest { + #[serde(rename = "plan")] + pub plan: Box, + #[serde(rename = "billingAddress")] + pub billing_address: Box, +} + +impl PreviewOrganizationSubscriptionPlanChangeTaxRequest { + pub fn new( + plan: models::OrganizationSubscriptionPlanChangeRequest, + billing_address: models::CheckoutBillingAddressRequest, + ) -> PreviewOrganizationSubscriptionPlanChangeTaxRequest { + PreviewOrganizationSubscriptionPlanChangeTaxRequest { + plan: Box::new(plan), + billing_address: Box::new(billing_address), + } + } +} diff --git a/crates/bitwarden-api-api/src/models/preview_organization_subscription_purchase_tax_request.rs b/crates/bitwarden-api-api/src/models/preview_organization_subscription_purchase_tax_request.rs new file mode 100644 index 000000000..6bb8b0ded --- /dev/null +++ b/crates/bitwarden-api-api/src/models/preview_organization_subscription_purchase_tax_request.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PreviewOrganizationSubscriptionPurchaseTaxRequest { + #[serde(rename = "purchase")] + pub purchase: Box, + #[serde(rename = "billingAddress")] + pub billing_address: Box, +} + +impl PreviewOrganizationSubscriptionPurchaseTaxRequest { + pub fn new( + purchase: models::OrganizationSubscriptionPurchaseRequest, + billing_address: models::CheckoutBillingAddressRequest, + ) -> PreviewOrganizationSubscriptionPurchaseTaxRequest { + PreviewOrganizationSubscriptionPurchaseTaxRequest { + purchase: Box::new(purchase), + billing_address: Box::new(billing_address), + } + } +} diff --git a/crates/bitwarden-api-api/src/models/preview_organization_subscription_update_tax_request.rs b/crates/bitwarden-api-api/src/models/preview_organization_subscription_update_tax_request.rs new file mode 100644 index 000000000..8cadc5fc0 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/preview_organization_subscription_update_tax_request.rs @@ -0,0 +1,29 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PreviewOrganizationSubscriptionUpdateTaxRequest { + #[serde(rename = "update")] + pub update: Box, +} + +impl PreviewOrganizationSubscriptionUpdateTaxRequest { + pub fn new( + update: models::OrganizationSubscriptionUpdateRequest, + ) -> PreviewOrganizationSubscriptionUpdateTaxRequest { + PreviewOrganizationSubscriptionUpdateTaxRequest { + update: Box::new(update), + } + } +} diff --git a/crates/bitwarden-api-api/src/models/preview_premium_subscription_purchase_tax_request.rs b/crates/bitwarden-api-api/src/models/preview_premium_subscription_purchase_tax_request.rs new file mode 100644 index 000000000..d1beed90a --- /dev/null +++ b/crates/bitwarden-api-api/src/models/preview_premium_subscription_purchase_tax_request.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct PreviewPremiumSubscriptionPurchaseTaxRequest { + #[serde(rename = "additionalStorage")] + pub additional_storage: i32, + #[serde(rename = "billingAddress")] + pub billing_address: Box, +} + +impl PreviewPremiumSubscriptionPurchaseTaxRequest { + pub fn new( + additional_storage: i32, + billing_address: models::MinimalBillingAddressRequest, + ) -> PreviewPremiumSubscriptionPurchaseTaxRequest { + PreviewPremiumSubscriptionPurchaseTaxRequest { + additional_storage, + billing_address: Box::new(billing_address), + } + } +} diff --git a/crates/bitwarden-api-api/src/models/preview_tax_amount_for_organization_trial_request_body.rs b/crates/bitwarden-api-api/src/models/preview_tax_amount_for_organization_trial_request_body.rs deleted file mode 100644 index aae5d1a05..000000000 --- a/crates/bitwarden-api-api/src/models/preview_tax_amount_for_organization_trial_request_body.rs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Bitwarden Internal API - * - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - * - * The version of the OpenAPI document: latest - * - * Generated by: https://openapi-generator.tech - */ - -use serde::{Deserialize, Serialize}; - -use crate::models; - -#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] -pub struct PreviewTaxAmountForOrganizationTrialRequestBody { - #[serde(rename = "planType")] - pub plan_type: models::PlanType, - #[serde(rename = "productType")] - pub product_type: models::ProductType, - #[serde(rename = "taxInformation")] - pub tax_information: Box, -} - -impl PreviewTaxAmountForOrganizationTrialRequestBody { - pub fn new( - plan_type: models::PlanType, - product_type: models::ProductType, - tax_information: models::TaxInformationDto, - ) -> PreviewTaxAmountForOrganizationTrialRequestBody { - PreviewTaxAmountForOrganizationTrialRequestBody { - plan_type, - product_type, - tax_information: Box::new(tax_information), - } - } -} diff --git a/crates/bitwarden-api-api/src/models/provider_setup_request_model.rs b/crates/bitwarden-api-api/src/models/provider_setup_request_model.rs index 9fc0fec26..a67af28c7 100644 --- a/crates/bitwarden-api-api/src/models/provider_setup_request_model.rs +++ b/crates/bitwarden-api-api/src/models/provider_setup_request_model.rs @@ -24,10 +24,10 @@ pub struct ProviderSetupRequestModel { pub token: String, #[serde(rename = "key")] pub key: String, - #[serde(rename = "taxInfo")] - pub tax_info: Box, - #[serde(rename = "paymentSource", skip_serializing_if = "Option::is_none")] - pub payment_source: Option>, + #[serde(rename = "paymentMethod")] + pub payment_method: Box, + #[serde(rename = "billingAddress")] + pub billing_address: Box, } impl ProviderSetupRequestModel { @@ -36,7 +36,8 @@ impl ProviderSetupRequestModel { billing_email: String, token: String, key: String, - tax_info: models::ExpandedTaxInfoUpdateRequestModel, + payment_method: models::MinimalTokenizedPaymentMethodRequest, + billing_address: models::BillingAddressRequest, ) -> ProviderSetupRequestModel { ProviderSetupRequestModel { name, @@ -44,8 +45,8 @@ impl ProviderSetupRequestModel { billing_email, token, key, - tax_info: Box::new(tax_info), - payment_source: None, + payment_method: Box::new(payment_method), + billing_address: Box::new(billing_address), } } } diff --git a/crates/bitwarden-api-api/src/models/restart_subscription_request.rs b/crates/bitwarden-api-api/src/models/restart_subscription_request.rs new file mode 100644 index 000000000..163f4582b --- /dev/null +++ b/crates/bitwarden-api-api/src/models/restart_subscription_request.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct RestartSubscriptionRequest { + #[serde(rename = "paymentMethod")] + pub payment_method: Box, + #[serde(rename = "billingAddress")] + pub billing_address: Box, +} + +impl RestartSubscriptionRequest { + pub fn new( + payment_method: models::MinimalTokenizedPaymentMethodRequest, + billing_address: models::CheckoutBillingAddressRequest, + ) -> RestartSubscriptionRequest { + RestartSubscriptionRequest { + payment_method: Box::new(payment_method), + billing_address: Box::new(billing_address), + } + } +} diff --git a/crates/bitwarden-api-api/src/models/secrets_manager_purchase_selections.rs b/crates/bitwarden-api-api/src/models/secrets_manager_purchase_selections.rs new file mode 100644 index 000000000..dace7782e --- /dev/null +++ b/crates/bitwarden-api-api/src/models/secrets_manager_purchase_selections.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct SecretsManagerPurchaseSelections { + #[serde(rename = "seats")] + pub seats: i32, + #[serde(rename = "additionalServiceAccounts")] + pub additional_service_accounts: i32, + #[serde(rename = "standalone", skip_serializing_if = "Option::is_none")] + pub standalone: Option, +} + +impl SecretsManagerPurchaseSelections { + pub fn new(seats: i32, additional_service_accounts: i32) -> SecretsManagerPurchaseSelections { + SecretsManagerPurchaseSelections { + seats, + additional_service_accounts, + standalone: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/secrets_manager_update_selections.rs b/crates/bitwarden-api-api/src/models/secrets_manager_update_selections.rs new file mode 100644 index 000000000..61ce8efd2 --- /dev/null +++ b/crates/bitwarden-api-api/src/models/secrets_manager_update_selections.rs @@ -0,0 +1,33 @@ +/* + * Bitwarden Internal API + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: latest + * + * Generated by: https://openapi-generator.tech + */ + +use serde::{Deserialize, Serialize}; + +use crate::models; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct SecretsManagerUpdateSelections { + #[serde(rename = "seats", skip_serializing_if = "Option::is_none")] + pub seats: Option, + #[serde( + rename = "additionalServiceAccounts", + skip_serializing_if = "Option::is_none" + )] + pub additional_service_accounts: Option, +} + +impl SecretsManagerUpdateSelections { + pub fn new() -> SecretsManagerUpdateSelections { + SecretsManagerUpdateSelections { + seats: None, + additional_service_accounts: None, + } + } +} diff --git a/crates/bitwarden-api-api/src/models/unlock_data_request_model.rs b/crates/bitwarden-api-api/src/models/unlock_data_request_model.rs index fc7681c09..58ad21663 100644 --- a/crates/bitwarden-api-api/src/models/unlock_data_request_model.rs +++ b/crates/bitwarden-api-api/src/models/unlock_data_request_model.rs @@ -15,7 +15,7 @@ use crate::models; #[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct UnlockDataRequestModel { #[serde(rename = "masterPasswordUnlockData")] - pub master_password_unlock_data: Box, + pub master_password_unlock_data: Box, #[serde(rename = "emergencyAccessUnlockData")] pub emergency_access_unlock_data: Option>, #[serde(rename = "organizationAccountRecoveryUnlockData")] @@ -29,7 +29,7 @@ pub struct UnlockDataRequestModel { impl UnlockDataRequestModel { pub fn new( - master_password_unlock_data: models::MasterPasswordUnlockDataModel, + master_password_unlock_data: models::MasterPasswordUnlockAndAuthenticationDataModel, emergency_access_unlock_data: Option>, organization_account_recovery_unlock_data: Option< Vec, diff --git a/crates/bitwarden-api-identity/README.md b/crates/bitwarden-api-identity/README.md index b977110f9..974656518 100644 --- a/crates/bitwarden-api-identity/README.md +++ b/crates/bitwarden-api-identity/README.md @@ -12,7 +12,7 @@ client. - API version: v1 - Package version: 1.0.0 - Server Git commit: - [`d384c0cfe60ec02226479d3cde200e4d785a7e50`](https://github.com/bitwarden/server/commit/d384c0cfe60ec02226479d3cde200e4d785a7e50) + [`d2577f670e1cf9ca32791135d2197cff1fe12096`](https://github.com/bitwarden/server/commit/d2577f670e1cf9ca32791135d2197cff1fe12096) - Generator version: 7.15.0 - Build package: `org.openapitools.codegen.languages.RustClientCodegen` diff --git a/crates/bitwarden-core/src/admin_console/policy.rs b/crates/bitwarden-core/src/admin_console/policy.rs index 5db183d28..5f5ff161f 100644 --- a/crates/bitwarden-core/src/admin_console/policy.rs +++ b/crates/bitwarden-core/src/admin_console/policy.rs @@ -49,6 +49,7 @@ pub enum PolicyType { RemoveUnlockWithPin = 14, RestrictedItemTypesPolicy = 15, UriMatchDefaults = 16, + AutotypeDefaultSetting = 17, } impl TryFrom for Policy { @@ -103,6 +104,9 @@ impl From for PolicyType { PolicyType::RestrictedItemTypesPolicy } bitwarden_api_api::models::PolicyType::UriMatchDefaults => PolicyType::UriMatchDefaults, + bitwarden_api_api::models::PolicyType::AutotypeDefaultSetting => { + PolicyType::AutotypeDefaultSetting + } } } } From 1461b3ba6bb6e2d0114770eb4572a1398b4789ef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:42:01 -0400 Subject: [PATCH 13/19] [deps]: Update rust Docker tag to v1.89 (#248) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- crates/memory-testing/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/memory-testing/Dockerfile b/crates/memory-testing/Dockerfile index 58f821922..fc1ded01b 100644 --- a/crates/memory-testing/Dockerfile +++ b/crates/memory-testing/Dockerfile @@ -1,7 +1,7 @@ ############################################### # Build stage # ############################################### -FROM rust:1.85-alpine AS base +FROM rust:1.89-alpine AS base WORKDIR /app # Make sure the correct rust toolchain is installed only once From 41674eae3aebdd90033cc46b5a4cc460fe2fb03a Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Fri, 10 Oct 2025 11:40:51 +0200 Subject: [PATCH 14/19] [PM-25901] Publish Bitwarden-licensed SDK to npm (#496) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## đŸŽŸī¸ Tracking ## 📔 Objective Publish a commercial version of the SDK to NPM ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## đŸĻŽ Reviewer guidelines - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or â„šī¸ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or âš ī¸ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or â™ģī¸ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --- .github/workflows/publish-wasm-internal.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-wasm-internal.yml b/.github/workflows/publish-wasm-internal.yml index 2845eefde..a425bda6e 100644 --- a/.github/workflows/publish-wasm-internal.yml +++ b/.github/workflows/publish-wasm-internal.yml @@ -57,13 +57,23 @@ jobs: fi npm: - name: Publish NPM + name: Publish NPM - ${{matrix.license_type.readable}} environment: NPM runs-on: ubuntu-24.04 needs: setup permissions: contents: read id-token: write + strategy: + matrix: + license_type: + - artifact_name: "sdk-internal" + npm_folder: "npm" + readable: "open source license" + - artifact_name: "commercial-sdk-internal" + npm_folder: "bitwarden_license/npm" + readable: "commercial license" + steps: - name: Checkout repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -80,8 +90,8 @@ jobs: workflow: build-wasm-internal.yml workflow_conclusion: success branch: ${{ inputs.release_type == 'Dry Run' && 'main' || github.ref_name }} - artifacts: sdk-internal - path: crates/bitwarden-wasm-internal/npm + artifacts: ${{ matrix.license_type.artifact_name }} + path: crates/bitwarden-wasm-internal/${{ matrix.license_type.npm_folder }} - name: Set version run: | From d584cb67f7222f584c4f7ae16e1b86b57820db68 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Fri, 10 Oct 2025 14:33:43 +0200 Subject: [PATCH 15/19] fix: use correct working directory when publishing (#500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## đŸŽŸī¸ Tracking ## 📔 Objective ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## đŸĻŽ Reviewer guidelines - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or â„šī¸ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or âš ī¸ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or â™ģī¸ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes --- .github/workflows/publish-wasm-internal.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish-wasm-internal.yml b/.github/workflows/publish-wasm-internal.yml index a425bda6e..dd3e15083 100644 --- a/.github/workflows/publish-wasm-internal.yml +++ b/.github/workflows/publish-wasm-internal.yml @@ -16,10 +16,6 @@ on: description: "Release Version" required: false -defaults: - run: - working-directory: crates/bitwarden-wasm-internal/npm - jobs: setup: name: Setup @@ -94,6 +90,7 @@ jobs: path: crates/bitwarden-wasm-internal/${{ matrix.license_type.npm_folder }} - name: Set version + working-directory: crates/bitwarden-wasm-internal/${{ matrix.license_type.npm_folder }} run: | npm version --no-git-tag-version $VERSION env: @@ -101,4 +98,5 @@ jobs: - name: Publish NPM if: ${{ inputs.release_type != 'Dry Run' }} + working-directory: crates/bitwarden-wasm-internal/${{ matrix.license_type.npm_folder }} run: npm publish --access public --tag latest From cc36132bc35644fc8577e1d3859966dd28edec21 Mon Sep 17 00:00:00 2001 From: Mick Letofsky Date: Fri, 10 Oct 2025 18:37:45 +0200 Subject: [PATCH 16/19] PM-26727 Sticky Claude Comments and More Specific prompts --- .github/workflows/review-code.yml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/review-code.yml b/.github/workflows/review-code.yml index b49f5cec8..83cbc3bb5 100644 --- a/.github/workflows/review-code.yml +++ b/.github/workflows/review-code.yml @@ -84,16 +84,18 @@ jobs: - name: Review with Claude Code if: steps.check_changes.outputs.vault_team_changes == 'true' - uses: anthropics/claude-code-action@a5528eec7426a4f0c9c1ac96018daa53ebd05bc4 # v1.0.7 + uses: anthropics/claude-code-action@ac1a3207f3f00b4a37e2f3a6f0935733c7c64651 # v1.0.11 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} track_progress: true + use_sticky_comment: true prompt: | REPO: ${{ github.repository }} PR NUMBER: ${{ github.event.pull_request.number }} TITLE: ${{ github.event.pull_request.title }} BODY: ${{ github.event.pull_request.body }} AUTHOR: ${{ github.event.pull_request.user.login }} + COMMIT: ${{ github.event.pull_request.head.sha }} Please review this pull request with a focus on: - Code quality and best practices @@ -103,7 +105,20 @@ jobs: Note: The PR branch is already checked out in the current working directory. - Provide detailed feedback using inline comments for specific issues. + Provide a comprehensive review including: + - Summary of changes since last review + - Critical issues found (be thorough) + - Suggested improvements (be thorough) + - Good practices observed (be concise - list only the most notable items without elaboration) + - Action items for the author + - Leverage collapsible
sections where appropriate for lengthy explanations or code snippets to enhance human readability + + When reviewing subsequent commits: + - Track status of previously identified issues (fixed/unfixed/reopened) + - Identify NEW problems introduced since last review + - Note if fixes introduced new issues + + IMPORTANT: Be comprehensive about issues and improvements. For good practices, be brief - just note what was done well without explaining why or praising excessively. claude_args: | - --allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)" + --allowedTools "mcp__github_comment__update_claude_comment,mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*)" From d37361be25b500e63fcb87088b82d856fa92caff Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 13 Oct 2025 12:30:03 +0200 Subject: [PATCH 17/19] Remove unused imports --- crates/bitwarden-crypto/src/store/key_rotation.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/bitwarden-crypto/src/store/key_rotation.rs b/crates/bitwarden-crypto/src/store/key_rotation.rs index e610f0663..818057733 100644 --- a/crates/bitwarden-crypto/src/store/key_rotation.rs +++ b/crates/bitwarden-crypto/src/store/key_rotation.rs @@ -49,9 +49,8 @@ pub fn dangerous_get_v2_rotated_account_keys( mod tests { use super::*; use crate::{ - AsymmetricCryptoKey, KeyDecryptable, KeyStore, Pkcs8PrivateKeyBytes, - PublicKeyEncryptionAlgorithm, SigningKey, - traits::tests::{TestAsymmKey, TestIds, TestSigningKey, TestSymmKey}, + AsymmetricCryptoKey, KeyDecryptable, KeyStore, Pkcs8PrivateKeyBytes, SigningKey, + traits::tests::TestIds, }; #[test] From 99fbb45626cdb7a9ff80c2eeb2c21db74008d015 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Wed, 22 Oct 2025 17:27:23 +0200 Subject: [PATCH 18/19] Add convenience functions and fix build --- .../bitwarden-crypto/examples/seal_struct.rs | 9 +-- .../src/safe/data_envelope.rs | 69 ++++++++++++------- crates/bitwarden-crypto/src/store/context.rs | 2 +- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/crates/bitwarden-crypto/examples/seal_struct.rs b/crates/bitwarden-crypto/examples/seal_struct.rs index f03bc7708..ee767f91b 100644 --- a/crates/bitwarden-crypto/examples/seal_struct.rs +++ b/crates/bitwarden-crypto/examples/seal_struct.rs @@ -51,8 +51,7 @@ fn main() { .into(); // Seal the item into an encrypted blob, and store the content-encryption-key in the context. - let sealed_item = DataEnvelope::seal(my_item, ExampleSymmetricKey::ItemKey, &mut ctx) - .expect("Sealing should work"); + let (sealed_item, cek) = DataEnvelope::seal(my_item, &mut ctx).expect("Sealing should work"); // Store the sealed item on disk disk.save("sealed_item", (&sealed_item).into()); @@ -64,11 +63,7 @@ fn main() { // Unseal the item again, using the content-encryption-key stored in the context. let my_item: MyItem = sealed_item - .unseal( - &DataEnvelopeNamespace::VaultItem, - ExampleSymmetricKey::ItemKey, - &mut ctx, - ) + .unseal(cek, &mut ctx) .expect("Unsealing should work"); assert!(matches!(my_item, MyItem::MyItemV1(item) if item.a == 42 && item.b == "Hello, World!")); } diff --git a/crates/bitwarden-crypto/src/safe/data_envelope.rs b/crates/bitwarden-crypto/src/safe/data_envelope.rs index 0a4a68e9d..f7bbb020a 100644 --- a/crates/bitwarden-crypto/src/safe/data_envelope.rs +++ b/crates/bitwarden-crypto/src/safe/data_envelope.rs @@ -10,7 +10,7 @@ use thiserror::Error; use wasm_bindgen::convert::FromWasmAbi; use crate::{ - CONTENT_TYPE_PADDED_CBOR, CoseEncrypt0Bytes, CryptoError, EncodingError, KeyIds, + CONTENT_TYPE_PADDED_CBOR, CoseEncrypt0Bytes, CryptoError, EncString, EncodingError, KeyIds, SerializedMessage, SymmetricCryptoKey, XChaCha20Poly1305Key, cose::{DATA_ENVELOPE_NAMESPACE, XCHACHA20_POLY1305}, ensure_equal, ensure_matches, @@ -71,16 +71,37 @@ impl DataEnvelope { /// context. pub fn seal( data: T, - cek_keyslot: Ids::Symmetric, ctx: &mut crate::store::KeyStoreContext, - ) -> Result + ) -> Result<(Self, Ids::Symmetric), DataEnvelopeError> where T: Serialize + SealableVersionedData, { let (envelope, cek) = Self::seal_ref(&data, &T::NAMESPACE)?; - ctx.set_symmetric_key_internal(cek_keyslot, SymmetricCryptoKey::XChaCha20Poly1305Key(cek)) + let cek_id = ctx + .generate_symmetric_key() + .map_err(|_| DataEnvelopeError::KeyStoreError)?; + ctx.set_symmetric_key_internal(cek_id, SymmetricCryptoKey::XChaCha20Poly1305Key(cek)) .map_err(|_| DataEnvelopeError::KeyStoreError)?; - Ok(envelope) + Ok((envelope, cek_id)) + } + + /// Seals a struct into an encrypted blob. The content encryption key is wrapped with the provided + /// wrapping key + pub fn seal_with_wrapping_key( + data: T, + wrapping_key: &Ids::Symmetric, + ctx: &mut crate::store::KeyStoreContext, + ) -> Result<(Self, EncString), DataEnvelopeError> + where + T: Serialize + SealableVersionedData, + { + let (envelope, cek) = Self::seal(data, ctx)?; + + let wrapped_cek = ctx + .wrap_symmetric_key(*wrapping_key, cek) + .map_err(|_| DataEnvelopeError::EncryptionError)?; + + Ok((envelope, wrapped_cek)) } /// Seals a struct into an encrypted blob, and returns the encrypted blob and the @@ -143,7 +164,6 @@ impl DataEnvelope { /// context. pub fn unseal( &self, - namespace: &DataEnvelopeNamespace, cek_keyslot: Ids::Symmetric, ctx: &mut crate::store::KeyStoreContext, ) -> Result @@ -155,11 +175,27 @@ impl DataEnvelope { .map_err(|_| DataEnvelopeError::KeyStoreError)?; match cek { - SymmetricCryptoKey::XChaCha20Poly1305Key(key) => self.unseal_ref(namespace, key), + SymmetricCryptoKey::XChaCha20Poly1305Key(key) => self.unseal_ref(&T::NAMESPACE, key), _ => Err(DataEnvelopeError::UnsupportedContentFormat), } } + // Unseals the data from the encrypted blob and wrapped content-encryption-key. + pub fn unseal_with_wrapping_key( + &self, + wrapping_key: &Ids::Symmetric, + wrapped_cek: &EncString, + ctx: &mut crate::store::KeyStoreContext, + ) -> Result + where + T: DeserializeOwned + SealableVersionedData, + { + let cek = ctx + .unwrap_symmetric_key(*wrapping_key, wrapped_cek) + .map_err(|_| DataEnvelopeError::DecryptionError)?; + self.unseal(cek, ctx) + } + /// Unseals the data from the encrypted blob using the provided content-encryption-key. fn unseal_ref( &self, @@ -582,25 +618,10 @@ mod tests { let mut ctx = key_store.context_mut(); // Seal with keystore using ExampleNamespace - let envelope = - DataEnvelope::seal(data, crate::traits::tests::TestSymmKey::A(0), &mut ctx).unwrap(); - - // Try to unseal with wrong namespace - should fail - let result: Result = envelope.unseal( - &DataEnvelopeNamespace::ExampleNamespace2, - crate::traits::tests::TestSymmKey::A(0), - &mut ctx, - ); - assert!(matches!(result, Err(DataEnvelopeError::InvalidNamespace))); + let (envelope, cek_id) = DataEnvelope::seal(data, &mut ctx).unwrap(); // Unseal with correct namespace - should succeed - let unsealed_data: TestData = envelope - .unseal( - &DataEnvelopeNamespace::ExampleNamespace, - crate::traits::tests::TestSymmKey::A(0), - &mut ctx, - ) - .unwrap(); + let unsealed_data: TestData = envelope.unseal(cek_id, &mut ctx).unwrap(); let TestData::TestDataV1(unsealed_data) = unsealed_data; assert_eq!(unsealed_data.field, 789); } diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 65de31187..8b2bff068 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -12,7 +12,7 @@ use crate::{ AsymmetricCryptoKey, BitwardenLegacyKeyBytes, ContentFormat, CoseEncrypt0Bytes, CryptoError, EncString, KeyId, KeyIds, LocalId, PublicKeyEncryptionAlgorithm, Result, RotatedUserKeys, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, SignedPublicKeyMessage, - SigningKey, SymmetricCryptoKey, UnsignedSharedKey, derive_shareable_key, + SigningKey, SymmetricCryptoKey, UnsignedSharedKey, derive_shareable_key, ensure, error::UnsupportedOperationError, signing, store::backend::StoreBackend, }; From d704375c861094bec144679922bfcd745f8ed6fd Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Wed, 22 Oct 2025 17:27:51 +0200 Subject: [PATCH 19/19] Fix clippy --- crates/bitwarden-crypto/src/safe/data_envelope.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bitwarden-crypto/src/safe/data_envelope.rs b/crates/bitwarden-crypto/src/safe/data_envelope.rs index f7bbb020a..96544713f 100644 --- a/crates/bitwarden-crypto/src/safe/data_envelope.rs +++ b/crates/bitwarden-crypto/src/safe/data_envelope.rs @@ -85,8 +85,8 @@ impl DataEnvelope { Ok((envelope, cek_id)) } - /// Seals a struct into an encrypted blob. The content encryption key is wrapped with the provided - /// wrapping key + /// Seals a struct into an encrypted blob. The content encryption key is wrapped with the + /// provided wrapping key pub fn seal_with_wrapping_key( data: T, wrapping_key: &Ids::Symmetric, @@ -180,7 +180,7 @@ impl DataEnvelope { } } - // Unseals the data from the encrypted blob and wrapped content-encryption-key. + /// Unseals the data from the encrypted blob and wrapped content-encryption-key. pub fn unseal_with_wrapping_key( &self, wrapping_key: &Ids::Symmetric,