fix: skip auth requirement for config-defined custom providers

Shows the auth panel only when provider credentials are actually required
Keeps custom providers defined in config from being treated as incomplete
Adds coverage for the new provider auth check
This commit is contained in:
Bohdan Triapitsyn
2026-08-19 10:24:35 +03:00
parent ef2afdc759
commit 13a45aa5a5
3 changed files with 24 additions and 5 deletions
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'bun:test';
import { shouldLoadAvailableProviders } from './providerAvailability';
import { requiresProviderAuth, shouldLoadAvailableProviders } from './providerAvailability';
import {
getOAuthAuthMethods,
normalizeAuthType,
@@ -15,6 +15,14 @@ describe('ProvidersPage available provider loading', () => {
});
});
describe('ProvidersPage provider authentication', () => {
test('does not require credentials for a custom provider defined in config', () => {
expect(requiresProviderAuth(true, false, true)).toBe(false);
expect(requiresProviderAuth(true, false, false)).toBe(true);
expect(requiresProviderAuth(true, true, false)).toBe(false);
});
});
describe('provider auth method helpers', () => {
test('normalizeAuthType recognizes oauth and api labels', () => {
expect(normalizeAuthType({ type: 'oauth', label: 'Login with Cursor' })).toBe('oauth');
@@ -23,7 +23,7 @@ import type { ModelMetadata } from '@/types';
import { getCurrentIntlLocale, useI18n } from '@/lib/i18n';
import { runtimeFetch } from '@/lib/runtime-fetch';
import { opencodeClient } from '@/lib/opencode/client';
import { shouldLoadAvailableProviders } from './providerAvailability';
import { requiresProviderAuth, shouldLoadAvailableProviders } from './providerAvailability';
import {
getOAuthAuthMethods,
parseAuthPayload,
@@ -324,7 +324,8 @@ export const ProvidersPage: React.FC = () => {
? provider.env.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0)
: [];
const hasCreds = Boolean(sources.auth.exists) || envEntries.length > 0;
if (!hasCreds) {
const isCustomProvider = Boolean(provider && isConfigDefinedCustomProvider(provider, sources));
if (requiresProviderAuth(true, hasCreds, isCustomProvider)) {
setShowAuthPanel(true);
}
}, [selectedProviderId, providerSources, providers]);
@@ -773,8 +774,12 @@ export const ProvidersPage: React.FC = () => {
const hasStoredAuth = Boolean(selectedSources?.auth.exists);
const hasEnvCredentials = providerEnv.length > 0;
const hasCredentials = hasStoredAuth || hasEnvCredentials;
const authStatusIncomplete = sourcesLoaded && !hasCredentials;
const showModelsSection = providerModels.length > 0 && (!sourcesLoaded || hasCredentials);
const authStatusIncomplete = requiresProviderAuth(
sourcesLoaded,
hasCredentials,
isEditableCustomProvider,
);
const showModelsSection = providerModels.length > 0 && !authStatusIncomplete;
const incompleteAuthHint = !showApiKeyAuth && oauthAuthMethods.length > 0
? t('settings.providers.page.auth.useReconnectHint')
: t('settings.providers.page.auth.incompleteHint');
@@ -1 +1,7 @@
export const shouldLoadAvailableProviders = (isAddMode: boolean): boolean => isAddMode;
export const requiresProviderAuth = (
sourcesLoaded: boolean,
hasCredentials: boolean,
isConfigDefinedCustomProvider: boolean,
): boolean => sourcesLoaded && !hasCredentials && !isConfigDefinedCustomProvider;