mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-05 08:01:23 +00:00
117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"github.com/warmbly/warmbly/internal/api/middleware"
|
|
"github.com/warmbly/warmbly/internal/app/websitetracking"
|
|
"github.com/warmbly/warmbly/internal/errx"
|
|
"github.com/warmbly/warmbly/internal/models"
|
|
)
|
|
|
|
// Website tracking settings (JWT only, MANAGE_SETTINGS).
|
|
|
|
func (h *Handler) GetWebsiteTrackingSettings(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.JSON(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
settings, xerr := h.WebsiteTrackingService.GetSettings(c.Request.Context(), *orgID)
|
|
if xerr != nil {
|
|
errx.JSON(c, xerr)
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, settings)
|
|
}
|
|
|
|
func (h *Handler) UpdateWebsiteTrackingSettings(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.JSON(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
userID, err := middleware.GetUserUUID(c)
|
|
if err != nil {
|
|
errx.JSON(c, errx.New(errx.BadRequest, "invalid user id"))
|
|
return
|
|
}
|
|
var req models.UpdateWebsiteTrackingSettingsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
errx.JSON(c, errx.ErrInvalid)
|
|
return
|
|
}
|
|
settings, xerr := h.WebsiteTrackingService.UpdateSettings(c.Request.Context(), *orgID, userID, &req)
|
|
if xerr != nil {
|
|
errx.JSON(c, xerr)
|
|
return
|
|
}
|
|
h.auditOrg(c, models.AuditActionUpdate, models.AuditEntitySettings, nil, nil, map[string]string{
|
|
"scope": "website_tracking",
|
|
})
|
|
c.JSON(http.StatusOK, settings)
|
|
}
|
|
|
|
// RotateWebsiteTrackingKey issues a new site key; the old one stops at once.
|
|
func (h *Handler) RotateWebsiteTrackingKey(c *gin.Context) {
|
|
orgID := middleware.GetOrganizationID(c)
|
|
if orgID == nil {
|
|
errx.JSON(c, errx.New(errx.BadRequest, "no organization selected"))
|
|
return
|
|
}
|
|
userID, err := middleware.GetUserUUID(c)
|
|
if err != nil {
|
|
errx.JSON(c, errx.New(errx.BadRequest, "invalid user id"))
|
|
return
|
|
}
|
|
settings, xerr := h.WebsiteTrackingService.RotateSiteKey(c.Request.Context(), *orgID, userID)
|
|
if xerr != nil {
|
|
errx.JSON(c, xerr)
|
|
return
|
|
}
|
|
h.auditOrg(c, models.AuditActionUpdate, models.AuditEntitySettings, nil, nil, map[string]string{
|
|
"scope": "website_tracking",
|
|
"action": "rotate_site_key",
|
|
})
|
|
c.JSON(http.StatusOK, settings)
|
|
}
|
|
|
|
// InternalIngestPageHit receives a page view from the tracking service.
|
|
//
|
|
// POST /api/v1/internal/page-hits
|
|
// -> 204 accepted or quietly rejected | 200 {"new_visitor_key":...}
|
|
// -> 400 malformed | 404 unknown site key (cached negatively at the edge)
|
|
func (h *Handler) InternalIngestPageHit(c *gin.Context) {
|
|
var req models.WebsiteHitRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
|
|
return
|
|
}
|
|
result, err := h.WebsiteTrackingService.Ingest(c.Request.Context(), &req)
|
|
switch {
|
|
case errors.Is(err, websitetracking.ErrMalformed):
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid hit"})
|
|
case errors.Is(err, websitetracking.ErrUnknownSite):
|
|
c.Status(http.StatusNotFound)
|
|
case errors.Is(err, websitetracking.ErrRejected):
|
|
c.Status(http.StatusNoContent)
|
|
case err != nil:
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "ingest failed"})
|
|
case result != nil && result.NewVisitorKey != "":
|
|
c.JSON(http.StatusOK, result)
|
|
default:
|
|
c.Status(http.StatusNoContent)
|
|
}
|
|
}
|
|
|
|
// websiteIdentifyForLink: may this click destination carry the identification ticket?
|
|
func (h *Handler) websiteIdentifyForLink(c *gin.Context, campaignID uuid.UUID, destination string) bool {
|
|
if h.WebsiteTrackingService == nil {
|
|
return false
|
|
}
|
|
return h.WebsiteTrackingService.ShouldIdentify(c.Request.Context(), campaignID, destination)
|
|
}
|