package common import ( "errors" "strings" ) type CodexCredentialMode string const ( CodexCredentialModeAPIKey CodexCredentialMode = "api_key" CodexCredentialModeOAuth CodexCredentialMode = "oauth" ) var ( ErrCodexOAuthCredentialRequired = errors.New("codex channel: oauth credential required") ErrCodexOAuthCredentialInvalidJSON = errors.New("codex channel: invalid oauth key json") ErrCodexOAuthAccessTokenRequired = errors.New("codex channel: access_token is required") ErrCodexOAuthAccountIDRequired = errors.New("codex channel: account_id is required") ) type CodexOAuthCredential struct { IDToken string `json:"id_token,omitempty"` AccessToken string `json:"access_token,omitempty"` RefreshToken string `json:"refresh_token,omitempty"` AccountID string `json:"account_id,omitempty"` LastRefresh string `json:"last_refresh,omitempty"` Email string `json:"email,omitempty"` Type string `json:"type,omitempty"` Expired string `json:"expired,omitempty"` } func ParseCodexOAuthCredential(raw string) (*CodexOAuthCredential, error) { trimmed := strings.TrimSpace(raw) if trimmed == "" || !strings.HasPrefix(trimmed, "{") { return nil, ErrCodexOAuthCredentialRequired } var credential CodexOAuthCredential if err := Unmarshal([]byte(trimmed), &credential); err != nil { return nil, ErrCodexOAuthCredentialInvalidJSON } if strings.TrimSpace(credential.AccessToken) == "" { return nil, ErrCodexOAuthAccessTokenRequired } if strings.TrimSpace(credential.AccountID) == "" { return nil, ErrCodexOAuthAccountIDRequired } return &credential, nil } func DetectCodexCredentialMode(raw string) CodexCredentialMode { if _, err := ParseCodexOAuthCredential(raw); err == nil { return CodexCredentialModeOAuth } return CodexCredentialModeAPIKey }