Skip to main content

bitwarden_shared_unlock/wasm/
follower.rs

1use bitwarden_threading::cancellation_token::wasm::{AbortController, AbortControllerExt};
2use wasm_bindgen::prelude::wasm_bindgen;
3
4use super::drivers::{JsSharedUnlockDriver, RawJsSharedUnlockDriver};
5use crate::{DeviceEvent, Follower, FollowerStartError};
6
7/// Shared-unlock follower for WASM clients.
8#[wasm_bindgen]
9pub struct SharedUnlockFollower {
10    follower: Follower<JsSharedUnlockDriver>,
11}
12
13#[wasm_bindgen]
14impl SharedUnlockFollower {
15    /// Creates a new shared-unlock follower
16    #[wasm_bindgen]
17    pub fn try_new(
18        ipc_client: &bitwarden_ipc::wasm::JsIpcClient,
19        driver: RawJsSharedUnlockDriver,
20    ) -> Result<Self, bitwarden_ipc::SubscribeError> {
21        let driver = JsSharedUnlockDriver::new(driver);
22        let follower = Follower::create(driver, ipc_client.client.clone());
23        Ok(Self { follower })
24    }
25
26    /// Starts the shared-unlock follower, which listens for messages from the leader and handles
27    /// them accordingly. The follower will also send heartbeat messages to the leader at
28    /// regular intervals to keep the shared session active.
29    #[wasm_bindgen]
30    pub async fn start(
31        &self,
32        abort_controller: Option<AbortController>,
33    ) -> Result<(), FollowerStartError> {
34        self.follower
35            .start(abort_controller.map(|abort| abort.to_cancellation_token()))
36            .await
37    }
38
39    /// Forwards a device event to the shared-unlock follower state machine.
40    #[wasm_bindgen]
41    pub async fn handle_device_event(&self, event: DeviceEvent) {
42        if let Err(error) = self.follower.handle_device_event(event).await {
43            tracing::error!(
44                ?error,
45                "Failed to handle shared unlock follower device event"
46            );
47        }
48    }
49}