package mail import ( "context" "testing" "time" "github.com/carlosframework/platform/internal/release" ) func TestDomainKeyIsAccountScoped(t *testing.T) { got := DomainKey("bag", "harbourmail.bag.oncarlos.com") want := "accounts/bag/email/domains/harbourmail.bag.oncarlos.com.json" if got != want { t.Fatalf("DomainKey = %q, want %q", got, want) } } func TestValidDomainRefusesWhatWouldEscapeTheKey(t *testing.T) { for _, ok := range []string{"harbourmail.bag.oncarlos.com", "example.com", "a-b.example.co.uk"} { if !ValidDomain(ok) { t.Fatalf("ValidDomain(%q) = false, want true", ok) } } // A domain becomes a bucket KEY and an IAM policy RESOURCE. Anything // that could traverse or inject must be refused here, at the only // place every caller passes through. for _, bad := range []string{"", ".", "../etc", "a/b.com", "UPPER.com", "-lead.com", "trail-.com", "a..b.com", // Wildcards are dangerous: the domain string becomes an IAM // ses:FromAddress condition value, where * would match every // address on earth. "*", "*.example.com"} { if ValidDomain(bad) { t.Fatalf("ValidDomain(%q) = true, want false", bad) } } } // Regions is a MAP, and this test is the reason: a domain verified in two // regions holds two independent identities, ARNs and DKIM token sets, and // a scalar region field would have to be migrated the day a second region // appears (spec §6a, §8). func TestRegionsAreIndependent(t *testing.T) { ctx, s := context.Background(), release.NewDirStore(t.TempDir()) now := time.Date(2026, 8, 19, 12, 0, 0, 0, time.UTC) rec := &DomainRecord{ Domain: "harbourmail.bag.oncarlos.com", Kind: KindPlatform, Apps: []string{"harbourmail"}, Regions: map[string]*RegionState{ "eu-west-1": {IdentityARN: "arn:aws:ses:eu-west-1:1:identity/harbourmail.bag.oncarlos.com", DKIMTokens: []string{"a", "b", "c"}, MailFrom: "mail-eu-west-1.harbourmail.bag.oncarlos.com", Status: StatusVerified, CheckedAt: now}, "us-east-1": {IdentityARN: "arn:aws:ses:us-east-1:1:identity/harbourmail.bag.oncarlos.com", DKIMTokens: []string{"d", "e", "f"}, MailFrom: "mail-us-east-1.harbourmail.bag.oncarlos.com", Status: StatusPending, CheckedAt: now}, }, CreatedAt: now, } if _, err := PutDomain(ctx, s, "bag", rec, ""); err != nil { t.Fatalf("PutDomain: %v", err) } out, _, err := GetDomain(ctx, s, "bag", "harbourmail.bag.oncarlos.com") if err != nil { t.Fatalf("GetDomain: %v", err) } if len(out.Regions) != 2 { t.Fatalf("regions = %d, want 2", len(out.Regions)) } if out.Regions["us-east-1"].DKIMTokens[0] != "d" { t.Fatal("per-region DKIM tokens did not round-trip independently") } } // Only a VERIFIED region contributes an ARN, so a pending domain grants // nothing (spec §6a). func TestVerifiedARNsSkipsPendingAndFailed(t *testing.T) { rec := &DomainRecord{Regions: map[string]*RegionState{ "eu-west-1": {IdentityARN: "arn-ok", Status: StatusVerified}, "us-east-1": {IdentityARN: "arn-pending", Status: StatusPending}, "ap-south-1": {IdentityARN: "arn-failed", Status: StatusFailed}, }} got := rec.VerifiedARNs() if len(got) != 1 || got[0] != "arn-ok" { t.Fatalf("VerifiedARNs = %v, want [arn-ok]", got) } } // The apps set is what makes account-scoping worth its cost: teardown of // one app must never revoke a sibling's verified domain (spec §6a). func TestAppsSetGuardsSiblingTeardown(t *testing.T) { rec := &DomainRecord{Apps: []string{"harbourmail"}} if !rec.AddApp("marketing") { t.Fatal("AddApp returned false for a new app") } if rec.AddApp("marketing") { t.Fatal("AddApp returned true for an app already present") } if !rec.RemoveApp("harbourmail") { t.Fatal("RemoveApp returned false for a present app") } if len(rec.Apps) != 1 || rec.Apps[0] != "marketing" { t.Fatalf("Apps = %v, want [marketing] — the sibling must survive", rec.Apps) } }