mirror of
https://github.com/openai/codex.git
synced 2026-11-09 20:50:33 +00:00
Implement proper fix: also set the token expiration time when it's expired
The old load path in codex-rs/rmcp-client/src/oauth.rs only set expires_in when the stored expiry was in the future:
// codex-rs/rmcp-client/src/oauth.rs:369-374 (original)
if let Some(expires_at) = entry.expires_at
&& let Some(seconds) = expires_in_from_timestamp(expires_at)
{
let duration = Duration::from_secs(seconds);
token_response.set_expires_in(Some(&duration));
}
And expires_in_from_timestamp returned None for expired tokens:
// codex-rs/rmcp-client/src/oauth.rs:444-453 (original)
if expires_at <= now_ms {
None
} else {
Some((expires_at - now_ms) / 1000)
}
So when the stored token was already expired, set_expires_in was never called, RMCP saw “no expiry,” and it didn’t auto-refresh on handshake.
This commit is contained in:
@@ -366,9 +366,8 @@ fn load_oauth_tokens_from_file(server_name: &str, url: &str) -> Result<Option<St
|
||||
token_response.set_scopes(Some(scopes.into_iter().map(Scope::new).collect()));
|
||||
}
|
||||
|
||||
if let Some(expires_at) = entry.expires_at
|
||||
&& let Some(seconds) = expires_in_from_timestamp(expires_at)
|
||||
{
|
||||
if let Some(expires_at) = entry.expires_at {
|
||||
let seconds = expires_in_from_timestamp(expires_at).unwrap_or(0);
|
||||
let duration = Duration::from_secs(seconds);
|
||||
token_response.set_expires_in(Some(&duration));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use std::time::Duration;
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use futures::FutureExt;
|
||||
use oauth2::TokenResponse;
|
||||
use mcp_types::CallToolRequestParams;
|
||||
use mcp_types::CallToolResult;
|
||||
use mcp_types::InitializeRequestParams;
|
||||
@@ -57,8 +56,6 @@ use crate::utils::convert_to_rmcp;
|
||||
use crate::utils::create_env_for_mcp_server;
|
||||
use crate::utils::run_with_timeout;
|
||||
|
||||
const REFRESH_SKEW_SECS: u64 = 60;
|
||||
|
||||
enum PendingTransport {
|
||||
ChildProcess(TokioChildProcess),
|
||||
StreamableHttp {
|
||||
@@ -401,13 +398,6 @@ async fn create_oauth_transport_and_runtime(
|
||||
let auth_client = AuthClient::new(http_client, manager);
|
||||
let auth_manager = auth_client.auth_manager.clone();
|
||||
|
||||
// If the stored token is expired or about to expire, refresh before the handshake.
|
||||
if should_refresh_initial_token(&initial_tokens.token_response.0) {
|
||||
if let Err(err) = auth_manager.lock().await.refresh_token().await {
|
||||
warn!("failed to refresh OAuth token before handshake: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
let transport = StreamableHttpClientTransport::with_client(
|
||||
auth_client,
|
||||
StreamableHttpClientTransportConfig::with_uri(url.to_string()),
|
||||
@@ -423,10 +413,3 @@ async fn create_oauth_transport_and_runtime(
|
||||
|
||||
Ok((transport, runtime))
|
||||
}
|
||||
|
||||
fn should_refresh_initial_token(token: &OAuthTokenResponse) -> bool {
|
||||
match token.expires_in() {
|
||||
Some(duration) => duration.as_secs() <= REFRESH_SKEW_SECS,
|
||||
None => token.refresh_token().is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user