120 lines
3.9 KiB
Go
120 lines
3.9 KiB
Go
package res_init
|
||
|
||
import (
|
||
"errors"
|
||
"testing"
|
||
|
||
"git.pcux.cn/xuans/Smail/config"
|
||
"git.pcux.cn/xuans/Smail/services/verification"
|
||
)
|
||
|
||
func TestVerificationDeliveryUsesProjectMailWithoutRelay(t *testing.T) {
|
||
settings := config.SMTPRuntimeSettings{
|
||
Relay: config.SMTPConfig{
|
||
RelayPort: 587,
|
||
Security: "starttls",
|
||
FromDomain: "example.com",
|
||
},
|
||
}
|
||
relayCalled := false
|
||
projectCalled := false
|
||
delivery := newVerificationDeliveryWithDependencies(
|
||
func() (config.SMTPRuntimeSettings, error) { return settings, nil },
|
||
func(config.SMTPRuntimeSettings, verification.Challenge, string) error {
|
||
relayCalled = true
|
||
return nil
|
||
},
|
||
func(challenge verification.Challenge, code string) error {
|
||
projectCalled = challenge.Email == "user@example.net" && code == "12345678"
|
||
return nil
|
||
},
|
||
)
|
||
|
||
if err := delivery(verification.Challenge{Email: "user@example.net"}, "12345678"); err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if relayCalled || !projectCalled {
|
||
t.Fatalf("relayCalled=%v projectCalled=%v", relayCalled, projectCalled)
|
||
}
|
||
}
|
||
|
||
func TestVerificationDeliveryDoesNotHidePartialRelayConfiguration(t *testing.T) {
|
||
expected := verification.ErrInvalidSMTPConfig
|
||
projectCalled := false
|
||
delivery := newVerificationDeliveryWithDependencies(
|
||
func() (config.SMTPRuntimeSettings, error) {
|
||
return config.SMTPRuntimeSettings{Relay: config.SMTPConfig{RelayEnabled: true, RelayHost: "smtp.example.com"}}, nil
|
||
},
|
||
func(config.SMTPRuntimeSettings, verification.Challenge, string) error { return expected },
|
||
func(verification.Challenge, string) error {
|
||
projectCalled = true
|
||
return nil
|
||
},
|
||
)
|
||
|
||
err := delivery(verification.Challenge{Email: "user@example.net"}, "12345678")
|
||
if !errors.Is(err, expected) {
|
||
t.Fatalf("error = %v, want %v", err, expected)
|
||
}
|
||
if projectCalled {
|
||
t.Fatal("partial relay configuration unexpectedly fell back to project mail")
|
||
}
|
||
}
|
||
|
||
func TestVerificationDeliveryPreservesSettingsError(t *testing.T) {
|
||
expected := errors.New("settings unavailable")
|
||
delivery := newVerificationDeliveryWithDependencies(
|
||
func() (config.SMTPRuntimeSettings, error) { return config.SMTPRuntimeSettings{}, expected },
|
||
func(config.SMTPRuntimeSettings, verification.Challenge, string) error { return nil },
|
||
func(verification.Challenge, string) error { return nil },
|
||
)
|
||
|
||
err := delivery(verification.Challenge{Email: "user@example.net"}, "12345678")
|
||
if !errors.Is(err, expected) {
|
||
t.Fatalf("error = %v, want wrapped settings error", err)
|
||
}
|
||
}
|
||
|
||
func TestPublicRecoveryLinkUsesWebDomain(t *testing.T) {
|
||
link, err := publicRecoveryLink("web.example.com", "one-time-token")
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if link != "https://web.example.com/rest/#/reset-password/one-time-token" {
|
||
t.Fatalf("public recovery link = %q", link)
|
||
}
|
||
if _, err := publicRecoveryLink("https://web.example.com/path", "one-time-token"); err == nil {
|
||
t.Fatal("invalid web domain was accepted")
|
||
}
|
||
}
|
||
|
||
func TestPublicRecoveryMailLinkUsesPublicHTTPSPort(t *testing.T) {
|
||
oldConfig, oldManager := config.Instance, config.CurrentManager()
|
||
config.SetRuntimeManager(nil)
|
||
config.Instance = &config.Config{HttpsPort: 8002}
|
||
t.Cleanup(func() {
|
||
config.Instance = oldConfig
|
||
config.SetRuntimeManager(oldManager)
|
||
})
|
||
for _, test := range []struct {
|
||
port int
|
||
want string
|
||
}{
|
||
{443, "https://web.example.com/rest/#/reset-password/one-time-token"},
|
||
{9443, "https://web.example.com:9443/rest/#/reset-password/one-time-token"},
|
||
{0, "https://web.example.com:8002/rest/#/reset-password/one-time-token"},
|
||
} {
|
||
config.Instance.PublicHTTPSPort = test.port
|
||
link, err := publicRecoveryLink("web.example.com", "one-time-token")
|
||
if err != nil || link != test.want {
|
||
t.Fatalf("恢复邮件公网链接不匹配:%q,%v", link, err)
|
||
}
|
||
}
|
||
for _, port := range []int{-1, 65536} {
|
||
config.Instance.PublicHTTPSPort = port
|
||
if _, err := publicRecoveryLink("web.example.com", "one-time-token"); err == nil {
|
||
t.Fatal("非法公网端口仍生成了邮件恢复链接")
|
||
}
|
||
}
|
||
}
|