Skip to content

Releases: wneessen/go-mail

v0.5.2: Better tests, minor bug fixes, unencrypted auth methods and fig-support.

06 Nov 10:37
b4aa414
Compare
Choose a tag to compare

Welcome to go-mail v0.5.2! This release is mainly a maintenance release.

fig.StringUnmarshaler support for SMTPAuthType

With #341 we introduce support for the fig.StringUnmarshaler interface for SMTPAuthType. This allows users of fig to reference the mail.SMTPAuthType directly in their fig config.

Allow unencrypted PLAIN and LOGIN smtp authentication

The PR #344 introduced two new SMTPAuthType types: SMTPAuthPlainNoEnc and SMTPAuthLoginNoEnc. Both allow PLAIN and LOGIN authentication over unencrypted connections. This can be useful if the connection has already been secured in a different way (e. g. a SSH tunnel).

Overhaul of the test suite and GH workflow

The PRs #348, #349 and #352 are a full overhaul of the go-mail test suite. Almost all tests have been rewritten to better coverage, visibility and maintainability. We've now covered +92% of all code. The Github workflow was also improved and is now less error prone.

During the tests rewrite a couple of minor bugs were found and fixed on the way:

  • Add error check for nil SMTP authentication method 1c8b290
  • Add error handling for nil DialContextFunc 35f92f2
  • Set fallbackPort to 0 in SetTLSPortPolicy 3efd2b5
  • Move delivery status update after writer close check 42c6379
  • Remove redundant connection check in auth function 5e3ebcc
  • Remove redundant connection check in send function 45ebcb9
  • Add nil check for smtpClient in checkConn function 4a8ac76
  • Refactor error handling in eml parser 769783f
  • Initialize address header map and enforce single 'From' address 08fe44c
  • Fix ToFromString to handle and trim empty addresses c99b6c3
  • Refine CcFromString to handle spaces and empty addresses 855d7f0
  • Improve BccFromString to handle spaces and empty addresses f079ea0
  • Refactor SetDate to use SetDateWithValue ae15a12
  • Initialize genHeader in RequestMDNTo method 4f97cd8
  • Refactor RequestMDNAddTo 4fe9022
  • Follow upstream for HELO during Quit bug 8353b4b - The reported upstream bug was caused by this PR. See: golang/go#70011

What's Changed

CI/CD maintenance changes

  • Bump actions/dependency-review-action from 4.3.4 to 4.3.5 by @dependabot in #343
  • Bump github/codeql-action from 3.26.13 to 3.27.0 by @dependabot in #345
  • Bump actions/setup-go from 5.0.2 to 5.1.0 by @dependabot in #346
  • Bump sonarsource/sonarqube-quality-gate-action from dc2f7b0dd95544cd550de3028f89193576e958b9 to 8406f4f1edaffef38e9fb9c53eb292fc1d7684fa by @dependabot in #351
  • Bump actions/dependency-review-action from 4.3.5 to 4.4.0 by @dependabot in #350

New Contributors

  • @sonalys made their first contribution in #353. Thank you very much for the bugfix!

Full Changelog: v0.5.1...v0.5.2

v0.5.1: SMTP auth fixes and logging optimizations

16 Oct 08:25
8ea80c0
Compare
Choose a tag to compare

Welcome to go-mail v0.5.1! This release brings a bug fix and some optimizations around logging.

Regression fix for SMTP authentication

With v0.5.0 we unintentionally introduced a regression for the SMTP authentication part of go-mail - at least for some edge cases. As reported in #332, in case the user did not provide an explicit SMTP authentication option, the Client would fail with an "server does not support SMTP AUTH" error. The quick work-around was setting SMTP Auth to "Custom" as pointed out in #328. While it improved the security of the package, as it would not skip authentication if none was given, it was breaking in some edge cases and the "Custom" auth type was not meant to be the default.

We now changed the SMTPAuthNoAuth from an empty string to "NOAUTH". This value is set as default for the Client in NewClient. This way we always have a fixed assignment and an empty string would not skip authentication. The auth() method has been updated to either assign the smtp.Auth function if SMTPAuthType is not set to "NOAUTH" or skip the part there is already an auth function set (this would only happen when SetSMTPAuthCustom or WithSMTPAuthCustom were used).

