feat: Add GEMINI_DEFAULT_AUTH_TYPE support (#4002)

This commit is contained in:
N. Taylor Mullen 2025-07-12 20:43:35 -07:00 committed by GitHub
parent 4442e893c3
commit 26a79fec25
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 199 additions and 25 deletions

View File

@ -18,6 +18,7 @@ describe('AuthDialog', () => {
beforeEach(() => { beforeEach(() => {
originalEnv = { ...process.env }; originalEnv = { ...process.env };
process.env.GEMINI_API_KEY = ''; process.env.GEMINI_API_KEY = '';
process.env.GEMINI_DEFAULT_AUTH_TYPE = '';
vi.clearAllMocks(); vi.clearAllMocks();
}); });
@ -59,28 +60,165 @@ describe('AuthDialog', () => {
); );
}); });
it('should detect GEMINI_API_KEY environment variable', () => { describe('GEMINI_API_KEY environment variable', () => {
process.env.GEMINI_API_KEY = 'foobar'; it('should detect GEMINI_API_KEY environment variable', () => {
process.env.GEMINI_API_KEY = 'foobar';
const settings: LoadedSettings = new LoadedSettings( const settings: LoadedSettings = new LoadedSettings(
{ {
settings: { settings: {
selectedAuthType: undefined, selectedAuthType: undefined,
},
path: '',
}, },
path: '', {
}, settings: {},
{ path: '',
settings: {}, },
path: '', [],
}, );
[],
);
const { lastFrame } = render( const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />, <AuthDialog onSelect={() => {}} settings={settings} />,
); );
expect(lastFrame()).toContain('Existing API key detected (GEMINI_API_KEY)'); expect(lastFrame()).toContain(
'Existing API key detected (GEMINI_API_KEY)',
);
});
it('should not show the GEMINI_API_KEY message if GEMINI_DEFAULT_AUTH_TYPE is set to something else', () => {
process.env.GEMINI_API_KEY = 'foobar';
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.LOGIN_WITH_GOOGLE;
const settings: LoadedSettings = new LoadedSettings(
{
settings: {
selectedAuthType: undefined,
},
path: '',
},
{
settings: {},
path: '',
},
[],
);
const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />,
);
expect(lastFrame()).not.toContain(
'Existing API key detected (GEMINI_API_KEY)',
);
});
it('should show the GEMINI_API_KEY message if GEMINI_DEFAULT_AUTH_TYPE is set to use api key', () => {
process.env.GEMINI_API_KEY = 'foobar';
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.USE_GEMINI;
const settings: LoadedSettings = new LoadedSettings(
{
settings: {
selectedAuthType: undefined,
},
path: '',
},
{
settings: {},
path: '',
},
[],
);
const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />,
);
expect(lastFrame()).toContain(
'Existing API key detected (GEMINI_API_KEY)',
);
});
});
describe('GEMINI_DEFAULT_AUTH_TYPE environment variable', () => {
it('should select the auth type specified by GEMINI_DEFAULT_AUTH_TYPE', () => {
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.LOGIN_WITH_GOOGLE;
const settings: LoadedSettings = new LoadedSettings(
{
settings: {
selectedAuthType: undefined,
},
path: '',
},
{
settings: {},
path: '',
},
[],
);
const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />,
);
// This is a bit brittle, but it's the best way to check which item is selected.
expect(lastFrame()).toContain('● Login with Google');
});
it('should fall back to default if GEMINI_DEFAULT_AUTH_TYPE is not set', () => {
const settings: LoadedSettings = new LoadedSettings(
{
settings: {
selectedAuthType: undefined,
},
path: '',
},
{
settings: {},
path: '',
},
[],
);
const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />,
);
// Default is LOGIN_WITH_GOOGLE
expect(lastFrame()).toContain('● Login with Google');
});
it('should show an error and fall back to default if GEMINI_DEFAULT_AUTH_TYPE is invalid', () => {
process.env.GEMINI_DEFAULT_AUTH_TYPE = 'invalid-auth-type';
const settings: LoadedSettings = new LoadedSettings(
{
settings: {
selectedAuthType: undefined,
},
path: '',
},
{
settings: {},
path: '',
},
[],
);
const { lastFrame } = render(
<AuthDialog onSelect={() => {}} settings={settings} />,
);
expect(lastFrame()).toContain(
'Invalid value for GEMINI_DEFAULT_AUTH_TYPE: "invalid-auth-type"',
);
// Default is LOGIN_WITH_GOOGLE
expect(lastFrame()).toContain('● Login with Google');
});
}); });
it('should prevent exiting when no auth method is selected and show error message', async () => { it('should prevent exiting when no auth method is selected and show error message', async () => {

View File

@ -18,18 +18,47 @@ interface AuthDialogProps {
initialErrorMessage?: string | null; initialErrorMessage?: string | null;
} }
function parseDefaultAuthType(
defaultAuthType: string | undefined,
): AuthType | null {
if (
defaultAuthType &&
Object.values(AuthType).includes(defaultAuthType as AuthType)
) {
return defaultAuthType as AuthType;
}
return null;
}
export function AuthDialog({ export function AuthDialog({
onSelect, onSelect,
settings, settings,
initialErrorMessage, initialErrorMessage,
}: AuthDialogProps): React.JSX.Element { }: AuthDialogProps): React.JSX.Element {
const [errorMessage, setErrorMessage] = useState<string | null>( const [errorMessage, setErrorMessage] = useState<string | null>(() => {
initialErrorMessage if (initialErrorMessage) {
? initialErrorMessage return initialErrorMessage;
: process.env.GEMINI_API_KEY }
? 'Existing API key detected (GEMINI_API_KEY). Select "Gemini API Key" option to use it.'
: null, const defaultAuthType = parseDefaultAuthType(
); process.env.GEMINI_DEFAULT_AUTH_TYPE,
);
if (process.env.GEMINI_DEFAULT_AUTH_TYPE && defaultAuthType === null) {
return (
`Invalid value for GEMINI_DEFAULT_AUTH_TYPE: "${process.env.GEMINI_DEFAULT_AUTH_TYPE}". ` +
`Valid values are: ${Object.values(AuthType).join(', ')}.`
);
}
if (
process.env.GEMINI_API_KEY &&
(!defaultAuthType || defaultAuthType === AuthType.USE_GEMINI)
) {
return 'Existing API key detected (GEMINI_API_KEY). Select "Gemini API Key" option to use it.';
}
return null;
});
const items = [ const items = [
{ {
label: 'Login with Google', label: 'Login with Google',
@ -55,6 +84,13 @@ export function AuthDialog({
return item.value === settings.merged.selectedAuthType; return item.value === settings.merged.selectedAuthType;
} }
const defaultAuthType = parseDefaultAuthType(
process.env.GEMINI_DEFAULT_AUTH_TYPE,
);
if (defaultAuthType) {
return item.value === defaultAuthType;
}
if (process.env.GEMINI_API_KEY) { if (process.env.GEMINI_API_KEY) {
return item.value === AuthType.USE_GEMINI; return item.value === AuthType.USE_GEMINI;
} }