Skip to main content

bitwarden_importers/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use bitwarden_collections::collection::CollectionId;
4use bitwarden_core::OrganizationId;
5use bitwarden_vault::{CipherType as VaultCipherType, FolderId};
6
7#[cfg(feature = "uniffi")]
8uniffi::setup_scaffolding!();
9#[cfg(feature = "uniffi")]
10mod uniffi_support;
11
12mod error;
13pub use error::ImportError;
14mod import;
15mod importer_client;
16pub use importer_client::{ImporterClient, ImporterClientExt};
17mod importers;
18pub(crate) use importers::keeper;
19mod pipeline;
20
21/// The 1Password access module: log in to an account and download its vaults.
22///
23/// Exposed only under the `test-utils` feature, for the out-of-tree CLI that drives it against
24/// a real account. Not part of this crate's supported API, and no stability is promised.
25// TODO: Remove once the importer consumes the module directly.
26#[cfg(feature = "test-utils")]
27pub use importers::onepassword::access as onepassword_access;
28
29/// Destination options for a vault import.
30///
31/// `organization_id` selects the destination: `None` imports into the user's personal vault (groups
32/// become personal folders), `Some` imports into that organization (ciphers are encrypted with the
33/// org key). `target_folder` (personal) and `target_collection` (organization) nest the import
34/// under an existing destination, mirroring the client's import-target behavior; each carries both
35/// its id and name together so a half-specified target can't be expressed. `restricted_types` are
36/// dropped before submission.
37#[allow(missing_docs)]
38#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
39#[cfg_attr(
40    feature = "wasm",
41    derive(serde::Serialize, serde::Deserialize, tsify::Tsify),
42    tsify(from_wasm_abi)
43)]
44pub struct ImportOptions {
45    pub organization_id: Option<OrganizationId>,
46    pub target_folder: Option<ImportTargetFolder>,
47    pub target_collection: Option<ImportTargetCollection>,
48    // `VaultCipherType` is the wasm-bindgen enum exported as `CipherType`; pin the TS name so
49    // tsify doesn't emit the Rust alias.
50    #[cfg_attr(feature = "wasm", tsify(type = "CipherType[]"))]
51    pub restricted_types: Vec<VaultCipherType>,
52}
53
54/// An existing personal folder to nest a personal import under.
55#[allow(missing_docs)]
56#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
57#[cfg_attr(
58    feature = "wasm",
59    derive(serde::Serialize, serde::Deserialize, tsify::Tsify),
60    tsify(from_wasm_abi)
61)]
62pub struct ImportTargetFolder {
63    pub id: FolderId,
64    pub name: String,
65}
66
67/// An existing organization collection to assign an org import to.
68#[allow(missing_docs)]
69#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
70#[cfg_attr(
71    feature = "wasm",
72    derive(serde::Serialize, serde::Deserialize, tsify::Tsify),
73    tsify(from_wasm_abi)
74)]
75pub struct ImportTargetCollection {
76    pub id: CollectionId,
77    pub name: String,
78}
79
80/// Counts of what an import submitted to the server, broken down by cipher type so the client can
81/// render its per-type result table.
82#[allow(missing_docs)]
83#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
84#[cfg_attr(
85    feature = "wasm",
86    derive(serde::Serialize, serde::Deserialize, tsify::Tsify),
87    tsify(into_wasm_abi)
88)]
89pub struct ImportSummary {
90    pub ciphers: Vec<CipherTypeCount>,
91    pub folders: u32,
92    pub collections: u32,
93}
94
95/// Number of imported ciphers of a given type.
96#[allow(missing_docs)]
97#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
98#[cfg_attr(
99    feature = "wasm",
100    derive(serde::Serialize, serde::Deserialize, tsify::Tsify),
101    tsify(into_wasm_abi)
102)]
103pub struct CipherTypeCount {
104    #[cfg_attr(feature = "wasm", tsify(type = "CipherType"))]
105    pub r#type: VaultCipherType,
106    pub count: u32,
107}