If SMTPAuthType is set to an empty string, the authentication assignment would fail as it is a not supported mechanism, therefore making sure that the client wouldn't accidentaly skip the authentication at all.

We are sorry if this broke your code with the v0.5.0 release. Thanks to @james-d-elliott and @ugexe for reporting this and for testing the fix.

SMTP authentication data logging

go-mail claims to ship with sane defaults. While this is true, there was one aspect where this wasn't true: debug logging. The debug logger would potentially expose SMTP authentication data to the logs, which could pose a risk. With v0.5.1 we now redact SMTP authentication data by default as a sane and secure default. We realize though, that you sometimes need access to the authentication data. Therefore two new options were introduced to the Client: WithLogAuthData() and SetLogAuthData(bool). With either of these you can instruct the Client to log full SMTP authentication data again.

Simplification of the message ID generation

As pointed out by @mitar in #326, the way we generated the message ID was much to complicated using different sources of randomness while already using a secure string generator. #329 simplied the message ID generation to only use the secure string generator and get rid of the rest of the strings and numbers we added to the message ID. We now have 64 possible characters to generate a 22 character long string, which provides approx. 132 bits of entropy. This should more than enough to guarantee a unique ID for each message.

What's Changed

  • Simplify message id generation and get rid of randnum by @wneessen in #329
  • Redact logging of SMTP authentication data by @wneessen in #338
  • Add default SMTP authentication type to NewClient by @wneessen in #335
  • code duplication reduction for jsonlog.go and stdlog.go by @sarff in #336

CI/CD maintenance changes

New Contributors

  • @sarff made their first contribution in #336. Thank you very much!

Full Changelog: v0.5.0...v0.5.1

v0.5.0: Concurrency-safety, SCRAM-SHA, improved error handling and better GoDoc documentation // *POTENTIALLY BREAKING*

06 Oct 16:07
a94e721
Compare
Choose a tag to compare

Welcome to go-mail v0.5.0! This release is a big one, bringing new features and improvements to the go-mail codebase!

Goroutine-/thread-safety (Potentially breaking)

With #307 we've made go-mail goroutine-safe by introducing a sync.Mutex. Concurrency-safety was a much requested feature, now allowing you to dial your Client and then use that Client in different goroutines. While we've added a lot of new tests (including a test SMTP server to which we connect to in different goroutines), this feature has not been extensively tested in an production environment. Therefore we've marked this features (and respectively this release) as a potentially breaking release. If you plan to use go-mail in a concurrency scenario, please test properly and report back any issues.

SCRAM-SHA-1(-PLUS) / SCRAM-SHA-256(-PLUS) SMTP authentication support

With #310 we have introduced SMTP authentication functions for SCRAM-SHA-1(-PLUS) and SCRAM-SHA-256(-PLUS). Most of the ground work was contributed by @drakkan. @wneessen cleaned up the code a bit, added channel bindings support and added several test cases.

SCRAM-SHA-X(-PLUS) isn't commonly supported, yet but I've tested the code with Dovecot (no channel binding support) and mox (supports both) and the code seems to be working properly. Feedback from using SCRAM with other systems is appreciated!

Thanks again to @drakkan for the excellent WIP code.

Improved error handling

With #301 the error handling was refactored in accordance to #168. Errors are not nested into each other anymore. The send logic for a single message has been moved to the non-version-specific Client.go while the version-specific only handle multi-message handling and error combination. Error messages now also refer to a message ID of the message that failed (if present), for easier debugging.

Thanks to @mitar for pointing out the flaws in the old error handling system and for suggesting the improvements.

Enhanced SMTP LOGIN authentication handling

With #312 we've refactored the SMTP LOGIN auth handling, to improve compatibility with various server responses.

In detail: before, we were only roughly following the Microsoft Spec they defined for MS Outlook.
Meaning:

  • Sending AUTH LOGIN (server might responds with "Username:")
  • Sending the username (server might responds with "Password:")
  • Sending the password (server authenticates)

