Skip to main content

bitwarden_user_crypto_management/pin_settings/
pin_settings_client.rs

1use bitwarden_core::key_management::{PinLockSystem, PinLockType, PinUnlockStatus};
2use bitwarden_error::bitwarden_error;
3use thiserror::Error;
4#[cfg(feature = "wasm")]
5use wasm_bindgen::prelude::*;
6
7use crate::UserCryptoManagementClient;
8
9#[derive(Clone)]
10#[cfg_attr(feature = "uniffi", derive(uniffi::Object))]
11#[cfg_attr(feature = "wasm", wasm_bindgen)]
12/// Sub-client for configuring PIN unlock behavior.
13pub struct PinSettingsClient {
14    pub(crate) client: bitwarden_core::Client,
15}
16
17#[derive(Debug, Error)]
18#[bitwarden_error(flat)]
19/// Errors returned by PIN settings operations.
20pub enum PinSettingsError {
21    #[error("Failed to set PIN state")]
22    /// Failed while enrolling or storing the PIN-protected key envelope.
23    SetPinState,
24}
25
26impl PinSettingsClient {
27    pub(crate) fn new(client: bitwarden_core::Client) -> Self {
28        Self { client }
29    }
30}
31
32#[cfg_attr(feature = "wasm", wasm_bindgen)]
33#[cfg_attr(feature = "uniffi", uniffi::export(async_runtime = "tokio"))]
34impl PinSettingsClient {
35    /// Sets or updates the account PIN and stores the corresponding unlock state.
36    ///
37    /// The `lock_type` determines how PIN unlock behaves for this account.
38    /// Returns an error when the PIN-protected state cannot be persisted.
39    pub async fn set_pin(
40        &self,
41        pin: String,
42        lock_type: bitwarden_core::key_management::PinLockType,
43    ) -> Result<(), PinSettingsError> {
44        PinLockSystem::with_client(&self.client)
45            .set_pin(pin, lock_type)
46            .await
47            .map_err(|_| PinSettingsError::SetPinState)
48    }
49
50    /// Unenrolls from PIN-based unlock
51    pub async fn unset_pin(&self) {
52        PinLockSystem::with_client(&self.client).unset_pin().await
53    }
54
55    /// Returns the current status of PIN unlock
56    pub async fn get_status(&self) -> PinUnlockStatus {
57        PinLockSystem::with_client(&self.client)
58            .get_pin_status()
59            .await
60    }
61
62    /// Returns the configured PIN lock type, if a PIN lock is set.
63    pub async fn get_lock_type(&self) -> Option<PinLockType> {
64        PinLockSystem::with_client(&self.client)
65            .get_pin_lock_type()
66            .await
67    }
68
69    /// Validates whether `pin` matches the currently configured unlock PIN.
70    pub async fn validate_pin(&self, pin: String) -> bool {
71        PinLockSystem::with_client(&self.client)
72            .validate_pin(pin)
73            .await
74    }
75
76    /// Returns the currently configured PIN, if available.
77    pub async fn get_pin(&self) -> Option<String> {
78        PinLockSystem::with_client(&self.client).get_pin().await
79    }
80}
81
82#[cfg_attr(feature = "wasm", wasm_bindgen)]
83#[cfg_attr(feature = "uniffi", uniffi::export)]
84impl UserCryptoManagementClient {
85    /// Returns the PIN settings sub-client.
86    pub fn pin_settings(&self) -> PinSettingsClient {
87        PinSettingsClient::new(self.client.clone())
88    }
89}