codex

package
v6.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2025 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package codex provides authentication and token management for OpenAI's Codex API. It handles the OAuth2 flow, including generating authorization URLs, exchanging authorization codes for tokens, and refreshing expired tokens. The package also defines data structures for storing and managing Codex authentication credentials.

Package codex provides authentication and token management functionality for OpenAI's Codex AI services. It handles OAuth2 PKCE (Proof Key for Code Exchange) code generation for secure authentication flows.

Package codex provides authentication and token management functionality for OpenAI's Codex AI services. It handles OAuth2 token storage, serialization, and retrieval for maintaining authenticated sessions with the Codex API.

Index

Constants

View Source
const LoginSuccessHtml = `` /* 5955-byte string literal not displayed */

LoginSuccessHTML is the HTML template for the page shown after a successful OAuth2 authentication with Codex. It informs the user that the authentication was successful and provides a countdown timer to automatically close the window.

View Source
const SetupNoticeHtml = `` /* 237-byte string literal not displayed */

SetupNoticeHTML is the HTML template for the section that provides instructions for additional setup. This is displayed on the success page when further actions are required from the user.

Variables

View Source
var (

	// ErrInvalidState represents an error for invalid OAuth state parameter.
	ErrInvalidState = &AuthenticationError{
		Type:    "invalid_state",
		Message: "OAuth state parameter is invalid",
		Code:    http.StatusBadRequest,
	}

	// ErrCodeExchangeFailed represents an error when exchanging authorization code for tokens fails.
	ErrCodeExchangeFailed = &AuthenticationError{
		Type:    "code_exchange_failed",
		Message: "Failed to exchange authorization code for tokens",
		Code:    http.StatusBadRequest,
	}

	// ErrServerStartFailed represents an error when starting the OAuth callback server fails.
	ErrServerStartFailed = &AuthenticationError{
		Type:    "server_start_failed",
		Message: "Failed to start OAuth callback server",
		Code:    http.StatusInternalServerError,
	}

	// ErrPortInUse represents an error when the OAuth callback port is already in use.
	ErrPortInUse = &AuthenticationError{
		Type:    "port_in_use",
		Message: "OAuth callback port is already in use",
		Code:    13,
	}

	// ErrCallbackTimeout represents an error when waiting for OAuth callback times out.
	ErrCallbackTimeout = &AuthenticationError{
		Type:    "callback_timeout",
		Message: "Timeout waiting for OAuth callback",
		Code:    http.StatusRequestTimeout,
	}

	// ErrBrowserOpenFailed represents an error when opening the browser for authentication fails.
	ErrBrowserOpenFailed = &AuthenticationError{
		Type:    "browser_open_failed",
		Message: "Failed to open browser for authentication",
		Code:    http.StatusInternalServerError,
	}
)

Common authentication error types.

Functions

func GetUserFriendlyMessage

func GetUserFriendlyMessage(err error) string

GetUserFriendlyMessage returns a user-friendly error message based on the error type.

func IsAuthenticationError

func IsAuthenticationError(err error) bool

IsAuthenticationError checks if an error is an authentication error.

func IsOAuthError

func IsOAuthError(err error) bool

IsOAuthError checks if an error is an OAuth error.

Types

type AuthenticationError

type AuthenticationError struct {
	// Type is the type of authentication error.
	Type string `json:"type"`
	// Message is a human-readable message describing the error.
	Message string `json:"message"`
	// Code is the HTTP status code associated with the error.
	Code int `json:"code"`
	// Cause is the underlying error that caused this authentication error.
	Cause error `json:"-"`
}

AuthenticationError represents authentication-related errors.

func NewAuthenticationError

func NewAuthenticationError(baseErr *AuthenticationError, cause error) *AuthenticationError

NewAuthenticationError creates a new authentication error with a cause based on a base error.

func (*AuthenticationError) Error

func (e *AuthenticationError) Error() string

Error returns a string representation of the authentication error.

type CodexAuth

