mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-30 18:33:04 +08:00
feat(codex): preserve OAuth login state during third-party provider switching
Codex provider switches now only write config.toml for third-party providers, injecting the API key as experimental_bearer_token. The user's auth.json (ChatGPT OAuth tokens) is preserved. Official providers with login material still write auth.json normally. Backfill restores bearer tokens into stored provider auth.OPENAI_API_KEY to maintain canonical shape.
This commit is contained in:
@@ -616,12 +616,11 @@ fn merge_codex_config(
|
||||
request: &mut DeepLinkImportRequest,
|
||||
config: &serde_json::Value,
|
||||
) -> Result<(), AppError> {
|
||||
// Auto-fill API key from auth.OPENAI_API_KEY
|
||||
// Auto-fill API key from auth.OPENAI_API_KEY or Codex mobile-compatible bearer token.
|
||||
if request.api_key.as_ref().is_none_or(|s| s.is_empty()) {
|
||||
if let Some(api_key) = config
|
||||
.get("auth")
|
||||
.and_then(|v| v.get("OPENAI_API_KEY"))
|
||||
.and_then(|v| v.as_str())
|
||||
let config_str = config.get("config").and_then(|v| v.as_str());
|
||||
if let Some(api_key) =
|
||||
crate::codex_config::extract_codex_api_key(config.get("auth"), config_str)
|
||||
{
|
||||
request.api_key = Some(api_key.to_string());
|
||||
}
|
||||
|
||||
@@ -267,6 +267,47 @@ fn test_parse_and_merge_config_claude() {
|
||||
assert_eq!(merged.model, Some("claude-sonnet-4.5".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_and_merge_config_codex_uses_bearer_token() {
|
||||
let config_toml = r#"model_provider = "rightcode"
|
||||
model = "gpt-5-codex"
|
||||
|
||||
[model_providers.rightcode]
|
||||
base_url = "https://rightcode.example/v1"
|
||||
wire_api = "responses"
|
||||
experimental_bearer_token = "sk-rightcode"
|
||||
"#;
|
||||
let config_json = serde_json::json!({
|
||||
"auth": {},
|
||||
"config": config_toml,
|
||||
})
|
||||
.to_string();
|
||||
let config_b64 = BASE64_STANDARD.encode(config_json.as_bytes());
|
||||
|
||||
let request = DeepLinkImportRequest {
|
||||
version: "v1".to_string(),
|
||||
resource: "provider".to_string(),
|
||||
app: Some("codex".to_string()),
|
||||
name: Some("RightCode".to_string()),
|
||||
config: Some(config_b64),
|
||||
config_format: Some("json".to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let merged = parse_and_merge_config(&request).unwrap();
|
||||
|
||||
assert_eq!(merged.api_key, Some("sk-rightcode".to_string()));
|
||||
assert_eq!(
|
||||
merged.endpoint,
|
||||
Some("https://rightcode.example/v1".to_string())
|
||||
);
|
||||
assert_eq!(
|
||||
merged.homepage,
|
||||
Some("https://rightcode.example".to_string())
|
||||
);
|
||||
assert_eq!(merged.model, Some("gpt-5-codex".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_and_merge_config_url_override() {
|
||||
let config_json = r#"{"env":{"ANTHROPIC_AUTH_TOKEN":"sk-old","ANTHROPIC_BASE_URL":"https://api.anthropic.com/v1"}}"#;
|
||||
|
||||
Reference in New Issue
Block a user