github.com/StackExchange/DNSControl@v0.2.8/docs/flattener/js.go (about)

     1  // +build js
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"net/http"
     9  	"strings"
    10  
    11  	"github.com/StackExchange/dnscontrol/pkg/spflib"
    12  	"github.com/gopherjs/jquery"
    13  )
    14  
    15  type gResolver struct{}
    16  
    17  type gResp struct {
    18  	Status int
    19  	Answer []struct {
    20  		Data string `json:"data"`
    21  	}
    22  }
    23  
    24  func (g gResolver) GetSPF(fqdn string) (string, error) {
    25  	resp, err := http.Get("https://dns.google.com/resolve?type=txt&name=" + fqdn)
    26  	if err != nil {
    27  		return "", err
    28  	}
    29  
    30  	defer resp.Body.Close()
    31  	dec := json.NewDecoder(resp.Body)
    32  	dat := &gResp{}
    33  	if err = dec.Decode(dat); err != nil {
    34  		return "", err
    35  	}
    36  	for _, a := range dat.Answer {
    37  		val := strings.Trim(a.Data, "\"")
    38  		if strings.HasPrefix(val, "v=spf1 ") {
    39  			return val, nil
    40  		}
    41  	}
    42  	return "", fmt.Errorf("No spf records found")
    43  }
    44  
    45  var jq = jquery.NewJQuery
    46  var parsed *spflib.SPFRecord
    47  var domain string
    48  
    49  var resolver = gResolver{}
    50  
    51  func main() {
    52  	jq(func() {
    53  		jq("#lookup_btn").On(jquery.CLICK, func(e jquery.Event) {
    54  			go func() {
    55  				domain = jq("#domain").Val()
    56  				text, err := resolver.GetSPF(domain)
    57  				fmt.Println(text)
    58  				if err != nil {
    59  					panic(err)
    60  				}
    61  				parsed, err = spflib.Parse(text, resolver)
    62  				if err != nil {
    63  					panic(err)
    64  				}
    65  				jq("#results").SetHtml(buildHTML(parsed, domain))
    66  				jq(".cb").On(jquery.CHANGE, func(e jquery.Event) {
    67  					updateDisabledChecks()
    68  					renderResults()
    69  				})
    70  				updateDisabledChecks()
    71  				renderResults()
    72  			}()
    73  		})
    74  	})
    75  }
    76  
    77  func updateDisabledChecks() {
    78  	jq("input:checkbox").Each(func(i int, el interface{}) {
    79  		fmt.Println(jq(el).Prop("disabled"))
    80  		jq(el).SetProp("disabled", false)
    81  	})
    82  	jq("input:checkbox:not(:checked)").Each(func(i int, el interface{}) {
    83  		fmt.Println(jq(el).Attr("id"))
    84  		jq(el).Next().Next().Find("input:checkbox").Each(func(i int, el interface{}) {
    85  			fmt.Println("^^", jq(el).Attr("id"))
    86  			jq(el).SetProp("disabled", true)
    87  		})
    88  	})
    89  }
    90  
    91  func renderResults() {
    92  	content := ""
    93  	addFlattened := func(mode string, filter string) {
    94  		flat := parsed.Flatten(filter)
    95  		lookups := 0
    96  		if filter != "*" {
    97  			lookups = parsed.Lookups() - len(strings.Split(filter, ","))
    98  		}
    99  		content += fmt.Sprintf(`
   100  <h3> %s flattened (length %d, %d lookups)</h3><code>%s</code>	
   101  `, mode, len(flat.TXT()), lookups, flat.TXT())
   102  		split := flat.TXTSplit("_spf%d." + domain)
   103  		if len(split) > 1 {
   104  			lookups += len(split) - 1
   105  			content += fmt.Sprintf("<h3>%s flattened split (%d lookups)</h3>", mode, lookups)
   106  			for k, v := range split {
   107  				content += fmt.Sprintf("<h4>%s</h4><code>%s</code>", k, v)
   108  			}
   109  		}
   110  	}
   111  	addFlattened("Fully", "*")
   112  
   113  	// look for selected divs
   114  	filters := []string{}
   115  	jq("input:checked").Each(func(i int, el interface{}) {
   116  		filters = append(filters, jq(el).Attr("id"))
   117  	})
   118  	if len(filters) > 0 {
   119  		addFlattened("Selectively", strings.Join(filters, ","))
   120  	}
   121  
   122  	jq("#flattened").SetHtml(content)
   123  }
   124  
   125  func buildHTML(rec *spflib.SPFRecord, domain string) string {
   126  	h := "<h1>" + domain + "</h1>"
   127  	h += fmt.Sprintf("<h2>%d lookups</h2>", rec.Lookups())
   128  	return h + genRoot(rec)
   129  }
   130  
   131  // html based on https://codepen.io/khoama/pen/hpljA
   132  func genRoot(rec *spflib.SPFRecord) string {
   133  	h := fmt.Sprintf(` 
   134  <ul>
   135  	<li class='root'>%s</li>
   136  	`, rec.TXT())
   137  	for _, p := range rec.Parts {
   138  		h += genPart(p)
   139  	}
   140  	h += "</ul>"
   141  	return h
   142  }
   143  
   144  func genPart(rec *spflib.SPFPart) string {
   145  	if !rec.IsLookup {
   146  		return fmt.Sprintf(`<li>%s</li>`, rec.Text)
   147  	}
   148  	h := fmt.Sprintf(`<li>
   149  	<input type="checkbox" class='cb' id="%s" name="%s" />
   150  	<label for="%s">%s(%d lookups)</label>`, rec.IncludeDomain, rec.IncludeDomain, rec.IncludeDomain, rec.Text, rec.IncludeRecord.Lookups()+1)
   151  	h += fmt.Sprintf("<ul>")
   152  	for _, p := range rec.IncludeRecord.Parts {
   153  		h += genPart(p)
   154  	}
   155  	h += "</ul>"
   156  	h += "</li>"
   157  	return h
   158  }