mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-23 14:10:50 +01:00
Compare commits
12 commits
637f5e03dd
...
c9523e85ae
Author | SHA1 | Date | |
---|---|---|---|
c9523e85ae | |||
5454f44f67 | |||
cfc8023a6d | |||
8b69fa92ae | |||
e61d1689f6 | |||
801a93459e | |||
2801193074 | |||
8efdf49d3d | |||
e288bcae5e | |||
590dfe97e7 | |||
84b5ebcebc | |||
|
647ff86b29 |
10 changed files with 25 additions and 22 deletions
|
@ -6,9 +6,9 @@ freebsd_task:
|
||||||
name: FreeBSD
|
name: FreeBSD
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- name: FreeBSD 13.2
|
- name: FreeBSD 13.3
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-13-2
|
image_family: freebsd-13-3
|
||||||
- name: FreeBSD 14.0
|
- name: FreeBSD 14.0
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-14-0
|
image_family: freebsd-14-0
|
||||||
|
|
6
.github/workflows/codecov.yml
vendored
6
.github/workflows/codecov.yml
vendored
|
@ -36,7 +36,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
go: [1.18, 1.19, '1.20', '1.21', '1.22']
|
go: ['1.20', '1.21', '1.22', '1.23']
|
||||||
steps:
|
steps:
|
||||||
- name: Harden Runner
|
- name: Harden Runner
|
||||||
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
|
||||||
|
@ -50,14 +50,14 @@ jobs:
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
- name: Install sendmail
|
- name: Install sendmail
|
||||||
if: matrix.go == '1.22' && matrix.os == 'ubuntu-latest'
|
if: matrix.go == '1.23' && matrix.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y install sendmail; which sendmail
|
sudo apt-get -y install sendmail; which sendmail
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: |
|
run: |
|
||||||
go test -v -race --coverprofile=coverage.coverprofile --covermode=atomic ./...
|
go test -v -race --coverprofile=coverage.coverprofile --covermode=atomic ./...
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
if: success() && matrix.go == '1.22' && matrix.os == 'ubuntu-latest'
|
if: success() && matrix.go == '1.23' && matrix.os == 'ubuntu-latest'
|
||||||
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
|
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
|
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
|
||||||
|
|
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
|
- uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
|
||||||
with:
|
with:
|
||||||
go-version: '1.22'
|
go-version: '1.23'
|
||||||
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
|
uses: golangci/golangci-lint-action@aaa42aa0628b4ae2578232a66b541047968fac86 # v6.1.0
|
||||||
|
|
2
.github/workflows/sonarqube.yml
vendored
2
.github/workflows/sonarqube.yml
vendored
|
@ -38,7 +38,7 @@ jobs:
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
|
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
|
||||||
with:
|
with:
|
||||||
go-version: '1.22.x'
|
go-version: '1.23.x'
|
||||||
|
|
||||||
- name: Run unit Tests
|
- name: Run unit Tests
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
## SPDX-License-Identifier: MIT
|
## SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
[run]
|
[run]
|
||||||
go = "1.22"
|
go = "1.23"
|
||||||
tests = true
|
tests = true
|
||||||
|
exclude-dirs = ["examples"]
|
||||||
|
|
||||||
[linters]
|
[linters]
|
||||||
enable = ["stylecheck", "whitespace", "containedctx", "contextcheck", "decorder",
|
enable = ["stylecheck", "whitespace", "containedctx", "contextcheck", "decorder",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ var newlineBytes = []byte(SingleNewLine)
|
||||||
// line length is reached
|
// line length is reached
|
||||||
func (l *Base64LineBreaker) Write(data []byte) (numBytes int, err error) {
|
func (l *Base64LineBreaker) Write(data []byte) (numBytes int, err error) {
|
||||||
if l.out == nil {
|
if l.out == nil {
|
||||||
err = fmt.Errorf(ErrNoOutWriter)
|
err = errors.New(ErrNoOutWriter)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if l.used+len(data) < MaxBodyLength {
|
if l.used+len(data) < MaxBodyLength {
|
||||||
|
|
2
doc.go
2
doc.go
|
@ -6,4 +6,4 @@
|
||||||
package mail
|
package mail
|
||||||
|
|
||||||
// VERSION is used in the default user agent string
|
// VERSION is used in the default user agent string
|
||||||
const VERSION = "0.4.2"
|
const VERSION = "0.4.3"
|
||||||
|
|
12
msg.go
12
msg.go
|
@ -743,7 +743,7 @@ func (m *Msg) SetBodyWriter(
|
||||||
// The content type will be set to text/html automatically
|
// The content type will be set to text/html automatically
|
||||||
func (m *Msg) SetBodyHTMLTemplate(tpl *ht.Template, data interface{}, opts ...PartOption) error {
|
func (m *Msg) SetBodyHTMLTemplate(tpl *ht.Template, data interface{}, opts ...PartOption) error {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return fmt.Errorf(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(&buffer, data); err != nil {
|
||||||
|
@ -758,7 +758,7 @@ func (m *Msg) SetBodyHTMLTemplate(tpl *ht.Template, data interface{}, opts ...Pa
|
||||||
// The content type will be set to text/plain automatically
|
// The content type will be set to text/plain automatically
|
||||||
func (m *Msg) SetBodyTextTemplate(tpl *tt.Template, data interface{}, opts ...PartOption) error {
|
func (m *Msg) SetBodyTextTemplate(tpl *tt.Template, data interface{}, opts ...PartOption) error {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return fmt.Errorf(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buf, data); err != nil {
|
if err := tpl.Execute(&buf, data); err != nil {
|
||||||
|
@ -790,7 +790,7 @@ func (m *Msg) AddAlternativeWriter(
|
||||||
// The content type will be set to text/html automatically
|
// The content type will be set to text/html automatically
|
||||||
func (m *Msg) AddAlternativeHTMLTemplate(tpl *ht.Template, data interface{}, opts ...PartOption) error {
|
func (m *Msg) AddAlternativeHTMLTemplate(tpl *ht.Template, data interface{}, opts ...PartOption) error {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return fmt.Errorf(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(&buffer, data); err != nil {
|
||||||
|
@ -805,7 +805,7 @@ func (m *Msg) AddAlternativeHTMLTemplate(tpl *ht.Template, data interface{}, opt
|
||||||
// The content type will be set to text/plain automatically
|
// The content type will be set to text/plain automatically
|
||||||
func (m *Msg) AddAlternativeTextTemplate(tpl *tt.Template, data interface{}, opts ...PartOption) error {
|
func (m *Msg) AddAlternativeTextTemplate(tpl *tt.Template, data interface{}, opts ...PartOption) error {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return fmt.Errorf(errTplPointerNil)
|
return errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(&buffer, data); err != nil {
|
||||||
|
@ -1314,7 +1314,7 @@ func fileFromReadSeeker(name string, reader io.ReadSeeker) *File {
|
||||||
// fileFromHTMLTemplate returns a File pointer form a given html/template.Template
|
// fileFromHTMLTemplate returns a File pointer form a given html/template.Template
|
||||||
func fileFromHTMLTemplate(name string, tpl *ht.Template, data interface{}) (*File, error) {
|
func fileFromHTMLTemplate(name string, tpl *ht.Template, data interface{}) (*File, error) {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return nil, fmt.Errorf(errTplPointerNil)
|
return nil, errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(&buffer, data); err != nil {
|
||||||
|
@ -1326,7 +1326,7 @@ func fileFromHTMLTemplate(name string, tpl *ht.Template, data interface{}) (*Fil
|
||||||
// fileFromTextTemplate returns a File pointer form a given text/template.Template
|
// fileFromTextTemplate returns a File pointer form a given text/template.Template
|
||||||
func fileFromTextTemplate(name string, tpl *tt.Template, data interface{}) (*File, error) {
|
func fileFromTextTemplate(name string, tpl *tt.Template, data interface{}) (*File, error) {
|
||||||
if tpl == nil {
|
if tpl == nil {
|
||||||
return nil, fmt.Errorf(errTplPointerNil)
|
return nil, errors.New(errTplPointerNil)
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if err := tpl.Execute(&buffer, data); err != nil {
|
if err := tpl.Execute(&buffer, data); err != nil {
|
||||||
|
|
|
@ -122,7 +122,7 @@ func TestMsgWriter_writeMsg(t *testing.T) {
|
||||||
em += fmt.Sprintf("* incorrect %q field", ea[e])
|
em += fmt.Sprintf("* incorrect %q field", ea[e])
|
||||||
}
|
}
|
||||||
em += fmt.Sprintf("\n\nFull message:\n%s", ms)
|
em += fmt.Sprintf("\n\nFull message:\n%s", ms)
|
||||||
t.Errorf(em)
|
t.Error(em)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,14 @@ const (
|
||||||
//
|
//
|
||||||
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
|
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
|
||||||
LoginXUsernameChallenge = "Username:"
|
LoginXUsernameChallenge = "Username:"
|
||||||
|
LoginXUsernameLowerChallenge = "username:"
|
||||||
|
|
||||||
// LoginXPasswordChallenge represents the Password Challenge response sent by the SMTP server per the AUTH LOGIN
|
// LoginXPasswordChallenge represents the Password Challenge response sent by the SMTP server per the AUTH LOGIN
|
||||||
// extension.
|
// extension.
|
||||||
//
|
//
|
||||||
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
|
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
|
||||||
LoginXPasswordChallenge = "Password:"
|
LoginXPasswordChallenge = "Password:"
|
||||||
|
LoginXPasswordLowerChallenge = "password:"
|
||||||
|
|
||||||
// LoginXDraftUsernameChallenge represents the Username Challenge response sent by the SMTP server per the IETF
|
// LoginXDraftUsernameChallenge represents the Username Challenge response sent by the SMTP server per the IETF
|
||||||
// draft AUTH LOGIN extension. It should be noted this extension is an expired draft which was never formally
|
// draft AUTH LOGIN extension. It should be noted this extension is an expired draft which was never formally
|
||||||
|
@ -76,9 +78,9 @@ func (a *loginAuth) Start(server *ServerInfo) (string, []byte, error) {
|
||||||
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
|
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
|
||||||
if more {
|
if more {
|
||||||
switch string(fromServer) {
|
switch string(fromServer) {
|
||||||
case LoginXUsernameChallenge, LoginXDraftUsernameChallenge:
|
case LoginXUsernameChallenge, LoginXUsernameLowerChallenge, LoginXDraftUsernameChallenge:
|
||||||
return []byte(a.username), nil
|
return []byte(a.username), nil
|
||||||
case LoginXPasswordChallenge, LoginXDraftPasswordChallenge:
|
case LoginXPasswordChallenge, LoginXPasswordLowerChallenge, LoginXDraftPasswordChallenge:
|
||||||
return []byte(a.password), nil
|
return []byte(a.password), nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))
|
return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))
|
||||||
|
|
Loading…
Reference in a new issue