()
| 449 | * @returns Whether or not the oauth account info was populated. |
| 450 | */ |
| 451 | export async function populateOAuthAccountInfoIfNeeded(): Promise<boolean> { |
| 452 | // Check env vars first (synchronous, no network call needed). |
| 453 | // SDK callers like Cowork can provide account info directly, which also |
| 454 | // eliminates the race condition where early telemetry events lack account info. |
| 455 | // NB: If/when adding additional SDK-relevant functionality requiring _other_ OAuth account properties, |
| 456 | // please reach out to #proj-cowork so the team can add additional env var fallbacks. |
| 457 | const envAccountUuid = process.env.CLAUDE_CODE_ACCOUNT_UUID |
| 458 | const envUserEmail = process.env.CLAUDE_CODE_USER_EMAIL |
| 459 | const envOrganizationUuid = process.env.CLAUDE_CODE_ORGANIZATION_UUID |
| 460 | const hasEnvVars = Boolean( |
| 461 | envAccountUuid && envUserEmail && envOrganizationUuid, |
| 462 | ) |
| 463 | if (envAccountUuid && envUserEmail && envOrganizationUuid) { |
| 464 | if (!getGlobalConfig().oauthAccount) { |
| 465 | storeOAuthAccountInfo({ |
| 466 | accountUuid: envAccountUuid, |
| 467 | emailAddress: envUserEmail, |
| 468 | organizationUuid: envOrganizationUuid, |
| 469 | }) |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | // Wait for any in-flight token refresh to complete first, since |
| 474 | // refreshOAuthToken already fetches and stores profile info |
| 475 | await checkAndRefreshOAuthTokenIfNeeded() |
| 476 | |
| 477 | const config = getGlobalConfig() |
| 478 | if ( |
| 479 | (config.oauthAccount && |
| 480 | config.oauthAccount.billingType !== undefined && |
| 481 | config.oauthAccount.accountCreatedAt !== undefined && |
| 482 | config.oauthAccount.subscriptionCreatedAt !== undefined) || |
| 483 | !isClaudeAISubscriber() || |
| 484 | !hasProfileScope() |
| 485 | ) { |
| 486 | return false |
| 487 | } |
| 488 | |
| 489 | const tokens = getClaudeAIOAuthTokens() |
| 490 | if (tokens?.accessToken) { |
| 491 | const profile = await getOauthProfileFromOauthToken(tokens.accessToken) |
| 492 | if (profile) { |
| 493 | if (hasEnvVars) { |
| 494 | logForDebugging( |
| 495 | 'OAuth profile fetch succeeded, overriding env var account info', |
| 496 | { level: 'info' }, |
| 497 | ) |
| 498 | } |
| 499 | storeOAuthAccountInfo({ |
| 500 | accountUuid: profile.account.uuid, |
| 501 | emailAddress: profile.account.email, |
| 502 | organizationUuid: profile.organization.uuid, |
| 503 | displayName: profile.account.display_name || undefined, |
| 504 | hasExtraUsageEnabled: |
| 505 | profile.organization.has_extra_usage_enabled ?? false, |
| 506 | billingType: profile.organization.billing_type ?? undefined, |
| 507 | accountCreatedAt: profile.account.created_at, |
| 508 | subscriptionCreatedAt: |
no test coverage detected