release: 1.4.0: Optional inbound relay (backup-MX) on port 25
Optional inbound relay (backup-MX / forwarder) on port 25, off by default. Mail is accepted only for domains configured in the panel and forwarded to an upstream; there are still no mailboxes. A dedicated security review of the inbound path is still open on the plan (Fable). Added: - `INBOUND_RELAY_ENABLE` (default `false`): when true, Postfix listens on - Panel **Inbound** pages (global administrator): domains, upstream host/port - Optional `INBOUND_ANTISPAM_MILTER` on the inbound listener only, plus - Inbound rate limit (`INBOUND_RATE_LIMIT_MESSAGES_PER_IP`, default 20) and Changed: - Compose publishes host port 25 even when the flag is off (nothing listens - Full-backup restore Resync also rebuilds inbound maps when the flag is on. Full detail: CHANGELOG.md (1.4.0).
This commit is contained in:
+29
-18
@@ -18,9 +18,10 @@ var assetsFS embed.FS
|
||||
|
||||
// Engine holds parsed page and fragment templates.
|
||||
type Engine struct {
|
||||
pages map[string]*template.Template
|
||||
fragments map[string]*template.Template
|
||||
version string
|
||||
pages map[string]*template.Template
|
||||
fragments map[string]*template.Template
|
||||
version string
|
||||
inboundEnabled bool
|
||||
}
|
||||
|
||||
// pageFiles maps a logical page name to its template files. Every page
|
||||
@@ -31,21 +32,24 @@ type Engine struct {
|
||||
// encryption fields on the two secret downloads) list that partial the same
|
||||
// way.
|
||||
var pageFiles = map[string][]string{
|
||||
"setup": {"templates/setup.html"},
|
||||
"login": {"templates/login.html"},
|
||||
"dashboard": {"templates/dashboard.html"},
|
||||
"settings": {"templates/settings.html"},
|
||||
"users": {"templates/users.html"},
|
||||
"user_form": {"templates/user_form.html"},
|
||||
"user_delete": {"templates/user_delete.html"},
|
||||
"backup": {"templates/backup.html", "templates/encrypt_fields.html"},
|
||||
"domain_detail": {"templates/domain_detail.html", "templates/encrypt_fields.html"},
|
||||
"domain_delete": {"templates/domain_delete.html"},
|
||||
"deliveries": {"templates/deliveries.html", "templates/deliveries_rows.html"},
|
||||
"delivery": {"templates/delivery.html"},
|
||||
"mail_queue": {"templates/mail_queue.html", "templates/mail_queue_body.html"},
|
||||
"system_log": {"templates/system_log.html", "templates/system_log_body.html"},
|
||||
"status": {"templates/status.html", "templates/status_body.html"},
|
||||
"setup": {"templates/setup.html"},
|
||||
"login": {"templates/login.html"},
|
||||
"dashboard": {"templates/dashboard.html"},
|
||||
"settings": {"templates/settings.html"},
|
||||
"users": {"templates/users.html"},
|
||||
"user_form": {"templates/user_form.html"},
|
||||
"user_delete": {"templates/user_delete.html"},
|
||||
"backup": {"templates/backup.html", "templates/encrypt_fields.html"},
|
||||
"domain_detail": {"templates/domain_detail.html", "templates/encrypt_fields.html"},
|
||||
"domain_delete": {"templates/domain_delete.html"},
|
||||
"inbound": {"templates/inbound.html"},
|
||||
"inbound_domain": {"templates/inbound_domain.html"},
|
||||
"inbound_delete": {"templates/inbound_delete.html"},
|
||||
"deliveries": {"templates/deliveries.html", "templates/deliveries_rows.html"},
|
||||
"delivery": {"templates/delivery.html"},
|
||||
"mail_queue": {"templates/mail_queue.html", "templates/mail_queue_body.html"},
|
||||
"system_log": {"templates/system_log.html", "templates/system_log_body.html"},
|
||||
"status": {"templates/status.html", "templates/status_body.html"},
|
||||
}
|
||||
|
||||
// fragmentFiles maps a fragment name (also its {{define}} block name) to its
|
||||
@@ -82,6 +86,12 @@ func New(version string) (*Engine, error) {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// SetInboundEnabled controls whether the Inbound nav item is shown. The
|
||||
// listener and routes are gated the same way (INBOUND_RELAY_ENABLE).
|
||||
func (e *Engine) SetInboundEnabled(v bool) {
|
||||
e.inboundEnabled = v
|
||||
}
|
||||
|
||||
// templateFuncs supplies helpers shared across page templates.
|
||||
func templateFuncs() template.FuncMap {
|
||||
return template.FuncMap{
|
||||
@@ -124,6 +134,7 @@ func (e *Engine) Render(w http.ResponseWriter, status int, page string, data any
|
||||
m["Version"] = e.version
|
||||
m["Copyright"] = legal.CopyrightLine
|
||||
m["SourceURL"] = legal.SourceURL
|
||||
m["InboundEnabled"] = e.inboundEnabled
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := tmpl.ExecuteTemplate(&buf, "layout.html", data); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user