diff options
author | Robin Jarry <robin@jarry.cc> | 2023-06-04 14:05:22 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-06-21 17:29:21 +0200 |
commit | be0bfc1ae28b49be6546626ff9eaadce5464a6c8 (patch) | |
tree | 60b9d8b812408db281c00d5a71197e118a736337 /commands | |
parent | b4ae11b4ec20b61a18e1ce08ea65014bcebc2f16 (diff) | |
download | aerc-be0bfc1ae28b49be6546626ff9eaadce5464a6c8.tar.gz |
worker: add jmap support
Add support for JMAP backends. This is on par with IMAP features with
some additions specific to JMAP:
* tagging
* sending emails
This makes use of git.sr.ht/~rockorager/go-jmap for the low level
interaction with the JMAP server. The transport is JSON over HTTPS.
For now, only oauthbearer with token is supported. If this proves
useful, we may need to file for an official three-legged oauth support
at JMAP providers.
I have tested most features and this seems to be reliable. There are
some quirks with the use-labels option. Especially when moving and
deleting messages from the "All mail" virtual folder (see aerc-jmap(5)).
Overall, the user experience is nice and there are a lot less background
updates issues than with IMAP (damn IDLE mode hanging after restoring
from sleep).
I know that not everyone has access to a JMAP provider. For those
interested, there are at least these two commercial offerings:
https://www.fastmail.com/
https://www.topicbox.com/
And, if you host your own mail, you can use a JMAP capable server:
https://stalw.art/jmap/
https://www.cyrusimap.org/imap/download/installation/http/jmap.html
Link: https://www.rfc-editor.org/rfc/rfc8620.html
Link: https://www.rfc-editor.org/rfc/rfc8621.html
Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'commands')
-rw-r--r-- | commands/account/rmdir.go | 1 | ||||
-rw-r--r-- | commands/compose/send.go | 36 | ||||
-rw-r--r-- | commands/help.go | 1 |
3 files changed, 36 insertions, 2 deletions
diff --git a/commands/account/rmdir.go b/commands/account/rmdir.go index e45a7a7a..9f6fedeb 100644 --- a/commands/account/rmdir.go +++ b/commands/account/rmdir.go @@ -80,6 +80,7 @@ func (RemoveDir) Execute(aerc *widgets.Aerc, args []string) error { acct.Worker().PostAction(&types.RemoveDirectory{ Directory: curDir, + Quiet: force, }, func(msg types.WorkerMessage) { switch msg := msg.(type) { case *types.Done: diff --git a/commands/compose/send.go b/commands/compose/send.go index eeea96cd..7eeb124c 100644 --- a/commands/compose/send.go +++ b/commands/compose/send.go @@ -174,6 +174,8 @@ func send(aerc *widgets.Aerc, composer *widgets.Composer, ctx sendCtx, fallthrough case "smtps": sender, err = newSmtpSender(ctx) + case "jmap": + sender, err = newJmapSender(composer, header, ctx) case "": sender, err = newSendmailSender(ctx) default: @@ -186,7 +188,7 @@ func send(aerc *widgets.Aerc, composer *widgets.Composer, ctx sendCtx, var writer io.Writer = sender - if config.CopyTo != "" { + if config.CopyTo != "" && ctx.scheme != "jmap" { writer = io.MultiWriter(writer, ©Buf) } err = composer.WriteMessage(header, writer) @@ -210,7 +212,7 @@ func send(aerc *widgets.Aerc, composer *widgets.Composer, ctx sendCtx, aerc.NewTab(composer, tabName) return } - if config.CopyTo != "" { + if config.CopyTo != "" && ctx.scheme != "jmap" { aerc.PushStatus("Copying to "+config.CopyTo, 10*time.Second) errch := copyToSent(composer.Worker(), config.CopyTo, copyBuf.Len(), ©Buf) @@ -512,6 +514,36 @@ func connectSmtps(host string) (*smtp.Client, error) { return conn, nil } +func newJmapSender( + composer *widgets.Composer, header *mail.Header, ctx sendCtx, +) (io.WriteCloser, error) { + var writer io.WriteCloser + done := make(chan error) + + composer.Worker().PostAction( + &types.StartSendingMessage{Header: header}, + func(msg types.WorkerMessage) { + switch msg := msg.(type) { + case *types.Done: + return + case *types.Unsupported: + done <- fmt.Errorf("unsupported by worker") + case *types.Error: + done <- msg.Error + case *types.MessageWriter: + writer = msg.Writer + default: + done <- fmt.Errorf("unexpected worker message: %#v", msg) + } + close(done) + }, + ) + + err := <-done + + return writer, err +} + func copyToSent(worker *types.Worker, dest string, n int, msg io.Reader, ) <-chan error { diff --git a/commands/help.go b/commands/help.go index b09e1143..b2654ab5 100644 --- a/commands/help.go +++ b/commands/help.go @@ -14,6 +14,7 @@ var pages = []string{ "binds", "config", "imap", + "jmap", "notmuch", "search", "sendmail", |