package main import ( "encoding/json" "fmt" "log" "net/http" "os" "strings" ) // RegistrationRequest represents the incoming registration request. type RegistrationRequest struct { Email string `json:"email"` Captcha string `json:"captcha"` } func registerHandler(w http.ResponseWriter, r *http.Request) { // Parse the request body var req RegistrationRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, fmt.Sprintf("Invalid request body: %v", err), http.StatusBadRequest) return } log.Printf("Received email: %s", req.Email) log.Printf("Received CAPTCHA token: %s", req.Captcha) // Validate email domain if !validateEmailDomain(req.Email) { http.Error(w, "Email domain is not allowed", http.StatusBadRequest) return } // Validate Turnstile token valid, err := validateRecaptcha(req.Captcha) if err != nil { log.Printf("CAPTCHA validation failed: %v", err) http.Error(w, fmt.Sprintf("CAPTCHA validation failed: %v", err), http.StatusInternalServerError) return } if !valid { log.Println("Invalid CAPTCHA token.") http.Error(w, "Invalid CAPTCHA", http.StatusUnauthorized) return } // Continue with Overleaf registration (omitted for brevity) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{ "message": "User registered successfully. Please check your email to set your password.", }) } func validateEmailDomain(email string) bool { allowedDomains := os.Getenv("ALLOWED_DOMAINS") if allowedDomains == "" { return false } parts := strings.Split(email, "@") if len(parts) != 2 { return false // Invalid email format } domain := parts[1] allowed := strings.Split(allowedDomains, ",") for _, allowedDomain := range allowed { if strings.TrimSpace(domain) == strings.TrimSpace(allowedDomain) { return true } } return false } func validateEnvVars(vars []string) error { for _, v := range vars { if os.Getenv(v) == "" { return fmt.Errorf("environment variable %s is not set", v) } } return nil }