package main import ( "encoding/json" "fmt" "io" "net/http" "net/url" "time" wruntime "github.com/wailsapp/wails/v2/pkg/runtime" ) type LauncherAuth struct { Id string Name string token string } type McProfile struct { Id string Name string } type devcodeResp struct { User_code string Device_code string Verification_url string Expires_in string Interval int Message string } type authenticationResp struct { Access_token string Token_type string Refresh_token string Expires_in string Error string Error_description string } type xboxAuthProperties struct { AuthMethod string SiteName string RpsTicket string } type xboxAuthRequest struct { Properties xboxAuthProperties RelyingParty string TokenType string } type xboxDisplayClaim struct { Uhs string Gtg string Xid string Agg string Usr string Utr string Prv string } type xboxDisplayClaims struct { Xui []xboxDisplayClaim } type xboxAuthResponse struct { IssueInstant time.Time NotAfter time.Time Token string DisplayClaims xboxDisplayClaims } type XSTSProperties struct { SandboxId string UserTokens []string } type XSTSRequest struct { Properties XSTSProperties RelyingParty string TokenType string } type McAuthRequest struct { Xtoken string `json:"xtoken"` Platform string `json:"platform"` } type McAuthResponse struct { Username string Access_token string Expires_in string Token_type string } func AuthCode(a App) (authenticationResp, error) { authentication := authenticationResp{} resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode", url.Values{ "client_id": {client_id}, "scope": {"XboxLive.SignIn XboxLive.offline_access"}, }) if err != nil { return authentication, fmt.Errorf("Unable to request device code: %e\n", err) } defer resp.Body.Close() if resp.StatusCode != 200 { return authentication, fmt.Errorf("Unable to request device code: %s\n", resp.Status) } data, _ := io.ReadAll(resp.Body) codeResp := devcodeResp{} json.Unmarshal(data, &codeResp) //display message wruntime.MessageDialog(a.Ctx, wruntime.MessageDialogOptions{Type: wruntime.InfoDialog, Title: "Authentication", Message: codeResp.Message}) ticker := time.NewTicker(time.Second * time.Duration(codeResp.Interval)) for range ticker.C { resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", url.Values{ "client_id": {client_id}, "grant_type": {"urn:ietf:params:oauth:grant-type:device_code"}, "device_code": {codeResp.Device_code}, }) if err != nil { return authentication, fmt.Errorf("Authentication request error %e\n", err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) json.Unmarshal(data, &authentication) if authentication.Error == "" { return authentication, nil } } return authentication, fmt.Errorf("Unknown error") } func TokenRefresh(app App, auth authenticationResp) (authenticationResp, error) { resp, err := http.PostForm("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", url.Values{ "client_id": {client_id}, "grant_type": {"refresh_token"}, "refresh_token": {auth.Refresh_token}, "scope": {"XboxLive.SignIn XboxLive.offline_access"}, }) if err != nil { return authenticationResp{}, fmt.Errorf("unable to request refresh token: %e\n", err) } defer resp.Body.Close() data, _ := io.ReadAll(resp.Body) authResp := authenticationResp{} json.Unmarshal(data, &authResp) return authResp, nil }