X-Git-Url: http://git.giacomolli.uk/onechat/blobdiff_plain/6d1d9d9a7cf90b25a2e10af1c5bc56faee7e494c..5a93b6124068c2a8748fc0bfbb2a2d151815bcf0:/chatgpt.go?ds=inline diff --git a/chatgpt.go b/chatgpt.go index 302e143..8849ada 100644 --- a/chatgpt.go +++ b/chatgpt.go @@ -131,6 +131,7 @@ func (a *ChatGPTAuth) Login(ctx context.Context, out io.Writer) error { defer a.mutex.Unlock() var code ChatGPTDeviceCode + err := a.postJSON(ctx, "/api/accounts/deviceauth/usercode", map[string]string{ "client_id": chatgptClientID, }, &code) @@ -145,7 +146,7 @@ func (a *ChatGPTAuth) Login(ctx context.Context, out io.Writer) error { _, err = fmt.Fprintf(out, "Open %s/codex/device on any device and enter this code:\n\n %s\n\nWaiting for the approval...\n", a.issuer, userCode) if err != nil { - return err + return fmt.Errorf("write device code: %w", err) } grant, err := a.poll(ctx, code.DeviceAuthID, userCode, chatgptPollInterval(code.Interval)) @@ -164,8 +165,11 @@ func (a *ChatGPTAuth) Login(ctx context.Context, out io.Writer) error { } _, err = fmt.Fprintln(out, "Logged in.") + if err != nil { + return fmt.Errorf("write login result: %w", err) + } - return err + return nil } // read reads the token file. @@ -180,6 +184,7 @@ func (a *ChatGPTAuth) read() (ChatGPTTokenFile, error) { } var tokens ChatGPTTokenFile + err = json.Unmarshal(data, &tokens) if err == nil && (tokens.AccessToken == "" || tokens.RefreshToken == "" || tokens.AccountID == "") { err = errors.New("a token or the account ID is missing") @@ -196,6 +201,7 @@ func (a *ChatGPTAuth) read() (ChatGPTTokenFile, error) { // It keeps the old refresh token and ID token when the answer has none. func (a *ChatGPTAuth) refresh(ctx context.Context, tokens ChatGPTTokenFile) (ChatGPTTokenFile, error) { var response ChatGPTTokenResponse + err := a.postJSON(ctx, "/oauth/token", map[string]string{ "client_id": chatgptClientID, "grant_type": "refresh_token", @@ -252,6 +258,7 @@ func (a *ChatGPTAuth) poll(ctx context.Context, deviceID, userCode string, inter for { var grant ChatGPTDeviceGrant + status, err := a.post(ctx, "/api/accounts/deviceauth/token", "application/json", body, &grant) if err == nil && (grant.AuthorizationCode == "" || grant.CodeVerifier == "") { err = errors.New("device grant has no authorization code or code verifier") @@ -269,6 +276,7 @@ func (a *ChatGPTAuth) poll(ctx context.Context, deviceID, userCode string, inter select { case <-ctx.Done(): timer.Stop() + return ChatGPTDeviceGrant{}, fmt.Errorf("wait for approval: %w", ctx.Err()) case <-timer.C: } @@ -286,6 +294,7 @@ func (a *ChatGPTAuth) exchange(ctx context.Context, grant ChatGPTDeviceGrant) (C } var response ChatGPTTokenResponse + _, err := a.post(ctx, "/oauth/token", "application/x-www-form-urlencoded", []byte(form.Encode()), &response) if err != nil { return ChatGPTTokenFile{}, fmt.Errorf("exchange code for tokens: %w", err) @@ -334,6 +343,7 @@ func (a *ChatGPTAuth) post(ctx context.Context, path, contentType string, body [ } request.Header.Set("Content-Type", contentType) + response, err := a.http.Do(request) if err != nil { return 0, fmt.Errorf("send request: %w", err) @@ -414,6 +424,7 @@ func chatgptPollInterval(raw json.RawMessage) time.Duration { // none. func chatgptAccountID(token string) string { var claims map[string]json.RawMessage + if !chatgptDecodeClaims(token, &claims) { return "" }