mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
fix(proxy): preserve Codex OAuth auth token on takeover (#3789)
* fix(proxy): preserve Codex OAuth auth token on takeover * style(proxy): format Codex OAuth takeover fix * fix(proxy): unconditionally inject AUTH_TOKEN placeholder for codex takeover The preserve-if-exists condition left #3784 unfixed on three paths: hot-switch passes the provider's settings (presets carry no ANTHROPIC_AUTH_TOKEN key), fresh installs never had the key, and live configs already stripped by older releases stay stripped. - Fold the bool parameter into the policy enum as ManagedAccount { keep_auth_token } so every construction site declares intent - Decide via !is_github_copilot() within the managed branch so URL-only codex providers (no provider_type meta) are covered, matching the predicate family used for policy selection - Inject the placeholder unconditionally instead of only when the key pre-exists; Copilot behavior is unchanged (API_KEY only) - Pin the previously uncovered cases with tests: codex without a pre-existing key, URL-only codex, and Copilot removing a stale AUTH_TOKEN --------- Co-authored-by: codeasier <liuyekang@huawei.com> Co-authored-by: Jason <farion1231@gmail.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
d70e3828fe
commit
2d64d8c619
@@ -48,7 +48,7 @@ const CLAUDE_ONE_M_MARKER_FOR_CLIENT: &str = "[1M]";
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ClaudeTakeoverAuthPolicy {
|
||||
PreserveExistingOrAuthToken,
|
||||
ManagedAccount,
|
||||
ManagedAccount { keep_auth_token: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -90,7 +90,12 @@ impl ProxyService {
|
||||
provider: &Provider,
|
||||
) {
|
||||
let auth_policy = if provider.uses_managed_account_auth() {
|
||||
ClaudeTakeoverAuthPolicy::ManagedAccount
|
||||
// Codex 系(含仅凭 base_url 识别、无 provider_type meta 的)必须保留
|
||||
// ANTHROPIC_AUTH_TOKEN 占位符:Claude Code 缺该键会弹登录提示(#3784)。
|
||||
// Copilot 维持仅 API_KEY 占位,避免与 /login 管理的 key 冲突(#1049)。
|
||||
ClaudeTakeoverAuthPolicy::ManagedAccount {
|
||||
keep_auth_token: !provider.is_github_copilot(),
|
||||
}
|
||||
} else {
|
||||
ClaudeTakeoverAuthPolicy::PreserveExistingOrAuthToken
|
||||
};
|
||||
@@ -180,7 +185,7 @@ impl ProxyService {
|
||||
);
|
||||
}
|
||||
}
|
||||
ClaudeTakeoverAuthPolicy::ManagedAccount => {
|
||||
ClaudeTakeoverAuthPolicy::ManagedAccount { keep_auth_token } => {
|
||||
for key in token_keys {
|
||||
env.remove(key);
|
||||
}
|
||||
@@ -188,6 +193,14 @@ impl ProxyService {
|
||||
"ANTHROPIC_API_KEY".to_string(),
|
||||
json!(PROXY_TOKEN_PLACEHOLDER),
|
||||
);
|
||||
if keep_auth_token {
|
||||
// 无条件注入而非"已存在才保留":热切换路径传入的是 provider
|
||||
// settings(预设不含该键),且旧版接管已把存量用户 live 中的键删光。
|
||||
env.insert(
|
||||
"ANTHROPIC_AUTH_TOKEN".to_string(),
|
||||
json!(PROXY_TOKEN_PLACEHOLDER),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2945,6 +2958,108 @@ mod tests {
|
||||
assert_env_str(env, "ANTHROPIC_DEFAULT_OPUS_MODEL", Some("claude-opus-4-8"));
|
||||
assert_env_str(env, "ANTHROPIC_DEFAULT_OPUS_MODEL_NAME", Some("gpt-5.4"));
|
||||
assert_env_str(env, "ANTHROPIC_API_KEY", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
assert_env_str(env, "ANTHROPIC_AUTH_TOKEN", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn managed_account_claude_takeover_codex_injects_auth_token_without_preexisting_key() {
|
||||
let mut provider = Provider::with_id(
|
||||
"codex".to_string(),
|
||||
"Codex".to_string(),
|
||||
json!({
|
||||
"env": {
|
||||
"ANTHROPIC_BASE_URL": "https://chatgpt.com/backend-api/codex"
|
||||
}
|
||||
}),
|
||||
None,
|
||||
);
|
||||
provider.meta = Some(ProviderMeta {
|
||||
provider_type: Some("codex_oauth".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// 全新安装/热切换形态:传入的 env 没有任何 token 键。
|
||||
let mut live_config = provider.settings_config.clone();
|
||||
ProxyService::apply_claude_takeover_fields_for_provider(
|
||||
&mut live_config,
|
||||
"http://127.0.0.1:15721",
|
||||
&provider,
|
||||
);
|
||||
|
||||
let env = live_config
|
||||
.get("env")
|
||||
.and_then(|value| value.as_object())
|
||||
.expect("env should exist");
|
||||
assert_env_str(env, "ANTHROPIC_API_KEY", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
assert_env_str(env, "ANTHROPIC_AUTH_TOKEN", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn managed_account_claude_takeover_codex_by_base_url_keeps_auth_token() {
|
||||
// 无 provider_type meta、仅凭 base_url 识别为受管 codex 的供应商,
|
||||
// 也必须保留 AUTH_TOKEN 占位符(与策略选择共用同一判定族)。
|
||||
let provider = Provider::with_id(
|
||||
"codex-url-only".to_string(),
|
||||
"Codex (URL only)".to_string(),
|
||||
json!({
|
||||
"env": {
|
||||
"ANTHROPIC_BASE_URL": "https://chatgpt.com/backend-api/codex"
|
||||
}
|
||||
}),
|
||||
None,
|
||||
);
|
||||
assert!(provider.uses_managed_account_auth());
|
||||
assert!(!provider.is_codex_oauth());
|
||||
|
||||
let mut live_config = provider.settings_config.clone();
|
||||
ProxyService::apply_claude_takeover_fields_for_provider(
|
||||
&mut live_config,
|
||||
"http://127.0.0.1:15721",
|
||||
&provider,
|
||||
);
|
||||
|
||||
let env = live_config
|
||||
.get("env")
|
||||
.and_then(|value| value.as_object())
|
||||
.expect("env should exist");
|
||||
assert_env_str(env, "ANTHROPIC_API_KEY", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
assert_env_str(env, "ANTHROPIC_AUTH_TOKEN", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn managed_account_claude_takeover_copilot_removes_stale_auth_token() {
|
||||
let mut provider = Provider::with_id(
|
||||
"copilot".to_string(),
|
||||
"GitHub Copilot".to_string(),
|
||||
json!({
|
||||
"env": {
|
||||
"ANTHROPIC_BASE_URL": "https://api.githubcopilot.com"
|
||||
}
|
||||
}),
|
||||
None,
|
||||
);
|
||||
provider.meta = Some(ProviderMeta {
|
||||
provider_type: Some("github_copilot".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let mut live_config = json!({
|
||||
"env": {
|
||||
"ANTHROPIC_BASE_URL": "https://stale.example.com",
|
||||
"ANTHROPIC_AUTH_TOKEN": "stale-token"
|
||||
}
|
||||
});
|
||||
ProxyService::apply_claude_takeover_fields_for_provider(
|
||||
&mut live_config,
|
||||
"http://127.0.0.1:15721",
|
||||
&provider,
|
||||
);
|
||||
|
||||
let env = live_config
|
||||
.get("env")
|
||||
.and_then(|value| value.as_object())
|
||||
.expect("env should exist");
|
||||
assert_env_str(env, "ANTHROPIC_API_KEY", Some(PROXY_TOKEN_PLACEHOLDER));
|
||||
assert_env_str(env, "ANTHROPIC_AUTH_TOKEN", None);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user