summaryrefslogtreecommitdiff
path: root/packages/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/core/src')
-rw-r--r--packages/core/src/code_assist/oauth2.test.ts64
-rw-r--r--packages/core/src/code_assist/oauth2.ts37
2 files changed, 85 insertions, 16 deletions
diff --git a/packages/core/src/code_assist/oauth2.test.ts b/packages/core/src/code_assist/oauth2.test.ts
index 821788d5..25718cb1 100644
--- a/packages/core/src/code_assist/oauth2.test.ts
+++ b/packages/core/src/code_assist/oauth2.test.ts
@@ -324,6 +324,70 @@ describe('oauth2', () => {
});
});
+ describe('credential loading order', () => {
+ it('should prioritize default cached credentials over GOOGLE_APPLICATION_CREDENTIALS', async () => {
+ // Setup default cached credentials
+ const defaultCreds = { refresh_token: 'default-cached-token' };
+ const defaultCredsPath = path.join(
+ tempHomeDir,
+ '.gemini',
+ 'oauth_creds.json',
+ );
+ await fs.promises.mkdir(path.dirname(defaultCredsPath), {
+ recursive: true,
+ });
+ await fs.promises.writeFile(
+ defaultCredsPath,
+ JSON.stringify(defaultCreds),
+ );
+
+ // Setup credentials via environment variable
+ const envCreds = { refresh_token: 'env-var-token' };
+ const envCredsPath = path.join(tempHomeDir, 'env_creds.json');
+ await fs.promises.writeFile(envCredsPath, JSON.stringify(envCreds));
+ vi.stubEnv('GOOGLE_APPLICATION_CREDENTIALS', envCredsPath);
+
+ const mockClient = {
+ setCredentials: vi.fn(),
+ getAccessToken: vi.fn().mockResolvedValue({ token: 'test-token' }),
+ getTokenInfo: vi.fn().mockResolvedValue({}),
+ on: vi.fn(),
+ };
+ (OAuth2Client as unknown as Mock).mockImplementation(
+ () => mockClient as unknown as OAuth2Client,
+ );
+
+ await getOauthClient(AuthType.LOGIN_WITH_GOOGLE, mockConfig);
+
+ // Assert the correct credentials were used
+ expect(mockClient.setCredentials).toHaveBeenCalledWith(defaultCreds);
+ expect(mockClient.setCredentials).not.toHaveBeenCalledWith(envCreds);
+ });
+
+ it('should fall back to GOOGLE_APPLICATION_CREDENTIALS if default cache is missing', async () => {
+ // Setup credentials via environment variable
+ const envCreds = { refresh_token: 'env-var-token' };
+ const envCredsPath = path.join(tempHomeDir, 'env_creds.json');
+ await fs.promises.writeFile(envCredsPath, JSON.stringify(envCreds));
+ vi.stubEnv('GOOGLE_APPLICATION_CREDENTIALS', envCredsPath);
+
+ const mockClient = {
+ setCredentials: vi.fn(),
+ getAccessToken: vi.fn().mockResolvedValue({ token: 'test-token' }),
+ getTokenInfo: vi.fn().mockResolvedValue({}),
+ on: vi.fn(),
+ };
+ (OAuth2Client as unknown as Mock).mockImplementation(
+ () => mockClient as unknown as OAuth2Client,
+ );
+
+ await getOauthClient(AuthType.LOGIN_WITH_GOOGLE, mockConfig);
+
+ // Assert the correct credentials were used
+ expect(mockClient.setCredentials).toHaveBeenCalledWith(envCreds);
+ });
+ });
+
describe('with GCP environment variables', () => {
it('should use GOOGLE_CLOUD_ACCESS_TOKEN when GOOGLE_GENAI_USE_GCA is true', async () => {
vi.stubEnv('GOOGLE_GENAI_USE_GCA', 'true');
diff --git a/packages/core/src/code_assist/oauth2.ts b/packages/core/src/code_assist/oauth2.ts
index a4dcf8a7..f479dd1b 100644
--- a/packages/core/src/code_assist/oauth2.ts
+++ b/packages/core/src/code_assist/oauth2.ts
@@ -351,27 +351,32 @@ export function getAvailablePort(): Promise<number> {
}
async function loadCachedCredentials(client: OAuth2Client): Promise<boolean> {
- try {
- const keyFile =
- process.env['GOOGLE_APPLICATION_CREDENTIALS'] ||
- getCachedCredentialPath();
+ const pathsToTry = [
+ getCachedCredentialPath(),
+ process.env['GOOGLE_APPLICATION_CREDENTIALS'],
+ ].filter((p): p is string => !!p);
- const creds = await fs.readFile(keyFile, 'utf-8');
- client.setCredentials(JSON.parse(creds));
+ for (const keyFile of pathsToTry) {
+ try {
+ const creds = await fs.readFile(keyFile, 'utf-8');
+ client.setCredentials(JSON.parse(creds));
- // This will verify locally that the credentials look good.
- const { token } = await client.getAccessToken();
- if (!token) {
- return false;
- }
+ // This will verify locally that the credentials look good.
+ const { token } = await client.getAccessToken();
+ if (!token) {
+ continue;
+ }
- // This will check with the server to see if it hasn't been revoked.
- await client.getTokenInfo(token);
+ // This will check with the server to see if it hasn't been revoked.
+ await client.getTokenInfo(token);
- return true;
- } catch (_) {
- return false;
+ return true;
+ } catch (_) {
+ // Ignore and try next path.
+ }
}
+
+ return false;
}
async function cacheCredentials(credentials: Credentials) {