diff --git a/api/auth.go b/api/auth.go index 14e6924..0e4c1ed 100644 --- a/api/auth.go +++ b/api/auth.go @@ -50,7 +50,7 @@ func StartSessionContinuation(context *RequestContext, req *http.Request, resp h } } -func InterceptCodeContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { +func InterceptOauthCodeContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { return func(success Continuation, failure Continuation) ContinuationChain { state := req.URL.Query().Get("state") code := req.URL.Query().Get("code") diff --git a/api/guestbook.go b/api/guestbook.go index 7b84f45..ee3c79a 100644 --- a/api/guestbook.go +++ b/api/guestbook.go @@ -1,8 +1,6 @@ package api import ( - "encoding/json" - "fmt" "log" "net/http" "strings" @@ -43,16 +41,11 @@ func SignGuestbookContinuation(context *RequestContext, req *http.Request, resp return func(success Continuation, failure Continuation) ContinuationChain { name := req.FormValue("name") message := req.FormValue("message") - hCaptchaResponse := req.FormValue("h-captcha-response") formErrors := FormError{ Errors: []string{}, } - if hCaptchaResponse == "" { - formErrors.Errors = append(formErrors.Errors, "hCaptcha is required") - } - entry := &database.GuestbookEntry{ ID: utils.RandomId(), Name: name, @@ -60,22 +53,19 @@ func SignGuestbookContinuation(context *RequestContext, req *http.Request, resp } formErrors.Errors = append(formErrors.Errors, validateGuestbookEntry(entry)...) - err := verifyHCaptcha(context.Args.HcaptchaSecret, hCaptchaResponse) - if err != nil { - log.Println(err) - - formErrors.Errors = append(formErrors.Errors, "hCaptcha verification failed") + if len(formErrors.Errors) == 0 { + _, err := database.SaveGuestbookEntry(context.DBConn, entry) + if err != nil { + log.Println(err) + formErrors.Errors = append(formErrors.Errors, "failed to save entry") + } } + if len(formErrors.Errors) > 0 { (*context.TemplateData)["FormError"] = formErrors (*context.TemplateData)["EntryForm"] = entry - return failure(context, req, resp) - } + resp.WriteHeader(http.StatusBadRequest) - _, err = database.SaveGuestbookEntry(context.DBConn, entry) - if err != nil { - log.Println(err) - resp.WriteHeader(http.StatusInternalServerError) return failure(context, req, resp) } @@ -96,46 +86,3 @@ func ListGuestbookContinuation(context *RequestContext, req *http.Request, resp return success(context, req, resp) } } - -func HcaptchaArgsContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { - return func(success Continuation, failure Continuation) ContinuationChain { - (*context.TemplateData)["HcaptchaArgs"] = HcaptchaArgs{ - SiteKey: context.Args.HcaptchaSiteKey, - } - log.Println(context.Args.HcaptchaSiteKey) - return success(context, req, resp) - } -} - -func verifyHCaptcha(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 -} diff --git a/api/hcaptcha.go b/api/hcaptcha.go new file mode 100644 index 0000000..a310c01 --- /dev/null +++ b/api/hcaptcha.go @@ -0,0 +1,69 @@ +package api + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" +) + +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 *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { + return func(success Continuation, failure Continuation) ContinuationChain { + (*context.TemplateData)["HcaptchaArgs"] = HcaptchaArgs{ + SiteKey: context.Args.HcaptchaSiteKey, + } + return success(context, req, resp) + } +} + +func CaptchaVerificationContinuation(context *RequestContext, req *http.Request, resp http.ResponseWriter) ContinuationChain { + return func(success Continuation, failure Continuation) ContinuationChain { + hCaptchaResponse := req.FormValue("h-captcha-response") + secretKey := context.Args.HcaptchaSecret + + err := verifyCaptcha(secretKey, hCaptchaResponse) + if err != nil { + (*context.TemplateData)["FormError"] = FormError{ + Errors: []string{"hCaptcha verification failed"}, + } + resp.WriteHeader(http.StatusBadRequest) + + return failure(context, req, resp) + } + + return success(context, req, resp) + } +}