diff --git a/backend/utils/send/send.go b/backend/utils/send/send.go index 0588cf9..222da49 100644 --- a/backend/utils/send/send.go +++ b/backend/utils/send/send.go @@ -270,7 +270,7 @@ func doSend(ctx *context.Context, fromDomain string, data []byte, to []*parsemai } }() - if domain == consts.TEST_DOMAIN { + if domain == consts.TEST_DOMAIN || isConfiguredMailDomain(domain, config.CurrentMailDomains().Accepted) { err := smtp.SendMailUnsafeContext(deliveryContext, "localhost", "127.0.0.1:25", nil, from, fromDomain, buildAddress(tos), data) if err != nil { recordFailure(err) @@ -336,6 +336,21 @@ func allowUnsafeSMTP(domain mxDomain) bool { return domain.localTest && domain.domain == "localhost" && domain.mxHost == "127.0.0.1" } +// isConfiguredMailDomain 判断收件域名是否属于当前 Smail 实例管理的域名。 +// 受管域名应交给本机 SMTP 服务处理,避免内部账户互发依赖公网 DNS 和 MX。 +func isConfiguredMailDomain(domain string, accepted []string) bool { + domain = strings.ToLower(strings.TrimSpace(domain)) + if domain == "" { + return false + } + for _, item := range accepted { + if domain == strings.ToLower(strings.TrimSpace(item)) { + return true + } + } + return false +} + func isCertificateVerificationError(err error) bool { var certificateErr *tls.CertificateVerificationError return errors.As(err, &certificateErr) diff --git a/backend/utils/send/send_test.go b/backend/utils/send/send_test.go index e750fb2..415f7cb 100644 --- a/backend/utils/send/send_test.go +++ b/backend/utils/send/send_test.go @@ -113,6 +113,28 @@ func TestAllowUnsafeSMTPRequiresExplicitLoopbackTestTarget(t *testing.T) { } } +func TestIsConfiguredMailDomain(t *testing.T) { + accepted := []string{"cdis.cn", "alias.cdis.cn"} + tests := []struct { + name string + domain string + want bool + }{ + {name: "primary domain", domain: "cdis.cn", want: true}, + {name: "case insensitive domain", domain: "CDIS.CN", want: true}, + {name: "accepted alias", domain: "alias.cdis.cn", want: true}, + {name: "external domain", domain: "example.com"}, + {name: "empty domain"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isConfiguredMailDomain(tt.domain, accepted); got != tt.want { + t.Fatalf("isConfiguredMailDomain(%q) = %v, want %v", tt.domain, got, tt.want) + } + }) + } +} + func TestParseRecipientAddressRejectsUnsafeInput(t *testing.T) { tests := []struct { name string