107 Commits

Author SHA1 Message Date
Mechiel Lukkien
14af5bbb12
when reparsing all messages, actually store the new mime structure in the database 2025-04-18 09:05:09 +02:00
Mechiel Lukkien
31c22618f5
automatically reparse all messages, in the background, after addition of header fields in the parsed mime form of messages in the message index database
With that recent change, we would keep track of Content-* headers of parsed
messages. We could ask admins to run a command to reparse messages for all
accounts. But instead we just do it automatically when opening the account. We
keep track whether we did the upgrade. And we do it in the background. Those
recent changes were to add optional fields to the IMAP fetch "bodystructure"
responses. There is a small chance that an IMAP client requests these fields
before they are properly populated with the reparse (only existing messages,
new incoming messages are parsed with the new code). We could try to detect
whether the upgrade has completed, and chance IMAP behaviour based on that. But
the complexity and long-term maintenance burden doesn't seem worth it. Worst
case, we'll temporarily claim some relatively unimportant headers aren't
present on a message. Most email clients won't even look at those fields, but
will parse them message themselves instead.
2025-04-16 20:06:58 +02:00
Mechiel Lukkien
1a6d268e1d
imapserver: check for UIDNEXT overflow when adding a message to a mailbox
Return an error, with instructions so a user may be able to work around the
issue.
2025-04-11 18:22:29 +02:00
Mechiel Lukkien
8bab38eac4
imapserver: implement NOTIFY extension from RFC 5465
NOTIFY is like IDLE, but where IDLE watches just the selected mailbox, NOTIFY
can watch all mailboxes. With NOTIFY, a client can also ask a server to
immediately return configurable fetch attributes for new messages, e.g. a
message preview, certain header fields, or simply the entire message.

Mild testing with evolution and fairemail.
2025-04-11 10:06:34 +02:00
Mechiel Lukkien
2defbce0bc
imapserver: return all the extensible fields for bodystructure, notably for content-disposition
The gmail iOS/Android app were showing mime image parts as (garbled) text
instead of rendering them as image. By returning all the optional fields in the
bodystructure fetch attribute, the gmail app renders the image as expected by
the user. So we now add all fields. We didn't before, because we weren't
keeping track of Content-MD5, Content-Language and Content-Location header
fields, since they aren't that useful.

Messages in mailboxes have to be reparsed:
	./mox reparse

Without reparsing, imap responses will claim the extra fields
(content-disposition) are absent for existing messages, instead of not claiming
anything at all, which is what we did before.

