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).
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/mixeme/selfpost/internal/web/validate"
|
|
)
|
|
|
|
// HandleDomainDMARC saves per-domain DMARC rua= settings.
|
|
func (h *Handlers) HandleDomainDMARC(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
w.Header().Set("Allow", "POST")
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
d, ok := h.lookupDomain(w, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
if err := r.ParseForm(); err != nil {
|
|
h.renderDomainDetail(w, r, http.StatusBadRequest, d, detailView{FormErr: "Invalid form submission."})
|
|
return
|
|
}
|
|
|
|
var rua sql.NullString
|
|
switch strings.TrimSpace(r.PostFormValue("dmarc_rua_mode")) {
|
|
case "inherit":
|
|
rua = sql.NullString{}
|
|
case "none":
|
|
rua = sql.NullString{Valid: true, String: ""}
|
|
case "custom":
|
|
email := strings.TrimSpace(r.PostFormValue("dmarc_rua_email"))
|
|
if err := validate.Email(email); err != nil {
|
|
h.renderDomainDetail(w, r, http.StatusBadRequest, d, detailView{FormErr: err.Error()})
|
|
return
|
|
}
|
|
if email == "" {
|
|
h.renderDomainDetail(w, r, http.StatusBadRequest, d, detailView{FormErr: "Enter a custom report address or choose another mode."})
|
|
return
|
|
}
|
|
rua = sql.NullString{Valid: true, String: email}
|
|
default:
|
|
h.renderDomainDetail(w, r, http.StatusBadRequest, d, detailView{FormErr: "Choose how aggregate reports are addressed for this domain."})
|
|
return
|
|
}
|
|
|
|
if err := h.store.UpdateDomainDMARCRua(d.ID, rua); err != nil {
|
|
logf("panel: domain %d: save dmarc rua: %v", d.ID, err)
|
|
h.renderDomainDetail(w, r, http.StatusInternalServerError, d, detailView{FormErr: "Could not save DMARC settings. Please check the logs and try again."})
|
|
return
|
|
}
|
|
h.dns.Forget(d.Name)
|
|
http.Redirect(w, r, fmt.Sprintf("/domains/%d?dmarc=1", d.ID), http.StatusSeeOther)
|
|
}
|