feat(auth): add hashed account ID to credential filenames for team plans

This commit is contained in:
Luis Pater
2026-01-20 11:36:29 +08:00
parent 7beaf0eaa2
commit 059bfee91b
2 changed files with 15 additions and 5 deletions

View File

@@ -12,19 +12,21 @@ import (
// CredentialFileName returns the filename used to persist Codex OAuth credentials. // CredentialFileName returns the filename used to persist Codex OAuth credentials.
// When planType is available (e.g. "plus", "team"), it is appended after the email // When planType is available (e.g. "plus", "team"), it is appended after the email
// as a suffix to disambiguate subscriptions. // as a suffix to disambiguate subscriptions.
func CredentialFileName(email, planType string, includeProviderPrefix bool) string { func CredentialFileName(email, planType, hashAccountID string, includeProviderPrefix bool) string {
email = strings.TrimSpace(email) email = strings.TrimSpace(email)
plan := normalizePlanTypeForFilename(planType) plan := normalizePlanTypeForFilename(planType)
prefix := "" prefix := ""
if includeProviderPrefix { if includeProviderPrefix {
prefix = "codex-" prefix = "codex"
} }
if plan == "" { if plan == "" {
return fmt.Sprintf("%s%s.json", prefix, email) return fmt.Sprintf("%s-%s.json", prefix, email)
} else if plan == "team" {
return fmt.Sprintf("%s-%s-%s-%s.json", prefix, hashAccountID, email, plan)
} }
return fmt.Sprintf("%s%s-%s.json", prefix, email, plan) return fmt.Sprintf("%s-%s-%s.json", prefix, email, plan)
} }
func normalizePlanTypeForFilename(planType string) string { func normalizePlanTypeForFilename(planType string) string {

View File

@@ -2,6 +2,8 @@ package auth
import ( import (
"context" "context"
"crypto/sha256"
"encoding/hex"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@@ -192,12 +194,18 @@ waitForCallback:
} }
planType := "" planType := ""
hashAccountID := ""
if tokenStorage.IDToken != "" { if tokenStorage.IDToken != "" {
if claims, errParse := codex.ParseJWTToken(tokenStorage.IDToken); errParse == nil && claims != nil { if claims, errParse := codex.ParseJWTToken(tokenStorage.IDToken); errParse == nil && claims != nil {
planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType) planType = strings.TrimSpace(claims.CodexAuthInfo.ChatgptPlanType)
accountID := strings.TrimSpace(claims.CodexAuthInfo.ChatgptAccountID)
if accountID != "" {
digest := sha256.Sum256([]byte(accountID))
hashAccountID = hex.EncodeToString(digest[:])[:8]
} }
} }
fileName := codex.CredentialFileName(tokenStorage.Email, planType, true) }
fileName := codex.CredentialFileName(tokenStorage.Email, planType, hashAccountID, true)
metadata := map[string]any{ metadata := map[string]any{
"email": tokenStorage.Email, "email": tokenStorage.Email,
} }