fix(providers): refresh credentials after auth save
Stop treating Provider.env length as credentials, refetch provider sources after OAuth/API key writes, and respect an explicit auth-panel Hide so OAuth-only providers do not stick on a stale "Credentials missing" / empty-models state after a successful login. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
committed by
herjarsa
co-authored by
Serhii Dziupin
parent
6950e113f4
commit
82bb814af7
@@ -4,8 +4,11 @@ import {
|
||||
getOAuthAuthMethods,
|
||||
normalizeAuthType,
|
||||
parseAuthPayload,
|
||||
requiresOpenCodeRestartAfterOAuth,
|
||||
requiresOpenCodeRestartAfterOAuth,
|
||||
providerHasCredentials,
|
||||
shouldAutoOpenAuthPanel,
|
||||
shouldShowApiKeyAuth,
|
||||
shouldShowModelsSection,
|
||||
} from './providerAuth';
|
||||
|
||||
describe('ProvidersPage available provider loading', () => {
|
||||
@@ -72,3 +75,106 @@ describe('provider auth method helpers', () => {
|
||||
expect(requiresOpenCodeRestartAfterOAuth('github-copilot')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('provider credential state helpers', () => {
|
||||
test('providerHasCredentials ignores declared env names and requires key or auth source', () => {
|
||||
// Built-in catalog entry with env var names but no actual credential.
|
||||
expect(providerHasCredentials({ key: undefined, authSourceExists: false })).toBe(false);
|
||||
expect(providerHasCredentials({ key: '', authSourceExists: false })).toBe(false);
|
||||
expect(providerHasCredentials({ key: ' ', authSourceExists: false })).toBe(false);
|
||||
|
||||
// OpenCode reports an active credential via provider.key.
|
||||
expect(providerHasCredentials({ key: 'sk-...', authSourceExists: false })).toBe(true);
|
||||
// Auth.json provenance alone is enough while sources are authoritative.
|
||||
expect(providerHasCredentials({ key: undefined, authSourceExists: true })).toBe(true);
|
||||
});
|
||||
|
||||
test('env-less OAuth-only provider without credentials opens panel and hides models', () => {
|
||||
const hasCredentials = providerHasCredentials({
|
||||
key: undefined,
|
||||
authSourceExists: false,
|
||||
});
|
||||
expect(hasCredentials).toBe(false);
|
||||
expect(shouldAutoOpenAuthPanel({
|
||||
sourcesLoaded: true,
|
||||
hasCredentials,
|
||||
userDismissed: false,
|
||||
})).toBe(true);
|
||||
expect(shouldShowModelsSection({
|
||||
modelCount: 1,
|
||||
sourcesLoaded: true,
|
||||
hasCredentials,
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
test('provider with stored auth or key shows Connected and models', () => {
|
||||
const fromKey = providerHasCredentials({ key: 'sk-live', authSourceExists: false });
|
||||
const fromAuth = providerHasCredentials({ key: undefined, authSourceExists: true });
|
||||
expect(fromKey).toBe(true);
|
||||
expect(fromAuth).toBe(true);
|
||||
expect(shouldAutoOpenAuthPanel({
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: fromKey,
|
||||
userDismissed: false,
|
||||
})).toBe(false);
|
||||
expect(shouldShowModelsSection({
|
||||
modelCount: 3,
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: fromAuth,
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
test('auth save followed by providers refresh recognizes credentials without stale missing state', () => {
|
||||
// Pre-save: sources say no auth, provider has no key yet.
|
||||
const before = providerHasCredentials({
|
||||
key: undefined,
|
||||
authSourceExists: false,
|
||||
});
|
||||
expect(before).toBe(false);
|
||||
expect(shouldShowModelsSection({
|
||||
modelCount: 2,
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: before,
|
||||
})).toBe(false);
|
||||
|
||||
// After reloadOpenCodeConfiguration, providers array gets a key even if the
|
||||
// sources snapshot has not been refetched yet.
|
||||
const afterProvidersRefresh = providerHasCredentials({
|
||||
key: 'oauth-token-present',
|
||||
authSourceExists: false,
|
||||
});
|
||||
expect(afterProvidersRefresh).toBe(true);
|
||||
expect(shouldAutoOpenAuthPanel({
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: afterProvidersRefresh,
|
||||
userDismissed: false,
|
||||
})).toBe(false);
|
||||
expect(shouldShowModelsSection({
|
||||
modelCount: 2,
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: afterProvidersRefresh,
|
||||
})).toBe(true);
|
||||
|
||||
// After sources refetch completes, auth.exists also becomes true.
|
||||
expect(providerHasCredentials({
|
||||
key: 'oauth-token-present',
|
||||
authSourceExists: true,
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
test('explicit hide keeps the auth panel closed while credentials are still missing', () => {
|
||||
expect(shouldAutoOpenAuthPanel({
|
||||
sourcesLoaded: true,
|
||||
hasCredentials: false,
|
||||
userDismissed: true,
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
test('models stay visible while sources are still loading', () => {
|
||||
expect(shouldShowModelsSection({
|
||||
modelCount: 4,
|
||||
sourcesLoaded: false,
|
||||
hasCredentials: false,
|
||||
})).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user