Merge pull request #877 from zhiqing0205/main

feat(codex): include plan type in auth filename
This commit is contained in:
Luis Pater
2026-01-20 11:11:25 +08:00
committed by GitHub
3 changed files with 67 additions and 3 deletions

View File

@@ -1383,9 +1383,11 @@ func (h *Handler) RequestCodexToken(c *gin.Context) {
claims, _ := codex.ParseJWTToken(tokenResp.IDToken) claims, _ := codex.ParseJWTToken(tokenResp.IDToken)
email := "" email := ""
accountID := "" accountID := ""
planType := ""
if claims != nil { if claims != nil {
email = claims.GetUserEmail() email = claims.GetUserEmail()
accountID = claims.GetAccountID() accountID = claims.GetAccountID()
planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType)
} }
// Build bundle compatible with existing storage // Build bundle compatible with existing storage
bundle := &codex.CodexAuthBundle{ bundle := &codex.CodexAuthBundle{
@@ -1402,10 +1404,11 @@ func (h *Handler) RequestCodexToken(c *gin.Context) {
// Create token storage and persist // Create token storage and persist
tokenStorage := openaiAuth.CreateTokenStorage(bundle) tokenStorage := openaiAuth.CreateTokenStorage(bundle)
fileName := codex.CredentialFileName(tokenStorage.Email, planType, true)
record := &coreauth.Auth{ record := &coreauth.Auth{
ID: fmt.Sprintf("codex-%s.json", tokenStorage.Email), ID: fileName,
Provider: "codex", Provider: "codex",
FileName: fmt.Sprintf("codex-%s.json", tokenStorage.Email), FileName: fileName,
Storage: tokenStorage, Storage: tokenStorage,
Metadata: map[string]any{ Metadata: map[string]any{
"email": tokenStorage.Email, "email": tokenStorage.Email,

View File

@@ -0,0 +1,55 @@
package codex
import (
"fmt"
"strings"
"unicode"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
// CredentialFileName returns the filename used to persist Codex OAuth credentials.
// When planType is available (e.g. "plus", "team"), it is appended after the email
// as a suffix to disambiguate subscriptions.
func CredentialFileName(email, planType string, includeProviderPrefix bool) string {
email = strings.TrimSpace(email)
plan := normalizePlanTypeForFilename(planType)
prefix := ""
if includeProviderPrefix {
prefix = "codex-"
}
if plan == "" {
return fmt.Sprintf("%s%s.json", prefix, email)
}
return fmt.Sprintf("%s%s-%s.json", prefix, email, plan)
}
func normalizePlanTypeForFilename(planType string) string {
planType = strings.TrimSpace(planType)
if planType == "" {
return ""
}
parts := strings.FieldsFunc(planType, func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsDigit(r)
})
if len(parts) == 0 {
return ""
}
for i, part := range parts {
parts[i] = titleToken(part)
}
return strings.Join(parts, "-")
}
func titleToken(token string) string {
token = strings.TrimSpace(token)
if token == "" {
return ""
}
return cases.Title(language.English).String(token)
}

View File

@@ -191,7 +191,13 @@ waitForCallback:
return nil, fmt.Errorf("codex token storage missing account information") return nil, fmt.Errorf("codex token storage missing account information")
} }
fileName := fmt.Sprintf("codex-%s.json", tokenStorage.Email) planType := ""
if tokenStorage.IDToken != "" {
if claims, errParse := codex.ParseJWTToken(tokenStorage.IDToken); errParse == nil && claims != nil {
planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType)
}
}
fileName := codex.CredentialFileName(tokenStorage.Email, planType, true)
metadata := map[string]any{ metadata := map[string]any{
"email": tokenStorage.Email, "email": tokenStorage.Email,
} }