This is the common approach for most mail systems/providers and is the specified way by Microsoft in their MS-XLOGIN spec.

Yet, there is also an old IETF draft for SMTP AUTH LOGIN that states for clients:

The contents of both challenges SHOULD be ignored.

Since there is no official standard RFC and we've seen different implementations of this mechanism (sending "Username:", "Username", "username", "User name", etc.) we now follow the IETF-Draft instead and ignore any server challange to allow compatiblity with most mail servers/providers. This way it works with servers that follow the Microsoft way but also any other kind of implementation (like i. e. Mox).

Improved GoDoc documentation

With #324 we revises the GoDoc documenation comments for the whole package. It provides much more details for each method in a more standardised format, allowing users of the package to get better information on what does what. This is especially helpful for LSP implementations like gopls.

Simplified random number generation

The random methods for generating random numbers have been simplified and the use of crypto/rand has been replaced by math/rand or math/rand/v2 (depending on the used Go version). We've realized that for our use cases, math/rand will provide enough randomness. It simplies the randNum code a lot.

Dependencies (Potentially breaking)

So far, we were always commited to keep go-mail dependency-free, meaning only relying on the Go Stdlib. So far this has been working well and we believe that people appreciate that no further dependcies are added to their project, when they import go-mail. Yet, we've finally reached a point, where adding new features might require us to import some limited dependencies. This happened with the SCRAM support in #310. We've done a poll beforehand to see if the community is fine with this and the common agreement is, that people are ok with a limited, well curated list of external packages as long as the packages are still maintained and have a good security reputation. Therefore this release adds the first dependencies to go-mail - both from the Go extended library:

  • golang.org/x/crypto
  • golang.org/x/text

As your codebase might not allow for additional dependencies, this feature is also marked as Potentially breaking

We hope you like this release and a big thanks goes out the community that contributed to this release.

What's Changed

CI/CD maintenance changes

  • Bump step-security/harden-runner from 2.9.1 to 2.10.1 by @dependabot in #297
  • Bump github/codeql-action from 3.26.6 to 3.26.7 by @dependabot in #299
  • Bump github/codeql-action from 3.26.7 to 3.26.8 by @dependabot in #300
  • Bump sonarsource/sonarqube-scan-action from 0c0f3958d90fc466625f1d1af1f47bddd4cc6bd1 to f885e52a7572cf7943f28637e75730227df2dbf2 by @dependabot in #304
  • Bump github/codeql-action from 3.26.8 to 3.26.9 by @dependabot in #306
  • Bump sonarsource/sonarqube-scan-action from f885e52a7572cf7943f28637e75730227df2dbf2 to 884b79409bbd464b2a59edc326a4b77dc56b2195 by @dependabot in #305
  • Bump github/codeql-action from 3.26.9 to 3.26.10 by @dependabot in #309
  • Fix GitHub actions by @wneessen in #315
  • Bump golang/govulncheck-action from 1.0.3 to 1.0.4 by @dependabot in #314
  • Bump codecov/codecov-action from 4.5.0 to 4.6.0 by @dependabot in #313
  • Bump golangci/golangci-lint-action from 6.1.0 to 6.1.1 by @dependabot in #318
  • Bump github/codeql-action from 3.26.10 to 3.26.11 by @dependabot in #321
  • Update GH test workflows by @wneessen in #319
  • Update GitHub Actions paths for Go and workflow files by @wneessen in #322

Full Changelog: v0.4.4...v0.5.0

v0.4.4: Re-release due to checksum mismatch

03 Sep 08:08
168f924
Compare
Choose a tag to compare

This release is identical to v0.4.3. Nothing changed. Due to an unfortunate misclick on my end, v0.4.3 was released twice which caused a checksum mismatch for some users. This release fixes the issue by releasing as a new tag.

Sorry for the inconveniences this caused.

