fix: harden DynDNS recovery and publish v1.5.1
This commit is contained in:
1 parent
3383b91e49
commit
81def77e3c
37 files changed
+2415
-250
No files matched your search
@@ -0,0 +1,70 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/root-kdw12/hetzner-api-dyndns-records-webinterface/internal/buildinfo"
|
||||
"github.com/root-kdw12/hetzner-api-dyndns-records-webinterface/internal/diagnostics"
|
||||
"github.com/root-kdw12/hetzner-api-dyndns-records-webinterface/internal/model"
|
||||
)
|
||||
|
||||
// Only this allowlisted report is downloadable, never raw Docker logs, stored
|
||||
// error messages, audit messages, configuration, credentials or session data.
|
||||
func (s *Server) downloadDiagnostics(w http.ResponseWriter, r *http.Request, _ *model.Session) {
|
||||
settings, err := s.store.GetSettings(r.Context())
|
||||
if err != nil {
|
||||
s.serverError(w, err)
|
||||
return
|
||||
}
|
||||
runs, err := s.store.RecentRuns(r.Context(), 100)
|
||||
if err != nil {
|
||||
s.serverError(w, err)
|
||||
return
|
||||
}
|
||||
type run struct {
|
||||
ID int64 `json:"id"`
|
||||
StartedAt time.Time `json:"started_at"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
report := struct {
|
||||
Format int `json:"format"`
|
||||
Version string `json:"version"`
|
||||
ExportedAt time.Time `json:"exported_at"`
|
||||
Network *diagnostics.Network `json:"current_network"`
|
||||
UpdaterEnabled bool `json:"updater_enabled"`
|
||||
IPv6Enabled bool `json:"ipv6_enabled"`
|
||||
IntervalSeconds int `json:"interval_seconds"`
|
||||
LastIPv4 string `json:"last_ipv4,omitempty"`
|
||||
LastIPv6 string `json:"last_ipv6,omitempty"`
|
||||
Runs []run `json:"recent_runs"`
|
||||
Events []diagnostics.Event `json:"events"`
|
||||
}{
|
||||
Format: 1, Version: buildinfo.Version, ExportedAt: time.Now().UTC(), Network: diagnostics.CurrentNetwork(),
|
||||
UpdaterEnabled: settings.UpdaterEnabled, IPv6Enabled: settings.IPv6Enabled, IntervalSeconds: settings.UpdateIntervalSeconds,
|
||||
Events: diagnostics.Snapshot(),
|
||||
}
|
||||
if ip, err := netip.ParseAddr(settings.LastIPv4); err == nil && ip.Zone() == "" {
|
||||
report.LastIPv4 = ip.String()
|
||||
}
|
||||
if ip, err := netip.ParseAddr(settings.LastIPv6); err == nil && ip.Zone() == "" {
|
||||
report.LastIPv6 = ip.String()
|
||||
}
|
||||
for _, item := range runs {
|
||||
status := "unknown"
|
||||
switch item.Status {
|
||||
case "running", "ok", "error", "partial":
|
||||
status = item.Status
|
||||
}
|
||||
report.Runs = append(report.Runs, run{item.ID, item.StartedAt, status})
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="domain-control-diagnostics.json"`)
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", " ")
|
||||
_ = encoder.Encode(report)
|
||||
}
|
||||
Reference in new issue
Block a user