diff options
| author | Gaurav <[email protected]> | 2025-07-11 10:57:35 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-11 17:57:35 +0000 |
| commit | 8f12e8a114546326ee5b39d6aae859da6d906d0b (patch) | |
| tree | 662576a2aa5d4854bb3cdfd467846787500a3e52 /packages/core/src/utils/user_account.ts | |
| parent | 93284281de4a1593de802f3823707b9c1a43171e (diff) | |
fix: clearcut logging (retry #3744) (#3751)
Diffstat (limited to 'packages/core/src/utils/user_account.ts')
| -rw-r--r-- | packages/core/src/utils/user_account.ts | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/packages/core/src/utils/user_account.ts b/packages/core/src/utils/user_account.ts new file mode 100644 index 00000000..6701dfe3 --- /dev/null +++ b/packages/core/src/utils/user_account.ts @@ -0,0 +1,115 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import path from 'node:path'; +import { promises as fsp, existsSync, readFileSync } from 'node:fs'; +import * as os from 'os'; +import { GEMINI_DIR, GOOGLE_ACCOUNTS_FILENAME } from './paths.js'; + +interface UserAccounts { + active: string | null; + old: string[]; +} + +function getGoogleAccountsCachePath(): string { + return path.join(os.homedir(), GEMINI_DIR, GOOGLE_ACCOUNTS_FILENAME); +} + +async function readAccounts(filePath: string): Promise<UserAccounts> { + try { + const content = await fsp.readFile(filePath, 'utf-8'); + if (!content.trim()) { + return { active: null, old: [] }; + } + return JSON.parse(content) as UserAccounts; + } catch (error) { + if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { + // File doesn't exist, which is fine. + return { active: null, old: [] }; + } + // File is corrupted or not valid JSON, start with a fresh object. + console.debug('Could not parse accounts file, starting fresh.', error); + return { active: null, old: [] }; + } +} + +export async function cacheGoogleAccount(email: string): Promise<void> { + const filePath = getGoogleAccountsCachePath(); + await fsp.mkdir(path.dirname(filePath), { recursive: true }); + + const accounts = await readAccounts(filePath); + + if (accounts.active && accounts.active !== email) { + if (!accounts.old.includes(accounts.active)) { + accounts.old.push(accounts.active); + } + } + + // If the new email was in the old list, remove it + accounts.old = accounts.old.filter((oldEmail) => oldEmail !== email); + + accounts.active = email; + await fsp.writeFile(filePath, JSON.stringify(accounts, null, 2), 'utf-8'); +} + +export function getCachedGoogleAccount(): string | null { + try { + const filePath = getGoogleAccountsCachePath(); + if (existsSync(filePath)) { + const content = readFileSync(filePath, 'utf-8').trim(); + if (!content) { + return null; + } + const accounts: UserAccounts = JSON.parse(content); + return accounts.active; + } + return null; + } catch (error) { + console.debug('Error reading cached Google Account:', error); + return null; + } +} + +export function getLifetimeGoogleAccounts(): number { + try { + const filePath = getGoogleAccountsCachePath(); + if (!existsSync(filePath)) { + return 0; + } + + const content = readFileSync(filePath, 'utf-8').trim(); + if (!content) { + return 0; + } + const accounts: UserAccounts = JSON.parse(content); + let count = accounts.old.length; + if (accounts.active) { + count++; + } + return count; + } catch (error) { + console.debug('Error reading lifetime Google Accounts:', error); + return 0; + } +} + +export async function clearCachedGoogleAccount(): Promise<void> { + const filePath = getGoogleAccountsCachePath(); + if (!existsSync(filePath)) { + return; + } + + const accounts = await readAccounts(filePath); + + if (accounts.active) { + if (!accounts.old.includes(accounts.active)) { + accounts.old.push(accounts.active); + } + accounts.active = null; + } + + await fsp.writeFile(filePath, JSON.stringify(accounts, null, 2), 'utf-8'); +} |
