foxcpp / maddy

✉️ Composable all-in-one mail server.
https://maddy.email
GNU General Public License v3.0
4.98k stars 240 forks source link

Add JMAP server support #19

Open emersion opened 5 years ago

emersion commented 5 years ago

https://jmap.io/

foxcpp commented 5 years ago

This will be a complicated problem because we just got our storage interfaces tied to IMAP. go-imap-sql is tied closely to IMAP too, so it basically can't be reworked for JMAP without actually rewriting it from scratch. I think it will be hard to design an efficient interface that can be used both by JMAP and IMAP. Probably all we can do it so have different storage backends support either JMAP or IMAP or both.

emersion commented 5 years ago

Yeah, I don't think there's a good way to abstract all backends behind a single storage interface. Backends will need to support it.

foxcpp commented 5 years ago

Existence of https://proxy.jmap.io/ hints that it is possible to map JMAP to IMAP. So, probably, it should not be hard to even create an interface adapter. Like, jmap.NewIMAPAdapter(goImapBackend) so clients can benefit from JMAP while the server is actually IMAP "behind the hood".

foxcpp commented 5 years ago

I'm slowly getting some pieces together in this repo.

foxcpp commented 4 years ago

Status update: JMAP is a big complex protocol that is not used by any popular clients and has no server libraries available for Go. IMAP is a big complex but also widespread protocol that is well-known, supported by any email client and has server library available for Go. Some of IMAP disadvantages come from incomplete client implementations, not protocol flaws, as JMAP developers want to convince you. I do not expect wide JMAP adoption in next several years, therefore the decision was made to prioritize improving IMAP implementation.

If somebody insists on having JMAP, I recommend looking at Cyrus email server, perhaps write a Go library for its SASL delegation protocol so it could be used with maddy just as easy as Dovecot.

josephg commented 3 years ago

If its helpful in any way, about a year ago I pulled out all the JMAP conversion code from cyrus into a mostly standalone C library, so at least you can convert from a mail envelope into jmap-compatible JSON. I designed it to be something I could use from nodejs (via wasm), but the code compiles to a native library just fine too. (Actually its easier to compile it natively because you can use your system's local copy of libicu).

It includes all the tricky parts like encoding headers, creating a small text snippet for preview, attachments and outputting both text and usable HTML for any email.

The code is fast enough that cyrus doesn't bother caching the json result - it just stores the raw email envelope and uses this code to convert when an inbox / email is opened through jmap.

Its a little bit of a mess - "some assembly required". But if nothing else, it could be helpful for conformance testing of another implementation.

https://github.com/josephg/mime-to-jmap

To compile it natively, copy/link CMake-native to CMakeLists.txt and build. You might need to change the libicu directory if you aren't on macos. (And if you just want to link the wasm version directly, you can extract that out of the npm module)

foxcpp commented 3 years ago

It is definitely helpful to have some known-working code to look at. Thanks for your work!