()
| 152 | /** Where the auth token is being sourced from, if any. */ |
| 153 | // this code is closely related to isAnthropicAuthEnabled |
| 154 | export function getAuthTokenSource() { |
| 155 | // --bare: API-key-only. apiKeyHelper (from --settings) is the only |
| 156 | // bearer-token-shaped source allowed. OAuth env vars, FD tokens, and |
| 157 | // keychain are ignored. |
| 158 | if (isBareMode()) { |
| 159 | if (getConfiguredApiKeyHelper()) { |
| 160 | return { source: 'apiKeyHelper' as const, hasToken: true } |
| 161 | } |
| 162 | return { source: 'none' as const, hasToken: false } |
| 163 | } |
| 164 | |
| 165 | if (process.env.ANTHROPIC_AUTH_TOKEN && !isManagedOAuthContext()) { |
| 166 | return { source: 'ANTHROPIC_AUTH_TOKEN' as const, hasToken: true } |
| 167 | } |
| 168 | |
| 169 | if (process.env.CLAUDE_CODE_OAUTH_TOKEN) { |
| 170 | return { source: 'CLAUDE_CODE_OAUTH_TOKEN' as const, hasToken: true } |
| 171 | } |
| 172 | |
| 173 | // Check for OAuth token from file descriptor (or its CCR disk fallback) |
| 174 | const oauthTokenFromFd = getOAuthTokenFromFileDescriptor() |
| 175 | if (oauthTokenFromFd) { |
| 176 | // getOAuthTokenFromFileDescriptor has a disk fallback for CCR subprocesses |
| 177 | // that can't inherit the pipe FD. Distinguish by env var presence so the |
| 178 | // org-mismatch message doesn't tell the user to unset a variable that |
| 179 | // doesn't exist. Call sites fall through correctly — the new source is |
| 180 | // !== 'none' (cli/handlers/auth.ts → oauth_token) and not in the |
| 181 | // isEnvVarToken set (auth.ts:1844 → generic re-login message). |
| 182 | if (process.env.CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR) { |
| 183 | return { |
| 184 | source: 'CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR' as const, |
| 185 | hasToken: true, |
| 186 | } |
| 187 | } |
| 188 | return { |
| 189 | source: 'CCR_OAUTH_TOKEN_FILE' as const, |
| 190 | hasToken: true, |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | // Check if apiKeyHelper is configured without executing it |
| 195 | // This prevents security issues where arbitrary code could execute before trust is established |
| 196 | const apiKeyHelper = getConfiguredApiKeyHelper() |
| 197 | if (apiKeyHelper && !isManagedOAuthContext()) { |
| 198 | return { source: 'apiKeyHelper' as const, hasToken: true } |
| 199 | } |
| 200 | |
| 201 | const oauthTokens = getClaudeAIOAuthTokens() |
| 202 | if (shouldUseClaudeAIAuth(oauthTokens?.scopes) && oauthTokens?.accessToken) { |
| 203 | return { source: 'claude.ai' as const, hasToken: true } |
| 204 | } |
| 205 | |
| 206 | return { source: 'none' as const, hasToken: false } |
| 207 | } |
| 208 | |
| 209 | export type ApiKeySource = |
| 210 | | 'ANTHROPIC_API_KEY' |
no test coverage detected