panel-notifications: Account, Server > Settings, Server > Health, help; e2e
test / test (push) Canceled after 0s
test / test (push) Canceled after 0s
The pages of the mockups accepted in 87fa0a4, built from the kit's partials
(written by a Sonnet agent into the working tree, reviewed here):
- Account: "Send me notifications" in the Profile form, saved with the
profile; an unticked box is off.
- Server > Settings: the instance switch (box 03), and box 04 Notification
mail with the DKIM and SPF records of the server's own name, drawn with the
record partial of a domain's DNS page and checked in DNS. Sending rate
limits are box 02 in the left column. A record that is not in place is
tagged as a warning, not a failure: notifications are sent without it.
- Server > Health: card 06 Notification mail with the state of each record
and a link to Settings, beside Configuration (07); part of the polled
fragment; Re-check DNS forces it too. Overview does not run this check.
- help.go: the Notifications topic and the clauses in Settings and Your
account, word for word with help.html.
If the server's key cannot be read the pages still render: the DKIM record
is left out and SPF is shown unchecked.
e2e: the administrator gets a mailbox behind the sink and the server's DKIM
record from Settings is published; the level-2 refusal of the next step must
then arrive as a notification from postmaster@mail.e2e.test, signed as that
name with the key Settings shows, and must not be a row of the Outbound log.
The rotation step now waits for Postfix to be running: it follows a step that
restarts the container, and logrotate's `postfix reload` failed in between.
On the test server, for this tree: go vet clean, go test ./... 23 packages
ok, make e2e ok (147 s); the notification reached the sink 28 s after the
refusal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -178,6 +178,41 @@ func SPFRecord(domain, value string, c DNSCheck) Record {
|
||||
return r
|
||||
}
|
||||
|
||||
// mailTag is the tag of a record of the server's own name. The records are not
|
||||
// needed for notifications to be sent, only for them to arrive, so a record
|
||||
// that is missing, wrong or weak is a warning here and never the red a
|
||||
// sending domain's would be; published and not checked keep their meaning.
|
||||
func mailTag(c DNSCheck) Tag {
|
||||
t := DNSStatusTag(c.Status, len(c.Found) > 0)
|
||||
if tagLevel(t.Status) == LevelFail {
|
||||
t.Status = "warn"
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// ServerMailDKIM is the DKIM record of the server's own name, which the panel
|
||||
// signs its notifications with: a domain's DKIM record in every other respect.
|
||||
func ServerMailDKIM(selector, host, value string, c DNSCheck) Record {
|
||||
r := DKIMRecord(selector, host, value, c)
|
||||
r.Status = mailTag(c)
|
||||
return r
|
||||
}
|
||||
|
||||
// ServerMailSPF is the SPF record of the server's own name. Without it
|
||||
// notifications are still sent, which is said under the value while it is not
|
||||
// in place.
|
||||
func ServerMailSPF(host, value string, c DNSCheck) Record {
|
||||
r := Record{Name: "SPF", Note: Plain("For the server's own name, not for your domains"),
|
||||
Host: host, Type: "TXT", Value: value}
|
||||
var standing Text
|
||||
if c.Status != "ok" {
|
||||
standing = Plain("Notifications are sent without it, and a receiver may file them as spam.")
|
||||
}
|
||||
applyCheck(&r, c, standing, nil)
|
||||
r.Status = mailTag(c)
|
||||
return r
|
||||
}
|
||||
|
||||
// DMARCRecordInput is what a DMARC record needs besides its check: where the
|
||||
// reports go in words (Source: the address, or "no reports") and the page that changes it,
|
||||
// the page of the reports themselves ("" when the panel has none), and whether
|
||||
|
||||
Reference in New Issue
Block a user