Accounts and all/some mailboxes can get their "uid validity" bumped ("./mox
bumpuidvalidity $account [$mailbox]"), which should trigger clients to load all
messages from scratch, but gmail doesn't appear to notice, so it would be
better to remove & add the account in gmail.

For issue #327, also relevant to issue #217.
2025-04-05 15:46:17 +02:00
Mechiel Lukkien
3ac38aacca
imapserver: fix storing previews when requested over imap and they are missing from the database
found while testing.
2025-03-29 20:13:10 +01:00
Mechiel Lukkien
aa631c604c
imapserver: implement PREVIEW extension (RFC 8970), and store previews in message database
We were already generating previews of plain text parts for the webmail
interface, but we didn't store them, so were generating the previews each time
messages were listed.

Now we store previews in the database for faster handling. And we also generate
previews for html parts if needed. We use the first part that has textual
content.

For IMAP, the previews can be requested by an IMAP client. When we get the
"LAZY" variant, which doesn't require us to generate a preview, we generate it
anyway, because it should be fast enough. So don't make clients first ask for
"PREVIEW (LAZY)" and then again a request for "PREVIEW".

We now also generate a preview when a message is added to the account. Except
for imports. It would slow us down, the previews aren't urgent, and they will
be generated on-demand at first-request.
2025-03-28 17:10:17 +01:00
Mechiel Lukkien
a2c79e25c1
check and log errors more often in deferred cleanup calls, and log remote-induced errors at lower priority
We normally check errors for all operations. But for some cleanup calls, eg
"defer file.Close()", we didn't. Now we also check and log most of those.
Partially because those errors can point to some mishandling or unexpected code
paths (eg file unexpected already closed). And in part to make it easier to use
"errcheck" to find the real missing error checks, there is too much noise now.

The log.Check function can now be used unconditionally for checking and logging
about errors. It adjusts the log level if the error is caused by a network
connection being closed, or a context is canceled or its deadline reached, or a
socket deadline is reached.
2025-03-24 14:06:05 +01:00
Mechiel Lukkien
a68a9d8a48
check whether mailboxes have message/etc counts through an "upgrade" boolean flag
Instead of using the per-mailbox flag, and going through all mailboxes when
opening an account.
2025-03-23 12:52:59 +01:00
Mechiel Lukkien
75036c3a71
Before moving message files in imapserver and webmail API, ensure the message destination directory for the newly assigned IDs exist.
Example symptom, when deleting a message in the webmail (which moves to Trash):

        l=error m="duplicating message in old mailbox for current sessions" err="link data/accounts/mjl/msg/I/368638 data/accounts/mjl/msg/J/368640: no such file or directory" pkg=webmail

Problem introduced a few weeks ago, where moving messages starting duplicating
the message first, and the copy is erased once all references (in IMAP
sessions) to the old mailbox have been removed.
2025-03-21 10:18:39 +01:00
Mechiel Lukkien
99f9eb438f
Minor cleanup: use the ModSeq from the Mailbox in a ChangeMailboxAdd, no need to add the ModSeq again 2025-03-20 00:10:47 +01:00
Mechiel Lukkien
ac4b006ecd
When removing an account, wait for the last account reference has gone away before removing the files.
The intent to remove the account is stored in the database. At startup, if
there are any such referenes, they are applied by removing the account
directories and the entry in the database. This ensures the account directory
is properly removed, even on incomplete shutdown.

Don't add an account when its directory already exits.
2025-03-15 14:20:35 +01:00
Mechiel Lukkien
c4255a96f8
In tests, make initializing store/, its switchboard and an account more consistent.
Initialize store and switchboard first, then open account, and close in reverse
order.

Replace all "CheckClosed" calls with "WaitClosed", future changings will keep
an account reference open for a bit after the last regular close, so we can't
know that an account should be closed during tests.

Remove one parameter from the (still too long) "start test server" function in
imapserver testing code.
2025-03-15 11:15:23 +01:00
Mechiel Lukkien
eadbda027c
Fix bug gathering "changes" to broadcast during a mailbox rename in certain situations
We weren't appending the individual changes to the slice, but the entire slice.
Since "Change" is an "any", this isn't a type error. So make a Change a
non-empty interface (I had seen an issue like this coming, should have made it
an interface then, at least now we have a reasonable method, to get the modseq
of a change).

Found while working on an imap webpush prototype.
2025-03-15 10:45:35 +01:00
Mechiel Lukkien
a553a107f0
Cleanup temporary files created during IMAP APPEND command.
Since a recent change (likely since implementing MULTIAPPEND), the temporary
files weren't removed any more. When changing it, I must have had the wrong
mental model about the MessageAdd method, assuming it would remove the temp
file.

Noticed during tests.
2025-03-10 09:26:24 +01:00
Mechiel Lukkien
2314397078
Fix recently introduced bug when authentication with password.
In case the precis check failed, our return of a nil account cleared acc, and
we were then trying to close it, returning in a nil pointer dereference.

Rewrite the return statements so we don't overwrite the named return variables.
2025-03-07 21:30:20 +01:00
Mechiel Lukkien
d78aa9d1d7
Fix previous commit, add missing error check and minor test refactor.
Unclear how I botched this up at the last minute before committing...
2025-03-07 10:30:55 +01:00
Mechiel Lukkien
51f58a52c9
When opening an account, check for unexpected message files in the file system, and adjust the next message ID autoincrement sequence in the database to prevent future message delivery failures.
Just to be cautious. This hasn't happened yet in practice that I'm aware of.
But in theory, mox could crash after it has written the message file during
delivery, but before the database transaction was committed. In that case, a
message file for the "next message id" is already present. Any future delivery
attempts will get assigned the same message id by the database, but writing the
file will fail because there already is one, causing delivery to fail (until
the file is moved away).

When opening an account, we now check in the file system if newer files exist
than we expect based on the last existing message in the database. If so, we
adjust the message ID the database will assign next.
2025-03-07 10:15:27 +01:00
Mechiel Lukkien
64f2f788b1
Run modernize to rewrite some older go constructs to newer ones
Mostly using slice.Sort, using min/max, slices.Concat, range of int and
fmt.Appendf for byte slices instead of strings.
2025-03-06 17:33:06 +01:00
Mechiel Lukkien
e572d01341
Don't allow mailboxes named "." or ".." and normalize names during imports too
It only serves to confuse. When exporting such mailboxes in zip files or tar
files, extracting will cause trouble.
2025-03-06 11:36:33 +01:00
Mechiel Lukkien
577944310c
Improve expunged message/UID tracking in IMAP sessions, track synchronization history for mailboxes/annotations.
Keeping the message files around, and the message details in the database, is
useful for IMAP sessions that haven't seen/processed the removal of a message
yet and try to fetch it. Before, we would return errors. Similarly, a session
that has a mailbox selected that is removed can (at least in theory) still read
messages.

The mechanics to do this need keeping removed mailboxes around too. JMAP needs
that anyway, so we now keep modseq/createseq/expunged history for mailboxes
too. And while we're at it, for annotations as well.

For future JMAP support, we now also keep the mailbox parent id around for a
mailbox, with an upgrade step to set the field for existing mailboxes and
fixing up potential missing parents (which could possibly have happened in an
obscure corner case that I doubt anyone ran into).
2025-03-06 11:35:44 +01:00
Mechiel Lukkien
2beb30cc20
Refactor how messages are added to mailboxes
DeliverMessage() is now MessageAdd(), and it takes a Mailbox object that it
modifies but doesn't write to the database (the caller must do it, and plenty
of times can do it more efficiently by doing it once for multiple messages).
The new AddOpts let the caller influence how many checks and how much of the
work MessageAdd() does. The zero-value AddOpts enable all checks and all the
work, but callers can take responsibility of some of the checks/work if it can
do it more efficiently itself.

