diff --git a/crates/flow-client/src/client.rs b/crates/flow-client/src/client.rs index aba0cb9489..de5a2d72c6 100644 --- a/crates/flow-client/src/client.rs +++ b/crates/flow-client/src/client.rs @@ -312,7 +312,7 @@ pub async fn refresh_authorizations( (Some(access), None) => { // We have an access token but no refresh token. Create one. let refresh_token = api_exec::( - client.rpc( + client.clone().with_creds(Some(access.to_owned())).rpc( "create_refresh_token", serde_json::json!({"multi_use": true, "valid_for": "90d", "detail": "Created by flowctl"}) .to_string(), diff --git a/crates/flowctl/src/auth/mod.rs b/crates/flowctl/src/auth/mod.rs index 17ead583a8..223f98c785 100644 --- a/crates/flowctl/src/auth/mod.rs +++ b/crates/flowctl/src/auth/mod.rs @@ -1,6 +1,7 @@ mod roles; use anyhow::Context; +use flow_client::client::refresh_authorizations; #[derive(Debug, clap::Args)] #[clap(rename_all = "kebab-case")] @@ -64,7 +65,20 @@ impl Auth { Ok(()) } Command::Roles(roles) => roles.run(ctx).await, - } + }?; + + // Ensure that any changes to the credentials fully propagate + // i.e if an access token is changed, we also need to make sure + // to generate and store an updated refresh token. + let (access_token, refresh_token) = refresh_authorizations( + &ctx.client, + ctx.config.user_access_token.to_owned(), + ctx.config.user_refresh_token.to_owned(), + ) + .await?; + ctx.config.user_access_token = Some(access_token); + ctx.config.user_refresh_token = Some(refresh_token); + Ok(()) } } diff --git a/crates/flowctl/src/lib.rs b/crates/flowctl/src/lib.rs index a794b77564..b7e10f2360 100644 --- a/crates/flowctl/src/lib.rs +++ b/crates/flowctl/src/lib.rs @@ -136,21 +136,25 @@ impl Cli { let anon_client: flow_client::Client = config.build_anon_client(); - let client = if let Ok((access, refresh)) = refresh_authorizations( + let client = match refresh_authorizations( &anon_client, config.user_access_token.to_owned(), config.user_refresh_token.to_owned(), ) .await { - // Make sure to store refreshed tokens back in Config so they get written back to disk - config.user_access_token = Some(access.to_owned()); - config.user_refresh_token = Some(refresh.to_owned()); + Ok((access, refresh)) => { + // Make sure to store refreshed tokens back in Config so they get written back to disk + config.user_access_token = Some(access.to_owned()); + config.user_refresh_token = Some(refresh.to_owned()); - anon_client.with_creds(Some(access)) - } else { - tracing::warn!("You are not authenticated. Run `auth login` to login to Flow."); - anon_client + anon_client.with_creds(Some(access)) + } + Err(err) => { + tracing::debug!(?err, "Error refreshing credentials"); + tracing::warn!("You are not authenticated. Run `auth login` to login to Flow."); + anon_client + } }; let mut context = CliContext {