aboutsummaryrefslogtreecommitdiffstats
path: root/crates/turtle/src/command
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 18:02:55 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-06-11 18:02:55 +0200
commit0b6ca5cb8ca4c46265e08e13053260d9b5cff568 (patch)
tree9dc656095f806e6dd1177e40b9a87cf6d6f10f1b /crates/turtle/src/command
parentchore(server): Remove the last remnants of the "hub" sync-server thingy (diff)
downloadatuin-0b6ca5cb8ca4c46265e08e13053260d9b5cff568.zip
feat(server): Make user stuff stateless
Diffstat (limited to '')
-rw-r--r--crates/turtle/src/command/client.rs16
-rw-r--r--crates/turtle/src/command/client/account.rs47
-rw-r--r--crates/turtle/src/command/client/account/change_password.rs55
-rw-r--r--crates/turtle/src/command/client/account/delete.rs45
-rw-r--r--crates/turtle/src/command/client/account/login.rs201
-rw-r--r--crates/turtle/src/command/client/account/logout.rs5
-rw-r--r--crates/turtle/src/command/client/account/register.rs67
-rw-r--r--crates/turtle/src/command/client/doctor.rs35
-rw-r--r--crates/turtle/src/command/client/setup.rs81
-rw-r--r--crates/turtle/src/command/client/store/push.rs2
-rw-r--r--crates/turtle/src/command/client/sync.rs14
-rw-r--r--crates/turtle/src/command/client/sync/status.rs6
12 files changed, 18 insertions, 556 deletions
diff --git a/crates/turtle/src/command/client.rs b/crates/turtle/src/command/client.rs
index 15df60f8..9d5b4605 100644
--- a/crates/turtle/src/command/client.rs
+++ b/crates/turtle/src/command/client.rs
@@ -43,9 +43,6 @@ fn cleanup_old_logs(log_dir: &Path, prefix: &str, retention_days: u64) {
#[cfg(feature = "sync")]
mod sync;
-#[cfg(feature = "sync")]
-mod account;
-
#[cfg(feature = "daemon")]
mod daemon;
@@ -58,7 +55,6 @@ mod info;
mod init;
mod search;
mod server;
-mod setup;
mod stats;
mod store;
mod wrapped;
@@ -66,10 +62,6 @@ mod wrapped;
#[derive(Subcommand, Debug)]
#[command(infer_subcommands = true)]
pub(crate) enum Cmd {
- /// Setup Atuin features
- #[command()]
- Setup,
-
/// Manipulate shell history
#[command(subcommand)]
History(history::Cmd),
@@ -92,10 +84,6 @@ pub(crate) enum Cmd {
#[command(subcommand)]
Server(server::Cmd),
- /// Manage your sync account
- #[cfg(feature = "sync")]
- Account(account::Cmd),
-
/// Manage the atuin data store
#[command(subcommand)]
Store(store::Cmd),
@@ -333,7 +321,6 @@ impl Cmd {
let theme = theme_manager.load_theme(theme_name.as_str(), settings.theme.max_depth);
match self {
- Self::Setup => setup::run(&settings).await,
Self::Import(import) => import.run(&db).await,
Self::Stats(stats) => stats.run(&db, &settings, theme).await,
Self::Search(search) => search.run(db, &mut settings, sqlite_store, theme).await,
@@ -341,9 +328,6 @@ impl Cmd {
#[cfg(feature = "sync")]
Self::Sync(sync) => sync.run(settings, &db, sqlite_store).await,
- #[cfg(feature = "sync")]
- Self::Account(account) => account.run(settings, sqlite_store).await,
-
Self::Store(store) => store.run(&settings, &db, sqlite_store).await,
Self::Server(server) => server.run().await,
diff --git a/crates/turtle/src/command/client/account.rs b/crates/turtle/src/command/client/account.rs
deleted file mode 100644
index f2ceb10b..00000000
--- a/crates/turtle/src/command/client/account.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use clap::{Args, Subcommand};
-use eyre::Result;
-
-use crate::atuin_client::record::sqlite_store::SqliteStore;
-use crate::atuin_client::settings::Settings;
-
-pub(crate) mod change_password;
-pub(crate) mod delete;
-pub(crate) mod login;
-pub(crate) mod logout;
-pub(crate) mod register;
-
-#[derive(Args, Debug)]
-pub(crate) struct Cmd {
- #[command(subcommand)]
- command: Commands,
-}
-
-#[derive(Subcommand, Debug)]
-pub(crate) enum Commands {
- /// Login to the configured server
- Login(login::Cmd),
-
- /// Register a new account
- Register(register::Cmd),
-
- /// Log out
- Logout,
-
- /// Delete your account, and all synced data
- Delete(delete::Cmd),
-
- /// Change your password
- ChangePassword(change_password::Cmd),
-}
-
-impl Cmd {
- pub(crate) async fn run(self, settings: Settings, store: SqliteStore) -> Result<()> {
- match self.command {
- Commands::Login(l) => l.run(&settings, &store).await,
- Commands::Register(r) => r.run(&settings).await,
- Commands::Logout => logout::run().await,
- Commands::Delete(d) => d.run(&settings).await,
- Commands::ChangePassword(c) => c.run(&settings).await,
- }
- }
-}
diff --git a/crates/turtle/src/command/client/account/change_password.rs b/crates/turtle/src/command/client/account/change_password.rs
deleted file mode 100644
index b23f518d..00000000
--- a/crates/turtle/src/command/client/account/change_password.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use clap::Parser;
-use eyre::{Result, bail};
-
-use crate::atuin_client::{auth, settings::Settings};
-use rpassword::prompt_password;
-
-#[derive(Parser, Debug)]
-pub(crate) struct Cmd {
- #[clap(long, short)]
- pub(crate) current_password: Option<String>,
-
- #[clap(long, short)]
- pub(crate) new_password: Option<String>,
-
- /// The two-factor authentication code for your account, if any
- #[clap(long, short)]
- pub(crate) totp_code: Option<String>,
-}
-
-impl Cmd {
- pub(crate) async fn run(&self, settings: &Settings) -> Result<()> {
- if !settings.logged_in().await? {
- bail!("You are not logged in");
- }
-
- let client = auth::auth_client(settings).await;
-
- let current_password = self.current_password.clone().unwrap_or_else(|| {
- prompt_password("Please enter the current password: ")
- .expect("Failed to read from input")
- });
-
- if current_password.is_empty() {
- bail!("please provide the current password");
- }
-
- let new_password = self.new_password.clone().unwrap_or_else(|| {
- prompt_password("Please enter the new password: ").expect("Failed to read from input")
- });
-
- if new_password.is_empty() {
- bail!("please provide a new password");
- }
-
- let totp_code = self.totp_code.clone();
-
- client
- .change_password(&current_password, &new_password, totp_code.as_deref())
- .await?;
-
- println!("Account password successfully changed!");
-
- Ok(())
- }
-}
diff --git a/crates/turtle/src/command/client/account/delete.rs b/crates/turtle/src/command/client/account/delete.rs
deleted file mode 100644
index 722c39ec..00000000
--- a/crates/turtle/src/command/client/account/delete.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use crate::atuin_client::{auth, settings::Settings};
-use clap::Parser;
-use eyre::{Result, bail};
-
-use super::login::read_user_password;
-
-#[derive(Parser, Debug)]
-pub(crate) struct Cmd {
- #[clap(long, short)]
- pub(crate) password: Option<String>,
-
- /// The two-factor authentication code for your account, if any
- #[clap(long, short)]
- pub(crate) totp_code: Option<String>,
-}
-
-impl Cmd {
- pub(crate) async fn run(&self, settings: &Settings) -> Result<()> {
- if !settings.logged_in().await? {
- bail!("You are not logged in");
- }
-
- let client = auth::auth_client(settings).await;
-
- let password = self.password.clone().unwrap_or_else(read_user_password);
-
- if password.is_empty() {
- bail!("please provide your password");
- }
-
- let mut totp_code = self.totp_code.clone();
-
- client
- .delete_account(&password, totp_code.as_deref())
- .await?;
-
- // Clean up sessions from meta store
- let meta = Settings::meta_store().await?;
- meta.delete_session().await?;
-
- println!("Your account is deleted");
-
- Ok(())
- }
-}
diff --git a/crates/turtle/src/command/client/account/login.rs b/crates/turtle/src/command/client/account/login.rs
deleted file mode 100644
index e9513879..00000000
--- a/crates/turtle/src/command/client/account/login.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-use std::{io, path::PathBuf};
-
-use clap::Parser;
-use eyre::{Context, Result, bail};
-use tokio::{fs::File, io::AsyncWriteExt};
-
-use crate::atuin_client::{
- auth,
- encryption::{decode_key, load_key},
- record::sqlite_store::SqliteStore,
- record::store::Store,
- record::sync::{self, SyncError},
- settings::{Settings, SyncAuth},
-};
-use rpassword::prompt_password;
-
-#[derive(Parser, Debug)]
-pub(crate) struct Cmd {
- #[clap(long, short)]
- pub(crate) username: Option<String>,
-
- #[clap(long, short)]
- pub(crate) password: Option<String>,
-
- /// The encryption key for your account
- #[clap(long, short)]
- pub(crate) key: Option<String>,
-
- /// The two-factor authentication code for your account, if any
- #[clap(long, short)]
- pub(crate) totp_code: Option<String>,
-
- #[clap(long, hide = true)]
- pub(crate) from_registration: bool,
-}
-
-fn get_input() -> Result<String> {
- let mut input = String::new();
- io::stdin().read_line(&mut input)?;
- Ok(input.trim_end_matches(&['\r', '\n'][..]).to_string())
-}
-
-impl Cmd {
- pub(crate) async fn run(&self, settings: &Settings, store: &SqliteStore) -> Result<()> {
- match settings.resolve_sync_auth().await {
- SyncAuth::Legacy { .. } => {
- println!("You are logged in to your sync server.");
- println!("Run 'atuin logout' to log out.");
- return Ok(());
- }
- SyncAuth::NotLoggedIn { .. } => {}
- }
-
- self.run_legacy_login(settings, store).await?;
-
- verify_key_against_remote(settings).await
- }
-
- /// Legacy login: always prompt for username/password interactively
- /// (or accept them via flags).
- async fn run_legacy_login(&self, settings: &Settings, store: &SqliteStore) -> Result<()> {
- let username = or_user_input(self.username.clone(), "username");
- let password = self.password.clone().unwrap_or_else(read_user_password);
-
- self.prompt_and_store_key(settings, store).await?;
-
- let client = auth::auth_client(settings).await;
- let response = client.login(&username, &password).await?;
-
- Settings::meta_store()
- .await?
- .save_session(&response.session)
- .await?;
-
- println!("Logged in!");
- Ok(())
- }
-
- async fn prompt_and_store_key(&self, settings: &Settings, store: &SqliteStore) -> Result<()> {
- let key_path = settings.key_path.as_str();
- let key_path = PathBuf::from(key_path);
-
- println!("IMPORTANT");
- println!(
- "If you are already logged in on another machine, you must ensure that the key you use here is the same as the key you used there."
- );
- println!("You can find your key by running 'atuin key' on the other machine.");
- println!("Do not share this key with anyone.");
- println!("\nRead more here: https://docs.atuin.sh/guide/sync/#login \n");
-
- let key = or_user_input(
- self.key.clone(),
- "encryption key [blank to use existing key file]",
- );
-
- if key.is_empty() {
- if key_path.exists() {
- let bytes = fs_err::read_to_string(&key_path).context(format!(
- "Existing key file at '{}' could not be read",
- key_path.to_string_lossy()
- ))?;
- if decode_key(bytes).is_err() {
- bail!(format!(
- "The key in existing key file at '{}' is invalid",
- key_path.to_string_lossy()
- ));
- }
- } else {
- panic!(
- "No key provided and no existing key file found. Please use 'atuin key' on your other machine, or recover your key from a backup"
- )
- }
- } else if !key_path.exists() {
- if decode_key(key.clone()).is_err() {
- bail!("The specified key is invalid");
- }
-
- let mut file = File::create(&key_path).await?;
- file.write_all(key.as_bytes()).await?;
- } else {
- // we now know that the user has logged in specifying a key, AND that the key path
- // exists
-
- // 1. check if the saved key and the provided key match. if so, nothing to do.
- // 2. if not, re-encrypt the local history and overwrite the key
- let current_key: [u8; 32] = load_key(settings)?.into();
-
- let encoded = key.clone(); // gonna want to save it in a bit
- let new_key: [u8; 32] = decode_key(key)
- .context("Could not decode provided key; is not valid base64-encoded key")?
- .into();
-
- if new_key != current_key {
- println!("\nRe-encrypting local store with new key");
-
- store.re_encrypt(&current_key, &new_key).await?;
-
- println!("Writing new key");
- let mut file = File::create(&key_path).await?;
- file.write_all(encoded.as_bytes()).await?;
- }
- }
-
- Ok(())
- }
-}
-
-async fn verify_key_against_remote(settings: &Settings) -> Result<()> {
- let key: [u8; 32] = load_key(settings)
- .context("could not load encryption key for verification")?
- .into();
-
- let client = sync::build_client(settings).await?;
- let remote_index = match client.record_status().await {
- Ok(idx) => idx,
- Err(e) => {
- tracing::warn!("could not fetch remote status to verify key: {e}");
- return Ok(());
- }
- };
-
- match sync::check_encryption_key(&client, &remote_index, &key).await {
- Ok(()) => Ok(()),
- Err(SyncError::WrongKey) => {
- // Roll back the saved session so the user is not left in a
- // half-authenticated state with a key that can't read the data.
- if let Ok(meta) = Settings::meta_store().await {
- let _ = meta.delete_session().await;
- }
- crate::print_error::print_error(
- "Wrong encryption key",
- "The encryption key on this machine does not match the data on the server. \
- You have been logged out.\n\n\
- To fix this, find your existing key by running `atuin key` on a machine that \
- already syncs successfully, then run `atuin login` again here with that key.",
- );
- std::process::exit(1);
- }
- Err(e) => {
- // Non-key error (e.g. transient network issue). Don't fail the
- // login — the user is authenticated and can sync later when the
- // network recovers.
- tracing::warn!("could not verify encryption key against remote: {e}");
- Ok(())
- }
- }
-}
-
-pub(super) fn or_user_input(value: Option<String>, name: &'static str) -> String {
- value.unwrap_or_else(|| read_user_input(name))
-}
-
-pub(super) fn read_user_password() -> String {
- let password = prompt_password("Please enter password: ");
- password.expect("Failed to read from input")
-}
-
-fn read_user_input(name: &'static str) -> String {
- eprint!("Please enter {name}: ");
- get_input().expect("Failed to read from input")
-}
diff --git a/crates/turtle/src/command/client/account/logout.rs b/crates/turtle/src/command/client/account/logout.rs
deleted file mode 100644
index 5708e34c..00000000
--- a/crates/turtle/src/command/client/account/logout.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use eyre::Result;
-
-pub(crate) async fn run() -> Result<()> {
- crate::atuin_client::logout::logout().await
-}
diff --git a/crates/turtle/src/command/client/account/register.rs b/crates/turtle/src/command/client/account/register.rs
deleted file mode 100644
index 64fb9f8d..00000000
--- a/crates/turtle/src/command/client/account/register.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-use clap::Parser;
-use eyre::{Result, bail};
-
-use super::login::or_user_input;
-use crate::atuin_client::settings::{Settings, SyncAuth};
-
-#[derive(Parser, Debug)]
-pub(crate) struct Cmd {
- #[clap(long, short)]
- pub(crate) username: Option<String>,
-
- #[clap(long, short)]
- pub(crate) password: Option<String>,
-
- #[clap(long, short)]
- pub(crate) email: Option<String>,
-}
-
-impl Cmd {
- pub(crate) async fn run(&self, settings: &Settings) -> Result<()> {
- match settings.resolve_sync_auth().await {
- SyncAuth::Legacy { .. } => {
- println!("You are already logged in.");
- println!("Run 'atuin logout' to log out.");
- return Ok(());
- }
-
- SyncAuth::NotLoggedIn { .. } => {}
- }
-
- // Legacy registration flow
- println!("Registering for an Atuin Sync account");
-
- let username = or_user_input(self.username.clone(), "username");
- let email = or_user_input(self.email.clone(), "email");
- let password = self
- .password
- .clone()
- .unwrap_or_else(super::login::read_user_password);
-
- if password.is_empty() {
- bail!("please provide a password");
- }
-
- let session = crate::atuin_client::api_client::register(
- settings.sync_address.as_str(),
- &username,
- &email,
- &password,
- )
- .await?;
-
- let meta = Settings::meta_store().await?;
- meta.save_session(&session.session).await?;
-
- let _key = crate::atuin_client::encryption::load_key(settings)?;
-
- println!(
- "Registration successful! Please make a note of your key (run 'atuin key') and keep it safe."
- );
- println!(
- "You will need it to log in on other devices, and we cannot help recover it if you lose it."
- );
-
- Ok(())
- }
-}
diff --git a/crates/turtle/src/command/client/doctor.rs b/crates/turtle/src/command/client/doctor.rs
index 1ed90c47..eec690a5 100644
--- a/crates/turtle/src/command/client/doctor.rs
+++ b/crates/turtle/src/command/client/doctor.rs
@@ -243,15 +243,8 @@ struct SyncInfo {
}
impl SyncInfo {
- pub(crate) async fn new(settings: &Settings) -> Self {
- // Build auth state description from raw token state without calling
- // resolve_sync_auth(), which has side effects (token migration cleanup)
- // that a diagnostic command should not trigger.
- let meta = Settings::meta_store().await.ok();
- let has_cli_token = match &meta {
- Some(m) => m.session_token().await.ok().flatten().is_some(),
- None => false,
- };
+ pub(crate) async fn new(settings: &Settings) -> Result<Self> {
+ let has_cli_token = settings.have_sync_key().await?;
let auth_state = if has_cli_token {
"Self-hosted (authenticated)".into()
@@ -259,13 +252,13 @@ impl SyncInfo {
"Not authenticated".into()
};
- Self {
+ Ok(Self {
auth_state,
auto_sync: settings.auto_sync,
last_sync: Settings::last_sync()
.await
.map_or_else(|_| "no last sync".to_string(), |v| v.to_string()),
- }
+ })
}
}
@@ -318,11 +311,11 @@ struct AtuinInfo {
}
impl AtuinInfo {
- pub(crate) async fn new(settings: &Settings) -> Self {
- let logged_in = settings.logged_in().await.unwrap_or(false);
+ pub(crate) async fn new(settings: &Settings) -> Result<Self> {
+ let logged_in = settings.have_sync_key().await?;
let sync = if logged_in {
- Some(SyncInfo::new(settings).await)
+ Some(SyncInfo::new(settings).await?)
} else {
None
};
@@ -335,13 +328,13 @@ impl AtuinInfo {
Err(_) => "error".to_string(),
};
- Self {
+ Ok(Self {
version: crate::VERSION.to_string(),
commit: crate::SHA.to_string(),
sync,
sqlite_version,
setting_paths: SettingPaths::new(settings),
- }
+ })
}
}
@@ -353,12 +346,12 @@ struct DoctorDump {
}
impl DoctorDump {
- pub(crate) async fn new(settings: &Settings) -> Self {
- Self {
- atuin: AtuinInfo::new(settings).await,
+ pub(crate) async fn new(settings: &Settings) -> Result<Self> {
+ Ok(Self {
+ atuin: AtuinInfo::new(settings).await?,
shell: ShellInfo::new(),
system: SystemInfo::new(),
- }
+ })
}
}
@@ -399,7 +392,7 @@ fn checks(info: &DoctorDump) {
pub(crate) async fn run(settings: &Settings) -> Result<()> {
println!("{}", "Atuin Doctor".bold());
println!("Checking for diagnostics");
- let dump = DoctorDump::new(settings).await;
+ let dump = DoctorDump::new(settings).await?;
checks(&dump);
diff --git a/crates/turtle/src/command/client/setup.rs b/crates/turtle/src/command/client/setup.rs
deleted file mode 100644
index 3231b6ec..00000000
--- a/crates/turtle/src/command/client/setup.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use crate::atuin_client::settings::Settings;
-
-use colored::Colorize;
-use eyre::Result;
-use std::io::{self, Write};
-use toml_edit::{DocumentMut, value};
-
-pub(crate) async fn run(_settings: &Settings) -> Result<()> {
- let enable_ai = prompt(
- "Atuin AI",
- "This will enable command generation and other AI features via the question mark key",
- Some(
- "By default, Atuin AI only has access to the name and version of your operating system and shell - your shell history is not sent to the AI.",
- ),
- )?;
-
- let enable_daemon = prompt(
- "Atuin Daemon",
- "This will enable improved search and history sync using a persistent background process",
- None,
- )?;
-
- let config_file = Settings::get_config_path()?;
- let config_str = tokio::fs::read_to_string(&config_file).await?;
- let mut doc = config_str.parse::<DocumentMut>()?;
-
- let mut changed = false;
- if enable_ai {
- changed = true;
- if !doc.contains_key("ai") {
- doc["ai"] = toml_edit::table();
- }
- doc["ai"]["enabled"] = value(true);
- }
-
- if enable_daemon {
- changed = true;
- if !doc.contains_key("daemon") {
- doc["daemon"] = toml_edit::table();
- }
- doc["daemon"]["enabled"] = value(true);
- doc["daemon"]["autostart"] = value(true);
- doc["search_mode"] = value("daemon-fuzzy");
- }
-
- if changed {
- tokio::fs::write(config_file, doc.to_string()).await?;
-
- println!(
- "{check} Settings updated successfully",
- check = "✓".bold().bright_green()
- );
- } else {
- println!(
- "{check} No settings changed",
- check = "✓".bold().bright_green()
- );
- }
-
- Ok(())
-}
-
-pub(crate) fn prompt(feature: &str, description: &str, note: Option<&str>) -> Result<bool> {
- println!(
- "> Enable {feature}?",
- feature = feature.bold().bright_blue()
- );
- if let Some(note) = note {
- println!(" {description}");
- print!(" {note} {q} ", q = "[Y/n]".bold());
- } else {
- print!(" {description} {q} ", q = "[Y/n]".bold());
- }
-
- io::stdout().flush().ok();
-
- let mut input = String::new();
- io::stdin().read_line(&mut input)?;
- let answer = input.trim().to_lowercase();
- Ok(answer.is_empty() || answer == "y" || answer == "yes")
-}
diff --git a/crates/turtle/src/command/client/store/push.rs b/crates/turtle/src/command/client/store/push.rs
index 042ad201..30177dbd 100644
--- a/crates/turtle/src/command/client/store/push.rs
+++ b/crates/turtle/src/command/client/store/push.rs
@@ -43,7 +43,7 @@ impl Push {
let client = Client::new(
&settings.sync_address,
- settings.sync_auth_token().await?,
+ settings.sync_auth().await?.into_auth_token()?,
settings.network_connect_timeout,
settings.network_timeout * 10, // we may be deleting a lot of data... so up the
// timeout
diff --git a/crates/turtle/src/command/client/sync.rs b/crates/turtle/src/command/client/sync.rs
index 8d7cb50a..7adf90ed 100644
--- a/crates/turtle/src/command/client/sync.rs
+++ b/crates/turtle/src/command/client/sync.rs
@@ -11,8 +11,6 @@ use crate::atuin_client::{
mod status;
-use crate::command::client::account;
-
#[derive(Subcommand, Debug)]
#[command(infer_subcommands = true)]
pub(crate) enum Cmd {
@@ -23,15 +21,6 @@ pub(crate) enum Cmd {
force: bool,
},
- /// Login to the configured server
- Login(account::login::Cmd),
-
- /// Log out
- Logout,
-
- /// Register with the configured server
- Register(account::register::Cmd),
-
/// Print the encryption key for transfer to another machine
Key {},
@@ -48,9 +37,6 @@ impl Cmd {
) -> Result<()> {
match self {
Self::Sync { force } => run(&settings, force, db, store).await,
- Self::Login(l) => l.run(&settings, &store).await,
- Self::Logout => account::logout::run().await,
- Self::Register(r) => r.run(&settings).await,
Self::Status => status::run(&settings).await,
Self::Key {} => {
use crate::atuin_client::encryption::{encode_key, load_key};
diff --git a/crates/turtle/src/command/client/sync/status.rs b/crates/turtle/src/command/client/sync/status.rs
index cb0d86e4..27b10dbd 100644
--- a/crates/turtle/src/command/client/sync/status.rs
+++ b/crates/turtle/src/command/client/sync/status.rs
@@ -1,16 +1,16 @@
-use crate::{SHA, VERSION};
use crate::atuin_client::{api_client, settings::Settings};
+use crate::{SHA, VERSION};
use colored::Colorize;
use eyre::{Result, bail};
pub(crate) async fn run(settings: &Settings) -> Result<()> {
- if !settings.logged_in().await? {
+ if !settings.have_sync_key().await? {
bail!("You are not logged in to a sync server - cannot show sync status");
}
let client = api_client::Client::new(
&settings.sync_address,
- settings.sync_auth_token().await?,
+ settings.sync_auth().await?.into_auth_token()?,
settings.network_connect_timeout,
settings.network_timeout,
)?;