13 Commits
Author SHA1 Message Date
dualfroz fd864f1379 feat: add --outgoing-ignore-tls to keep the relay off STARTTLS (#377)
The relay connection only had `secure`, so with `secure: false` nodemailer
still upgraded to STARTTLS whenever the server advertised it, and there was
no way to talk cleartext to such a server. Pass nodemailer's `ignoreTLS`
through as `ignoreTLS` on the relay config, wired to
--outgoing-ignore-tls / MAILDEV_OUTGOING_IGNORE_TLS / `outgoingIgnoreTls`.
2026-10-03 02:24:38 +02:00
upstream a9a83f64f1 Upstream maildev/maildev state of the touched files before f000b5e316 2026-10-03 02:24:38 +02:00
dualfroz 3f93b59a2e fix(smtp): skip the reverse DNS lookup of connecting clients (#104)
smtp-server reverse resolves every connecting client before it sends the
220 greeting, unless disableReverseLookup is set. MailDev never reads the
resolved hostname, and without a network the lookup does not answer, so
each connection waited for smtp-server to give up on it.
2026-10-03 02:18:43 +02:00
dualfroz 53640c6990 fix(smtp): reject the relay when the outgoing server cannot be reached
SMTPConnection only calls the connect() callback once the handshake
succeeds; a refused or timed out connection is emitted as an 'error'
event, which was only logged. relay() then never settled, so its finally
block (which now releases the email stream) never ran, auto-relay held
the incoming SMTP transaction open without a reply, and the REST relay
request hung. Reject the connect promise from the 'error' handler.
2026-10-02 15:59:20 +02:00
dualfroz 5479067fab fix(smtp): close the raw email stream when a relay does not send it (#423)
relayEmail opens a read stream on the .eml file for every relay, and only
client.send() ever consumed it. When the auto-relay rules left no
recipients, or the outgoing server failed the send (e.g. rejected a
recipient), the stream was never read or destroyed and its file
descriptor stayed open. Destroy it on the early return and in the finally
block; after a successful send it is already fully read, so that is a
no-op.
2026-10-02 15:57:49 +02:00
upstream 27e7633a30 Upstream maildev/maildev state of the touched files before 661742ab9d 2026-10-02 15:57:49 +02:00
dualfroz a10bcd3e4c fix: parse MAILDEV_HTTPS as a boolean (#294)
MAILDEV_HTTPS is listed in BOOLEAN_VARS, but envVarToConfigKey() had no
entry for `https`, so the boolean pass skipped it and the raw string from
ENV_MAPPING stayed in the config. MAILDEV_HTTPS=false then enabled HTTPS
and validation demanded httpsCert and httpsKey.
2026-10-02 15:52:08 +02:00
upstream 7f6defcdc5 Upstream maildev/maildev state of the touched files before ac15c79ff9 2026-10-02 15:52:08 +02:00
dualfroz ed77334df2 Build CID attachment URLs against the API route and base path (#582)
* fix: build CID attachment URLs against the API route and base path

replaceCidReferences rewrote cid: references to /email/:id/attachment/:file,
which matches no route: attachments are served from the API server, mounted
at ${basePath}/api. When MailDev sits under a subpath the prefix was missing
as well, which is the setup described in #439.

Emit ${basePath}/api/email/:id/attachment/:file, root-relative by default, and
thread the API server's basePath through getEmailHtml. baseUrl still prefixes
//host for a caller that passes it.

On the current code this does not change what the web UI shows for a typical
message: mailparser already inlines related parts as data: URIs, and a cid:
that survives parsing is one that matches no attachment. replaceCidReferences
is exported from @maildev/smtp, though, so the URL it builds should resolve.

Refs #439

* fix: omit the base path prefix when it resolves to the root

A caller passing basePath '/' produced //api/email/..., which a browser reads as a protocol-relative URL rather than a path. Strip the slashes first and only add a prefix when something is left.
2026-09-22 14:00:23 -04:00
upstream 77bb28b844 Upstream maildev/maildev state of the touched files before f6ee0b5f24 2026-09-22 20:00:23 +02:00
dualfroz 15ecda681f fix: omit the base path prefix when it resolves to the root
A caller passing basePath '/' produced //api/email/..., which a browser reads as a protocol-relative URL rather than a path. Strip the slashes first and only add a prefix when something is left.
2026-09-17 16:18:50 +02:00
dualfroz 8dceaec54a fix: build CID attachment URLs against the API route and base path
replaceCidReferences rewrote cid: references to /email/:id/attachment/:file,
which matches no route: attachments are served from the API server, mounted
at ${basePath}/api. When MailDev sits under a subpath the prefix was missing
as well, which is the setup described in #439.

Emit ${basePath}/api/email/:id/attachment/:file, root-relative by default, and
thread the API server's basePath through getEmailHtml. baseUrl still prefixes
//host for a caller that passes it.

On the current code this does not change what the web UI shows for a typical
message: mailparser already inlines related parts as data: URIs, and a cid:
that survives parsing is one that matches no attachment. replaceCidReferences
is exported from @maildev/smtp, though, so the URL it builds should resolve.

Refs #439
2026-09-13 15:31:28 +02:00
upstream 1ce2ff856b Upstream maildev/maildev state of the touched files before ec889a40ce 2026-09-11 23:33:43 +02:00