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