type CodexAuth struct {
	// contains filtered or unexported fields
}

CodexAuth handles the OpenAI OAuth2 authentication flow. It manages the HTTP client and provides methods for generating authorization URLs, exchanging authorization codes for tokens, and refreshing access tokens.

func NewCodexAuth

func NewCodexAuth(cfg *config.Config) *CodexAuth

NewCodexAuth creates a new CodexAuth service instance. It initializes an HTTP client with proxy settings from the provided configuration.

func (*CodexAuth) CreateTokenStorage

func (o *CodexAuth) CreateTokenStorage(bundle *CodexAuthBundle) *CodexTokenStorage

CreateTokenStorage creates a new CodexTokenStorage from a CodexAuthBundle. It populates the storage struct with token data, user information, and timestamps.

func (*CodexAuth) ExchangeCodeForTokens

func (o *CodexAuth) ExchangeCodeForTokens(ctx context.Context, code string, pkceCodes *PKCECodes) (*CodexAuthBundle, error)

ExchangeCodeForTokens exchanges an authorization code for access and refresh tokens. It performs an HTTP POST request to the OpenAI token endpoint with the provided authorization code and PKCE verifier.

func (*CodexAuth) GenerateAuthURL

func (o *CodexAuth) GenerateAuthURL(state string, pkceCodes *PKCECodes) (string, error)

GenerateAuthURL creates the OAuth authorization URL with PKCE (Proof Key for Code Exchange). It constructs the URL with the necessary parameters, including the client ID, response type, redirect URI, scopes, and PKCE challenge.

func (*CodexAuth) RefreshTokens

func (o *CodexAuth) RefreshTokens(ctx context.Context, refreshToken string) (*CodexTokenData, error)

RefreshTokens refreshes an access token using a refresh token. This method is called when an access token has expired. It makes a request to the token endpoint to obtain a new set of tokens.

func (*CodexAuth) RefreshTokensWithRetry

func (o *CodexAuth) RefreshTokensWithRetry(ctx context.Context, refreshToken string, maxRetries int) (*CodexTokenData, error)

RefreshTokensWithRetry refreshes tokens with a built-in retry mechanism. It attempts to refresh the tokens up to a specified maximum number of retries, with an exponential backoff strategy to handle transient network errors.

func (*CodexAuth) UpdateTokenStorage

func (o *CodexAuth) UpdateTokenStorage(storage *CodexTokenStorage, tokenData *CodexTokenData)

UpdateTokenStorage updates an existing CodexTokenStorage with new token data. This is typically called after a successful token refresh to persist the new credentials.

type CodexAuthBundle

type CodexAuthBundle struct {
	// APIKey is the OpenAI API key obtained from token exchange
	APIKey string `json:"api_key"`
	// TokenData contains the OAuth tokens from the authentication flow
	TokenData CodexTokenData `json:"token_data"`
	// LastRefresh is the timestamp of the last token refresh
	LastRefresh string `json:"last_refresh"`
}

CodexAuthBundle aggregates all authentication-related data after the OAuth flow is complete. This includes the API key, token data, and the timestamp of the last refresh.

type CodexAuthInfo

type CodexAuthInfo struct {
	ChatgptAccountID               string          `json:"chatgpt_account_id"`
	ChatgptPlanType                string          `json:"chatgpt_plan_type"`
	ChatgptSubscriptionActiveStart any             `json:"chatgpt_subscription_active_start"`
	ChatgptSubscriptionActiveUntil any             `json:"chatgpt_subscription_active_until"`
	ChatgptSubscriptionLastChecked time.Time       `json:"chatgpt_subscription_last_checked"`
	ChatgptUserID                  string          `json:"chatgpt_user_id"`
	Groups                         []any           `json:"groups"`
	Organizations                  []Organizations `json:"organizations"`
	UserID                         string          `json:"user_id"`
}

CodexAuthInfo contains authentication-related details specific to Codex. This includes ChatGPT account information, subscription status, and user/organization IDs.

