refactor(auth): export Codex constants and slim down handler

This commit is contained in:
hkfires
2026-01-23 21:52:46 +08:00
parent e7f13aa008
commit 405df58f72
2 changed files with 26 additions and 74 deletions

View File

@@ -11,7 +11,6 @@ import (
"io" "io"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -1346,73 +1345,25 @@ func (h *Handler) RequestCodexToken(c *gin.Context) {
} }
log.Debug("Authorization code received, exchanging for tokens...") log.Debug("Authorization code received, exchanging for tokens...")
// Extract client_id from authURL // Exchange code for tokens using internal auth service
clientID := "" bundle, errExchange := openaiAuth.ExchangeCodeForTokens(ctx, code, pkceCodes)
if u2, errP := url.Parse(authURL); errP == nil { if errExchange != nil {
clientID = u2.Query().Get("client_id") authErr := codex.NewAuthenticationError(codex.ErrCodeExchangeFailed, errExchange)
}
// Exchange code for tokens with redirect equal to mgmtRedirect
form := url.Values{
"grant_type": {"authorization_code"},
"client_id": {clientID},
"code": {code},
"redirect_uri": {"http://localhost:1455/auth/callback"},
"code_verifier": {pkceCodes.CodeVerifier},
}
httpClient := util.SetProxy(&h.cfg.SDKConfig, &http.Client{})
req, _ := http.NewRequestWithContext(ctx, "POST", "https://auth.openai.com/oauth/token", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "application/json")
resp, errDo := httpClient.Do(req)
if errDo != nil {
authErr := codex.NewAuthenticationError(codex.ErrCodeExchangeFailed, errDo)
SetOAuthSessionError(state, "Failed to exchange authorization code for tokens") SetOAuthSessionError(state, "Failed to exchange authorization code for tokens")
log.Errorf("Failed to exchange authorization code for tokens: %v", authErr) log.Errorf("Failed to exchange authorization code for tokens: %v", authErr)
return return
} }
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body) // Extract additional info for filename generation
if resp.StatusCode != http.StatusOK { claims, _ := codex.ParseJWTToken(bundle.TokenData.IDToken)
SetOAuthSessionError(state, fmt.Sprintf("Token exchange failed with status %d", resp.StatusCode))
log.Errorf("token exchange failed with status %d: %s", resp.StatusCode, string(respBody))
return
}
var tokenResp struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
IDToken string `json:"id_token"`
ExpiresIn int `json:"expires_in"`
}
if errU := json.Unmarshal(respBody, &tokenResp); errU != nil {
SetOAuthSessionError(state, "Failed to parse token response")
log.Errorf("failed to parse token response: %v", errU)
return
}
claims, _ := codex.ParseJWTToken(tokenResp.IDToken)
email := ""
accountID := ""
planType := "" planType := ""
if claims != nil {
email = claims.GetUserEmail()
accountID = claims.GetAccountID()
planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType)
}
hashAccountID := "" hashAccountID := ""
if accountID != "" { if claims != nil {
digest := sha256.Sum256([]byte(accountID)) planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType)
hashAccountID = hex.EncodeToString(digest[:])[:8] if accountID := claims.GetAccountID(); accountID != "" {
} digest := sha256.Sum256([]byte(accountID))
// Build bundle compatible with existing storage hashAccountID = hex.EncodeToString(digest[:])[:8]
bundle := &codex.CodexAuthBundle{ }
TokenData: codex.CodexTokenData{
IDToken: tokenResp.IDToken,
AccessToken: tokenResp.AccessToken,
RefreshToken: tokenResp.RefreshToken,
AccountID: accountID,
Email: email,
Expire: time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second).Format(time.RFC3339),
},
LastRefresh: time.Now().Format(time.RFC3339),
} }
// Create token storage and persist // Create token storage and persist

View File

@@ -19,11 +19,12 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
// OAuth configuration constants for OpenAI Codex
const ( const (
openaiAuthURL = "https://auth.openai.com/oauth/authorize" AuthURL = "https://auth.openai.com/oauth/authorize"
openaiTokenURL = "https://auth.openai.com/oauth/token" TokenURL = "https://auth.openai.com/oauth/token"
openaiClientID = "app_EMoamEEZ73f0CkXaXp7hrann" ClientID = "app_EMoamEEZ73f0CkXaXp7hrann"
redirectURI = "http://localhost:1455/auth/callback" RedirectURI = "http://localhost:1455/auth/callback"
) )
// CodexAuth handles the OpenAI OAuth2 authentication flow. // CodexAuth handles the OpenAI OAuth2 authentication flow.
@@ -50,9 +51,9 @@ func (o *CodexAuth) GenerateAuthURL(state string, pkceCodes *PKCECodes) (string,
} }
params := url.Values{ params := url.Values{
"client_id": {openaiClientID}, "client_id": {ClientID},
"response_type": {"code"}, "response_type": {"code"},
"redirect_uri": {redirectURI}, "redirect_uri": {RedirectURI},
"scope": {"openid email profile offline_access"}, "scope": {"openid email profile offline_access"},
"state": {state}, "state": {state},
"code_challenge": {pkceCodes.CodeChallenge}, "code_challenge": {pkceCodes.CodeChallenge},
@@ -62,7 +63,7 @@ func (o *CodexAuth) GenerateAuthURL(state string, pkceCodes *PKCECodes) (string,
"codex_cli_simplified_flow": {"true"}, "codex_cli_simplified_flow": {"true"},
} }
authURL := fmt.Sprintf("%s?%s", openaiAuthURL, params.Encode()) authURL := fmt.Sprintf("%s?%s", AuthURL, params.Encode())
return authURL, nil return authURL, nil
} }
@@ -77,13 +78,13 @@ func (o *CodexAuth) ExchangeCodeForTokens(ctx context.Context, code string, pkce
// Prepare token exchange request // Prepare token exchange request
data := url.Values{ data := url.Values{
"grant_type": {"authorization_code"}, "grant_type": {"authorization_code"},
"client_id": {openaiClientID}, "client_id": {ClientID},
"code": {code}, "code": {code},
"redirect_uri": {redirectURI}, "redirect_uri": {RedirectURI},
"code_verifier": {pkceCodes.CodeVerifier}, "code_verifier": {pkceCodes.CodeVerifier},
} }
req, err := http.NewRequestWithContext(ctx, "POST", openaiTokenURL, strings.NewReader(data.Encode())) req, err := http.NewRequestWithContext(ctx, "POST", TokenURL, strings.NewReader(data.Encode()))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create token request: %w", err) return nil, fmt.Errorf("failed to create token request: %w", err)
} }
@@ -163,13 +164,13 @@ func (o *CodexAuth) RefreshTokens(ctx context.Context, refreshToken string) (*Co
} }
data := url.Values{ data := url.Values{
"client_id": {openaiClientID}, "client_id": {ClientID},
"grant_type": {"refresh_token"}, "grant_type": {"refresh_token"},
"refresh_token": {refreshToken}, "refresh_token": {refreshToken},
"scope": {"openid profile email"}, "scope": {"openid profile email"},
} }
req, err := http.NewRequestWithContext(ctx, "POST", openaiTokenURL, strings.NewReader(data.Encode())) req, err := http.NewRequestWithContext(ctx, "POST", TokenURL, strings.NewReader(data.Encode()))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create refresh request: %w", err) return nil, fmt.Errorf("failed to create refresh request: %w", err)
} }