// +build js package main import ( "encoding/json" "fmt" "net/http" "strings" "github.com/StackExchange/dnscontrol/pkg/spflib" "github.com/gopherjs/jquery" ) type gResolver struct{} type gResp struct { Status int Answer []struct { Data string `json:"data"` } } func (g gResolver) GetTxt(fqdn string) ([]string, error) { resp, err := http.Get("https://dns.google.com/resolve?type=txt&name=" + fqdn) if err != nil { return nil, err } defer resp.Body.Close() dec := json.NewDecoder(resp.Body) dat := &gResp{} if err = dec.Decode(dat); err != nil { return nil, err } list := []string{} for _, a := range dat.Answer { list = append(list, strings.Trim(a.Data, "\"")) } return list, nil } var jq = jquery.NewJQuery var parsed *spflib.SPFRecord var domain string func main() { jq(func() { jq("#lookup_btn").On(jquery.CLICK, func(e jquery.Event) { go func() { domain = jq("#domain").Val() rec, err := spflib.Lookup(domain, gResolver{}) if err != nil { panic(err) } parsed, err = spflib.Parse(rec, gResolver{}) if err != nil { // todo: show a better error panic(err) } jq("#results").SetHtml(buildHTML(parsed, domain)) jq(".cb").On(jquery.CHANGE, func(e jquery.Event) { updateDisabledChecks() renderResults() }) updateDisabledChecks() renderResults() }() }) }) } func updateDisabledChecks() { jq("input:checkbox").Each(func(i int, el interface{}) { fmt.Println(jq(el).Prop("disabled")) jq(el).SetProp("disabled", false) }) jq("input:checkbox:not(:checked)").Each(func(i int, el interface{}) { fmt.Println(jq(el).Attr("id")) jq(el).Next().Next().Find("input:checkbox").Each(func(i int, el interface{}) { fmt.Println("^^", jq(el).Attr("id")) jq(el).SetProp("disabled", true) }) }) } func renderResults() { content := "" addFlattened := func(mode string, filter string) { flat := parsed.Flatten(filter) lookups := 0 if filter != "*" { lookups = parsed.Lookups() - len(strings.Split(filter, ",")) } content += fmt.Sprintf(`

%s flattened (length %d, %d lookups)

%s `, mode, len(flat.TXT()), lookups, flat.TXT()) split := flat.TXTSplit("_spf%d." + domain) if len(split) > 1 { lookups += len(split) - 1 content += fmt.Sprintf("

%s flattened split (%d lookups)

", mode, lookups) for k, v := range split { content += fmt.Sprintf("

%s

%s", k, v) } } } addFlattened("Fully", "*") // look for selected divs filters := []string{} jq("input:checked").Each(func(i int, el interface{}) { filters = append(filters, jq(el).Attr("id")) }) if len(filters) > 0 { addFlattened("Selectively", strings.Join(filters, ",")) } jq("#flattened").SetHtml(content) } func buildHTML(rec *spflib.SPFRecord, domain string) string { h := "

" + domain + "

" h += fmt.Sprintf("

%d lookups

", rec.Lookups()) return h + genRoot(rec) } // html based on https://codepen.io/khoama/pen/hpljA func genRoot(rec *spflib.SPFRecord) string { h := fmt.Sprintf(` " return h } func genPart(rec *spflib.SPFPart) string { if !rec.IsLookup { return fmt.Sprintf(`
  • %s
  • `, rec.Text) } h := fmt.Sprintf(`
  • `, rec.IncludeDomain, rec.IncludeDomain, rec.IncludeDomain, rec.Text, rec.IncludeRecord.Lookups()+1) h += fmt.Sprintf("" h += "
  • " return h }