type CodexTokenData

type CodexTokenData struct {
	// IDToken is the JWT ID token containing user claims
	IDToken string `json:"id_token"`
	// AccessToken is the OAuth2 access token for API access
	AccessToken string `json:"access_token"`
	// RefreshToken is used to obtain new access tokens
	RefreshToken string `json:"refresh_token"`
	// AccountID is the OpenAI account identifier
	AccountID string `json:"account_id"`
	// Email is the OpenAI account email
	Email string `json:"email"`
	// Expire is the timestamp of the token expire
	Expire string `json:"expired"`
}

CodexTokenData holds the OAuth token information obtained from OpenAI. It includes the ID token, access token, refresh token, and associated user details.

type CodexTokenStorage

type CodexTokenStorage struct {
	// IDToken is the JWT ID token containing user claims and identity information.
	IDToken string `json:"id_token"`
	// AccessToken is the OAuth2 access token used for authenticating API requests.
	AccessToken string `json:"access_token"`
	// RefreshToken is used to obtain new access tokens when the current one expires.
	RefreshToken string `json:"refresh_token"`
	// AccountID is the OpenAI account identifier associated with this token.
	AccountID string `json:"account_id"`
	// LastRefresh is the timestamp of the last token refresh operation.
	LastRefresh string `json:"last_refresh"`
	// Email is the OpenAI account email address associated with this token.
	Email string `json:"email"`
	// Type indicates the authentication provider type, always "codex" for this storage.
	Type string `json:"type"`
	// Expire is the timestamp when the current access token expires.
	Expire string `json:"expired"`
}

CodexTokenStorage stores OAuth2 token information for OpenAI Codex API authentication. It maintains compatibility with the existing auth system while adding Codex-specific fields for managing access tokens, refresh tokens, and user account information.

func (*CodexTokenStorage) SaveTokenToFile

func (ts *CodexTokenStorage) SaveTokenToFile(authFilePath string) error

SaveTokenToFile serializes the Codex token storage to a JSON file. This method creates the necessary directory structure and writes the token data in JSON format to the specified file path for persistent storage.

Parameters:

  • authFilePath: The full path where the token file should be saved

Returns:

  • error: An error if the operation fails, nil otherwise

type JWTClaims

type JWTClaims struct {
	AtHash        string        `json:"at_hash"`
	Aud           []string      `json:"aud"`
	AuthProvider  string        `json:"auth_provider"`
	AuthTime      int           `json:"auth_time"`
	Email         string        `json:"email"`
	EmailVerified bool          `json:"email_verified"`
	Exp           int           `json:"exp"`
	CodexAuthInfo CodexAuthInfo `json:"https://api.openai.com/auth"`
	Iat           int           `json:"iat"`
	Iss           string        `json:"iss"`
	Jti           string        `json:"jti"`
	Rat           int           `json:"rat"`
	Sid           string        `json:"sid"`
	Sub           string        `json:"sub"`
}

JWTClaims represents the claims section of a JSON Web Token (JWT). It includes standard claims like issuer, subject, and expiration time, as well as custom claims specific to OpenAI's authentication.

func ParseJWTToken

func ParseJWTToken(token string) (*JWTClaims, error)

ParseJWTToken parses a JWT token string and extracts its claims without performing cryptographic signature verification. This is useful for introspecting the token's contents to retrieve user information from an ID token after it has been validated by the authentication server.

func (*JWTClaims) GetAccountID

func (c *JWTClaims) GetAccountID() string

GetAccountID extracts the user's account ID (subject) from the JWT claims. It retrieves the unique identifier for the user's ChatGPT account.

func (*JWTClaims) GetUserEmail

func (c *JWTClaims) GetUserEmail() string

GetUserEmail extracts the user's email address from the JWT claims.

type OAuthError

