aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/xoauth2.go40
-rw-r--r--worker/imap/connect.go2
2 files changed, 40 insertions, 2 deletions
diff --git a/lib/xoauth2.go b/lib/xoauth2.go
index 83f06309..c0f654b8 100644
--- a/lib/xoauth2.go
+++ b/lib/xoauth2.go
@@ -12,9 +12,12 @@ import (
"context"
"encoding/json"
"fmt"
+ "os"
+ "path"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-sasl"
+ "github.com/kyoh86/xdg"
"golang.org/x/oauth2"
)
@@ -69,17 +72,52 @@ func (c *Xoauth2) ExchangeRefreshToken(refreshToken string) (*oauth2.Token, erro
return c.OAuth2.TokenSource(context.TODO(), token).Token()
}
-func (c *Xoauth2) Authenticate(username string, password string, client *client.Client) error {
+func SaveRefreshToken(refreshToken string, acct string) error {
+ p := path.Join(xdg.CacheHome(), "aerc", acct+"-xoauth2.token")
+ if _, err := os.Stat(p); os.IsNotExist(err) {
+ _ = os.MkdirAll(path.Join(xdg.CacheHome(), "aerc"), 0o700)
+ }
+
+ return os.WriteFile(
+ p,
+ []byte(refreshToken),
+ 0o600,
+ )
+}
+
+func GetRefreshToken(acct string) ([]byte, error) {
+ p := path.Join(xdg.CacheHome(), "aerc", acct+"-xoauth2.token")
+ return os.ReadFile(p)
+}
+
+func (c *Xoauth2) Authenticate(
+ username string,
+ password string,
+ account string,
+ client *client.Client,
+) error {
if ok, err := client.SupportAuth("XOAUTH2"); err != nil || !ok {
return fmt.Errorf("Xoauth2 not supported %w", err)
}
if c.OAuth2.Endpoint.TokenURL != "" {
+ usedCache := false
+ if r, err := GetRefreshToken(account); err == nil && len(r) > 0 {
+ password = string(r)
+ usedCache = true
+ }
+
token, err := c.ExchangeRefreshToken(password)
if err != nil {
+ if usedCache {
+ return fmt.Errorf("try removing cached refresh token. %w", err)
+ }
return err
}
password = token.AccessToken
+ if err := SaveRefreshToken(token.RefreshToken, account); err != nil {
+ return err
+ }
}
saslClient := NewXoauth2Client(username, password)
diff --git a/worker/imap/connect.go b/worker/imap/connect.go
index 5be916e7..6f341753 100644
--- a/worker/imap/connect.go
+++ b/worker/imap/connect.go
@@ -82,7 +82,7 @@ func (w *IMAPWorker) connect() (*client.Client, error) {
}
} else if w.config.xoauth2.Enabled {
if err := w.config.xoauth2.Authenticate(
- username, password, c); err != nil {
+ username, password, w.worker.Name, c); err != nil {
return nil, err
}
} else if err := c.Login(username, password); err != nil {