This simplifies the code in most places, and makes it more efficient. The
checks to update per-mailbox keywords is a bit simpler too now.

We are also more careful to close the junk filter without saving it in case of
errors.

Still part of more upcoming changes.
2025-03-06 11:35:43 +01:00
Mechiel Lukkien
ea64936a67
Cleanup message file when DeliverMailbox fails.
Part of larger changes.
2025-03-06 11:35:43 +01:00
Mechiel Lukkien
5ba51adb14
When retraining ham/spam messages, don't make existence of the messages optional.
If messages that should exist don't, that's a real error we don't want to hide.
Part of larger changes.
2025-03-06 11:35:43 +01:00
Mechiel Lukkien
ffc7ed96bc
When delivering a message to a mailbox, remember last dir we delivered to
In the common case, it's the same as the previous delivery. That means we don't
have to try to create the directory (fewer syscalls) and that we can sync the
dir to disk.

This also tweaks the defer handling in case of a late failure.
2025-03-06 11:35:43 +01:00
Mechiel Lukkien
1037a756fa
when delivering a message to a mailbox, lazily parse the parsed form of the message
it isn't always needed, so this can improve performance a bit.
come up as part of other refactoring.
2025-03-06 11:35:43 +01:00
Mechiel Lukkien
394bdef39d
In storage consistency checks, verify the junk filter has the expected word counts
Fix up a test or two. Simplify the XOR logic when we train the junk filter:
Only if junk or nonjunk is set, but not when both (or none are set). i.e. when
the values aren't the same.

Locking the account when we do consistency checks prevents spurious test
failures that may have been introduced in the previous commit.
2025-02-26 14:44:05 +01:00
Mechiel Lukkien
aa85baf511
add consistency check (enabled during tests only) for unexpected message files in the account message directory 2025-02-26 11:40:36 +01:00
Mechiel Lukkien
78e0c0255f
imapserver: implement MULTIAPPEND extension, rfc 3502
MULTIAPPEND modifies the existing APPEND command to allow multiple messages. it
is somewhat more involved than a regular append of a single message since the
operation (of adding multiple messages) must be atomic. either all are added,
or none are.

we check as early as possible if the messages won't cause an over-quota error.
2025-02-24 15:47:47 +01:00
Mechiel Lukkien
2809136451
imap metadata extension: allow keys in the /shared/ namespace too
not just /private. /shared/ is the more commonly implemented namespace, because
it is easier te implement: you don't need per-user/account storage of metadata.
i initially approached it from the other direction: we don't have a mechanism
to share metadata with other accounts, so everything is private, and i assumed
that would be what a user would prefer. but email clients make the decisions,
and they'll likely try the /shared/ namespace.
2025-02-23 20:19:07 +01:00
Mechiel Lukkien
9f3cb7340b
update modseq when changing mailbox/server metadata, and also for specialuse changes, and keep track of modseq for mailboxes
i added the metadata extension to the imapserver recently. then i wondered how
a client would efficiently find changed metadata. turns out the qresync rfc
mentions that metadata changes should set a new modseq on the mailbox.
shouldn't be hard, except that we were not explicitly keeping track of modseqs
per mailbox. we only kept them for messages, and we were just looking up the
latest message modseq when we needed the modseq (we keep db entries for
expunged messages, so this worked out fine). that approach isn't enough
anymore. so know we keep track of modseq & createseq for mailboxes, just as for
messages. and we also track modseq/createseq for annotations. there's a good
chance jmap is going to need it.

