diff --git a/src/sso.rs b/src/sso.rs index 71793dbd..5fe6e684 100644 --- a/src/sso.rs +++ b/src/sso.rs @@ -424,13 +424,13 @@ pub async fn exchange_refresh_token( Some(TokenWrapper::Refresh(refresh_token)) => { // Use new refresh_token if returned let (new_refresh_token, access_token, expires_in) = - Client::exchange_refresh_token(refresh_token.clone()).await?; + Client::exchange_refresh_token(refresh_token).await?; create_auth_tokens( device, user, client_id, - new_refresh_token.or(Some(refresh_token)), + new_refresh_token, access_token, expires_in, ) diff --git a/src/sso_client.rs b/src/sso_client.rs index 3d2a3c48..1336af64 100644 --- a/src/sso_client.rs +++ b/src/sso_client.rs @@ -240,11 +240,19 @@ impl Client { Ok(token_response) => token_response, }; - Ok(( - token_response.refresh_token().map(|token| token.secret().clone()), - token_response.access_token().secret().clone(), - token_response.expires_in(), - )) + // Always surface a refresh token: + // - If the IdP (e.g., Authentik) returned a rotated one, use it. + // - Otherwise, keep using the one we just used for this request. + let access = token_response.access_token().secret().clone(); + let expires_in = token_response.expires_in(); + + let new_refresh = token_response + .refresh_token() + .map(|t| t.secret().clone()) + .unwrap_or_else(|| rt.secret().clone()); + + Ok((Some(new_refresh), access, expires_in)) + } }