release: 1.1.0: Domain-admin role and internal/web package split
The first MINOR after 1.0.0: send-only DMARC guidance in the panel, AGPL packaging on every page, and an internal split of `internal/web` ahead of domain-admin work. Upgrading runs one SQLite migration (empty defaults; existing DNS guidance is unchanged until you set a report address). Changed: - `internal/web` split into subpackages (`web/view`, `web/auth`, `web/validate`, Added: - panel: DMARC guidance for send-only relays — the suggested `_dmarc` record - AGPL packaging hygiene: [NOTICE](NOTICE) names the copyright holder and the - [docs/roadmap.md](docs/roadmap.md) — candidate item **visual-style** (panel Full detail: CHANGELOG.md (1.1.0).
This commit is contained in:
@@ -293,7 +293,7 @@ func TestDMARC(t *testing.T) {
|
||||
txt["_dmarc.example.com"] = c.record
|
||||
}
|
||||
f := &fakeResolver{txt: txt}
|
||||
got := newTestChecker(f).checkDMARC(context.Background(), "example.com")
|
||||
got := newTestChecker(f).checkDMARC(context.Background(), Query{Name: "example.com"})
|
||||
if got.Status != c.want {
|
||||
t.Errorf("status = %q, want %q (%s)", got.Status, c.want, got.Detail)
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func TestDMARC(t *testing.T) {
|
||||
|
||||
func TestDMARCNonePolicyIsExplained(t *testing.T) {
|
||||
f := &fakeResolver{txt: map[string][]string{"_dmarc.example.com": {"v=DMARC1; p=none"}}}
|
||||
got := newTestChecker(f).checkDMARC(context.Background(), "example.com")
|
||||
got := newTestChecker(f).checkDMARC(context.Background(), Query{Name: "example.com"})
|
||||
if !strings.Contains(got.Detail, "monitoring only") {
|
||||
t.Errorf("p=none is not explained: %s", got.Detail)
|
||||
}
|
||||
@@ -357,3 +357,20 @@ func TestForgetDropsTheCachedDomain(t *testing.T) {
|
||||
t.Error("Forget did not drop the cached result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportAuth(t *testing.T) {
|
||||
f := &fakeResolver{txt: map[string][]string{"_report._dmarc.hub.example": {"v=DMARC1;"}}}
|
||||
got := newTestChecker(f).checkReportAuth(context.Background(), "hub.example")
|
||||
if got.Status != health.StatusOK {
|
||||
t.Fatalf("status = %q (%s)", got.Status, got.Detail)
|
||||
}
|
||||
|
||||
f = &fakeResolver{}
|
||||
got = newTestChecker(f).checkReportAuth(context.Background(), "hub.example")
|
||||
if got.Status != health.StatusWarn {
|
||||
t.Fatalf("missing = %q, want warn", got.Status)
|
||||
}
|
||||
if !strings.Contains(got.Detail, ReportAuthExample()) {
|
||||
t.Errorf("advice %q should cite %q", got.Detail, ReportAuthExample())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user