this also adds consistency checks for modseq/createseq on mailboxes and
annotations to the account storage. it helped spot cases i missed where the
values need to be updated.
2025-02-22 22:52:18 +01:00
Mechiel Lukkien
02c4715724
remove intention to implement \important special-use mailbox and $important message flag, rfc 8457
they are intended to be used by the server to automatically mark some messages
as important, based on server-defined heuristics. we don't have such heuristics
at the moment. perhaps in the future, but until then there are no plans.
2025-02-19 22:44:04 +01:00
Mechiel Lukkien
dcaa99a85c
implement IMAP CREATE-SPECIAL-USE extension for the mailbox create command, part of rfc 6154
we already supported special-use flags. settable through the webmail interface,
and new accounts already got standard mailboxes with special-use flags
predefined. but now the IMAP "CREATE" command implements creating mailboxes
with special-use flags.
2025-02-19 20:39:26 +01:00
Mechiel Lukkien
7288e038e6
implement imap savedate extension, rfc 8514
it makes a new field available on stored messages. not when they they were
received (over smtp) or appended to the mailbox (over imap), but when they were
last "saved" in the mailbox. copy/move of a message (eg to the trash) resets
the "savedate" value. this helps implement "remove messages from trash after X
days".
2025-02-19 17:11:20 +01:00
Mechiel Lukkien
f30c44eddb
implement the imap metadata extension, rfc 5464
this allows setting per-mailbox and per-server annotations (metadata). we have
a fixed maximum for total number of annotations (1000) and their total size
(1000000 bytes). this size isn't held against the regular quota for simplicity.
we send unsolicited metadata responses when a connection is in the idle
command and a change to a metadata item is made.

we currently only implement the /private/ namespace.  we should implement the
/shared/ namespace, for mox-global metadata annotations.  only the admin should
be able to configure those, probably through the config file, cli, or admin web
interface.

for issue #290
2025-02-17 22:57:33 +01:00
Mechiel Lukkien
3e53abc4db
add account config option to prevent the account for setting their own custom password, and enable by default for new accounts
accounts with this option enabled can only generate get a new randomly
generated password. this prevents password reuse across services and weak
passwords. existing accounts keep their current ability to set custom
passwords. only admins can change this setting for an account.

related to issue #286 by skyguy
2025-02-15 12:44:18 +01:00
Mechiel Lukkien
1277d78cb1
keep track of login attempts, both successful and failures
and show them in the account and admin interfaces. this should help with
debugging, to find misconfigured clients, and potentially find attackers trying
to login.

we include details like login name, account name, protocol, authentication
mechanism, ip addresses, tls connection properties, user-agent. and of course
the result.

we group entries by their details. repeat connections don't cause new records
in the database, they just increase the count on the existing record.

we keep data for at most 30 days. and we keep at most 10k entries per account.
to prevent unbounded growth. for successful login attempts, we store them all
for 30d. if a bad user causes so many entries this becomes a problem, it will
be time to talk to the user...

there is no pagination/searching yet in the admin/account interfaces. so the
list may be long. we only show the 10 most recent login attempts by default.
the rest is only shown on a separate page.

there is no way yet to disable this. may come later, either as global setting
or per account.
2025-02-06 14:16:13 +01:00
Mechiel Lukkien
f9280b0891
reduce logging about db schema initializations during tests
they were a bit too noisy, not helpful
2025-01-30 10:21:16 +01:00
Mechiel Lukkien
2d3d726f05
add config options to disable a domain and to disable logins for an account
to facilitate migrations from/to other mail setups.

a domain can be added in "disabled" mode (or can be disabled/enabled later on).
you can configure a disabled domain, but incoming/outgoing messages involving
the domain are rejected with temporary error codes (as this may occur during a
migration, remote servers will try again, hopefully to the correct machine or
after this machine has been configured correctly). also, no acme tls certs will
be requested for disabled domains (the autoconfig/mta-sts dns records may still
point to the current/previous machine). accounts with addresses at disabled
domains can still login, unless logins are disabled for their accounts.

