buhapp-backend/internal/handlers/consent.go
ga c6d219c51f Telegram WebApp support + consent endpoint
- Telegram bot (long polling)
- /api/v1/auth/telegram (validate initData, auto-create user)
- /api/v1/auth/consents (record acceptances)
- users.telegram_id column, GetByTelegramID/CreateWithTelegramID
- ValidateInitData (HMAC-SHA256 with WebAppData secret)
2026-08-20 17:43:20 +00:00

66 lines
1.7 KiB
Go

package handlers
import (
"time"
"github.com/gofiber/fiber/v2"
"github.com/buhapp/backend/internal/audit"
"github.com/buhapp/backend/internal/consent"
)
type ConsentHandlers struct {
Consent *consent.Repo
Audit *audit.Repo
}
func NewConsentHandlers(c *consent.Repo, a *audit.Repo) *ConsentHandlers {
return &ConsentHandlers{Consent: c, Audit: a}
}
type consentRequest struct {
Adult bool `json:"adult"`
Terms bool `json:"terms"`
Privacy bool `json:"privacy"`
Disclaimer bool `json:"disclaimer"`
}
func (h *ConsentHandlers) Accept(c *fiber.Ctx) error {
me, err := userID(c)
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "no user"})
}
var req consentRequest
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid JSON"})
}
if !req.Adult || !req.Terms || !req.Privacy || !req.Disclaimer {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "all consents required"})
}
docs := []struct {
Type consent.DocType
}{
{consent.DocTerms},
{consent.DocPrivacy},
{consent.DocDisclaimer},
{consent.DocAdult},
}
for _, d := range docs {
err := h.Consent.Record(c.UserContext(), &consent.Consent{
UserID: me,
DocType: d.Type,
DocVersion: "1.0",
IP: c.IP(),
UserAgent: c.Get("User-Agent"),
})
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "db error"})
}
}
_ = h.Audit.Log(c.UserContext(), &audit.Event{
UserID: &me, Action: "consents.accept",
IP: c.IP(), UserAgent: c.Get("User-Agent"),
})
return c.JSON(fiber.Map{"ok": true, "accepted_at": time.Now()})
}