Files
llmgw/internal/mail/mail_test.go
Ilker ManapandClaude Opus 5.5 66f702d5c1 A forgotten password is set through a one-time link
/forgot mails a link to set a new password when the cluster's mail settings
say how - SMTP relay, sender, and the public base_url the link points at,
never the request's Host - and says the same whether or not the address has
an account. /reset sets it once, closing every session. Links are kept by
their hash in password_resets, good for an hour, a newer one replacing an
older. Without mail, /forgot says to ask an operator, and llmgw users
reset-link makes the link to hand over. Single sign-on accounts get none.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-07 13:20:11 +02:00

94 lines
2.3 KiB
Go

package mail
import (
"bufio"
"context"
"net"
"strings"
"testing"
)
// relay is the least of an SMTP server: it takes one message and keeps it.
func relay(t *testing.T) (addr string, got chan string) {
t.Helper()
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
got = make(chan string, 1)
go func() {
c, err := ln.Accept()
if err != nil {
return
}
defer c.Close()
r := bufio.NewReader(c)
say := func(s string) { _, _ = c.Write([]byte(s + "\r\n")) }
say("220 relay ready")
var data strings.Builder
inData := false
for {
line, err := r.ReadString('\n')
if err != nil {
return
}
if inData {
if line == ".\r\n" {
inData = false
got <- data.String()
say("250 kept")
continue
}
data.WriteString(line)
continue
}
switch cmd := strings.ToUpper(strings.TrimSpace(line)); {
case strings.HasPrefix(cmd, "EHLO"), strings.HasPrefix(cmd, "HELO"):
say("250 relay")
case strings.HasPrefix(cmd, "DATA"):
inData = true
say("354 go on")
case strings.HasPrefix(cmd, "QUIT"):
say("221 bye")
return
default:
say("250 ok")
}
}
}()
t.Cleanup(func() { _ = ln.Close() })
return ln.Addr().String(), got
}
func TestAMessageGoesThroughTheRelay(t *testing.T) {
addr, got := relay(t)
c := Config{SMTP: addr, From: "llmgw <llmgw@example.com>", BaseURL: "https://llm.example.com"}
if err := c.Validate(); err != nil {
t.Fatal(err)
}
if err := c.Send(context.Background(), "ayse@example.com", "Set a new password", "Hello,\nthe link."); err != nil {
t.Fatal(err)
}
msg := <-got
for _, want := range []string{"Subject: Set a new password", "To: ayse@example.com", "Hello,\r\nthe link."} {
if !strings.Contains(msg, want) {
t.Errorf("the message lacks %q:\n%s", want, msg)
}
}
}
func TestHalfAMailConfigurationIsRefused(t *testing.T) {
if err := (Config{}).Validate(); err != nil || (Config{}).Enabled() {
t.Errorf("none: %v", err)
}
if err := (Config{SMTP: "smtp.example.com:587"}).Validate(); err == nil {
t.Error("a relay without a sender was accepted")
}
if err := (Config{SMTP: "smtp.example.com:587", From: "a@b.c", BaseURL: "llm.example.com"}).Validate(); err == nil {
t.Error("a base URL without a scheme was accepted")
}
if got := address("llmgw <llmgw@example.com>"); got != "llmgw@example.com" {
t.Errorf("%q", got)
}
}