Add detected-cookies public REST endpoint for cookie auto-discovery

The JS SDK will override document.cookie to detect unknown cookies set
by the website and report them to a new POST /{bannerID}/detected-cookies
endpoint. Reported cookies are inserted into the "Uncategorised" category
and a draft version is created so the admin can review them.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-22 16:29:06 +04:00
parent 990dfa8438
commit e52b7cc19e
2 changed files with 138 additions and 0 deletions

View File

@@ -127,6 +127,15 @@ type (
Action coredata.CookieConsentAction
}
DetectedCookie struct {
Name string
Duration string
}
ReportDetectedCookiesRequest struct {
Cookies []DetectedCookie
}
BannerConfig struct {
BannerID gid.GID `json:"banner_id"`
Version int `json:"version"`
@@ -1717,3 +1726,62 @@ func (s *Service) RecordConsent(
return record, nil
}
func (s *Service) ReportDetectedCookies(
ctx context.Context,
bannerID gid.GID,
req ReportDetectedCookiesRequest,
) error {
return s.pg.WithTx(
ctx,
func(ctx context.Context, tx pg.Tx) error {
var banner coredata.CookieBanner
if err := banner.LoadActiveByID(ctx, tx, bannerID); err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return ErrBannerNotFound
}
return fmt.Errorf("cannot load active cookie banner: %w", err)
}
scope := coredata.NewScopeFromObjectID(banner.ID)
var uncategorised coredata.CookieCategory
if err := uncategorised.LoadUncategorisedByCookieBannerID(ctx, tx, scope, banner.ID); err != nil {
return fmt.Errorf("cannot load uncategorised category: %w", err)
}
inserted := 0
now := time.Now()
for _, dc := range req.Cookies {
cookie := &coredata.Cookie{
ID: gid.New(scope.GetTenantID(), coredata.CookieEntityType),
OrganizationID: banner.OrganizationID,
CookieBannerID: banner.ID,
CookieCategoryID: uncategorised.ID,
Name: dc.Name,
Duration: dc.Duration,
Description: "",
CreatedAt: now,
UpdatedAt: now,
}
if err := cookie.Insert(ctx, tx, scope); err != nil {
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
continue
}
return fmt.Errorf("cannot insert detected cookie: %w", err)
}
inserted++
}
if inserted > 0 {
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, banner.ID); err != nil {
return fmt.Errorf("cannot ensure draft version: %w", err)
}
}
return nil
},
)
}