Skip to content

Commit

Permalink
minecraft/auth: Improve authentication errors & fix ExpiresIn deseria…
Browse files Browse the repository at this point in the history
…lization (#232)
  • Loading branch information
HashimTheArab authored Aug 2, 2024
1 parent 1d84b30 commit 01d3093
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
24 changes: 13 additions & 11 deletions minecraft/auth/live.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package auth
import (
"encoding/json"
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2/microsoft"
"io"
"net/http"
"net/url"
"os"
"time"

"golang.org/x/oauth2"
"golang.org/x/oauth2/microsoft"
)

// TokenSource holds an oauth2.TokenSource which uses device auth to get a code. The user authenticates using
Expand Down Expand Up @@ -143,7 +144,7 @@ func pollDeviceAuth(deviceCode string) (t *oauth2.Token, err error) {
Expiry: time.Now().Add(time.Duration(poll.ExpiresIn) * time.Second),
}, nil
}
return nil, fmt.Errorf("non-empty unknown poll error: %v", poll.Error)
return nil, fmt.Errorf("%v: %v", poll.Error, poll.ErrorDescription)
}

// refreshToken refreshes the oauth2.Token passed and returns a new oauth2.Token. An error is returned if
Expand Down Expand Up @@ -181,15 +182,16 @@ type deviceAuthConnect struct {
DeviceCode string `json:"device_code"`
VerificationURI string `json:"verification_uri"`
Interval int `json:"interval"`
ExpiresIn int `json:"expiresIn"`
ExpiresIn int `json:"expires_in"`
}

type deviceAuthPoll struct {
Error string `json:"error"`
UserID string `json:"user_id"`
TokenType string `json:"token_type"`
Scope string `json:"scope"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int `json:"expires_in"`
Error string `json:"error"`
ErrorDescription string `json:"error_description"`
UserID string `json:"user_id"`
TokenType string `json:"token_type"`
Scope string `json:"scope"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int `json:"expires_in"`
}
34 changes: 32 additions & 2 deletions minecraft/auth/xbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
"encoding/binary"
"encoding/json"
"fmt"
"github.com/google/uuid"
"golang.org/x/oauth2"
"net/http"
"time"

"github.com/google/uuid"
"golang.org/x/oauth2"
)

// XBLToken holds info on the authorization token used for authenticating with XBOX Live.
Expand Down Expand Up @@ -93,6 +94,10 @@ func obtainXBLToken(ctx context.Context, c *http.Client, key *ecdsa.PrivateKey,
_ = resp.Body.Close()
}()
if resp.StatusCode != 200 {
// Xbox Live returns a custom error code in the x-err header.
if errorCode := resp.Header.Get("x-err"); errorCode != "" {
return nil, fmt.Errorf("POST %v: %v", "https://sisu.xboxlive.com/authorize", parseXboxErrorCode(errorCode))
}
return nil, fmt.Errorf("POST %v: %v", "https://sisu.xboxlive.com/authorize", resp.Status)
}
info := new(XBLToken)
Expand Down Expand Up @@ -191,3 +196,28 @@ func sign(request *http.Request, body []byte, key *ecdsa.PrivateKey) {
func windowsTimestamp() int64 {
return (time.Now().Unix() + 11644473600) * 10000000
}

// parseXboxError returns the message associated with an Xbox Live error code.
func parseXboxErrorCode(code string) string {
switch code {
case "2148916227":
return "Your account was banned by Xbox for violating one or more Community Standards for Xbox and is unable to be used."
case "2148916229":
return "Your account is currently restricted and your guardian has not given you permission to play online. Login to https://account.microsoft.com/family/ and have your guardian change your permissions."
case "2148916233":
return "Your account currently does not have an Xbox profile. Please create one at https://signup.live.com/signup"
case "2148916234":
return "Your account has not accepted Xbox's Terms of Service. Please login and accept them."
case "2148916235":
return "Your account resides in a region that Xbox has not authorized use from. Xbox has blocked your attempt at logging in."
case "2148916236":
return "Your account requires proof of age. Please login to https://login.live.com/login.srf and provide proof of age."
case "2148916237":
return "Your account has reached its limit for playtime. Your account has been blocked from logging in."
case "2148916238":
return "The account date of birth is under 18 years and cannot proceed unless the account is added to a family by an adult."
default:
return fmt.Sprintf("unknown error code: %v", code)
}
}

0 comments on commit 01d3093

Please sign in to comment.