mirror of
https://github.com/warmbly/warmbly.git
synced 2026-10-05 00:02:12 +00:00
fix: accept a live refresh token as proof of the offline_access grant when checking Microsoft consent, because the v2.0 token response echoes only the scopes the access token is valid for and never lists offline_access, which was turning working Outlook mailboxes away at onboarding (#500)
This commit is contained in:
@@ -419,6 +419,10 @@ func fetchInboxOwner(ctx context.Context, provider models.InboxProvider, accessT
|
||||
// Microsoft return a space-separated "scope" alongside the token; an empty or
|
||||
// absent one means the provider did not say, which is not the same as "nothing
|
||||
// was granted" and must not be read as a denial.
|
||||
//
|
||||
// Microsoft does not echo offline_access in the scope list (documented: it is
|
||||
// not an access-token scope), even when a refresh token was issued, so a live
|
||||
// refresh token confers it: without one there is nothing to refresh.
|
||||
func grantedScopes(tok *oauth2.Token) (map[string]bool, bool) {
|
||||
raw, _ := tok.Extra("scope").(string)
|
||||
if strings.TrimSpace(raw) == "" {
|
||||
@@ -428,6 +432,9 @@ func grantedScopes(tok *oauth2.Token) (map[string]bool, bool) {
|
||||
for _, sc := range strings.Fields(raw) {
|
||||
out[sc] = true
|
||||
}
|
||||
if tok.RefreshToken != "" {
|
||||
out["offline_access"] = true
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
|
||||
@@ -173,6 +173,22 @@ func TestOutlookPartialConsentIsRefused(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Microsoft does not echo offline_access in the scope list for personal
|
||||
// accounts even when a refresh token was issued, so the live token confers
|
||||
// the grant the list omits.
|
||||
func TestOutlookRefreshTokenSatisfiesOfflineAccess(t *testing.T) {
|
||||
want := []string{
|
||||
"https://graph.microsoft.com/Mail.Send",
|
||||
"https://graph.microsoft.com/Mail.ReadWrite",
|
||||
"offline_access",
|
||||
}
|
||||
xerr := checkGrantedScopes(context.Background(), models.InboxProviderOutlook, want,
|
||||
tokenWithScope("https://graph.microsoft.com/Mail.Send https://graph.microsoft.com/Mail.ReadWrite"))
|
||||
if xerr != nil {
|
||||
t.Fatalf("a live refresh token must satisfy offline_access, got %v", xerr)
|
||||
}
|
||||
}
|
||||
|
||||
// ── what may be recorded ─────────────────────────────────────────────────────
|
||||
|
||||
// A decode failure and a missing address both carry status 200, and that body
|
||||
|
||||
Reference in New Issue
Block a user