@@ -2,12 +2,14 @@ package yaakcli
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "github.com/pkg/browser"
78 "github.com/pterm/pterm"
89 "github.com/spf13/cobra"
10+ "golang.org/x/oauth2"
11+ "net"
912 "net/http"
10- "net/url"
1113 "os"
1214 "os/signal"
1315 "time"
@@ -19,72 +21,84 @@ var loginCmd = &cobra.Command{
1921 Long : "Open a web browser to authenticate with Yaak. Works with all browsers including Safari." ,
2022 Run : func (cmd * cobra.Command , args []string ) {
2123 CheckError (deleteAuthToken ())
22-
23- pterm .Info .Println ("Starting browser-based login..." )
24-
25- // Save the token to a config file
26- confirm := pterm .DefaultInteractiveConfirm
27- confirm .DefaultValue = true
28- open , err := confirm .Show ("Open default browser" )
29- CheckError (err )
30-
31- if ! open {
32- os .Exit (0 )
33- return
34- }
24+ baseURL := prodStagingDevStr ("https://yaak.app" , "https://todo.yaak.app" , "http://localhost:9444" )
3525
3626 // Create a channel to receive the auth token
3727 tokenChan := make (chan string , 1 )
3828
3929 // Set up a simple HTTP server to handle the OAuth callback
40- server := & http.Server {
41- Addr : "localhost:8085" ,
30+ listener , err := net .Listen ("tcp" , "127.0.0.1:0" )
31+ CheckError (err )
32+
33+ addr := listener .Addr ().(* net.TCPAddr )
34+ redirectURL := fmt .Sprintf ("http://127.0.0.1:%d/oauth/callback" , addr .Port )
35+
36+ // Open the browser to the login page
37+ oauthConfig := oauth2.Config {
38+ ClientID : "yaak-cli" ,
39+ ClientSecret : "" ,
40+ Endpoint : oauth2.Endpoint {
41+ AuthURL : baseURL + "/login/oauth/authorize" ,
42+ TokenURL : baseURL + "/login/oauth/access_token" ,
43+ },
44+ RedirectURL : redirectURL ,
45+ Scopes : nil ,
4246 }
47+ loginURL , err := AuthorizationURL (& oauthConfig )
48+ CheckError (err )
4349
44- // Define the handler for the callback
45- http .HandleFunc ("/oauth/callback" , func (w http.ResponseWriter , r * http.Request ) {
50+ mux := http .NewServeMux ()
51+
52+ mux .HandleFunc ("/oauth/callback" , func (w http.ResponseWriter , r * http.Request ) {
53+ h := OAuthRedirectHandler {
54+ State : loginURL .State ,
55+ CodeVerifier : loginURL .CodeVerifier ,
56+ OAuthConfig : & oauthConfig ,
57+ }
58+ token , err := h .ExchangeCode (r )
4659 // Get the token from the query parameters
47- token := r .URL .Query ().Get ("token" )
48- if token == "" {
60+ if err != nil {
4961 w .WriteHeader (http .StatusBadRequest )
50- _ , _ = fmt .Fprintf (w , "Error: No token provided" )
62+ _ , _ = fmt .Fprintf (w , "Failed to get access token: %s" , err . Error () )
5163 return
5264 }
5365
5466 // Send the token to the channel
5567 tokenChan <- token
5668
5769 // Return a success message to the browser
58- redirectTo := prodStagingDevStr (
59- "https://yaak.app/login-cli/success" ,
60- "https://todo.yaak.app/login-cli/success" ,
61- "http://localhost:9444/login-cli/success" ,
62- )
70+ redirectTo := baseURL + "/login/oauth/success"
6371 http .Redirect (w , r , redirectTo , http .StatusFound )
6472 })
6573
74+ server := & http.Server {Handler : mux }
75+
6676 // Start the server in a goroutine
6777 go func () {
68- if err := server .ListenAndServe ( ); err != http .ErrServerClosed {
78+ if err := server .Serve ( listener ); ! errors . Is ( err , http .ErrServerClosed ) {
6979 pterm .Error .Printf ("HTTP server error: %v\n " , err )
7080 os .Exit (1 )
7181 }
7282 }()
7383
84+ pterm .Info .Println ("Initiating login to" , loginURL )
85+
86+ confirm := pterm .DefaultInteractiveConfirm
87+ confirm .DefaultValue = true
88+ open , err := confirm .Show ("Open default browser" )
89+ CheckError (err )
90+
91+ if ! open {
92+ os .Exit (0 )
93+ return
94+ }
95+
7496 // Set up a signal handler to gracefully shut down the server
7597 sigChan := make (chan os.Signal , 1 )
7698 signal .Notify (sigChan , os .Interrupt )
7799
78- // Open the browser to the login page
79- redirect := "http://localhost:8085/oauth/callback"
80- loginURL := prodStagingDevStr (
81- "https://yaak.app/login-cli?redirect=" ,
82- "https://todo.yaak.app/login-cli?redirect=" ,
83- "http://localhost:9444/login-cli?redirect=" ,
84- ) + url .QueryEscape (redirect )
85-
86100 // Open the browser based on the operating system
87- err = browser .OpenURL (loginURL )
101+ err = browser .OpenURL (loginURL . String () )
88102 if err != nil {
89103 pterm .Error .Printf ("Failed to open browser: %v\n " , err )
90104 pterm .Info .Println ("Please open the following URL manually:" )
0 commit comments