fix(mail): set RFC 5322 compliant Message-ID using public URL domain

Fixes #2522
This commit is contained in:
kolaente 2026-04-03 19:59:08 +02:00 committed by kolaente
parent 2f9ff51c60
commit bbcd0648ac
2 changed files with 51 additions and 0 deletions

View File

@ -17,7 +17,9 @@
package mail package mail
import ( import (
"crypto/rand"
"embed" "embed"
"encoding/hex"
"fmt" "fmt"
"io" "io"
@ -78,6 +80,13 @@ func SendTestMail(opts *Opts) error {
func getMessage(opts *Opts) *mail.Msg { func getMessage(opts *Opts) *mail.Msg {
m := mail.NewMsg() m := mail.NewMsg()
m.SetUserAgent("Vikunja " + version.Version) m.SetUserAgent("Vikunja " + version.Version)
// Set an RFC 5322 compliant Message-ID using the public URL domain
// instead of relying on os.Hostname() which is unreliable in containers.
randBytes := make([]byte, 16)
_, _ = rand.Read(randBytes)
messageID := hex.EncodeToString(randBytes) + "@" + GetMailDomain()
m.SetMessageIDWithValue(messageID)
if opts.From == "" { if opts.From == "" {
opts.From = "Vikunja <" + config.MailerFromEmail.GetString() + ">" opts.From = "Vikunja <" + config.MailerFromEmail.GetString() + ">"
} }

View File

@ -0,0 +1,42 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-present Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package mail
import (
"testing"
"code.vikunja.io/api/pkg/config"
"github.com/stretchr/testify/assert"
)
func TestGetMessageSetsMessageID(t *testing.T) {
config.ServicePublicURL.Set("https://tasks.example.com/")
config.MailerFromEmail.Set("test@example.com")
opts := &Opts{
To: "recipient@example.com",
Subject: "Test",
Message: "Hello",
ContentType: ContentTypePlain,
}
m := getMessage(opts)
msgID := m.GetMessageID()
assert.NotEmpty(t, msgID)
assert.Contains(t, msgID, "@tasks.example.com>")
}