From de00171064a418319d3de13596abd0b54c91c38b Mon Sep 17 00:00:00 2001 From: Antonio Date: Mon, 17 Jul 2023 04:32:59 +0800 Subject: [PATCH] bump deps --- go.mod | 2 +- go.sum | 2 + tools/authenticator/auth/auth.go | 417 ------------------------------- tools/authenticator/go.mod | 10 +- tools/authenticator/go.sum | 6 + tools/authenticator/main.go | 6 +- 6 files changed, 18 insertions(+), 425 deletions(-) delete mode 100644 tools/authenticator/auth/auth.go diff --git a/go.mod b/go.mod index c40f66e..8e50888 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module freechatgpt go 1.20 require ( - github.com/acheong08/OpenAIAuth v0.0.0-20230609193408-55a0f33f1057 + github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507 github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd github.com/acheong08/funcaptcha v1.2.2-0.20230702093045-02d1fbf1b0e8 github.com/bogdanfinn/fhttp v0.5.23 diff --git a/go.sum b/go.sum index 33f343b..4d5fa6d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/acheong08/OpenAIAuth v0.0.0-20230609193408-55a0f33f1057 h1:AmqKpClFTUHREYekSfSy3Yn7MR/oc6WTfKtEyzB/J7o= github.com/acheong08/OpenAIAuth v0.0.0-20230609193408-55a0f33f1057/go.mod h1:ES3Dh9hnbR2mDPlNTagj5e3b4nXECd4tbAjVgxggXEE= +github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507 h1:1kZEmE1DeQEeIMHhQUqn+NqOdApF9BIv835ox09E2k8= +github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507/go.mod h1:bkiXtklBFVpWHyWTys6Zhqb521i/gtT8cIUKWVx2m/M= github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd h1:oIpfrRhD7Jus41dotbK+SQjWSFRnf1cLZUYCZpF/o/4= github.com/acheong08/endless v0.0.0-20230615162514-90545c7793fd/go.mod h1:0yO7neMeJLvKk/B/fq5votDY8rByrOPDubpvU+6saKo= github.com/acheong08/funcaptcha v0.2.1-0.20230628085018-57a8c9b81bc8 h1:COt2vPM8gz+PiUjeWH1enYPfMM3FiM/HFELqU6nO2PQ= diff --git a/tools/authenticator/auth/auth.go b/tools/authenticator/auth/auth.go deleted file mode 100644 index 2170216..0000000 --- a/tools/authenticator/auth/auth.go +++ /dev/null @@ -1,417 +0,0 @@ -package auth - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "net/url" - "regexp" - "strings" - - "crypto/rand" - - http "github.com/bogdanfinn/fhttp" - tls_client "github.com/bogdanfinn/tls-client" - pkce "github.com/nirasan/go-oauth-pkce-code-verifier" -) - -type Error struct { - Location string - StatusCode int - Details string - Error error -} - -func NewError(location string, statusCode int, details string, err error) *Error { - return &Error{ - Location: location, - StatusCode: statusCode, - Details: details, - Error: err, - } -} - -type Authenticator struct { - EmailAddress string - Password string - Proxy string - Session tls_client.HttpClient - UserAgent string - State string - URL string - Verifier_code string - Verifier_challenge string - AuthRequest AuthRequest - AuthResult AuthResult -} - -type AuthRequest struct { - ClientID string `json:"client_id"` - Scope string `json:"scope"` - ResponseType string `json:"response_type"` - RedirectURL string `json:"redirect_url"` - Audience string `json:"audience"` - Prompt string `json:"prompt"` - State string `json:"state"` - CodeChallenge string `json:"code_challenge"` - CodeChallengeMethod string `json:"code_challenge_method"` -} - -type AuthResult struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - PUID string `json:"puid"` -} - -func NewAuthDetails(challenge string) AuthRequest { - // Generate state (secrets.token_urlsafe(32)) - b := make([]byte, 32) - rand.Read(b) - state := base64.URLEncoding.EncodeToString(b) - return AuthRequest{ - ClientID: "pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh", - Scope: "openid email profile offline_access model.request model.read organization.read", - ResponseType: "code", - RedirectURL: "com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback", - Audience: "https://api.openai.com/v1", - Prompt: "login", - State: state, - CodeChallenge: challenge, - CodeChallengeMethod: "S256", - } -} - -func NewAuthenticator(emailAddress, password, proxy string) *Authenticator { - auth := &Authenticator{ - EmailAddress: emailAddress, - Password: password, - Proxy: proxy, - UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", - } - jar := tls_client.NewCookieJar() - options := []tls_client.HttpClientOption{ - tls_client.WithTimeoutSeconds(20), - tls_client.WithClientProfile(tls_client.Firefox_102), - tls_client.WithNotFollowRedirects(), - tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument - // Proxy - tls_client.WithProxyUrl(proxy), - } - auth.Session, _ = tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) - - // PKCE - verifier, _ := pkce.CreateCodeVerifier() - auth.Verifier_code = verifier.String() - auth.Verifier_challenge = verifier.CodeChallengeS256() - - auth.AuthRequest = NewAuthDetails(auth.Verifier_challenge) - - return auth -} - -func (auth *Authenticator) URLEncode(str string) string { - return url.QueryEscape(str) -} - -func (auth *Authenticator) Begin() *Error { - // Just realized that the client id is hardcoded in the JS file - - return auth.partOne() -} -func (auth *Authenticator) partOne() *Error { - - auth_url := "https://auth0.openai.com/authorize" - headers := map[string]string{ - "User-Agent": auth.UserAgent, - "Content-Type": "application/x-www-form-urlencoded", - "Accept": "*/*", - "Sec-Gpc": "1", - "Accept-Language": "en-US,en;q=0.8", - "Origin": "https://chat.openai.com", - "Sec-Fetch-Site": "same-origin", - "Sec-Fetch-Mode": "cors", - "Sec-Fetch-Dest": "empty", - "Referer": "https://chat.openai.com/auth/login", - "Accept-Encoding": "gzip, deflate", - } - // Construct payload - payload := url.Values{ - "client_id": {auth.AuthRequest.ClientID}, - "scope": {auth.AuthRequest.Scope}, - "response_type": {auth.AuthRequest.ResponseType}, - "redirect_uri": {auth.AuthRequest.RedirectURL}, - "audience": {auth.AuthRequest.Audience}, - "prompt": {auth.AuthRequest.Prompt}, - "state": {auth.AuthRequest.State}, - "code_challenge": {auth.AuthRequest.CodeChallenge}, - "code_challenge_method": {auth.AuthRequest.CodeChallengeMethod}, - } - auth_url = auth_url + "?" + payload.Encode() - req, _ := http.NewRequest("GET", auth_url, nil) - - for k, v := range headers { - req.Header.Set(k, v) - } - - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("part_one", 0, "Failed to send request", err) - } - defer resp.Body.Close() - body, err := io.ReadAll(resp.Body) - if err != nil { - return NewError("part_one", 0, "Failed to read body", err) - } - - if resp.StatusCode == 302 { - return auth.partTwo("https://auth0.openai.com" + resp.Header.Get("Location")) - } else { - return NewError("part_one", resp.StatusCode, string(body), fmt.Errorf("error: Check details")) - } -} - -func (auth *Authenticator) partTwo(url string) *Error { - - headers := map[string]string{ - "Host": "auth0.openai.com", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - "Connection": "keep-alive", - "User-Agent": auth.UserAgent, - "Accept-Language": "en-US,en;q=0.9", - "Referer": "https://ios.chat.openai.com/", - } - - req, _ := http.NewRequest("GET", url, nil) - for k, v := range headers { - req.Header.Set(k, v) - } - - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("part_two", 0, "Failed to make request", err) - } - defer resp.Body.Close() - body, _ := io.ReadAll(resp.Body) - - if resp.StatusCode == 302 || resp.StatusCode == 200 { - - stateRegex := regexp.MustCompile(`state=(.*)`) - stateMatch := stateRegex.FindStringSubmatch(string(body)) - if len(stateMatch) < 2 { - return NewError("part_two", 0, "Could not find state in response", fmt.Errorf("error: Check details")) - } - - state := strings.Split(stateMatch[1], `"`)[0] - return auth.partThree(state) - } else { - return NewError("__part_two", resp.StatusCode, string(body), fmt.Errorf("error: Check details")) - - } -} -func (auth *Authenticator) partThree(state string) *Error { - - url := fmt.Sprintf("https://auth0.openai.com/u/login/identifier?state=%s", state) - emailURLEncoded := auth.URLEncode(auth.EmailAddress) - - payload := fmt.Sprintf( - "state=%s&username=%s&js-available=false&webauthn-available=true&is-brave=false&webauthn-platform-available=true&action=default", - state, emailURLEncoded, - ) - - headers := map[string]string{ - "Host": "auth0.openai.com", - "Origin": "https://auth0.openai.com", - "Connection": "keep-alive", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - "User-Agent": auth.UserAgent, - "Referer": fmt.Sprintf("https://auth0.openai.com/u/login/identifier?state=%s", state), - "Accept-Language": "en-US,en;q=0.9", - "Content-Type": "application/x-www-form-urlencoded", - } - - req, _ := http.NewRequest("POST", url, strings.NewReader(payload)) - - for k, v := range headers { - req.Header.Set(k, v) - } - - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("part_four", 0, "Failed to send request", err) - } - defer resp.Body.Close() - - if resp.StatusCode == 302 || resp.StatusCode == 200 { - return auth.partFour(state) - } else { - return NewError("__part_four", resp.StatusCode, "Your email address is invalid.", fmt.Errorf("error: Check details")) - - } - -} -func (auth *Authenticator) partFour(state string) *Error { - - url := fmt.Sprintf("https://auth0.openai.com/u/login/password?state=%s", state) - emailURLEncoded := auth.URLEncode(auth.EmailAddress) - passwordURLEncoded := auth.URLEncode(auth.Password) - payload := fmt.Sprintf("state=%s&username=%s&password=%s&action=default", state, emailURLEncoded, passwordURLEncoded) - - headers := map[string]string{ - "Host": "auth0.openai.com", - "Origin": "https://auth0.openai.com", - "Connection": "keep-alive", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - "User-Agent": auth.UserAgent, - "Referer": fmt.Sprintf("https://auth0.openai.com/u/login/password?state=%s", state), - "Accept-Language": "en-US,en;q=0.9", - "Content-Type": "application/x-www-form-urlencoded", - } - - req, _ := http.NewRequest("POST", url, strings.NewReader(payload)) - - for k, v := range headers { - req.Header.Set(k, v) - } - - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("part_five", 0, "Failed to send request", err) - } - defer resp.Body.Close() - - if resp.StatusCode == 302 { - redirectURL := resp.Header.Get("Location") - return auth.partFive(state, redirectURL) - } else { - body := bytes.NewBuffer(nil) - body.ReadFrom(resp.Body) - return NewError("__part_five", resp.StatusCode, body.String(), fmt.Errorf("error: Check details")) - - } - -} -func (auth *Authenticator) partFive(oldState string, redirectURL string) *Error { - - url := "https://auth0.openai.com" + redirectURL - - headers := map[string]string{ - "Host": "auth0.openai.com", - "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", - "Connection": "keep-alive", - "User-Agent": auth.UserAgent, - "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8", - "Referer": fmt.Sprintf("https://auth0.openai.com/u/login/password?state=%s", oldState), - } - - req, _ := http.NewRequest("GET", url, nil) - - for k, v := range headers { - req.Header.Set(k, v) - } - - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("part_six", 0, "Failed to send request", err) - } - defer resp.Body.Close() - - if resp.StatusCode == 302 { - auth.URL = resp.Header.Get("Location") - return auth.partSix() - } else { - return NewError("__part_six", resp.StatusCode, resp.Status, fmt.Errorf("error: Check details")) - - } - -} -func (auth *Authenticator) partSix() *Error { - code := regexp.MustCompile(`code=(.*)&`).FindStringSubmatch(auth.URL) - if len(code) == 0 { - return NewError("__get_access_token", 0, auth.URL, fmt.Errorf("error: Check details")) - } - payload, _ := json.Marshal(map[string]string{ - "redirect_uri": "com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback", - "grant_type": "authorization_code", - "client_id": "pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh", - "code": code[1], - "code_verifier": auth.Verifier_code, - "state": auth.State, - }) - - req, _ := http.NewRequest("POST", "https://auth0.openai.com/oauth/token", strings.NewReader(string(payload))) - for k, v := range map[string]string{ - "User-Agent": auth.UserAgent, - "content-type": "application/json", - } { - req.Header.Set(k, v) - } - resp, err := auth.Session.Do(req) - if err != nil { - return NewError("get_access_token", 0, "Failed to send request", err) - } - defer resp.Body.Close() - // Parse response - body, _ := io.ReadAll(resp.Body) - // Parse as JSON - var data map[string]interface{} - - err = json.Unmarshal(body, &data) - - if err != nil { - return NewError("get_access_token", 0, "Response was not JSON", err) - } - - // Check if access token in data - if _, ok := data["access_token"]; !ok { - return NewError("get_access_token", 0, "Missing access token", fmt.Errorf("error: Check details")) - } - auth.AuthResult.AccessToken = data["access_token"].(string) - auth.AuthResult.RefreshToken = data["refresh_token"].(string) - - return nil -} - -func (auth *Authenticator) GetAccessToken() string { - return auth.AuthResult.AccessToken -} - -func (auth *Authenticator) GetPUID() (string, *Error) { - // Check if user has access token - if auth.AuthResult.AccessToken == "" { - return "", NewError("get_puid", 0, "Missing access token", fmt.Errorf("error: Check details")) - } - // Make request to https://chat.openai.com/backend-api/models - req, _ := http.NewRequest("GET", "https://chat.openai.com/backend-api/models", nil) - // Add headers - req.Header.Add("Authorization", "Bearer "+auth.AuthResult.AccessToken) - req.Header.Add("User-Agent", auth.UserAgent) - req.Header.Add("Accept", "application/json") - req.Header.Add("Accept-Language", "en-US,en;q=0.9") - req.Header.Add("Referer", "https://chat.openai.com/") - req.Header.Add("Origin", "https://chat.openai.com") - req.Header.Add("Connection", "keep-alive") - - resp, err := auth.Session.Do(req) - if err != nil { - return "", NewError("get_puid", 0, "Failed to make request", err) - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - return "", NewError("get_puid", resp.StatusCode, "Failed to make request", fmt.Errorf("error: Check details")) - } - // Find `_puid` cookie in response - for _, cookie := range resp.Cookies() { - if cookie.Name == "_puid" { - auth.AuthResult.PUID = cookie.Value - return cookie.Value, nil - } - } - // If cookie not found, return error - return "", NewError("get_puid", 0, "PUID cookie not found", fmt.Errorf("error: Check details")) -} - -func (auth *Authenticator) GetAuthResult() AuthResult { - return auth.AuthResult -} diff --git a/tools/authenticator/go.mod b/tools/authenticator/go.mod index e6a8108..c5ceb41 100644 --- a/tools/authenticator/go.mod +++ b/tools/authenticator/go.mod @@ -2,16 +2,16 @@ module authenticator go 1.20 -require ( - github.com/bogdanfinn/fhttp v0.5.22 - github.com/bogdanfinn/tls-client v1.3.12 - github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c -) +require github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507 require ( github.com/andybalholm/brotli v1.0.5 // indirect + github.com/bogdanfinn/fhttp v0.5.22 // indirect + github.com/bogdanfinn/tls-client v1.3.12 // indirect github.com/bogdanfinn/utls v1.5.16 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/klauspost/compress v1.16.5 // indirect + github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c // indirect github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect golang.org/x/crypto v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect diff --git a/tools/authenticator/go.sum b/tools/authenticator/go.sum index 716c40b..bf86521 100644 --- a/tools/authenticator/go.sum +++ b/tools/authenticator/go.sum @@ -1,3 +1,7 @@ +github.com/acheong08/OpenAIAuth v0.0.0-20230716132312-c206753c0819 h1:LE8tbbgfCcsUJZfQlpCF95eA+b2M6Q30ipzFjcpWp/I= +github.com/acheong08/OpenAIAuth v0.0.0-20230716132312-c206753c0819/go.mod h1:ES3Dh9hnbR2mDPlNTagj5e3b4nXECd4tbAjVgxggXEE= +github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507 h1:1kZEmE1DeQEeIMHhQUqn+NqOdApF9BIv835ox09E2k8= +github.com/acheong08/OpenAIAuth v0.0.0-20230716134840-dbf5ba4f9507/go.mod h1:bkiXtklBFVpWHyWTys6Zhqb521i/gtT8cIUKWVx2m/M= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/bogdanfinn/fhttp v0.5.22 h1:U1jhZRtuaOanWWcm1WdMFnwMvSxUQgvO6berqAVTc5o= @@ -6,6 +10,8 @@ github.com/bogdanfinn/tls-client v1.3.12 h1:jpNj7owMY/oULUQyAhAv6tRFkliFGLyr8Qx1 github.com/bogdanfinn/tls-client v1.3.12/go.mod h1:Q46nwIm0wPCweDM3XZcupxEIsTOWo3HVYSSsDj02/Qo= github.com/bogdanfinn/utls v1.5.16 h1:NhhWkegEcYETBMj9nvgO4lwvc6NcLH+znrXzO3gnw4M= github.com/bogdanfinn/utls v1.5.16/go.mod h1:mHeRCi69cUiEyVBkKONB1cAbLjRcZnlJbGzttmiuK4o= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20220510032225-4f9f17eaec4c h1:4RYnE0ISVwRxm9Dfo7utw1dh0kdRDEmVYq2MFVLy5zI= diff --git a/tools/authenticator/main.go b/tools/authenticator/main.go index b17ee6c..8634379 100644 --- a/tools/authenticator/main.go +++ b/tools/authenticator/main.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "authenticator/auth" + auth "github.com/acheong08/OpenAIAuth/auth" ) type Account struct { @@ -126,7 +126,9 @@ func main() { println("Status code: " + fmt.Sprint(err.StatusCode)) println("Details: " + err.Details) println("Embedded error: " + err.Error.Error()) - return + // Sleep for 10 seconds + time.Sleep(10 * time.Second) + continue } access_token := authenticator.GetAccessToken() // Append access token to access_tokens.txt