()
| 175 | /** Where the auth token is being sourced from, if any. */ |
| 176 | // this code is closely related to isAnthropicAuthEnabled |
| 177 | export function getAuthTokenSource() { |
| 178 | // --bare: API-key-only. apiKeyHelper (from --settings) is the only |
| 179 | // bearer-token-shaped source allowed. OAuth env vars, FD tokens, and |
| 180 | // keychain are ignored. |
| 181 | if (isBareMode()) { |
| 182 | if (getConfiguredApiKeyHelper()) { |
| 183 | return { source: 'apiKeyHelper' as const, hasToken: true } |
| 184 | } |
| 185 | return { source: 'none' as const, hasToken: false } |
| 186 | } |
| 187 | |
| 188 | if (isOpenAICompatibleProviderActive() && getConfiguredProviderAuthToken()) { |
| 189 | return { source: 'providerAuthToken' as const, hasToken: true } |
| 190 | } |
| 191 | |
| 192 | if ( |
| 193 | process.env.ANTHROPIC_AUTH_TOKEN && |
| 194 | !isManagedOAuthContext() |
| 195 | ) { |
| 196 | return { source: 'ANTHROPIC_AUTH_TOKEN' as const, hasToken: true } |
| 197 | } |
| 198 | |
| 199 | if (process.env.CLAUDE_CODE_OAUTH_TOKEN) { |
| 200 | return { source: 'CLAUDE_CODE_OAUTH_TOKEN' as const, hasToken: true } |
| 201 | } |
| 202 | |
| 203 | // Check for OAuth token from file descriptor (or its CCR disk fallback) |
| 204 | const oauthTokenFromFd = getOAuthTokenFromFileDescriptor() |
| 205 | if (oauthTokenFromFd) { |
| 206 | // getOAuthTokenFromFileDescriptor has a disk fallback for CCR subprocesses |
| 207 | // that can't inherit the pipe FD. Distinguish by env var presence so the |
| 208 | // org-mismatch message doesn't tell the user to unset a variable that |
| 209 | // doesn't exist. Call sites fall through correctly — the new source is |
| 210 | // !== 'none' (cli/handlers/auth.ts → oauth_token) and not in the |
| 211 | // isEnvVarToken set (auth.ts:1844 → generic re-login message). |
| 212 | if (process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR) { |
| 213 | return { |
| 214 | source: 'CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR' as const, |
| 215 | hasToken: true, |
| 216 | } |
| 217 | } |
| 218 | return { |
| 219 | source: 'CCR_OAUTH_TOKEN_FILE' as const, |
| 220 | hasToken: true, |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | // Check if apiKeyHelper is configured without executing it |
| 225 | // This prevents security issues where arbitrary code could execute before trust is established |
| 226 | const apiKeyHelper = getConfiguredApiKeyHelper() |
| 227 | if (apiKeyHelper && !isManagedOAuthContext()) { |
| 228 | return { source: 'apiKeyHelper' as const, hasToken: true } |
| 229 | } |
| 230 | |
| 231 | const oauthTokens = getClaudeAIOAuthTokens() |
| 232 | if (shouldUseClaudeAIAuth(oauthTokens?.scopes) && oauthTokens?.accessToken) { |
| 233 | return { source: 'claude.ai' as const, hasToken: true } |
| 234 | } |
no test coverage detected