What's Changed

  • Bump github/codeql-action from 3.26.2 to 3.26.3 by @dependabot in #289
  • Bump github/codeql-action from 3.26.3 to 3.26.4 by @dependabot in #290
  • Bump github/codeql-action from 3.26.4 to 3.26.5 by @dependabot in #291
  • Bump github/codeql-action from 3.26.5 to 3.26.6 by @dependabot in #292
  • Bump sonarsource/sonarqube-quality-gate-action from 72f24ebf1f81eda168a979ce14b8203273b7c3ad to dc2f7b0dd95544cd550de3028f89193576e958b9 by @dependabot in #293
  • Bump actions/upload-artifact from 4.3.6 to 4.4.0 by @dependabot in #294
  • Update doc.go by @wneessen in #295

Full Changelog: v0.4.3...v0.4.4

v0.4.3: Maintenance release

16 Aug 08:50
c9523e8
Compare
Choose a tag to compare

Welcome to go-mail v0.4.3! This is mainly a maintenance release introducing some minor fixes and improvements. I want to go back to tighter release schedule, so the users that provided PRs don't have to wait too long for their PRs to make it into a release.

I want to thank @NorbertHauriel, @alfa-alex and @lipangeng for their contributions to this release!

What's Changed

CI/CD maintenance changes

New Contributors

Full Changelog: v0.4.2...v0.4.3

v0.4.2: EML parsing, AuthTypes, SMTP/Fallback port selection and more

28 Jun 12:48
ffdea83
Compare
Choose a tag to compare

This release of go-mail brings some new features as well as some code clean up and stability improvments.

EML parsing

With #145 / #249 a new parsing feature has been added to go-mail which allows the user to parse generic EML files into a go-mail Msg struct. This is helpful if you have a already sent mail and want to re-use it with go-mail. Three new public methods have been added: EMLToMsgFromString, EMLToMsgFromReader and EMLToMsgFromFile, allowing the user to parse the EML from different sources.

Caveat: Even though I put lots of efforts into testing this new feature and I am certain that most cases should work without issue, emails are still a complex topic with lots of written and unwritten standards. There might be some special cases in which the parsing might be off. In this case, please raise an issue with an example of the mail, so that I can have a look.

SMTPAuthNoAuth AuthType

The SMTPAuthNoAuth AuthType has been added as convenience feature. It is equivalent to performing no authentication at all. It can be used for mail servers that do not support/require authentication. It is still advised to use the Client without the WithSMTPAuth option, instead.

Refactoring of variable names for readability

When I started go-mail, I was following the Go best practices document, choosing mostly single-character variable names. Looking at the code base size of go-mail and considering how many people work with the code base and actually contribute to the project now, I think this was the wrong decision, as it makes it hard for contributors to follow the code - especially given that I have not followed the recommendation of using more descriptive variables names for global context variables. Therefore with #182 I've refactored all variable names for better readability.

Note: The code in the smtp/ directory has been left untouched so that syncing with the upstream stdlib is not made more complicated than it has to be.

Refinement of the SMTP port selection and fallback logic

It has been pointed out in #181 that the changes to the default ports and fallback ports wasn't well thought through. With #207 this behaviour has been reworked. The clients' functions WithSSLPort, WithTLSPortPolicy, SetTLSPortPolicy, and SetSSLPort were revised to avoid overriding previously set ports. Additionally, the deprecation notes have been removed and replaced with notes on best-practice recommendations, referring the new *Port() methods.

User-Agent skipping

With #178 and option to skip the setting of the User-Agent has been added. This option is suitable for scenarios like SMTP proxies where headers are conditionally passed based on receipt. Thanks a lot to @gegorov2030 for their contribution!

What's Changed

Read more

v0.4.1: Improved logging, attachment removing, delivery status indicaton and more *POTENTIALLY BREAKING*

14 Feb 15:51
56512b5
Compare
Choose a tag to compare

This release of go-mail brings some new features as well as some code clean up and stability improvments.

Improved logging interface (Potentially Breaking Change)

