chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import Foundation
|
||||
|
||||
public enum TokenAccountInjection: Sendable {
|
||||
case cookieHeader
|
||||
case environment(key: String)
|
||||
}
|
||||
|
||||
public struct TokenAccountSupport: Sendable {
|
||||
public let title: String
|
||||
public let subtitle: String
|
||||
public let placeholder: String
|
||||
public let injection: TokenAccountInjection
|
||||
public let requiresManualCookieSource: Bool
|
||||
public let cookieName: String?
|
||||
public let environmentKeysToScrub: [String]
|
||||
|
||||
public init(
|
||||
title: String,
|
||||
subtitle: String,
|
||||
placeholder: String,
|
||||
injection: TokenAccountInjection,
|
||||
requiresManualCookieSource: Bool,
|
||||
cookieName: String?,
|
||||
environmentKeysToScrub: [String] = [])
|
||||
{
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.placeholder = placeholder
|
||||
self.injection = injection
|
||||
self.requiresManualCookieSource = requiresManualCookieSource
|
||||
self.cookieName = cookieName
|
||||
self.environmentKeysToScrub = environmentKeysToScrub
|
||||
}
|
||||
}
|
||||
|
||||
public enum TokenAccountSupportCatalog {
|
||||
public static func support(for provider: UsageProvider) -> TokenAccountSupport? {
|
||||
supportByProvider[provider]
|
||||
}
|
||||
|
||||
public static func envOverride(for provider: UsageProvider, token: String) -> [String: String]? {
|
||||
guard let support = self.support(for: provider) else { return nil }
|
||||
switch support.injection {
|
||||
case let .environment(key):
|
||||
return [key: token]
|
||||
case .cookieHeader:
|
||||
if provider == .claude,
|
||||
case let route = ClaudeCredentialRouting.resolve(tokenAccountToken: token, manualCookieHeader: nil)
|
||||
{
|
||||
switch route {
|
||||
case let .oauth(accessToken):
|
||||
return [ClaudeOAuthCredentialsStore.environmentTokenKey: accessToken]
|
||||
case let .adminAPIKey(apiKey):
|
||||
return [ClaudeAdminAPISettingsReader.adminAPIKeyEnvironmentKey: apiKey]
|
||||
case .none, .webCookie:
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public static func scrubEnvironmentForSelectedAccount(
|
||||
_ environment: inout [String: String],
|
||||
provider: UsageProvider,
|
||||
token _: String)
|
||||
{
|
||||
guard let support = self.support(for: provider) else { return }
|
||||
switch support.injection {
|
||||
case let .environment(key):
|
||||
environment.removeValue(forKey: key)
|
||||
for key in support.environmentKeysToScrub {
|
||||
environment.removeValue(forKey: key)
|
||||
}
|
||||
case .cookieHeader:
|
||||
guard provider == .claude else { return }
|
||||
environment.removeValue(forKey: ClaudeOAuthCredentialsStore.environmentTokenKey)
|
||||
for key in ClaudeAdminAPISettingsReader.apiKeyEnvironmentKeys {
|
||||
environment.removeValue(forKey: key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func normalizedCookieHeader(for provider: UsageProvider, token: String) -> String {
|
||||
guard let support = self.support(for: provider) else {
|
||||
return token.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
return self.normalizedCookieHeader(token, support: support)
|
||||
}
|
||||
|
||||
public static func isClaudeOAuthToken(_ token: String) -> Bool {
|
||||
ClaudeCredentialRouting.resolve(tokenAccountToken: token, manualCookieHeader: nil).isOAuth
|
||||
}
|
||||
|
||||
public static func normalizedCookieHeader(_ token: String, support: TokenAccountSupport) -> String {
|
||||
let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard let cookieName = support.cookieName else { return trimmed }
|
||||
let lower = trimmed.lowercased()
|
||||
if lower.contains("cookie:") || trimmed.contains("=") {
|
||||
return trimmed
|
||||
}
|
||||
return "\(cookieName)=\(trimmed)"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user