fatto ordine
This commit is contained in:
88
controllers/subscribe_controller.go
Normal file
88
controllers/subscribe_controller.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/mail"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SubscribeController struct {
|
||||
DB *gorm.DB
|
||||
IsUniqueConstraint func(error) bool
|
||||
}
|
||||
|
||||
type subscribeRequest struct {
|
||||
Email string `json:"email"`
|
||||
BrowserData map[string]any `json:"browserData"`
|
||||
}
|
||||
|
||||
const subscriptionCookieName = "bag_exchange_subscribed"
|
||||
|
||||
func (s *SubscribeController) Subscribe(c fiber.Ctx) error {
|
||||
var req subscribeRequest
|
||||
if err := json.Unmarshal(c.Body(), &req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(map[string]string{"error": "invalid payload"})
|
||||
}
|
||||
|
||||
email := strings.ToLower(strings.TrimSpace(req.Email))
|
||||
if _, err := mail.ParseAddress(email); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(map[string]string{"error": "invalid email"})
|
||||
}
|
||||
|
||||
emailHash := hashEmail(email)
|
||||
if c.Cookies(subscriptionCookieName) == emailHash {
|
||||
return c.Status(fiber.StatusConflict).JSON(map[string]string{"status": "already_submitted"})
|
||||
}
|
||||
|
||||
browserData := "{}"
|
||||
if len(req.BrowserData) > 0 {
|
||||
payload, err := json.Marshal(req.BrowserData)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(map[string]string{"error": "invalid browser data"})
|
||||
}
|
||||
browserData = string(payload)
|
||||
}
|
||||
|
||||
err := s.DB.Table("subscribers").Create(map[string]any{
|
||||
"email": email,
|
||||
"ip_address": c.IP(),
|
||||
"user_agent": c.Get("User-Agent"),
|
||||
"accept_language": c.Get("Accept-Language"),
|
||||
"browser_data": browserData,
|
||||
}).Error
|
||||
if err != nil {
|
||||
if s.IsUniqueConstraint != nil && s.IsUniqueConstraint(err) {
|
||||
setSubscriptionCookie(c, emailHash)
|
||||
return c.Status(fiber.StatusConflict).JSON(map[string]string{"status": "already_submitted"})
|
||||
}
|
||||
log.Printf("unable to insert subscriber: %v", err)
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(map[string]string{"error": "unable to save subscription"})
|
||||
}
|
||||
|
||||
setSubscriptionCookie(c, emailHash)
|
||||
return c.Status(fiber.StatusCreated).JSON(map[string]string{"status": "subscribed"})
|
||||
}
|
||||
|
||||
func hashEmail(email string) string {
|
||||
sum := sha256.Sum256([]byte(strings.ToLower(strings.TrimSpace(email))))
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
func setSubscriptionCookie(c fiber.Ctx, value string) {
|
||||
c.Cookie(&fiber.Cookie{
|
||||
Name: subscriptionCookieName,
|
||||
Value: value,
|
||||
Path: "/",
|
||||
HTTPOnly: false,
|
||||
Secure: false,
|
||||
Expires: time.Now().AddDate(1, 0, 0),
|
||||
MaxAge: 60 * 60 * 24 * 365,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user