Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func exchangeCode(code, redirectURI, clientID, clientSecret string) error {
AccessToken: resp.AccessToken,
RefreshToken: resp.RefreshToken,
ExpiresAt: time.Now().Add(time.Duration(resp.ExpiresIn) * time.Second).Add(-5 * time.Minute),
UserID: resp.UserID,
UserID: resp.UserID.String(),
ClientID: clientID,
ClientSecret: clientSecret,
}
Expand All @@ -201,19 +201,19 @@ func refresh(store *TokenStore) error {
store.AccessToken = resp.AccessToken
store.RefreshToken = resp.RefreshToken
store.ExpiresAt = time.Now().Add(time.Duration(resp.ExpiresIn) * time.Second).Add(-5 * time.Minute)
if resp.UserID != "" {
store.UserID = resp.UserID
if resp.UserID.String() != "" {
store.UserID = resp.UserID.String()
}
return save(store)
}

type tokenResponse struct {
UserID string `json:"userid"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
TokenType string `json:"token_type"`
UserID json.Number `json:"userid"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
TokenType string `json:"token_type"`
}

func postToken(form url.Values, out *tokenResponse) error {
Expand Down
30 changes: 30 additions & 0 deletions internal/auth/auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package auth

import (
"encoding/json"
"testing"
)

// Withings returns userid as a JSON string on the initial authorization_code
// grant and as a JSON number on the refresh_token grant. tokenResponse.UserID
// must unmarshal both without error — json.Number accepts either form.
func TestTokenResponse_UserIDUnmarshalsStringAndNumber(t *testing.T) {
cases := []struct {
name string
body string
}{
{"string form (initial login)", `{"userid":"12345","access_token":"a","refresh_token":"r","expires_in":10800,"scope":"s","token_type":"Bearer"}`},
{"number form (refresh)", `{"userid":12345,"access_token":"a","refresh_token":"r","expires_in":10800,"scope":"s","token_type":"Bearer"}`},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
var resp tokenResponse
if err := json.Unmarshal([]byte(tc.body), &resp); err != nil {
t.Fatalf("unmarshal failed: %v", err)
}
if resp.UserID.String() != "12345" {
t.Fatalf("UserID = %q, want %q", resp.UserID.String(), "12345")
}
})
}
}
Loading