mirror of https://git.sr.ht/~rjarry/aerc
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.0 KiB
Go
188 lines
5.0 KiB
Go
package imap
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.sr.ht/~rjarry/aerc/lib/xdg"
|
|
"git.sr.ht/~rjarry/aerc/worker/lib"
|
|
"git.sr.ht/~rjarry/aerc/worker/middleware"
|
|
"git.sr.ht/~rjarry/aerc/worker/types"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
func (w *IMAPWorker) handleConfigure(msg *types.Configure) error {
|
|
w.config.name = msg.Config.Name
|
|
u, err := url.Parse(msg.Config.Source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
w.config.scheme = u.Scheme
|
|
if strings.HasSuffix(w.config.scheme, "+insecure") {
|
|
w.config.scheme = strings.TrimSuffix(w.config.scheme, "+insecure")
|
|
w.config.insecure = true
|
|
}
|
|
|
|
if strings.HasSuffix(w.config.scheme, "+oauthbearer") {
|
|
w.config.scheme = strings.TrimSuffix(w.config.scheme, "+oauthbearer")
|
|
w.config.oauthBearer.Enabled = true
|
|
q := u.Query()
|
|
|
|
oauth2 := &oauth2.Config{}
|
|
if q.Get("token_endpoint") != "" {
|
|
oauth2.ClientID = q.Get("client_id")
|
|
oauth2.ClientSecret = q.Get("client_secret")
|
|
oauth2.Scopes = []string{q.Get("scope")}
|
|
oauth2.Endpoint.TokenURL = q.Get("token_endpoint")
|
|
}
|
|
w.config.oauthBearer.OAuth2 = oauth2
|
|
}
|
|
|
|
if strings.HasSuffix(w.config.scheme, "+xoauth2") {
|
|
w.config.scheme = strings.TrimSuffix(w.config.scheme, "+xoauth2")
|
|
w.config.xoauth2.Enabled = true
|
|
q := u.Query()
|
|
|
|
oauth2 := &oauth2.Config{}
|
|
if q.Get("token_endpoint") != "" {
|
|
oauth2.ClientID = q.Get("client_id")
|
|
oauth2.ClientSecret = q.Get("client_secret")
|
|
oauth2.Scopes = []string{q.Get("scope")}
|
|
oauth2.Endpoint.TokenURL = q.Get("token_endpoint")
|
|
}
|
|
w.config.xoauth2.OAuth2 = oauth2
|
|
}
|
|
|
|
w.config.addr = u.Host
|
|
if !strings.ContainsRune(w.config.addr, ':') {
|
|
w.config.addr += ":" + w.config.scheme
|
|
}
|
|
|
|
w.config.user = u.User
|
|
w.config.folders = msg.Config.Folders
|
|
w.config.headers = msg.Config.Headers
|
|
w.config.headersExclude = msg.Config.HeadersExclude
|
|
|
|
w.config.idle_timeout = 10 * time.Second
|
|
w.config.idle_debounce = 10 * time.Millisecond
|
|
|
|
w.config.connection_timeout = 30 * time.Second
|
|
w.config.keepalive_period = 0 * time.Second
|
|
w.config.keepalive_probes = 3
|
|
w.config.keepalive_interval = 3
|
|
|
|
w.config.reconnect_maxwait = 30 * time.Second
|
|
|
|
w.config.cacheEnabled = false
|
|
w.config.cacheMaxAge = 30 * 24 * time.Hour // 30 days
|
|
|
|
for key, value := range msg.Config.Params {
|
|
switch key {
|
|
case "idle-timeout":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid idle-timeout value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.idle_timeout = val
|
|
case "idle-debounce":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid idle-debounce value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.idle_debounce = val
|
|
case "reconnect-maxwait":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid reconnect-maxwait value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.reconnect_maxwait = val
|
|
case "connection-timeout":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid connection-timeout value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.connection_timeout = val
|
|
case "keepalive-period":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid keepalive-period value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.keepalive_period = val
|
|
case "keepalive-probes":
|
|
val, err := strconv.Atoi(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid keepalive-probes value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.keepalive_probes = val
|
|
case "keepalive-interval":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf(
|
|
"invalid keepalive-interval value %v: %w",
|
|
value, err)
|
|
}
|
|
w.config.keepalive_interval = int(val.Seconds())
|
|
case "cache-headers":
|
|
cache, err := strconv.ParseBool(value)
|
|
if err != nil {
|
|
// Return an error here because the user tried to set header
|
|
// caching, and we want them to know they didn't set it right -
|
|
// one way or the other
|
|
return fmt.Errorf("invalid cache-headers value %v: %w", value, err)
|
|
}
|
|
w.config.cacheEnabled = cache
|
|
case "cache-max-age":
|
|
val, err := time.ParseDuration(value)
|
|
if err != nil || val < 0 {
|
|
return fmt.Errorf("invalid cache-max-age value %v: %w", value, err)
|
|
}
|
|
w.config.cacheMaxAge = val
|
|
case "use-gmail-ext":
|
|
val, err := strconv.ParseBool(value)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid use-gmail-ext value %v: %w", value, err)
|
|
}
|
|
w.config.useXGMEXT = val
|
|
}
|
|
}
|
|
if w.config.cacheEnabled {
|
|
w.initCacheDb(msg.Config.Name)
|
|
}
|
|
w.idler = newIdler(w.config, w.worker, w.executeIdle)
|
|
w.observer = newObserver(w.config, w.worker)
|
|
|
|
if name, ok := msg.Config.Params["folder-map"]; ok {
|
|
file := xdg.ExpandHome(name)
|
|
f, err := os.Open(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
fmap, order, err := lib.ParseFolderMap(bufio.NewReader(f))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
w.worker = middleware.NewFolderMapper(w.worker, fmap, order)
|
|
}
|
|
|
|
return nil
|
|
}
|