cookiebanner: capture script initiator URL on detected trackers

When third-party JS sets a cookie or writes to local/sessionStorage
inside a customer page, the SDK now walks the synchronous call stack
to find the first non-extension, non-Probo, non-first-party http(s)
URL. That origin+path is sent as initiator_url on the report payload,
persisted in a new nullable column on detected_trackers, and preserved
across upserts via COALESCE.

This unlocks per-vendor attribution for cookies and storage writes
without needing pattern name matching, so future categorisation logic
can simply look up the initiator URL in the existing tracker_resources
table and inherit that vendor's category.

GraphQL/MCP exposure is intentionally deferred -- the column is captured
now, surfaced later.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-05-11 10:38:30 +04:00
parent 04fdaed772
commit d17c8ba044
7 changed files with 159 additions and 19 deletions

View File

@@ -113,6 +113,7 @@ type (
Name string
MaxAgeSeconds *int
Source coredata.CookieSource
InitiatorURL *string
}
ReportDetectedCookiesRequest struct {
@@ -120,9 +121,10 @@ type (
}
DetectedStorageItem struct {
Key string
StorageType coredata.TrackerType
ValueSize *int
Key string
StorageType coredata.TrackerType
ValueSize *int
InitiatorURL *string
}
DetectedResourceItem struct {
@@ -2035,6 +2037,7 @@ func (s *Service) ReportDetectedTrackers(
Identifier: dc.Name,
MaxAgeSeconds: dc.MaxAgeSeconds,
Source: &dc.Source,
InitiatorURL: dc.InitiatorURL,
},
&inserted,
); err != nil {
@@ -2051,9 +2054,10 @@ func (s *Service) ReportDetectedTrackers(
uncategorised.ID,
now,
detectedTrackerInfo{
TrackerType: ds.StorageType,
Identifier: ds.Key,
ValueSize: ds.ValueSize,
TrackerType: ds.StorageType,
Identifier: ds.Key,
ValueSize: ds.ValueSize,
InitiatorURL: ds.InitiatorURL,
},
&inserted,
); err != nil {
@@ -2096,6 +2100,7 @@ type detectedTrackerInfo struct {
MaxAgeSeconds *int
Source *coredata.CookieSource
ValueSize *int
InitiatorURL *string
}
func (s *Service) reportDetectedTracker(
@@ -2168,6 +2173,7 @@ func (s *Service) reportDetectedTracker(
MaxAgeSeconds: info.MaxAgeSeconds,
Source: info.Source,
ValueSize: info.ValueSize,
InitiatorURL: info.InitiatorURL,
LastDetectedAt: now,
CreatedAt: now,
UpdatedAt: now,