fix(mal): distinguish silent token refresh from a fresh re-login
Two MAL login issues were caused by the refresh path being conflated with the full browser OAuth flow: 1. A spurious 'It is now safe to close your browser tab' dialog was shown after a *silent* background token refresh, even though the browser was never opened. The dialog now belongs only to the browser-callback handler (handleMyAnimeListCallback); the refresh raises no dialog. 2. When both the access token and the refresh token were invalid, the app reported MAL as logged in without a username. Now, if a refresh fails (HttpClient error, non-2xx, or an empty access token), the stale tokens are cleared and a fresh browser OAuth login is automatically initiated instead of silently returning an empty user. refreshMyAnimeListAuthorizationToken now returns a bool indicating whether a fresh access token was actually obtained, letting GetMyAnimeListLoggedInUser decide between retrying with the refreshed token or falling back to a full re-login.
This commit is contained in:
+30
-12
@@ -235,7 +235,7 @@ func getMyAnimeListAuthorizationToken(content string, verifier *CodeVerifier) My
|
|||||||
return post
|
return post
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshMyAnimeListAuthorizationToken() {
|
func refreshMyAnimeListAuthorizationToken() bool {
|
||||||
dataForURLs := struct {
|
dataForURLs := struct {
|
||||||
GrantType string `json:"grant_type"`
|
GrantType string `json:"grant_type"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
@@ -260,13 +260,15 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
response, err := http.NewRequest("POST", "https://myanimelist.net/v1/oauth2/token", strings.NewReader(data.Encode()))
|
response, err := http.NewRequest("POST", "https://myanimelist.net/v1/oauth2/token", strings.NewReader(data.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed at response, %s\n", err)
|
log.Printf("Failed at response, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
response.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
response.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
res, resErr := client.Do(response)
|
res, resErr := client.Do(response)
|
||||||
if resErr != nil {
|
if resErr != nil {
|
||||||
log.Printf("Failed at res, %s\n", err)
|
log.Printf("Failed at res, %s\n", resErr)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
@@ -274,13 +276,22 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
returnedBody, err := io.ReadAll(res.Body)
|
returnedBody, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Could not read returned body, %s\n", err)
|
log.Printf("Could not read returned body, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(returnedBody, &myAnimeListJwt)
|
var refreshed MyAnimeListJWT
|
||||||
|
err = json.Unmarshal(returnedBody, &refreshed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed at unmarshal, %s\n", err)
|
log.Printf("Failed at unmarshal, %s\n", err)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if refreshed.AccessToken == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
myAnimeListJwt = refreshed
|
||||||
|
|
||||||
_ = myAnimeListRing.Set(keyring.Item{
|
_ = myAnimeListRing.Set(keyring.Item{
|
||||||
Key: "MyAnimeListTokenType",
|
Key: "MyAnimeListTokenType",
|
||||||
Data: []byte(myAnimeListJwt.TokenType),
|
Data: []byte(myAnimeListJwt.TokenType),
|
||||||
@@ -297,26 +308,33 @@ func refreshMyAnimeListAuthorizationToken() {
|
|||||||
Key: "MyAnimeListRefreshToken",
|
Key: "MyAnimeListRefreshToken",
|
||||||
Data: []byte(myAnimeListJwt.RefreshToken),
|
Data: []byte(myAnimeListJwt.RefreshToken),
|
||||||
})
|
})
|
||||||
_, err = runtime.MessageDialog(*wailsContext, runtime.MessageDialogOptions{
|
return true
|
||||||
Title: "MyAnimeList Authorization",
|
|
||||||
Message: "It is now safe to close your browser tab",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetMyAnimeListLoggedInUser() MyAnimeListUser {
|
func (a *App) GetMyAnimeListLoggedInUser() MyAnimeListUser {
|
||||||
a.MyAnimeListLogin()
|
a.MyAnimeListLogin()
|
||||||
user := createUser()
|
user := createUser()
|
||||||
if user.Name == "" {
|
if user.Name == "" && !a.refreshMyAnimeListAndGetUser(&user) {
|
||||||
refreshMyAnimeListAuthorizationToken()
|
a.LogoutMyAnimeList()
|
||||||
|
a.MyAnimeListLogin()
|
||||||
user = createUser()
|
user = createUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) refreshMyAnimeListAndGetUser(user *MyAnimeListUser) bool {
|
||||||
|
if !refreshMyAnimeListAuthorizationToken() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
freshUser := createUser()
|
||||||
|
if freshUser.Name == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*user = freshUser
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func createUser() MyAnimeListUser {
|
func createUser() MyAnimeListUser {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user