Serves a page explaining why a domain was blocked instead of leaving a sinkholed client with a dead connection. Binds its own HTTP/HTTPS listeners with self-signed, per-hostname TLS certs generated on the fly, re-evaluates the requesting client against the policy engine per request, and renders an HTML template editable from Settings with a live preview. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TTKpGMQzpfDsvedu1hvSUf
53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
package web
|
|
|
|
import (
|
|
"fmt"
|
|
"html"
|
|
"net/http"
|
|
|
|
"github.com/owen/vibedns/internal/app"
|
|
"github.com/owen/vibedns/internal/blockpage"
|
|
)
|
|
|
|
func (s *Server) handleSettingsBlockPage(w http.ResponseWriter, r *http.Request) error {
|
|
boundHTTP, boundHTTPS := s.app.BlockPage.ListenAddrs()
|
|
s.settingsPage(w, r, "settings_blockpage", "blockpage", "Block Page Settings", map[string]any{
|
|
"Running": s.app.BlockPage.Running(),
|
|
"BoundHTTP": boundHTTP,
|
|
"BoundHTTPS": boundHTTPS,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func (s *Server) handleSettingsBlockPageSave(w http.ResponseWriter, r *http.Request) error {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
}
|
|
next := s.app.Settings()
|
|
next.BlockPage.Enabled = formBool(r, "enabled")
|
|
next.BlockPage.HTTPListen = formString(r, "http_listen")
|
|
next.BlockPage.HTTPSListen = formString(r, "https_listen")
|
|
next.BlockPage.HTML = r.FormValue("html")
|
|
|
|
if err := s.app.SaveSettings(r.Context(), s.actor(r), app.GroupBlockPage, next); err != nil {
|
|
return err
|
|
}
|
|
setFlash(w, r, "success", "Block page settings saved.")
|
|
return s.redirect(w, r, "/settings/blockpage")
|
|
}
|
|
|
|
// handleSettingsBlockPagePreview renders the HTML in the request body with
|
|
// sample data, without saving it, so the editor can show a live preview.
|
|
func (s *Server) handleSettingsBlockPagePreview(w http.ResponseWriter, r *http.Request) error {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
}
|
|
out, err := blockpage.Render(r.FormValue("html"))
|
|
if err != nil {
|
|
out = fmt.Sprintf("<pre style=\"white-space:pre-wrap;font-family:monospace;color:#c00;padding:1em\">Template error: %s</pre>", html.EscapeString(err.Error()))
|
|
}
|
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
_, _ = w.Write([]byte(out))
|
|
return nil
|
|
}
|