From bed251bb7f96b42f35442b10f07582887809e5eb Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 23 Apr 2026 17:42:00 +0700 Subject: [PATCH] Add interactive form/report --- checker/interactive.go | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 checker/interactive.go diff --git a/checker/interactive.go b/checker/interactive.go new file mode 100644 index 0000000..561ee91 --- /dev/null +++ b/checker/interactive.go @@ -0,0 +1,65 @@ +package checker + +import ( + "errors" + "net/http" + "slices" + "strconv" + "strings" + + sdk "git.happydns.org/checker-sdk-go/checker" +) + +// RenderForm implements sdk.CheckerInteractive. +func (p *xmppProvider) RenderForm() []sdk.CheckerOptionField { + return []sdk.CheckerOptionField{ + { + Id: "domain", + Type: "string", + Label: "Domain", + Placeholder: "example.com", + Required: true, + }, + { + Id: "mode", + Type: "string", + Label: "Mode", + Default: string(ModeBoth), + Choices: validModes, + }, + { + Id: "timeout", + Type: "number", + Label: "Per-endpoint timeout (seconds)", + Default: 10, + }, + } +} + +// ParseForm implements sdk.CheckerInteractive. +func (p *xmppProvider) ParseForm(r *http.Request) (sdk.CheckerOptions, error) { + domain := strings.TrimSpace(r.FormValue("domain")) + domain = strings.TrimSuffix(domain, ".") + if domain == "" { + return nil, errors.New("domain is required") + } + + opts := sdk.CheckerOptions{"domain": domain} + + if mode := strings.TrimSpace(r.FormValue("mode")); mode != "" { + if !slices.Contains(validModes, mode) { + return nil, errors.New("mode must be one of: c2s, s2s, both") + } + opts["mode"] = mode + } + + if to := strings.TrimSpace(r.FormValue("timeout")); to != "" { + v, err := strconv.ParseFloat(to, 64) + if err != nil { + return nil, errors.New("timeout must be a number") + } + opts["timeout"] = v + } + + return opts, nil +}