bitwarden_core/key_management/
state_bridge.rs1use std::sync::{Arc, Mutex};
9
10use bitwarden_crypto::{EncString, SymmetricCryptoKey, safe::PasswordProtectedKeyEnvelope};
11#[cfg(feature = "wasm")]
12use wasm_bindgen::prelude::*;
13
14use crate::{
15 Client,
16 key_management::{
17 MasterPasswordUnlockData, V2UpgradeToken,
18 account_cryptographic_state::WrappedAccountCryptographicState,
19 },
20};
21
22pub struct StateBridge {
24 implementation: Mutex<Option<Arc<dyn StateBridgeImpl + Send + Sync>>>,
25}
26
27impl StateBridge {
28 pub fn new() -> Self {
30 Self {
31 implementation: Mutex::new(None),
32 }
33 }
34
35 pub fn is_registered(&self) -> bool {
37 self.implementation
38 .lock()
39 .expect("Mutex is not poisoned")
40 .is_some()
41 }
42
43 pub fn register(&self, implementation: Box<dyn StateBridgeImpl + Send + Sync>) {
45 *self.implementation.lock().expect("Mutex is not poisoned") = Some(implementation.into());
46 }
47}
48
49impl Default for StateBridge {
50 fn default() -> Self {
51 Self::new()
52 }
53}
54
55#[derive(Clone)]
58#[cfg_attr(feature = "uniffi", derive(uniffi::Object))]
59#[cfg_attr(feature = "wasm", wasm_bindgen)]
60pub struct StateBridgeClient {
61 pub(crate) client: crate::Client,
62}
63
64impl Client {
65 pub fn km_state_bridge(&self) -> StateBridgeClient {
67 StateBridgeClient {
68 client: self.clone(),
69 }
70 }
71}
72
73impl StateBridgeClient {
74 pub fn is_bridge_registered(&self) -> bool {
76 self.client.internal.state_bridge.is_registered()
77 }
78
79 pub fn register_bridge(&self, bridge_impl: Box<dyn StateBridgeImpl + Send + Sync>) {
81 self.client.internal.state_bridge.register(bridge_impl);
82 }
83}
84
85#[cfg(target_arch = "wasm32")]
86#[wasm_bindgen]
87extern "C" {
88 #[wasm_bindgen(typescript_type = "WasmStateBridge")]
92 pub type RawWasmStateBridge;
93}
94
95#[cfg(target_arch = "wasm32")]
96use bitwarden_threading::ThreadBoundRunner;
97
98#[cfg(target_arch = "wasm32")]
99pub struct WasmStateBridge(pub(crate) ThreadBoundRunner<RawWasmStateBridge>);
103
104#[cfg(target_arch = "wasm32")]
105#[wasm_bindgen]
106impl StateBridgeClient {
107 pub fn register_bridge_impl(&self, bridge_impl: RawWasmStateBridge) {
109 self.client
110 .internal
111 .state_bridge
112 .register(Box::new(WasmStateBridge(ThreadBoundRunner::new(
113 bridge_impl,
114 ))));
115 }
116}
117
118bitwarden_state_bridge_macro::state_bridge! {
126 user_key: SymmetricCryptoKey as ts "SymmetricKey",
127 persistent_pin_envelope: PasswordProtectedKeyEnvelope as ts "PasswordProtectedKeyEnvelope",
128 ephemeral_pin_envelope: PasswordProtectedKeyEnvelope as ts "PasswordProtectedKeyEnvelope",
129 encrypted_pin: EncString as ts "EncString",
130 v2_upgrade_token: V2UpgradeToken as ts "V2UpgradeToken",
131 account_cryptographic_state: WrappedAccountCryptographicState as ts "WrappedAccountCryptographicState",
132 masterpassword_unlock_data: MasterPasswordUnlockData as ts "MasterPasswordUnlockData",
133}