Refresh an expired access token using the stored refresh token.
(&self)
| 221 | } |
| 222 | /// Refresh an expired access token using the stored refresh token. |
| 223 | pub async fn refresh_token(&self) -> Result<(), OAuthError> { |
| 224 | let entry = auth::get_for_url(&self.mcp_name, &self.server_url) |
| 225 | .await |
| 226 | .ok_or(OAuthError::NoRefreshToken)?; |
| 227 | |
| 228 | let tokens = entry.tokens.ok_or(OAuthError::NoRefreshToken)?; |
| 229 | let refresh = tokens.refresh_token.ok_or(OAuthError::NoRefreshToken)?; |
| 230 | |
| 231 | let (client_id, client_secret, auth_url, token_url, redirect_url) = self.parsed_config()?; |
| 232 | |
| 233 | let mut client = oauth2::basic::BasicClient::new(client_id) |
| 234 | .set_auth_uri(auth_url) |
| 235 | .set_token_uri(token_url) |
| 236 | .set_redirect_uri(redirect_url); |
| 237 | |
| 238 | if let Some(secret) = client_secret { |
| 239 | client = client.set_client_secret(secret); |
| 240 | } |
| 241 | |
| 242 | let http_client = reqwest::Client::new(); |
| 243 | |
| 244 | let token_result = client |
| 245 | .exchange_refresh_token(&RefreshToken::new(refresh)) |
| 246 | .request_async(&http_client) |
| 247 | .await |
| 248 | .map_err(|e| OAuthError::TokenRefresh(e.to_string()))?; |
| 249 | |
| 250 | self.save_token_result(&token_result).await?; |
| 251 | |
| 252 | Ok(()) |
| 253 | } |
| 254 | |
| 255 | /// Helper: persist a token response to the auth store. |
| 256 | async fn save_token_result<EF: oauth2::ExtraTokenFields>( |
no test coverage detected