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}