···
···
func (s *Signup) signup(w http.ResponseWriter, r *http.Request) {
122
+
s.pages.Signup(w, pages.SignupParams{
123
+
CloudflareSiteKey: s.config.Cloudflare.TurnstileSiteKey,
http.Error(w, "signup is disabled", http.StatusFailedDependency)
emailId := r.FormValue("email")
131
+
cfToken := r.FormValue("cf-turnstile-response")
135
+
if err := s.validateCaptcha(cfToken, r); err != nil {
136
+
s.l.Warn("turnstile validation failed", "error", err)
137
+
s.pages.Notice(w, noticeId, "Captcha validation failed.")
if !email.IsValidEmail(emailId) {
s.pages.Notice(w, noticeId, "Invalid email address.")
···
273
+
type turnstileResponse struct {
274
+
Success bool `json:"success"`
275
+
ErrorCodes []string `json:"error-codes,omitempty"`
276
+
ChallengeTs string `json:"challenge_ts,omitempty"`
277
+
Hostname string `json:"hostname,omitempty"`
280
+
func (s *Signup) validateCaptcha(cfToken string, r *http.Request) error {
282
+
return errors.New("captcha token is empty")
285
+
if s.config.Cloudflare.TurnstileSecretKey == "" {
286
+
return errors.New("turnstile secret key not configured")
289
+
data := url.Values{}
290
+
data.Set("secret", s.config.Cloudflare.TurnstileSecretKey)
291
+
data.Set("response", cfToken)
293
+
// include the client IP if we have it
294
+
if remoteIP := r.Header.Get("CF-Connecting-IP"); remoteIP != "" {
295
+
data.Set("remoteip", remoteIP)
296
+
} else if remoteIP := r.Header.Get("X-Forwarded-For"); remoteIP != "" {
297
+
if ips := strings.Split(remoteIP, ","); len(ips) > 0 {
298
+
data.Set("remoteip", strings.TrimSpace(ips[0]))
301
+
data.Set("remoteip", r.RemoteAddr)
304
+
resp, err := http.PostForm("https://challenges.cloudflare.com/turnstile/v0/siteverify", data)
306
+
return fmt.Errorf("failed to verify turnstile token: %w", err)
308
+
defer resp.Body.Close()
310
+
var turnstileResp turnstileResponse
311
+
if err := json.NewDecoder(resp.Body).Decode(&turnstileResp); err != nil {
312
+
return fmt.Errorf("failed to decode turnstile response: %w", err)
315
+
if !turnstileResp.Success {
316
+
s.l.Warn("turnstile validation failed", "error_codes", turnstileResp.ErrorCodes)
317
+
return errors.New("turnstile validation failed")