History

Merge branch 'router-for-me:main' into main

Luis Pater committed 11 months agov6.6.7-0

Commit ba6aa5f2 parents 75ce091 1c52a895 files · +97 −5Browse files

Unified · Split

5 files
  1. internal/api/handlers/management/auth_files.go +14 −2
  2. internal/auth/iflow/cookie_helpers.go +61 −0
  3. internal/auth/iflow/iflow_auth.go +8 −1
  4. internal/cmd/iflow_cookie.go +13 −1
  5. sdk/auth/iflow.go +1 −1
internal/api/handlers/management/auth_files.go+14−2
@@ -1745,6 +1745,17 @@ func (h *Handler) RequestIFlowCookieToken(c *gin.Context) { · 1744 unmodified lines
17451745 return
17461746 }
17471747
1748+ // Check for duplicate BXAuth before authentication
1749+ bxAuth := iflowauth.ExtractBXAuth(cookieValue)
1750+ if existingFile, err := iflowauth.CheckDuplicateBXAuth(h.cfg.AuthDir, bxAuth); err != nil {
1751+ c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "error": "failed to check duplicate"})
1752+ return
1753+ } else if existingFile != "" {
1754+ existingFileName := filepath.Base(existingFile)
1755+ c.JSON(http.StatusConflict, gin.H{"status": "error", "error": "duplicate BXAuth found", "existing_file": existingFileName})
1756+ return
1757+ }
1758+
17481759 authSvc := iflowauth.NewIFlowAuth(h.cfg)
17491760 tokenData, errAuth := authSvc.AuthenticateWithCookie(ctx, cookieValue)
17501761 if errAuth != nil {
@@ -1767,11 +1778,12 @@ func (h *Handler) RequestIFlowCookieToken(c *gin.Context) { · 16 unmodified lines
17671778 }
17681779
17691780 tokenStorage.Email = email
1781+ timestamp := time.Now().Unix()
17701782
17711783 record := &coreauth.Auth{
1772− ID: fmt.Sprintf("iflow-%s.json", fileName),
1784+ ID: fmt.Sprintf("iflow-%s-%d.json", fileName, timestamp),
17731785 Provider: "iflow",
1774− FileName: fmt.Sprintf("iflow-%s.json", fileName),
1786+ FileName: fmt.Sprintf("iflow-%s-%d.json", fileName, timestamp),
17751787 Storage: tokenStorage,
17761788 Metadata: map[string]any{
17771789 "email": email,
internal/auth/iflow/cookie_helpers.go+61−0
@@ -1,7 +1,10 @@
11 package iflow
22
33 import (
4+ "encoding/json"
45 "fmt"
6+ "os"
7+ "path/filepath"
58 "strings"
69 )
710
@@ -36,3 +39,61 @@ func SanitizeIFlowFileName(raw string) string { · 28 unmodified lines
3639 }
3740 return strings.TrimSpace(result.String())
3841 }
42+
43+// ExtractBXAuth extracts the BXAuth value from a cookie string.
44+func ExtractBXAuth(cookie string) string {
45+ parts := strings.Split(cookie, ";")
46+ for _, part := range parts {
47+ part = strings.TrimSpace(part)
48+ if strings.HasPrefix(part, "BXAuth=") {
49+ return strings.TrimPrefix(part, "BXAuth=")
50+ }
51+ }
52+ return ""
53+}
54+
55+// CheckDuplicateBXAuth checks if the given BXAuth value already exists in any iflow auth file.
56+// Returns the path of the existing file if found, empty string otherwise.
57+func CheckDuplicateBXAuth(authDir, bxAuth string) (string, error) {
58+ if bxAuth == "" {
59+ return "", nil
60+ }
61+
62+ entries, err := os.ReadDir(authDir)
63+ if err != nil {
64+ if os.IsNotExist(err) {
65+ return "", nil
66+ }
67+ return "", fmt.Errorf("read auth dir failed: %w", err)
68+ }
69+
70+ for _, entry := range entries {
71+ if entry.IsDir() {
72+ continue
73+ }
74+ name := entry.Name()
75+ if !strings.HasPrefix(name, "iflow-") || !strings.HasSuffix(name, ".json") {
76+ continue
77+ }
78+
79+ filePath := filepath.Join(authDir, name)
80+ data, err := os.ReadFile(filePath)
81+ if err != nil {
82+ continue
83+ }
84+
85+ var tokenData struct {
86+ Cookie string `json:"cookie"`
87+ }
88+ if err := json.Unmarshal(data, &tokenData); err != nil {
89+ continue
90+ }
91+
92+ existingBXAuth := ExtractBXAuth(tokenData.Cookie)
93+ if existingBXAuth != "" && existingBXAuth == bxAuth {
94+ return filePath, nil
95+ }
96+ }
97+
98+ return "", nil
99+}
internal/auth/iflow/iflow_auth.go+8−1
@@ -506,11 +506,18 @@ func (ia *IFlowAuth) CreateCookieTokenStorage(data *IFlowTokenData) *IFlowTokenS · 505 unmodified lines
506506 return nil
507507 }
508508
509+ // Only save the BXAuth field from the cookie
510+ bxAuth := ExtractBXAuth(data.Cookie)
511+ cookieToSave := ""
512+ if bxAuth != "" {
513+ cookieToSave = "BXAuth=" + bxAuth + ";"
514+ }
515+
509516 return &IFlowTokenStorage{
510517 APIKey: data.APIKey,
511518 Email: data.Email,
512519 Expire: data.Expire,
513− Cookie: data.Cookie,
520+ Cookie: cookieToSave,
514521 LastRefresh: time.Now().Format(time.RFC3339),
515522 Type: "iflow",
516523 }
internal/cmd/iflow_cookie.go+13−1
@@ -5,7 +5,9 @@ import ( · 4 unmodified lines
55 "context"
66 "fmt"
77 "os"
8+ "path/filepath"
89 "strings"
10+ "time"
911
1012 "github.com/router-for-me/CLIProxyAPI/v6/internal/auth/iflow"
1113 "github.com/router-for-me/CLIProxyAPI/v6/internal/config"
@@ -37,6 +39,16 @@ func DoIFlowCookieAuth(cfg *config.Config, options *LoginOptions) { · 25 unmodified lines
3739 return
3840 }
3941
42+ // Check for duplicate BXAuth before authentication
43+ bxAuth := iflow.ExtractBXAuth(cookie)
44+ if existingFile, err := iflow.CheckDuplicateBXAuth(cfg.AuthDir, bxAuth); err != nil {
45+ fmt.Printf("Failed to check duplicate: %v\n", err)
46+ return
47+ } else if existingFile != "" {
48+ fmt.Printf("Duplicate BXAuth found, authentication already exists: %s\n", filepath.Base(existingFile))
49+ return
50+ }
51+
4052 // Authenticate with cookie
4153 auth := iflow.NewIFlowAuth(cfg)
4254 ctx := context.Background()
@@ -82,5 +94,5 @@ func promptForCookie(promptFn func(string) (string, error)) (string, error) { · 39 unmodified lines
8294 // getAuthFilePath returns the auth file path for the given provider and email
8395 func getAuthFilePath(cfg *config.Config, provider, email string) string {
8496 fileName := iflow.SanitizeIFlowFileName(email)
85− return fmt.Sprintf("%s/%s-%s.json", cfg.AuthDir, provider, fileName)
97+ return fmt.Sprintf("%s/%s-%s-%d.json", cfg.AuthDir, provider, fileName, time.Now().Unix())
8698 }
sdk/auth/iflow.go+1−1
@@ -107,7 +107,7 @@ func (a *IFlowAuthenticator) Login(ctx context.Context, cfg *config.Config, opts · 106 unmodified lines
107107 return nil, fmt.Errorf("iflow authentication failed: missing account identifier")
108108 }
109109
110− fileName := fmt.Sprintf("iflow-%s.json", email)
110+ fileName := fmt.Sprintf("iflow-%s-%d.json", email, time.Now().Unix())
111111 metadata := map[string]any{
112112 "email": email,
113113 "api_key": tokenStorage.APIKey,