mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-27 15:13:37 +08:00
Merge provider auth token env cleanup into main
The prior provider-auth fix stopped the SDK client from reading a local API key when ANTHROPIC_AUTH_TOKEN was present, but desktop settings layering can still populate ANTHROPIC_API_KEY before the client is created. This merge brings in the provider env cleanup that writes an explicit empty ANTHROPIC_API_KEY for bearer-token providers, so cc-haha managed settings override stale original settings and sidecar sessions do not send mixed auth headers. Constraint: Main already contained the first provider-auth merge, so this merge only carries the follow-up env cleanup delta Rejected: Rebuild only without a code merge | packaged sidecar verification depends on the provider runtime env change being in main Confidence: high Scope-risk: moderate Directive: Do not remove the empty ANTHROPIC_API_KEY override from auth_token providers without re-running sidecar header capture against stale original settings Tested: bun run check:server Tested: desktop/scripts/build-macos-arm64.sh Tested: Packaged sidecar proxy capture with stale original API key showed Authorization=true and x-api-key=false Tested: PackyCodex2ccCustom and 胜算云 packaged-sidecar live calls returned ok Not-tested: Full manual UI click-through in the rebuilt macOS app window
This commit is contained in:
commit
984967a60e
@ -8,6 +8,7 @@ import { ProviderService } from '../services/providerService.js'
|
|||||||
describe('ConversationService', () => {
|
describe('ConversationService', () => {
|
||||||
let tmpDir: string
|
let tmpDir: string
|
||||||
let originalConfigDir: string | undefined
|
let originalConfigDir: string | undefined
|
||||||
|
let originalApiKey: string | undefined
|
||||||
let originalAuthToken: string | undefined
|
let originalAuthToken: string | undefined
|
||||||
let originalBaseUrl: string | undefined
|
let originalBaseUrl: string | undefined
|
||||||
let originalModel: string | undefined
|
let originalModel: string | undefined
|
||||||
@ -19,6 +20,7 @@ describe('ConversationService', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'cc-haha-conversation-service-'))
|
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'cc-haha-conversation-service-'))
|
||||||
originalConfigDir = process.env.CLAUDE_CONFIG_DIR
|
originalConfigDir = process.env.CLAUDE_CONFIG_DIR
|
||||||
|
originalApiKey = process.env.ANTHROPIC_API_KEY
|
||||||
originalAuthToken = process.env.ANTHROPIC_AUTH_TOKEN
|
originalAuthToken = process.env.ANTHROPIC_AUTH_TOKEN
|
||||||
originalBaseUrl = process.env.ANTHROPIC_BASE_URL
|
originalBaseUrl = process.env.ANTHROPIC_BASE_URL
|
||||||
originalModel = process.env.ANTHROPIC_MODEL
|
originalModel = process.env.ANTHROPIC_MODEL
|
||||||
@ -28,6 +30,7 @@ describe('ConversationService', () => {
|
|||||||
originalDiagnosticsFile = process.env.CLAUDE_CODE_DIAGNOSTICS_FILE
|
originalDiagnosticsFile = process.env.CLAUDE_CODE_DIAGNOSTICS_FILE
|
||||||
|
|
||||||
process.env.CLAUDE_CONFIG_DIR = tmpDir
|
process.env.CLAUDE_CONFIG_DIR = tmpDir
|
||||||
|
process.env.ANTHROPIC_API_KEY = 'stale-parent-api-key'
|
||||||
process.env.ANTHROPIC_AUTH_TOKEN = 'test-token'
|
process.env.ANTHROPIC_AUTH_TOKEN = 'test-token'
|
||||||
process.env.ANTHROPIC_BASE_URL = 'https://example.invalid/anthropic'
|
process.env.ANTHROPIC_BASE_URL = 'https://example.invalid/anthropic'
|
||||||
process.env.ANTHROPIC_MODEL = 'test-model'
|
process.env.ANTHROPIC_MODEL = 'test-model'
|
||||||
@ -43,6 +46,9 @@ describe('ConversationService', () => {
|
|||||||
if (originalConfigDir === undefined) delete process.env.CLAUDE_CONFIG_DIR
|
if (originalConfigDir === undefined) delete process.env.CLAUDE_CONFIG_DIR
|
||||||
else process.env.CLAUDE_CONFIG_DIR = originalConfigDir
|
else process.env.CLAUDE_CONFIG_DIR = originalConfigDir
|
||||||
|
|
||||||
|
if (originalApiKey === undefined) delete process.env.ANTHROPIC_API_KEY
|
||||||
|
else process.env.ANTHROPIC_API_KEY = originalApiKey
|
||||||
|
|
||||||
if (originalAuthToken === undefined) delete process.env.ANTHROPIC_AUTH_TOKEN
|
if (originalAuthToken === undefined) delete process.env.ANTHROPIC_AUTH_TOKEN
|
||||||
else process.env.ANTHROPIC_AUTH_TOKEN = originalAuthToken
|
else process.env.ANTHROPIC_AUTH_TOKEN = originalAuthToken
|
||||||
|
|
||||||
@ -199,7 +205,7 @@ describe('ConversationService', () => {
|
|||||||
expect(env.ANTHROPIC_MODEL).toBe('new-provider-sonnet')
|
expect(env.ANTHROPIC_MODEL).toBe('new-provider-sonnet')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('buildChildEnv preserves provider capability overrides from presets', async () => {
|
test('buildChildEnv clears stale api key for bearer-token providers', async () => {
|
||||||
const providerService = new ProviderService()
|
const providerService = new ProviderService()
|
||||||
const provider = await providerService.addProvider({
|
const provider = await providerService.addProvider({
|
||||||
presetId: 'jiekouai',
|
presetId: 'jiekouai',
|
||||||
@ -223,7 +229,7 @@ describe('ConversationService', () => {
|
|||||||
|
|
||||||
expect(env.ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
expect(env.ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
||||||
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('provider-key')
|
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('provider-key')
|
||||||
expect(env.ANTHROPIC_API_KEY).toBeUndefined()
|
expect(env.ANTHROPIC_API_KEY).toBe('')
|
||||||
expect(env.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6')
|
expect(env.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6')
|
||||||
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES).toBe('none')
|
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL_SUPPORTED_CAPABILITIES).toBe('none')
|
||||||
})
|
})
|
||||||
|
|||||||
@ -67,7 +67,7 @@ describe('Real Provider Configs', () => {
|
|||||||
const settings = await readCcHahaSettings()
|
const settings = await readCcHahaSettings()
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.minimaxi.com/anthropic')
|
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.minimaxi.com/anthropic')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-fake-test-key-for-testing-only')
|
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-fake-test-key-for-testing-only')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBeUndefined()
|
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBe('')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_MODEL).toBe('MiniMax-M2.7-highspeed')
|
expect((settings.env as Record<string, string>).ANTHROPIC_MODEL).toBe('MiniMax-M2.7-highspeed')
|
||||||
expect(JSON.parse((settings.env as Record<string, string>).CLAUDE_CODE_MODEL_CONTEXT_WINDOWS)).toMatchObject({
|
expect(JSON.parse((settings.env as Record<string, string>).CLAUDE_CODE_MODEL_CONTEXT_WINDOWS)).toMatchObject({
|
||||||
'MiniMax-M2.7': 204800,
|
'MiniMax-M2.7': 204800,
|
||||||
@ -116,7 +116,7 @@ describe('Real Provider Configs', () => {
|
|||||||
settings = await readCcHahaSettings()
|
settings = await readCcHahaSettings()
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-fake-test-key-for-testing-only')
|
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-fake-test-key-for-testing-only')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBeUndefined()
|
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBe('')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_MODEL).toBe('claude-opus-4-7')
|
expect((settings.env as Record<string, string>).ANTHROPIC_MODEL).toBe('claude-opus-4-7')
|
||||||
expect((settings.env as Record<string, string>).CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBeUndefined()
|
expect((settings.env as Record<string, string>).CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBeUndefined()
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ describe('Real Provider Configs', () => {
|
|||||||
// 验证新字段写入
|
// 验证新字段写入
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
expect((settings.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.jiekou.ai/anthropic')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk_test')
|
expect((settings.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk_test')
|
||||||
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBeUndefined()
|
expect((settings.env as Record<string, string>).ANTHROPIC_API_KEY).toBe('')
|
||||||
|
|
||||||
// 验证已有字段保留
|
// 验证已有字段保留
|
||||||
expect(settings.customField).toBe('should_be_preserved')
|
expect(settings.customField).toBe('should_be_preserved')
|
||||||
@ -252,7 +252,7 @@ describe('Real Provider Configs', () => {
|
|||||||
const haha = await readCcHahaSettings()
|
const haha = await readCcHahaSettings()
|
||||||
expect((haha.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.minimaxi.com/anthropic')
|
expect((haha.env as Record<string, string>).ANTHROPIC_BASE_URL).toBe('https://api.minimaxi.com/anthropic')
|
||||||
expect((haha.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-haha-key')
|
expect((haha.env as Record<string, string>).ANTHROPIC_AUTH_TOKEN).toBe('sk-haha-key')
|
||||||
expect((haha.env as Record<string, string>).ANTHROPIC_API_KEY).toBeUndefined()
|
expect((haha.env as Record<string, string>).ANTHROPIC_API_KEY).toBe('')
|
||||||
|
|
||||||
console.log('✅ 原版 settings.json 完好无损,Haha 配置独立存储')
|
console.log('✅ 原版 settings.json 完好无损,Haha 配置独立存储')
|
||||||
})
|
})
|
||||||
|
|||||||
@ -305,7 +305,7 @@ describe('ProviderService', () => {
|
|||||||
const env = settings.env as Record<string, string>
|
const env = settings.env as Record<string, string>
|
||||||
expect(env.ANTHROPIC_BASE_URL).toBe('https://new-api.example.com')
|
expect(env.ANTHROPIC_BASE_URL).toBe('https://new-api.example.com')
|
||||||
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-new-key')
|
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-new-key')
|
||||||
expect(env.ANTHROPIC_API_KEY).toBeUndefined()
|
expect(env.ANTHROPIC_API_KEY).toBe('')
|
||||||
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -445,7 +445,7 @@ describe('ProviderService', () => {
|
|||||||
const env = settings.env as Record<string, string>
|
const env = settings.env as Record<string, string>
|
||||||
expect(env.ANTHROPIC_BASE_URL).toBe('https://second-api.example.com')
|
expect(env.ANTHROPIC_BASE_URL).toBe('https://second-api.example.com')
|
||||||
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-second-key')
|
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-second-key')
|
||||||
expect(env.ANTHROPIC_API_KEY).toBeUndefined()
|
expect(env.ANTHROPIC_API_KEY).toBe('')
|
||||||
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
||||||
expect(env.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('model-haiku')
|
expect(env.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('model-haiku')
|
||||||
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('model-sonnet')
|
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('model-sonnet')
|
||||||
@ -963,7 +963,7 @@ describe('Providers API', () => {
|
|||||||
const env = settings.env as Record<string, string>
|
const env = settings.env as Record<string, string>
|
||||||
expect(env.ANTHROPIC_BASE_URL).toBe('https://second.example.com')
|
expect(env.ANTHROPIC_BASE_URL).toBe('https://second.example.com')
|
||||||
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-second')
|
expect(env.ANTHROPIC_AUTH_TOKEN).toBe('sk-second')
|
||||||
expect(env.ANTHROPIC_API_KEY).toBeUndefined()
|
expect(env.ANTHROPIC_API_KEY).toBe('')
|
||||||
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
expect(env.ANTHROPIC_MODEL).toBe('model-main')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -143,7 +143,10 @@ function buildProviderAuthEnv(
|
|||||||
case 'api_key':
|
case 'api_key':
|
||||||
return key ? { ANTHROPIC_API_KEY: key } : {}
|
return key ? { ANTHROPIC_API_KEY: key } : {}
|
||||||
case 'auth_token':
|
case 'auth_token':
|
||||||
return key ? { ANTHROPIC_AUTH_TOKEN: key } : {}
|
return {
|
||||||
|
ANTHROPIC_API_KEY: '',
|
||||||
|
...(key ? { ANTHROPIC_AUTH_TOKEN: key } : {}),
|
||||||
|
}
|
||||||
case 'auth_token_empty_api_key':
|
case 'auth_token_empty_api_key':
|
||||||
return {
|
return {
|
||||||
ANTHROPIC_API_KEY: '',
|
ANTHROPIC_API_KEY: '',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user