// Base code taken from: https://gist.github.com/marians/3b55318106df0e4e648158f1ffb43d38 package main import ( "context" "crypto/tls" // "fmt" "log" "net/http" // "net/url" "time" "github.com/fatih/color" //"github.com/skratchdot/open-golang/open" //"github.com/mxschmitt/playwright-go" "github.com/webview/webview" "golang.org/x/oauth2" ) var ( conf *oauth2.Config ctx context.Context w webview.WebView ) // func callbackHandler(w http.ResponseWriter, r *http.Request) { // queryParts, _ := url.ParseQuery(r.URL.RawQuery) // // Use the authorization code that is pushed to the redirect // // URL. // code := queryParts["code"][0] // log.Printf("code: %s\n", code) // // Exchange will do the handshake to retrieve the initial access token. // tok, err := conf.Exchange(ctx, code) // if err != nil { // log.Fatal(err) // } // log.Printf("Token: %s", tok) // // The HTTP Client returned by conf.Client will refresh the token as necessary. // client := conf.Client(ctx, tok) // resp, err := client.Get("https://embed.gog.com/user/data/games") // if err != nil { // log.Fatal(err) // } else { // log.Println(color.CyanString("Authentication successful")) // } // defer resp.Body.Close() // // show succes page // msg := "

Success!

" // msg = msg + "

You are authenticated and can now return to the CLI.

" // fmt.Fprintf(w, msg) // } func giveCode(code string) { log.Printf("Code: %s", code) // Exchange will do the handshake to retrieve the initial access token. tok, err := conf.Exchange(ctx, code) if err != nil { log.Fatal(err) } log.Printf("Token: %s", tok) // The HTTP Client returned by conf.Client will refresh the token as necessary. client := conf.Client(ctx, tok) _, err = client.Get("https://embed.gog.com/user/data/games") if err != nil { log.Fatal(err) } else { log.Println(color.CyanString("Authentication successful")) } w.Navigate(`data:text/html,

Success!

You are authenticated and can now return to the CLI.

`) time.Sleep(1 * time.Second) w.Destroy() } func openBrowser(url string) { w = webview.New(true) defer w.Destroy() w.SetTitle("Login") w.SetSize(600,600, webview.HintNone) w.Navigate(url) w.Bind("giveCode", giveCode) w.Init(` var params = new URLSearchParams(window.location.search); if (params.has('code')) { giveCode(params.get('code')); } `) w.Run() } // func plOpenBrowser(url string) { // pw, err := playwright.Run() // if err != nil { // log.Fatalf("Could not start playwright: %v", err) // } // browser, err := pw.Firefox.Launch() // if err != nil { // log.Fatalf("Could not launch browser: %v", err) // } // page, err := browser.NewPage() // if err != nil { // log.Fatalf("Could not create page: %v", err) // } // _, err = page.Goto(url) // if err != nil { // log.Fatalf("Could not go to %s: %v", url, err) // } // log.Println("Opened the url") // } func main() { ctx = context.Background() conf = &oauth2.Config{ ClientID: "46899977096215655", ClientSecret: "", Scopes: []string{}, Endpoint: oauth2.Endpoint{ AuthURL: "https://auth.gog.com/auth", TokenURL: "https://auth.gog.com/token", }, // my own callback URL RedirectURL: "https://embed.gog.com/on_login_success?origin=client", //"http://127.0.0.1:9999/oauth/callback", } // add transport for self-signed certificate to context tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } sslcli := &http.Client{Transport: tr} ctx = context.WithValue(ctx, oauth2.HTTPClient, sslcli) // Redirect user to consent page to ask for permission // for the scopes specified above. url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) log.Println(color.CyanString("You will now be taken to your browser for authentication")) time.Sleep(1 * time.Second) //open.Run(url) openBrowser(url) time.Sleep(1 * time.Second) log.Printf("Authentication URL: %s\n", url) //http.HandleFunc("/oauth/callback", callbackHandler) //log.Fatal(http.ListenAndServe(":9999", nil)) }