package hcaptcha import ( "encoding/json" "fmt" "net/http" "strings" "git.hatecomputers.club/hatecomputers/hatecomputers.club/api/types" ) type HcaptchaArgs struct { SiteKey string } func verifyCaptcha(secret, response string) error { verifyURL := "https://hcaptcha.com/siteverify" body := strings.NewReader("secret=" + secret + "&response=" + response) req, err := http.NewRequest("POST", verifyURL, body) if err != nil { return err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &http.Client{} resp, err := client.Do(req) if err != nil { return err } jsonResponse := struct { Success bool `json:"success"` }{} err = json.NewDecoder(resp.Body).Decode(&jsonResponse) if err != nil { return err } if !jsonResponse.Success { return fmt.Errorf("hcaptcha verification failed") } defer resp.Body.Close() return nil } func CaptchaArgsContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain { return func(success types.Continuation, failure types.Continuation) types.ContinuationChain { (*context.TemplateData)["HcaptchaArgs"] = HcaptchaArgs{ SiteKey: context.Args.HcaptchaSiteKey, } return success(context, req, resp) } } func CaptchaVerificationContinuation(context *types.RequestContext, req *http.Request, resp http.ResponseWriter) types.ContinuationChain { return func(success types.Continuation, failure types.Continuation) types.ContinuationChain { hCaptchaResponse := req.FormValue("h-captcha-response") secretKey := context.Args.HcaptchaSecret err := verifyCaptcha(secretKey, hCaptchaResponse) if err != nil { (*context.TemplateData)["Error"] = types.BannerMessages{ Messages: []string{"hCaptcha verification failed"}, } resp.WriteHeader(http.StatusBadRequest) return failure(context, req, resp) } return success(context, req, resp) } }