an account now has an option to disable logins. you can specify an error
message to show. this will be shown in smtp, imap and the web interfaces. it
could contain a message about migrations, and possibly a URL to a page with
information about how to migrate. incoming/outgoing email involving accounts
with login disabled are still accepted/delivered as normal (unless the domain
involved in the messages is disabled too). account operations by the admin,
such as importing/exporting messages still works.

in the admin web interface, listings of domains/accounts show if they are disabled.
domains & accounts can be enabled/disabled through the config file, cli
commands and admin web interface.

for issue #175 by RobSlgm
2025-01-25 20:39:20 +01:00
Mechiel Lukkien
3f727cf380
webmail: move 2 config options from localstorage to the settings popup, storing their values on the server
these settings are applied anywhere the webmail is open.  the settings are for
showing keyboard shortcuts in the lower right after a mouse interaction, and
showing additional headers.  the shorcuts were configurable in the "help" popup
before.  the additional headers were only configurable through the developer
console before.

the "mailto:" (un)register buttons are now in the settings popup too.
2024-12-07 12:32:54 +01:00
Mechiel Lukkien
b77f44ab58
webmail: add setting to show html version of a message by default, instead of text version
related to issue #196 by GildedHonour
2024-08-23 14:02:55 +02:00
Mechiel Lukkien
bf8cfd9724
add debug logging about bstore db schema upgrades
bstore was updated to v0.0.6 to add this logging.
this simplifies some of the db-handling code in mtastsdb,tlsrptdb,dmarcdb. we
now call the package-level Init() and Close() in all tests properly.
2024-05-10 14:44:37 +02:00
Mechiel Lukkien
ff6cca1bf9
fix flaky test: close account before marking thread-upgrade as finished
store/threads_test.go opens an account, starts the threading upgrade, waits for
it to finish, runs some tests, and closes the account at the end, verifying all
references are gone. the "thread upgrade" goroutine has its own account
reference. it closes its account after having signaled completion of the
upgrade. in between that time, all checks from the tests could run, its account
closed and its no-more-account-references check would fail. the fix is
hopefully to mark the thread upgrade process finished after closing the
account. hard to verify, but this only happens very rarely.
2024-04-28 14:09:40 +02:00
Mechiel Lukkien
960a51242d
add aliases/lists: when sending to an alias, the message gets delivered to all members
the members must currently all be addresses of local accounts.

a message sent to an alias is accepted if at least one of the members accepts
it. if no members accepts it (e.g. due to bad reputation of sender), the
message is rejected.

if a message is submitted to both an alias addresses and to recipients that are
members of the alias in an smtp transaction, the message will be delivered to
such members only once.  the same applies if the address in the message
from-header is the address of a member: that member won't receive the message
(they sent it). this prevents duplicate messages.

aliases have three configuration options:
- PostPublic: whether anyone can send through the alias, or only members.
  members-only lists can be useful inside organizations for internal
  communication. public lists can be useful for support addresses.
- ListMembers: whether members can see the addresses of other members. this can
  be seen in the account web interface. in the future, we could export this in
  other ways, so clients can expand the list.
- AllowMsgFrom: whether messages can be sent through the alias with the alias
  address used in the message from-header. the webmail knows it can use that
  address, and will use it as from-address when replying to a message sent to
  that address.

ideas for the future:
- allow external addresses as members. still with some restrictions, such as
  requiring a valid dkim-signature so delivery has a chance to succeed. will
  also need configuration of an admin that can receive any bounces.
- allow specifying specific members who can sent through the list (instead of
  all members).

for github issue #57 by hmfaysal.
also relevant for #99 by naturalethic.
thanks to damir & marin from sartura for discussing requirements/features.
2024-04-24 19:15:30 +02:00
Mechiel Lukkien
6c0439cf7b
webmail: when moving a single message out of/to the inbox, ask if user wants to create a rule to automatically do that server-side for future deliveries
if the message has a list-id header, we assume this is a (mailing) list
message, and we require a dkim/spf-verified domain (we prefer the shortest that
is a suffix of the list-id value). the rule we would add will mark such
messages as from a mailing list, changing filtering rules on incoming messages
(not enforcing dmarc policies). messages will be matched on list-id header and
will only match if they have the same dkim/spf-verified domain.

if the message doesn't have a list-id header, we'll ask to match based on
"message from" address.

