Handle expired session on logout and clear token on 401
- Treat 401 Unauthorized during logout as success since the session is already expired on the server - Clear the local token and show a helpful message when any command fails with "Unauthorized access." - Add clear_smb_token helper to remove the token file for an environment
keypair34 committed
Apr 6, 2026 at 22:47 UTC
4287896a8a2186bb4b5751a52b4db59f031f132a
5 files changed
+42
-10
crates/cli/src/account/logout/mod.rs
+9
-1
@@ -70,6 +70,14 @@ async fn do_process_logout(env: Environment) -> Result<()> {
70
let token = get_smb_token(env)?;
71
match logout(env, client(), token).await {
72
Ok(_) => Ok(()),
73
- Err(e) => Err(anyhow!("{e}")),
73
+ Err(e) => {
74
+ // A 401 means the session is already expired on the server.
75
+ // Treat this as success — the session is gone either way.
76
+ if e.to_string().contains("Unauthorized") {
77
+ Ok(())
78
+ } else {
79
+ Err(anyhow!("{e}"))
80
+ }
81
+ }
82
}
83
}
crates/cli/src/lib.rs
+2
@@ -7,6 +7,8 @@ pub mod project;
7
mod token;
8
mod ui;
9
10
+pub use token::clear_smb_token::clear_smb_token;
11
+
12
pub(crate) fn client() -> (&'static SmbClient, &'static str) {
13
let secret = env!("CLI_CLIENT_SECRET");
14
(&SmbClient::Cli, secret)
crates/cli/src/main.rs
+19
-9
@@ -4,6 +4,7 @@ use {
4
console::style,
5
smbcloud_cli::{
6
account::{login::process_login, logout::process_logout, me::process_me, process_account},
7
+ clear_smb_token,
8
cli::{Cli, CommandResult, Commands},
9
deploy::process_deploy::process_deploy,
10
project::{crud_create::process_project_init, process::process_project},
@@ -72,25 +73,34 @@ fn setup_logging(env: Environment, level: Option<EnvFilter>) -> Result<()> {
73
74
#[tokio::main]
75
async fn main() {
75
- match run().await {
76
+ let cli = Cli::parse();
77
+ let environment = cli.environment;
78
+ match run(cli).await {
79
Ok(result) => {
80
result.stop_and_persist();
81
std::process::exit(0);
82
}
83
Err(e) => {
81
- println!(
82
- "\n{} {}",
83
- style("✘".to_string()).for_stderr().red(),
84
- style(e).red()
85
- );
84
+ if e.to_string().contains("Unauthorized access.") {
85
+ let _ = clear_smb_token(environment);
86
+ println!(
87
+ "\n{} {}",
88
+ style("✘".to_string()).for_stderr().red(),
89
+ style("Your session has expired. Please login again with `smb login`.").red()
90
+ );
91
+ } else {
92
+ println!(
93
+ "\n{} {}",
94
+ style("✘".to_string()).for_stderr().red(),
95
+ style(e).red()
96
+ );
97
+ }
98
std::process::exit(1);
99
}
100
}
101
}
102
91
-async fn run() -> Result<CommandResult> {
92
- let cli = Cli::parse();
93
-
103
+async fn run(cli: Cli) -> Result<CommandResult> {
104
// println!("Environment: {}", cli.environment);
105
106
let log_level_error: Result<CommandResult> = Err(anyhow!(
crates/cli/src/token/clear_smb_token.rs
new
+11
@@ -0,0 +1,11 @@
1
+use {
2
+ crate::token::smb_token_file_path::smb_token_file_path, anyhow::Result,
3
+ smbcloud_network::environment::Environment, std::fs,
4
+};
5
+
6
+pub fn clear_smb_token(env: Environment) -> Result<()> {
7
+ if let Some(path) = smb_token_file_path(env) {
8
+ fs::remove_file(path)?;
9
+ }
10
+ Ok(())
11
+}
crates/cli/src/token/mod.rs
+1
@@ -1,3 +1,4 @@
1
+pub(crate) mod clear_smb_token;
2
pub(crate) mod get_smb_token;
3
pub(crate) mod is_logged_in;
4
pub(crate) mod smb_token_file_path;