mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-26 02:04:37 +08:00
fix(ai): revalidate credentials when base URL changes in openai-compat mode
This commit is contained in:
1 parent
61380f53cc
commit
46204db9b8
3 files changed
+68
-2
No files matched your search
@@ -44,4 +44,52 @@ describe('canReuseExistingApiKey', () => {
|
||||
|
||||
assert.equal(result, false)
|
||||
})
|
||||
|
||||
it('requires a new key when base URL changes in openai-compat mode', () => {
|
||||
const result = canReuseExistingApiKey({
|
||||
mode: 'edit',
|
||||
existingApiKeySet: true,
|
||||
hasNewApiKey: false,
|
||||
originalProvider: 'openai-compatible',
|
||||
currentProvider: 'openai-compatible',
|
||||
originalConnectionMode: 'openai-compat',
|
||||
currentConnectionMode: 'openai-compat',
|
||||
originalBaseUrl: 'https://api.provider-a.com',
|
||||
currentBaseUrl: 'https://api.provider-b.com',
|
||||
})
|
||||
|
||||
assert.equal(result, false)
|
||||
})
|
||||
|
||||
it('allows reusing key when base URL is unchanged in openai-compat mode (trailing slash normalized)', () => {
|
||||
const result = canReuseExistingApiKey({
|
||||
mode: 'edit',
|
||||
existingApiKeySet: true,
|
||||
hasNewApiKey: false,
|
||||
originalProvider: 'openai-compatible',
|
||||
currentProvider: 'openai-compatible',
|
||||
originalConnectionMode: 'openai-compat',
|
||||
currentConnectionMode: 'openai-compat',
|
||||
originalBaseUrl: 'https://api.provider-a.com/',
|
||||
currentBaseUrl: 'https://api.provider-a.com',
|
||||
})
|
||||
|
||||
assert.equal(result, true)
|
||||
})
|
||||
|
||||
it('allows reusing key when base URL is unchanged in openai-compat mode', () => {
|
||||
const result = canReuseExistingApiKey({
|
||||
mode: 'edit',
|
||||
existingApiKeySet: true,
|
||||
hasNewApiKey: false,
|
||||
originalProvider: 'openai-compatible',
|
||||
currentProvider: 'openai-compatible',
|
||||
originalConnectionMode: 'openai-compat',
|
||||
currentConnectionMode: 'openai-compat',
|
||||
originalBaseUrl: 'https://api.provider-a.com',
|
||||
currentBaseUrl: 'https://api.provider-a.com',
|
||||
})
|
||||
|
||||
assert.equal(result, true)
|
||||
})
|
||||
})
|
||||
@@ -8,6 +8,10 @@ export interface ApiKeyReuseInput {
|
||||
currentProvider: string
|
||||
originalConnectionMode?: ConnectionMode
|
||||
currentConnectionMode: ConnectionMode
|
||||
/** Original base URL (for openai-compat mode endpoint change detection) */
|
||||
originalBaseUrl?: string
|
||||
/** Current base URL entered by the user */
|
||||
currentBaseUrl?: string
|
||||
}
|
||||
|
||||
export function getConnectionModeForConfig(config: {
|
||||
@@ -23,11 +27,21 @@ export function getConnectionModeForConfig(config: {
|
||||
}
|
||||
|
||||
export function canReuseExistingApiKey(input: ApiKeyReuseInput): boolean {
|
||||
return (
|
||||
const baseConditions =
|
||||
input.mode === 'edit' &&
|
||||
!!input.existingApiKeySet &&
|
||||
!input.hasNewApiKey &&
|
||||
input.originalProvider === input.currentProvider &&
|
||||
input.originalConnectionMode === input.currentConnectionMode
|
||||
)
|
||||
|
||||
if (!baseConditions) return false
|
||||
|
||||
// For openai-compat mode, a base URL change means a different endpoint/service,
|
||||
// so the existing credential must not be silently reused without re-validation.
|
||||
if (input.currentConnectionMode === 'openai-compat') {
|
||||
const normalizeUrl = (url?: string) => url?.trim().replace(/\/+$/, '') || ''
|
||||
return normalizeUrl(input.originalBaseUrl) === normalizeUrl(input.currentBaseUrl)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -174,6 +174,8 @@ export function useAIConfigForm(props: {
|
||||
currentProvider: provider,
|
||||
originalConnectionMode: props.config.value ? getConnectionModeForConfig(props.config.value) : undefined,
|
||||
currentConnectionMode: connectionMode.value,
|
||||
originalBaseUrl: props.config.value?.baseUrl,
|
||||
currentBaseUrl: baseUrl.trim() || undefined,
|
||||
})
|
||||
|
||||
if (isLocalMode.value) {
|
||||
@@ -709,6 +711,8 @@ export function useAIConfigForm(props: {
|
||||
currentProvider: formData.value.provider,
|
||||
originalConnectionMode: props.config.value ? getConnectionModeForConfig(props.config.value) : undefined,
|
||||
currentConnectionMode: connectionMode.value,
|
||||
originalBaseUrl: props.config.value?.baseUrl,
|
||||
currentBaseUrl: formData.value.baseUrl.trim() || undefined,
|
||||
})
|
||||
if (isEditWithExistingKey) {
|
||||
return doSave()
|
||||
|
||||
Reference in new issue
Block a user