The debug logging system in go-mail has been refactored. A new custom log type Log was introduced, that includes the message direction, format and arguments. The Logger interface and the Stdlog implementation were modified to accept this new type. This change is breaking custom implementations of the Logger interface, but the new interface provides much more flexibility (#136/#141). Additionally we added support for JSON logging (#142) using the log/slog package that has been added to the stdlib in Go 1.21.

This change is breaking custom logger implementations

Removal of attachments/embeds

#147 adds support for removing all attachments/embeds/parts from a Msg. This allows to re-use a Msg and allows for replacing message parts.

The following methods can be used:

  • Msg.UnsetAllAttachments()
  • Msg.UnsetAllEmbeds()
  • Msg.UnsetAllParts()

Thanks to @leahoop for their first PR!

Reading of multiple addresses from a single comma-separated string

#155/#152 add support for three new methods that allow to read multiple recipient addresses for the TO:, CC: and BCC: fields from a single comma-separated string.

The following methods have been added:

  • Msg.ToFromString(string)
  • Msg.CcFromString(string)
  • Msg.BccFromString(string)

Thanks to @suntong for requesting this useful feature!

Delivery status indication for messages

With #167 we added support for delivery status indication of messages. This is especially helpful for bulk mailings to identify if a message was actually delivered or not. A helper method IsDelivered has been added that will return true after successful delivery of a Msg. Thanks to @mitar for requesting this useful feature!

Making use of best practice default ports and fallback ports

When using SSL or STARTTLS, so far the default port was always 25, which is against best practices as described in RFC8314, section 3.3. With #170 we've deprecated the WithSSL() and WithTLSPolicy options in favour of WithSSLPort(bool) and WithTLSPortPolicy(TLSPolicy).

  • WithSSLPort tells the Client to use a SSL/TLS connection and automatically sets the port to 465.
  • WithTLSPortPolicy tells the client to use the provided TLSPolicy and sets the correct port automatically. Port 587 is used for TLSMandatory and TLSOpportunistic. NoTLS will allways use port 25. If the connection fails with TLSOpportunistic, a plaintext connection is attempted on port 25 as a fallback.

Thanks to @muhlemmer for raising the request and providing the first part of the PR.

AUTH LOGIN extension draft

We've added support for the auth login extension draft. This effectively is a draft that expired and was deprecated in favor of the AUTH PLAIN SASL extension (#163).

Thanks to @james-d-elliott for the PR!

Code cleanup and stability

The codebase has been reviewed and a couple of potential nil pointer dereferences have been identified and fixed.
Additionally, a potential panic has been fixed in fileFromReader (#161) - thanks to @rami-dabain for their first PR!

What's Changed

  • Replace hardcoded '2' in Output with const CallDepth by @wneessen in #137
  • Fix nil pointer dereference in msgwriter due to missing error handling by @wneessen in #139
  • Update Go version to 1.21 in GitHub workflows by @wneessen in #140
  • Refactor logging for clearer messaging direction by @wneessen in #141
  • #142 Add structured JSON logger and associated tests by @wneessen in #143
  • #147 add remove attachments and embeds methods by @leahoop in #148
  • Feature/147 add method to remove any attachmentembed by @wneessen in #149
  • Add new methods and tests for handling email addresses by @wneessen in #155
  • Eleminate potential null pointer exceptions by @wneessen in #157
  • Added return error to fileFromReader by @rami-dabain in #161
  • feat(smtp): auth login extension draft support by @james-d-elliott in #163
  • Upstream sync / refine function comments to include return type GoDoc links by @wneessen in #165
  • Add delivery status indication for messages by @wneessen in #167
  • Update FreeBSD version in .cirrus.yml by @wneessen in #169
  • Add default ports and fallback behavior for SSL and TLS by @wneessen and @muhlemmer in #170
  • Add Charset support for message parts by @wneessen in #172
  • Add "X-Auto-Response-Suppress" header and update SetBulk method by @wneessen in #173
  • Update Go version in GitHub workflow files by @wneessen in #174

New Contributors

Full Changelog: v0.4.0...v0.4.1

v0.4.0: Custom dial contexts and OAUTH2 support

08 Jul 11:40
2b27643
Compare
Choose a tag to compare

This release adds two great improvements to go-mail.

Custom dial contexts

The newly added option allows for providing custom dial contexts, to use i. e. for some more extra processes in establish a connection such as using proxy, DNS hook, and so on. The dial context can be provided via the WithDialContextFunc option on the Client. Huge thanks to @sters for their contribution to the project!

OAUTH2 support

@drakkan (Developer of the excellent SFTPGO) added a new SMTP auth option for OAUTH2 authentication tokens (aka XOAUTH2). We now support Google and Microsoft O365 OAUTH2 authentication tokens. With this, go-mail now support 4 different SMTP Auth variants: LOGIN, PLAIN, CRAM-MD, XOAUTH2.
Thanks again @drakkan for this contribution and also big thanks to @james-d-elliott for helping to test this new option and providing their broad knowledge to this feature.

Other changes

We've synced up the changes that were made to the official go net/smtp package with our own copy. So this way go-mail is fully in sync with the official go package again.

What's Changed

New Contributors

Full Changelog: v0.3.9...v0.4.0

v0.3.9 SMTP client port, debug logging and more

18 Mar 10:06
89fd5df
Compare
Choose a tag to compare

This release is the biggest since the initial release of the library. While there wasn't really much change on the surface, there happend a lot under the hood.

net/smtp fork

go-mail heavily relies on the Go stdlib net/smtp package. Unfortunately this lib is in feature freeze mode, so that enhancing/extending the package is not possible. This restricted us - at least to a certain degree - as we can't add features that would be useful for go-mail. For that reason we ported/forked the whole package over and adjusted all parts of go-mail to use it instead.

The original license has been imported and the license headers have been adjusted to reflect the go-mail's MIT license and the original Go BSD-3-Clause license. Additionally, the license headers have been converted to SPDX style.

Debug logging

Since we now have full control over the SMTP client part of go-mail, this allowed us to implement ldebug logging for the SMTP communication. Via the Client.WithDebugLog client option the user can enable this feature. It will then make use of the new smtp/Client.SetDebugLog method. Once the flag is set to true, the SMTP client will start logging incoming and outgoing messages to os.Stderr.

We've also implemented a simple log.Logger interface, as well as a standard logger that satisfies this interface. This allows the user to provide a custom logger, as long as the interface is stasified. If no custom logger is provided, the Stdlog will be used (which makes use of the Go stdlib again). Accordingly, a Client.WithLogger option and Client.SetLogger method have been implemented. Same applies for the smtp counterparts.

Details can be found in #102 and #115 .

More support for middlewares

With #108, #109 and #117 we provide more access to message parts (like attachments or embeds) for middlewares. Parts can now be gotten, set and deleted by middlewares.

Fix attachment reader consectuive writes

Msg.AttachReader() would not output the attached file after consecutive writes (e.g. a write to a file and then send via Client). In #111 we fixed this behaviour by first reading the io.Reader into memory and then creating a new bytes.Reader, which does support seeking. In the writeFunc we then seek to position 0 after a successful io.Copy. This is probably not the most memory efficient way of handling this, but otherwise we'll have to break the io.Reader interface, which we do not want..

To compensate this, additionally, a new way of attaching/embedding files has been added: Msg.AttachReadSeeker() and Msg.EmbedReadSeeker() which take a io.ReadSeekeras argument instead. These two methods will skip the reading into memory and make use of the Seek method of the corresponding interface instead.

We recommend to make use of the new methods instead, to make the memory footprint low.

Special thanks

Special thanks go to @Karitham, @cvette and @halilylm for reporting bugs and/or providing PRs to address issues. Also big thanks to @james-d-elliott of the Authelia project for providing helpful insights on various issues with the library.

What's Changed

New Contributors

Full Changelog: v0.3.8...v0.3.9

v0.3.8: Fix bug in SMTP LOGIN Auth for servers with non-normative responses

07 Jan 11:03
1e959a5
Compare
Choose a tag to compare

This release fixes a bug in the SMTP LOGIN Auth part of go-mail as reported in #94. The changes introduced in d0f0435 and 6a446bd caused issues with SMTP servers like ProtonMail Bridge, which respond with non-normative messages.

Thanks to @james-d-elliott from the Authelia team for the investigation and report.

What's Changed

  • Fix SMTP AUTH LOGIN method for servers with uncommon success messages by @wneessen in #95

Full Changelog: v0.3.7...v0.3.8