package cloudflare import ( "bytes" "encoding/json" "errors" "html/template" "io" "net/http" "strings" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/router" ) var VerifyUrl = "https://challenges.cloudflare.com/turnstile/v0/siteverify" type TurnstileResponse struct { Success bool `json:"success"` ErrorCodes []string `json:"error-codes,omitempty"` ChallengeTS string `json:"challenge_ts,omitempty"` Hostname string `json:"hostname,omitempty"` } type TurnStilleCaptcha struct { SiteKey string SecretKey string } func ServeTurnstilleCaptchaJS(app *pocketbase.PocketBase, se *core.ServeEvent) *router.Route[*core.RequestEvent] { return se.Router.GET("/api/email/script.js", func(e *core.RequestEvent) error { // www.abrasive.ma-al.pl // siteKey: "0x4AAAAAABdgeAdu4Pxxovj3" // secretKey: "0x4AAAAAABdgeHJDjMwmeX5aXaXGh6HWZbw" settings, err := GetSettings(app) if err != nil { return err } file, err := JS.ReadFile("TurnStilleCaptcha.js") if err != nil { return err } templ, err := template.New("test").Parse(string(file)) buf := bytes.Buffer{} templ.Execute(&buf, map[string]interface{}{ "SiteKey": settings.SiteKey, }) if err != nil { return err } e.Response.Header().Set("Content-Type", "application/javascript") return e.String(http.StatusOK, buf.String()) }) } func GetSettings(app *pocketbase.PocketBase) (*TurnStilleCaptcha, error) { record, err := app.FindFirstRecordByFilter("settings", "key='turnstile'", nil) settings := TurnStilleCaptcha{} json.Unmarshal([]byte(record.GetString("value")), &settings) if err != nil { return nil, err } return &settings, nil } func VerifyTurnstile(app *pocketbase.PocketBase, token, ip string) error { conf, err := GetSettings(app) if err != nil { return err } data := map[string]string{"secret": conf.SecretKey, "response": token, "remoteip": ip} jsonData, _ := json.Marshal(data) resp, err := http.Post(VerifyUrl, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return err } defer resp.Body.Close() var turnstileResp TurnstileResponse body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &turnstileResp) if !turnstileResp.Success { return errors.New(turnstileResp.ChallengeTS + ": " + strings.Join(turnstileResp.ErrorCodes, " ")) } return nil }