Skip to content

Commit

Permalink
feat: comment anti-spam prevention
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed May 6, 2024
1 parent f3717ff commit 3a1487b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
4 changes: 4 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ login:
comments:
# Must be set to enable. Page to which to redirect users after commenting.
redirect: /my-thank-you-page/
# Case-insensitive "captcha" value for anti-spam verification. If not empty,
# users will have to insert this value into a input field with name 'captcha'.
# Think about something they know about you: your name, last name, etc.
captcha: John

# Webmentions configuration.
webmentions:
Expand Down
11 changes: 11 additions & 0 deletions core/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ func (c *ServerConfig) validate() error {
return err
}

err = c.Comments.validate()
if err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -161,6 +166,12 @@ func (u *Login) validate() error {

type Comments struct {
Redirect string
Captcha string
}

func (c *Comments) validate() error {
c.Captcha = strings.ToLower(c.Captcha)
return nil
}

type Webmentions struct {
Expand Down
14 changes: 10 additions & 4 deletions server/webmentions.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"time"

"github.com/microcosm-cc/bluemonday"
Expand All @@ -25,9 +26,9 @@ func (s *Server) commentsPost(w http.ResponseWriter, r *http.Request) {
return
}

// Bot control honeypot field. If it's non-empty, just fake it was successful.
if r.Form.Get("url") != "" {
s.serveErrorHTML(w, r, http.StatusBadRequest, errors.New("fell into honeypot trap"))
// Anti-spam prevention with user-defined captcha value.
if s.c.Comments.Captcha != "" && r.Form.Get("captcha") != strings.ToLower(s.c.Comments.Captcha) {
s.serveErrorHTML(w, r, http.StatusBadRequest, errors.New("anti-spam verification failed"))
return
}

Expand All @@ -53,7 +54,12 @@ func (s *Server) commentsPost(w http.ResponseWriter, r *http.Request) {
website = sanitize.Sanitize(website)
content = sanitize.Sanitize(content)

if len(content) == 0 || len(content) > 500 || len(name) > 100 || len(website) > 100 {
if len(name) == 0 || len(content) == 0 {
s.serveErrorHTML(w, r, http.StatusBadRequest, errors.New("name and content are required"))
return
}

if len(content) > 1000 || len(name) > 200 || len(website) > 200 {
s.serveErrorHTML(w, r, http.StatusBadRequest, errors.New("content, name, or website outside of limits"))
return
}
Expand Down

0 comments on commit 3a1487b

Please sign in to comment.