we don't ask the user in several cases:
- if the destination/source mailbox is a special-use mailbox (e.g.
  trash,archive,sent,junk; inbox isn't included)
- if the rule already exist (no point in adding it again).
- if the user said "no, not for this list-id/from-address" in the past.
- if the user said "no, not for messages moved to this mailbox" in the past.

we'll add the rule if the message was moved out of the inbox.
if the message was moved to the inbox, we check if there is a matching rule
that we can remove.

we now remember the "no" answers (for list-id, msg-from-addr and mailbox) in
the account database.

to implement the msgfrom rules, this adds support to rulesets for matching on
message "from" address. before, we could match on smtp from address (and other
fields). rulesets now also have a field for comments. webmail adds a note that
it created the rule, with the date.

manual editing of the rulesets is still in the webaccount page. this webmail
functionality is just a convenient way to add/remove common rules.
2024-04-21 17:14:08 +02:00
Mechiel Lukkien
0f735a1710
webmail: remember per from-address whether we should show the text/html/html-with-external-resources version of a message 2024-04-20 21:25:52 +02:00
Mechiel Lukkien
70adf353ee
webmail: add server-side stored settings, for signature, top/bottom reply and showing the security indications below address input fields
should solve #102
2024-04-19 18:02:24 +02:00
Mechiel Lukkien
c9451d4d06
in webmail & webapisrv, store bcc header in sent messages
when sending a message with bcc's, prepend the bcc header to the message we
store in the sent folder. still not in the message we send to the recipients.
2024-04-16 17:57:46 +02:00
Mechiel Lukkien
09fcc49223
add a webapi and webhooks for a simple http/json-based api
for applications to compose/send messages, receive delivery feedback, and
maintain suppression lists.

this is an alternative to applications using a library to compose messages,
submitting those messages using smtp, and monitoring a mailbox with imap for
DSNs, which can be processed into the equivalent of suppression lists. but you
need to know about all these standards/protocols and find libraries. by using
the webapi & webhooks, you just need a http & json library.

unfortunately, there is no standard for these kinds of api, so mox has made up
yet another one...

matching incoming DSNs about deliveries to original outgoing messages requires
keeping history of "retired" messages (delivered from the queue, either
successfully or failed). this can be enabled per account. history is also
useful for debugging deliveries. we now also keep history of each delivery
attempt, accessible while still in the queue, and kept when a message is
retired. the queue webadmin pages now also have pagination, to show potentially
large history.

a queue of webhook calls is now managed too. failures are retried similar to
message deliveries. webhooks can also be saved to the retired list after
completing. also configurable per account.

messages can be sent with a "unique smtp mail from" address. this can only be
used if the domain is configured with a localpart catchall separator such as
"+". when enabled, a queued message gets assigned a random "fromid", which is
added after the separator when sending. when DSNs are returned, they can be
related to previously sent messages based on this fromid. in the future, we can
implement matching on the "envid" used in the smtp dsn extension, or on the
"message-id" of the message. using a fromid can be triggered by authenticating
with a login email address that is configured as enabling fromid.

suppression lists are automatically managed per account. if a delivery attempt
results in certain smtp errors, the destination address is added to the
suppression list. future messages queued for that recipient will immediately
fail without a delivery attempt. suppression lists protect your mail server
reputation.

submitted messages can carry "extra" data through the queue and webhooks for
outgoing deliveries. through webapi as a json object, through smtp submission
as message headers of the form "x-mox-extra-<key>: value".

to make it easy to test webapi/webhooks locally, the "localserve" mode actually
puts messages in the queue. when it's time to deliver, it still won't do a full
delivery attempt, but just delivers to the sender account. unless the recipient
address has a special form, simulating a failure to deliver.

admins now have more control over the queue. "hold rules" can be added to mark
newly queued messages as "on hold", pausing delivery. rules can be about
certain sender or recipient domains/addresses, or apply to all messages pausing
the entire queue. also useful for (local) testing.

new config options have been introduced. they are editable through the admin
and/or account web interfaces.

the webapi http endpoints are enabled for newly generated configs with the
quickstart, and in localserve. existing configurations must explicitly enable
the webapi in mox.conf.

gopherwatch.org was created to dogfood this code. it initially used just the
compose/smtpclient/imapclient mox packages to send messages and process
delivery feedback. it will get a config option to use the mox webapi/webhooks
instead. the gopherwatch code to use webapi/webhook is smaller and simpler, and
developing that shaped development of the mox webapi/webhooks.

for issue #31 by cuu508
2024-04-15 21:49:02 +02:00
Mechiel Lukkien
d74610c345
bugfix: missing account close in queue direct send
found while writing new tests for upcoming functionality.
the test had an embarrassing workaround for the symptoms...
2024-04-08 20:22:52 +02:00