bitwarden_uniffi/tools/
mod.rs1use std::sync::Arc;
2
3use bitwarden_collections::collection::Collection;
4use bitwarden_exporters::{Account, ExportFormat};
5use bitwarden_generators::{
6 PassphraseGeneratorRequest, PasswordGeneratorRequest, UsernameGeneratorRequest,
7};
8use bitwarden_importers::{
9 Credentials, ImportOptions, ImportSummary, OnePasswordImportSummary, OnePasswordTotpResult,
10 OnePasswordTwoFactorUi,
11};
12use bitwarden_vault::{Cipher, EncryptionContext, Folder};
13
14use crate::error::Result;
15
16mod sends;
17pub use sends::SendClient;
18
19mod ssh;
20pub use ssh::SshClient;
21
22#[derive(uniffi::Object)]
23pub struct GeneratorClients(pub(crate) bitwarden_generators::GeneratorClient);
24
25#[uniffi::export(async_runtime = "tokio")]
26impl GeneratorClients {
27 pub fn password(&self, settings: PasswordGeneratorRequest) -> Result<String> {
29 Ok(self.0.password(settings)?)
30 }
31
32 pub fn passphrase(&self, settings: PassphraseGeneratorRequest) -> Result<String> {
34 Ok(self.0.passphrase(settings)?)
35 }
36
37 pub fn password_rules(&self, rules: String) -> Result<PasswordGeneratorRequest> {
39 Ok(self.0.password_rules(rules)?)
40 }
41
42 pub async fn username(&self, settings: UsernameGeneratorRequest) -> Result<String> {
44 Ok(self.0.username(settings).await?)
45 }
46}
47
48#[derive(uniffi::Object)]
49pub struct ExporterClient(pub(crate) bitwarden_exporters::ExporterClient);
50
51#[uniffi::export(async_runtime = "tokio")]
52impl ExporterClient {
53 pub async fn export_vault(
55 &self,
56 folders: Vec<Folder>,
57 ciphers: Vec<Cipher>,
58 format: ExportFormat,
59 ) -> Result<String> {
60 Ok(self.0.export_vault(folders, ciphers, format).await?)
61 }
62
63 pub fn export_organization_vault(
65 &self,
66 collections: Vec<Collection>,
67 ciphers: Vec<Cipher>,
68 format: ExportFormat,
69 ) -> Result<String> {
70 Ok(self
71 .0
72 .export_organization_vault(collections, ciphers, format)?)
73 }
74
75 pub fn export_cxf(&self, account: Account, ciphers: Vec<Cipher>) -> Result<String> {
82 Ok(self.0.export_cxf(account, ciphers)?)
83 }
84
85 pub fn import_cxf(&self, payload: String) -> Result<Vec<EncryptionContext>> {
92 Ok(self.0.import_cxf(payload)?)
93 }
94}
95
96#[derive(uniffi::Object)]
97pub struct ImporterClient(pub(crate) bitwarden_importers::ImporterClient);
98
99#[uniffi::export(async_runtime = "tokio")]
100impl ImporterClient {
101 pub async fn import_kdbx(
103 &self,
104 file: Vec<u8>,
105 password: Option<String>,
106 key_file: Option<Vec<u8>>,
107 options: ImportOptions,
108 ) -> Result<ImportSummary> {
109 Ok(self
110 .0
111 .import_kdbx(file, password, key_file, options)
112 .await?)
113 }
114
115 pub async fn import_onepassword(
121 &self,
122 credentials: Credentials,
123 two_factor: Arc<dyn OnePasswordTwoFactorPrompt>,
124 options: ImportOptions,
125 ) -> Result<OnePasswordImportSummary> {
126 Ok(self
127 .0
128 .import_onepassword(credentials, &TwoFactorPromptBridge(two_factor), options)
129 .await?)
130 }
131}
132
133#[uniffi::export(with_foreign)]
135#[async_trait::async_trait]
136pub trait OnePasswordTwoFactorPrompt: Send + Sync {
137 async fn provide_totp(&self, attempt: u32) -> Result<Option<String>>;
140}
141
142struct TwoFactorPromptBridge(Arc<dyn OnePasswordTwoFactorPrompt>);
145
146#[async_trait::async_trait]
147impl OnePasswordTwoFactorUi for TwoFactorPromptBridge {
148 async fn provide_totp(&self, attempt: u32) -> OnePasswordTotpResult {
149 match self.0.provide_totp(attempt).await {
151 Ok(Some(code)) => OnePasswordTotpResult::Code(code),
152 Ok(None) | Err(_) => OnePasswordTotpResult::Cancel,
153 }
154 }
155}