type OAuthError struct {
	// Code is the OAuth error code.
	Code string `json:"error"`
	// Description is a human-readable description of the error.
	Description string `json:"error_description,omitempty"`
	// URI is a URI identifying a human-readable web page with information about the error.
	URI string `json:"error_uri,omitempty"`
	// StatusCode is the HTTP status code associated with the error.
	StatusCode int `json:"-"`
}

OAuthError represents an OAuth-specific error.

func NewOAuthError

func NewOAuthError(code, description string, statusCode int) *OAuthError

NewOAuthError creates a new OAuth error with the specified code, description, and status code.

func (*OAuthError) Error

func (e *OAuthError) Error() string

Error returns a string representation of the OAuth error.

type OAuthResult

type OAuthResult struct {
	// Code is the authorization code received from the OAuth provider
	Code string
	// State is the state parameter used to prevent CSRF attacks
	State string
	// Error contains any error message if the OAuth flow failed
	Error string
}

OAuthResult contains the result of the OAuth callback. It holds either the authorization code and state for successful authentication or an error message if the authentication failed.

type OAuthServer

type OAuthServer struct {
	// contains filtered or unexported fields
}

OAuthServer handles the local HTTP server for OAuth callbacks. It listens for the authorization code response from the OAuth provider and captures the necessary parameters to complete the authentication flow.

func NewOAuthServer

func NewOAuthServer(port int) *OAuthServer

NewOAuthServer creates a new OAuth callback server. It initializes the server with the specified port and creates channels for handling OAuth results and errors.

Parameters:

  • port: The port number on which the server should listen

Returns:

  • *OAuthServer: A new OAuthServer instance

func (*OAuthServer) IsRunning

func (s *OAuthServer) IsRunning() bool

IsRunning returns whether the server is currently running.

Returns:

  • bool: True if the server is running, false otherwise

func (*OAuthServer) Start

func (s *OAuthServer) Start() error

Start starts the OAuth callback server. It sets up the HTTP handlers for the callback and success endpoints, and begins listening on the specified port.

Returns:

  • error: An error if the server fails to start

func (*OAuthServer) Stop

func (s *OAuthServer) Stop(ctx context.Context) error

Stop gracefully stops the OAuth callback server. It performs a graceful shutdown of the HTTP server with a timeout.

Parameters:

  • ctx: The context for controlling the shutdown process

Returns:

  • error: An error if the server fails to stop gracefully

func (*OAuthServer) WaitForCallback

func (s *OAuthServer) WaitForCallback(timeout time.Duration) (*OAuthResult, error)

WaitForCallback waits for the OAuth callback with a timeout. It blocks until either an OAuth result is received, an error occurs, or the specified timeout is reached.

Parameters:

  • timeout: The maximum time to wait for the callback

Returns:

  • *OAuthResult: The OAuth result if successful
  • error: An error if the callback times out or an error occurs

type Organizations

type Organizations struct {
	ID        string `json:"id"`
	IsDefault bool   `json:"is_default"`
	Role      string `json:"role"`
	Title     string `json:"title"`
}

Organizations defines the structure for organization details within the JWT claims. It holds information about the user's organization, such as ID, role, and title.

type PKCECodes

type PKCECodes struct {
	// CodeVerifier is the cryptographically random string used to correlate
	// the authorization request to the token request
	CodeVerifier string `json:"code_verifier"`
	// CodeChallenge is the SHA256 hash of the code verifier, base64url-encoded
	CodeChallenge string `json:"code_challenge"`
}

PKCECodes holds the verification codes for the OAuth2 PKCE (Proof Key for Code Exchange) flow. PKCE is an extension to the Authorization Code flow to prevent CSRF and authorization code injection attacks.

func GeneratePKCECodes

func GeneratePKCECodes() (*PKCECodes, error)

GeneratePKCECodes generates a new pair of PKCE (Proof Key for Code Exchange) codes. It creates a cryptographically random code verifier and its corresponding SHA256 code challenge, as specified in RFC 7636. This is a critical security feature for the OAuth 2.0 authorization code flow.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL