Skip to main content

bw/platform/
sync.rs

1use bitwarden_sync::{SyncError, SyncRequest};
2use chrono::SecondsFormat;
3use clap::Args;
4use color_eyre::eyre::eyre;
5
6use crate::{
7    client_state::{BwCommand, LoggedIn},
8    render::CommandResult,
9};
10
11#[derive(Args, Clone)]
12pub struct SyncArgs {
13    #[arg(short = 'f', long, help = "Force a full sync.")]
14    pub force: bool,
15
16    #[arg(long, help = "Get the last sync date.")]
17    pub last: bool,
18}
19
20impl BwCommand for SyncArgs {
21    type Client = LoggedIn;
22
23    async fn run(self, LoggedIn { user, .. }: LoggedIn) -> CommandResult {
24        if self.last {
25            let output = user
26                .sync()
27                .last_sync()
28                .await
29                // Convert to RFC3339 with millisecond precision, to match the old CLI's format.
30                .map(|t| t.to_rfc3339_opts(SecondsFormat::Millis, true))
31                .unwrap_or_else(|| "None".to_string());
32            return Ok(output.into());
33        }
34
35        match user
36            .sync()
37            .sync(SyncRequest {
38                force: self.force,
39                exclude_subdomains: None,
40            })
41            .await
42        {
43            Ok(_) => Ok("Syncing complete.".into()),
44            Err(SyncError::AccountDeleted) => {
45                // TODO: This should wipe the session in the same way as bw logout, but it's not
46                // implemented yet
47                user.unlock().invalidate_session_key().await.ok();
48                Err(eyre!(
49                    "This account has been deleted. Local session state has been cleared."
50                ))
51            }
52            Err(e) => Err(e.into()),
53        }
54    }
55}