Skip to content

Commit

Permalink
Merge pull request #3 from wneessen/v0.1.2_honeypot
Browse files Browse the repository at this point in the history
v0.1.2: Honeypot and typos
  • Loading branch information
wneessen authored Aug 11, 2021
2 parents 00f590c + 5b764e2 commit 620c418
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 6 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ simple API that can be accessed via JavaScript `Fetch()` or `XMLHttpRequest`.
* Only display form-fields that are configured in for the form in the resulting mail
* Check for required form fields
* Anti-SPAM functionality via built-in, auto-expiring and single-use security token feature
* Anti-SPAM functionality via honeypot fields
* Limit form access to specific domains
* Per-form mail server configuration

### Planed features
* [ ] Anti-SPAM functionality via honeypot fields
* [ ] Form field-type validation
* [ ] Form body templates (possibly HTML)
* [ ] hCaptcha/gCaptcha support
Expand Down Expand Up @@ -77,7 +77,8 @@ Again the JSON syntax of the form configuration is very simple, yet flexible.
"content": {
"subject": "New message through the www.example.com contact form",
"fields": ["name", "email", "message"],
"required_fields": ["name", "email"]
"required_fields": ["name", "email"],
"honeypot": "street"
},
"server": {
"host": "mail.example.com",
Expand All @@ -97,6 +98,7 @@ Again the JSON syntax of the form configuration is very simple, yet flexible.
* `subject (type: string)`: Subject for the mail notification of the form submission
* `fields (type: []string)`: List of field names that should show up in the mail notification
* `required_fields (type: []string)`: List of field names that are required to submitted
* `honeypot (type: string)`: Name of the honeypot field, that is expected to be empty (Anti-SPAM)
* `server (type: struct)`: The struct for the forms mail server configuration
* `host (type: string)`: Hostname of the sending mail server
* `port (type: uint32)`: Port to connect to on the sending mail server
Expand Down
10 changes: 9 additions & 1 deletion apirequest/sendform.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (a *ApiRequest) SendFormParse(r *http.Request) (int, error) {
return 0, nil
}

// SendFormValidate validates that all requirement are fullfilled and returns an error
// SendFormValidate validates that all requirement are fulfilled and returns an error
// if the validation failed
func (a *ApiRequest) SendFormValidate(r *http.Request) (int, error) {
l := log.WithFields(log.Fields{
Expand Down Expand Up @@ -77,6 +77,7 @@ func (a *ApiRequest) SendFormValidate(r *http.Request) (int, error) {
missingFields := []string{}
for _, f := range formObj.Content.RequiredFields {
if r.Form.Get(f) == "" {
l.Warnf("Form includes a honeypot field which is not empty. Denying request")
missingFields = append(missingFields, f)
}
}
Expand All @@ -85,6 +86,13 @@ func (a *ApiRequest) SendFormValidate(r *http.Request) (int, error) {
return 400, fmt.Errorf("Required fields missing: %s", strings.Join(missingFields, ", "))
}

// Anti-SPAM honeypot handling
if formObj.Content.Honeypot != nil {
if r.Form.Get(*formObj.Content.Honeypot) != "" {
return 400, fmt.Errorf("Invalid form data")
}
}

// Check the token
reqOrigin := r.Header.Get("origin")
if reqOrigin == "" {
Expand Down
4 changes: 2 additions & 2 deletions form/form.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Form struct {
Subject string
Fields []string
RequiredFields []string `fig:"required_fields"`
Honeypot string `fig:"honeypot"`
Honeypot *string `fig:"honeypot"`
}
Server struct {
Host string `fig:"host" validate:"required"`
Expand All @@ -32,7 +32,7 @@ type Form struct {
}

// NewForm returns a new Form object to the caller. It fails with an error when
// the form is question wasn't found or does not fullfill the syntax requirements
// the form is question wasn't found or does not fulfill the syntax requirements
func NewForm(c *config.Config, i string) (Form, error) {
l := log.WithFields(log.Fields{
"action": "form.NewForm",
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func serve(c *config.Config) {
}
}()

// Initalize the Api request object
// Initialize the Api request object
apiReq := &apirequest.ApiRequest{
Cache: cacheObj,
Config: c,
Expand Down

0 comments on commit 620c418

Please sign in to comment.