bitwarden_server_communication_config/
platform_api.rs

1use bitwarden_error::bitwarden_error;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5/// A cookie acquired from the platform
6///
7/// Represents a single cookie name/value pair as received from the browser or HTTP client.
8/// For sharded cookies (AWS ALB pattern), each shard is a separate `AcquiredCookie` with
9/// its own name including the `-{N}` suffix (e.g., `AWSELBAuthSessionCookie-0`).
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
11#[cfg_attr(
12    feature = "wasm",
13    derive(tsify::Tsify),
14    tsify(into_wasm_abi, from_wasm_abi)
15)]
16#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
17pub struct AcquiredCookie {
18    /// Cookie name
19    ///
20    /// For sharded cookies, this includes the shard suffix (e.g., `AWSELBAuthSessionCookie-0`)
21    /// For unsharded cookies, this is the cookie name without any suffix.
22    pub name: String,
23    /// Cookie value
24    pub value: String,
25}
26
27/// Errors that can occur during cookie acquisition
28#[derive(Debug, Error, Clone, PartialEq, Eq)]
29#[bitwarden_error(flat)]
30pub enum AcquireCookieError {
31    /// Cookie acquisition was cancelled by the user
32    #[error("Cookie acquisition was cancelled")]
33    Cancelled,
34
35    /// The server configuration does not support cookie acquisition
36    #[error("Server configuration does not support SSO cookie acquisition (Direct bootstrap)")]
37    UnsupportedConfiguration,
38
39    /// The acquired cookie name does not match the expected cookie name
40    #[error("Cookie name mismatch: expected {expected}, got {actual}")]
41    CookieNameMismatch {
42        /// Expected cookie name from server configuration
43        expected: String,
44        /// Actual cookie name returned by platform
45        actual: String,
46    },
47
48    /// Failed to retrieve server configuration from repository
49    #[error("Failed to get server configuration: {0}")]
50    RepositoryGetError(String),
51
52    /// Failed to save updated configuration to repository
53    #[error("Failed to save server configuration: {0}")]
54    RepositorySaveError(String),
55}
56
57/// Platform API for acquiring cookies from the platform client
58///
59/// This trait abstracts the platform-specific logic for acquiring SSO cookies
60/// from load balancers. Platform clients (web, mobile, desktop) implement this
61/// trait to provide cookie acquisition through browser interactions or native
62/// HTTP client capabilities.
63#[cfg_attr(feature = "uniffi", uniffi::export(with_foreign))]
64#[async_trait::async_trait]
65pub trait ServerCommunicationConfigPlatformApi: Send + Sync {
66    /// Acquires cookies for the given hostname
67    ///
68    /// The platform client should trigger any necessary user interaction
69    /// (e.g., browser redirect to IdP) to acquire cookies from the
70    /// load balancer.
71    ///
72    /// For sharded cookies, the platform should return multiple `AcquiredCookie`
73    /// entries, each with its full name including the `-{N}` suffix.
74    ///
75    /// # Arguments
76    ///
77    /// * `hostname` - The server hostname (e.g., "vault.acme.com")
78    ///
79    /// # Returns
80    ///
81    /// - `Some(cookies)` - Cookies were successfully acquired
82    /// - `None` - Cookie acquisition failed or was cancelled
83    async fn acquire_cookies(&self, hostname: String) -> Option<Vec<AcquiredCookie>>;
84}