@@ -25,7 +25,6 @@ import (
2525 "github.com/NGLSL/CLIProxyAPI/v6/internal/auth/claude"
2626 "github.com/NGLSL/CLIProxyAPI/v6/internal/auth/codex"
2727 geminiAuth "github.com/NGLSL/CLIProxyAPI/v6/internal/auth/gemini"
28- iflowauth "github.com/NGLSL/CLIProxyAPI/v6/internal/auth/iflow"
2928 "github.com/NGLSL/CLIProxyAPI/v6/internal/auth/kimi"
3029 "github.com/NGLSL/CLIProxyAPI/v6/internal/interfaces"
3130 "github.com/NGLSL/CLIProxyAPI/v6/internal/misc"
@@ -2355,215 +2354,6 @@ func (h *Handler) RequestKimiToken(c *gin.Context) {
23552354 c .JSON (200 , gin.H {"status" : "ok" , "url" : authURL , "state" : state })
23562355}
23572356
2358- func (h * Handler ) RequestIFlowToken (c * gin.Context ) {
2359- ctx := context .Background ()
2360- ctx = PopulateAuthContext (ctx , c )
2361-
2362- fmt .Println ("Initializing iFlow authentication..." )
2363-
2364- state := fmt .Sprintf ("ifl-%d" , time .Now ().UnixNano ())
2365- authSvc := iflowauth .NewIFlowAuth (h .cfg )
2366- authURL , redirectURI := authSvc .AuthorizationURL (state , iflowauth .CallbackPort )
2367-
2368- RegisterOAuthSession (state , "iflow" )
2369-
2370- isWebUI := isWebUIRequest (c )
2371- var forwarder * callbackForwarder
2372- if isWebUI {
2373- targetURL , errTarget := h .managementCallbackURL ("/iflow/callback" )
2374- if errTarget != nil {
2375- log .WithError (errTarget ).Error ("failed to compute iflow callback target" )
2376- c .JSON (http .StatusInternalServerError , gin.H {"status" : "error" , "error" : "callback server unavailable" })
2377- return
2378- }
2379- var errStart error
2380- if forwarder , errStart = startCallbackForwarder (iflowauth .CallbackPort , "iflow" , targetURL ); errStart != nil {
2381- log .WithError (errStart ).Error ("failed to start iflow callback forwarder" )
2382- c .JSON (http .StatusInternalServerError , gin.H {"status" : "error" , "error" : "failed to start callback server" })
2383- return
2384- }
2385- }
2386-
2387- go func () {
2388- if isWebUI {
2389- defer stopCallbackForwarderInstance (iflowauth .CallbackPort , forwarder )
2390- }
2391- fmt .Println ("Waiting for authentication..." )
2392-
2393- waitFile := filepath .Join (h .cfg .AuthDir , fmt .Sprintf (".oauth-iflow-%s.oauth" , state ))
2394- deadline := time .Now ().Add (5 * time .Minute )
2395- var resultMap map [string ]string
2396- for {
2397- if ! IsOAuthSessionPending (state , "iflow" ) {
2398- return
2399- }
2400- if time .Now ().After (deadline ) {
2401- SetOAuthSessionError (state , "Authentication failed" )
2402- fmt .Println ("Authentication failed: timeout waiting for callback" )
2403- return
2404- }
2405- if data , errR := os .ReadFile (waitFile ); errR == nil {
2406- _ = os .Remove (waitFile )
2407- _ = json .Unmarshal (data , & resultMap )
2408- break
2409- }
2410- time .Sleep (500 * time .Millisecond )
2411- }
2412-
2413- if errStr := strings .TrimSpace (resultMap ["error" ]); errStr != "" {
2414- SetOAuthSessionError (state , "Authentication failed" )
2415- fmt .Printf ("Authentication failed: %s\n " , errStr )
2416- return
2417- }
2418- if resultState := strings .TrimSpace (resultMap ["state" ]); resultState != state {
2419- SetOAuthSessionError (state , "Authentication failed" )
2420- fmt .Println ("Authentication failed: state mismatch" )
2421- return
2422- }
2423-
2424- code := strings .TrimSpace (resultMap ["code" ])
2425- if code == "" {
2426- SetOAuthSessionError (state , "Authentication failed" )
2427- fmt .Println ("Authentication failed: code missing" )
2428- return
2429- }
2430-
2431- tokenData , errExchange := authSvc .ExchangeCodeForTokens (ctx , code , redirectURI )
2432- if errExchange != nil {
2433- SetOAuthSessionError (state , "Authentication failed" )
2434- fmt .Printf ("Authentication failed: %v\n " , errExchange )
2435- return
2436- }
2437-
2438- tokenStorage := authSvc .CreateTokenStorage (tokenData )
2439- identifier := strings .TrimSpace (tokenStorage .Email )
2440- if identifier == "" {
2441- identifier = fmt .Sprintf ("%d" , time .Now ().UnixMilli ())
2442- tokenStorage .Email = identifier
2443- }
2444- record := & coreauth.Auth {
2445- ID : fmt .Sprintf ("iflow-%s.json" , identifier ),
2446- Provider : "iflow" ,
2447- FileName : fmt .Sprintf ("iflow-%s.json" , identifier ),
2448- Storage : tokenStorage ,
2449- Metadata : map [string ]any {"email" : identifier , "api_key" : tokenStorage .APIKey },
2450- Attributes : map [string ]string {"api_key" : tokenStorage .APIKey },
2451- }
2452-
2453- savedPath , errSave := h .saveTokenRecord (ctx , record )
2454- if errSave != nil {
2455- SetOAuthSessionError (state , "Failed to save authentication tokens" )
2456- log .Errorf ("Failed to save authentication tokens: %v" , errSave )
2457- return
2458- }
2459-
2460- fmt .Printf ("Authentication successful! Token saved to %s\n " , savedPath )
2461- if tokenStorage .APIKey != "" {
2462- fmt .Println ("API key obtained and saved" )
2463- }
2464- fmt .Println ("You can now use iFlow services through this CLI" )
2465- CompleteOAuthSession (state )
2466- CompleteOAuthSessionsByProvider ("iflow" )
2467- }()
2468-
2469- c .JSON (http .StatusOK , gin.H {"status" : "ok" , "url" : authURL , "state" : state })
2470- }
2471-
2472- func (h * Handler ) RequestIFlowCookieToken (c * gin.Context ) {
2473- ctx := context .Background ()
2474-
2475- var payload struct {
2476- Cookie string `json:"cookie"`
2477- }
2478- if err := c .ShouldBindJSON (& payload ); err != nil {
2479- c .JSON (http .StatusBadRequest , gin.H {"status" : "error" , "error" : "cookie is required" })
2480- return
2481- }
2482-
2483- cookieValue := strings .TrimSpace (payload .Cookie )
2484-
2485- if cookieValue == "" {
2486- c .JSON (http .StatusBadRequest , gin.H {"status" : "error" , "error" : "cookie is required" })
2487- return
2488- }
2489-
2490- cookieValue , errNormalize := iflowauth .NormalizeCookie (cookieValue )
2491- if errNormalize != nil {
2492- c .JSON (http .StatusBadRequest , gin.H {"status" : "error" , "error" : errNormalize .Error ()})
2493- return
2494- }
2495-
2496- // Check for duplicate BXAuth before authentication
2497- bxAuth := iflowauth .ExtractBXAuth (cookieValue )
2498- if existingFile , err := iflowauth .CheckDuplicateBXAuth (h .cfg .AuthDir , bxAuth ); err != nil {
2499- c .JSON (http .StatusInternalServerError , gin.H {"status" : "error" , "error" : "failed to check duplicate" })
2500- return
2501- } else if existingFile != "" {
2502- existingFileName := filepath .Base (existingFile )
2503- c .JSON (http .StatusConflict , gin.H {"status" : "error" , "error" : "duplicate BXAuth found" , "existing_file" : existingFileName })
2504- return
2505- }
2506-
2507- authSvc := iflowauth .NewIFlowAuth (h .cfg )
2508- tokenData , errAuth := authSvc .AuthenticateWithCookie (ctx , cookieValue )
2509- if errAuth != nil {
2510- c .JSON (http .StatusBadRequest , gin.H {"status" : "error" , "error" : errAuth .Error ()})
2511- return
2512- }
2513-
2514- tokenData .Cookie = cookieValue
2515-
2516- tokenStorage := authSvc .CreateCookieTokenStorage (tokenData )
2517- email := strings .TrimSpace (tokenStorage .Email )
2518- if email == "" {
2519- c .JSON (http .StatusBadRequest , gin.H {"status" : "error" , "error" : "failed to extract email from token" })
2520- return
2521- }
2522-
2523- fileName := iflowauth .SanitizeIFlowFileName (email )
2524- if fileName == "" {
2525- fileName = fmt .Sprintf ("iflow-%d" , time .Now ().UnixMilli ())
2526- } else {
2527- fileName = fmt .Sprintf ("iflow-%s" , fileName )
2528- }
2529-
2530- tokenStorage .Email = email
2531- timestamp := time .Now ().Unix ()
2532-
2533- record := & coreauth.Auth {
2534- ID : fmt .Sprintf ("%s-%d.json" , fileName , timestamp ),
2535- Provider : "iflow" ,
2536- FileName : fmt .Sprintf ("%s-%d.json" , fileName , timestamp ),
2537- Storage : tokenStorage ,
2538- Metadata : map [string ]any {
2539- "email" : email ,
2540- "api_key" : tokenStorage .APIKey ,
2541- "expired" : tokenStorage .Expire ,
2542- "cookie" : tokenStorage .Cookie ,
2543- "type" : tokenStorage .Type ,
2544- "last_refresh" : tokenStorage .LastRefresh ,
2545- },
2546- Attributes : map [string ]string {
2547- "api_key" : tokenStorage .APIKey ,
2548- },
2549- }
2550-
2551- savedPath , errSave := h .saveTokenRecord (ctx , record )
2552- if errSave != nil {
2553- c .JSON (http .StatusInternalServerError , gin.H {"status" : "error" , "error" : "failed to save authentication tokens" })
2554- return
2555- }
2556-
2557- fmt .Printf ("iFlow cookie authentication successful. Token saved to %s\n " , savedPath )
2558- c .JSON (http .StatusOK , gin.H {
2559- "status" : "ok" ,
2560- "saved_path" : savedPath ,
2561- "email" : email ,
2562- "expired" : tokenStorage .Expire ,
2563- "type" : tokenStorage .Type ,
2564- })
2565- }
2566-
25672357type projectSelectionRequiredError struct {}
25682358
25692359func (e * projectSelectionRequiredError ) Error () string {
0 commit comments