Remove cookie_patterns legacy, migrate to tracker_patterns
Delete coredata.CookiePattern and all associated CRUD methods, rename shared types (CookiePatternOrderField, CookiePatternFilter, CookiePatternMatchType) to TrackerPattern equivalents, and migrate all API surfaces (GraphQL, MCP, CLI, n8n) to tracker_pattern naming. The worker was already migrated in the base branch; this commit completes the removal by dropping the old GraphQL schema/resolvers, service methods, CLI commands, and n8n operations that operated on the legacy cookie_patterns table. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -104,9 +104,9 @@ func setPatternExcluded(t *testing.T, c *testutil.Client, patternID string, excl
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern { id excluded }
|
trackerPattern { id excluded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@@ -114,10 +114,10 @@ func setPatternExcluded(t *testing.T, c *testutil.Client, patternID string, excl
|
|||||||
var result struct{}
|
var result struct{}
|
||||||
require.NoError(t, c.Execute(query, map[string]any{
|
require.NoError(t, c.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"excluded": excluded,
|
"excluded": excluded,
|
||||||
},
|
},
|
||||||
}, &result), "updateCookiePattern excluded mutation failed")
|
}, &result), "updateTrackerPattern excluded mutation failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// upsertTranslation upserts a translation for a banner+language pair and
|
// upsertTranslation upserts a translation for a banner+language pair and
|
||||||
@@ -323,13 +323,13 @@ func TestCookieBannerVersioning_NoOpUpdates(t *testing.T) {
|
|||||||
assert.Equal(t, "PUBLISHED", got.State)
|
assert.Equal(t, "PUBLISHED", got.State)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("UpdateCookiePattern on visible pattern with same value does not bump version", func(t *testing.T) {
|
t.Run("UpdateTrackerPattern on visible pattern with same value does not bump version", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "visible-noop"})
|
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "visible-noop"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID, factory.Attrs{
|
patternID := factory.CreateTrackerPattern(owner, categoryID, factory.Attrs{
|
||||||
"displayName": "GA Tracker",
|
"displayName": "GA Tracker",
|
||||||
"description": "Original description",
|
"description": "Original description",
|
||||||
})
|
})
|
||||||
@@ -338,15 +338,15 @@ func TestCookieBannerVersioning_NoOpUpdates(t *testing.T) {
|
|||||||
baseline := published.Version
|
baseline := published.Version
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) { cookiePattern { id } }
|
updateTrackerPattern(input: $input) { trackerPattern { id } }
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
var result struct{}
|
var result struct{}
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"displayName": "GA Tracker",
|
"displayName": "GA Tracker",
|
||||||
"description": "Original description",
|
"description": "Original description",
|
||||||
},
|
},
|
||||||
@@ -368,7 +368,7 @@ func TestCookieBannerVersioning_ExcludedPattern(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-update"})
|
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-update"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID, factory.Attrs{
|
patternID := factory.CreateTrackerPattern(owner, categoryID, factory.Attrs{
|
||||||
"displayName": "Original",
|
"displayName": "Original",
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -377,32 +377,32 @@ func TestCookieBannerVersioning_ExcludedPattern(t *testing.T) {
|
|||||||
baseline := published.Version
|
baseline := published.Version
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern { id displayName description }
|
trackerPattern { id displayName description }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"displayName": "Renamed Excluded",
|
"displayName": "Renamed Excluded",
|
||||||
"description": "Now with notes",
|
"description": "Now with notes",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "Renamed Excluded", result.UpdateCookiePattern.CookiePattern.DisplayName)
|
assert.Equal(t, "Renamed Excluded", result.UpdateTrackerPattern.TrackerPattern.DisplayName)
|
||||||
assert.Equal(t, "Now with notes", result.UpdateCookiePattern.CookiePattern.Description)
|
assert.Equal(t, "Now with notes", result.UpdateTrackerPattern.TrackerPattern.Description)
|
||||||
|
|
||||||
got := latestVersion(t, owner, bannerID)
|
got := latestVersion(t, owner, bannerID)
|
||||||
assert.Equal(t, baseline, got.Version, "excluded pattern fields are invisible to visitors")
|
assert.Equal(t, baseline, got.Version, "excluded pattern fields are invisible to visitors")
|
||||||
@@ -415,23 +415,23 @@ func TestCookieBannerVersioning_ExcludedPattern(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-delete"})
|
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-delete"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
setPatternExcluded(t, owner, patternID, true)
|
setPatternExcluded(t, owner, patternID, true)
|
||||||
published := publishBanner(t, owner, bannerID)
|
published := publishBanner(t, owner, bannerID)
|
||||||
baseline := published.Version
|
baseline := published.Version
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation DeleteCookiePattern($input: DeleteCookiePatternInput!) {
|
mutation DeleteTrackerPattern($input: DeleteTrackerPatternInput!) {
|
||||||
deleteCookiePattern(input: $input) {
|
deleteTrackerPattern(input: $input) {
|
||||||
deletedCookiePatternId
|
deletedTrackerPatternId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
var result struct{}
|
var result struct{}
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{"cookiePatternId": patternID},
|
"input": map[string]any{"trackerPatternId": patternID},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -447,16 +447,16 @@ func TestCookieBannerVersioning_ExcludedPattern(t *testing.T) {
|
|||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-move-a"})
|
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-move-a"})
|
||||||
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-move-b"})
|
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "excl-move-b"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryA)
|
patternID := factory.CreateTrackerPattern(owner, categoryA)
|
||||||
|
|
||||||
setPatternExcluded(t, owner, patternID, true)
|
setPatternExcluded(t, owner, patternID, true)
|
||||||
published := publishBanner(t, owner, bannerID)
|
published := publishBanner(t, owner, bannerID)
|
||||||
baseline := published.Version
|
baseline := published.Version
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation MoveCookiePatternToCategory($input: MoveCookiePatternToCategoryInput!) {
|
mutation MoveTrackerPatternToCategory($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern { id }
|
trackerPattern { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@@ -464,7 +464,7 @@ func TestCookieBannerVersioning_ExcludedPattern(t *testing.T) {
|
|||||||
var result struct{}
|
var result struct{}
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"targetCookieCategoryId": categoryB,
|
"targetCookieCategoryId": categoryB,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
@@ -604,13 +604,13 @@ func TestCookieBannerVersioning_RealChangesStillBumpVersion(t *testing.T) {
|
|||||||
assert.Equal(t, "DRAFT", got.State)
|
assert.Equal(t, "DRAFT", got.State)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("UpdateCookiePattern displayName change on visible pattern creates a new draft", func(t *testing.T) {
|
t.Run("UpdateTrackerPattern displayName change on visible pattern creates a new draft", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "real-change"})
|
categoryID := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "real-change"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID, factory.Attrs{
|
patternID := factory.CreateTrackerPattern(owner, categoryID, factory.Attrs{
|
||||||
"displayName": "Original",
|
"displayName": "Original",
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -618,14 +618,14 @@ func TestCookieBannerVersioning_RealChangesStillBumpVersion(t *testing.T) {
|
|||||||
baseline := published.Version
|
baseline := published.Version
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) { cookiePattern { id } }
|
updateTrackerPattern(input: $input) { trackerPattern { id } }
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
var result struct{}
|
var result struct{}
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"displayName": "Renamed",
|
"displayName": "Renamed",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
"go.probo.inc/probo/e2e/internal/testutil"
|
"go.probo.inc/probo/e2e/internal/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCookiePattern_Create(t *testing.T) {
|
func TestTrackerPattern_Create(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("with EXACT match type", func(t *testing.T) {
|
t.Run("with EXACT match type", func(t *testing.T) {
|
||||||
@@ -34,9 +34,9 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
@@ -57,8 +57,8 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
CreateCookiePattern struct {
|
CreateTrackerPattern struct {
|
||||||
CookiePatternEdge struct {
|
TrackerPatternEdge struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
@@ -70,11 +70,11 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
} `json:"cookiePatternEdge"`
|
} `json:"trackerPatternEdge"`
|
||||||
CookieBanner struct {
|
CookieBanner struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"cookieBanner"`
|
} `json:"cookieBanner"`
|
||||||
} `json:"createCookiePattern"`
|
} `json:"createTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
maxAge := 86400
|
maxAge := 86400
|
||||||
@@ -90,7 +90,7 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
node := result.CreateCookiePattern.CookiePatternEdge.Node
|
node := result.CreateTrackerPattern.TrackerPatternEdge.Node
|
||||||
assert.NotEmpty(t, node.ID)
|
assert.NotEmpty(t, node.ID)
|
||||||
assert.Equal(t, "_ga", node.Pattern)
|
assert.Equal(t, "_ga", node.Pattern)
|
||||||
assert.Equal(t, "EXACT", node.MatchType)
|
assert.Equal(t, "EXACT", node.MatchType)
|
||||||
@@ -99,7 +99,7 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
assert.Equal(t, maxAge, *node.MaxAgeSeconds)
|
assert.Equal(t, maxAge, *node.MaxAgeSeconds)
|
||||||
assert.Equal(t, "Google Analytics tracking cookie", node.Description)
|
assert.Equal(t, "Google Analytics tracking cookie", node.Description)
|
||||||
assert.Equal(t, "SCRIPT", node.Source)
|
assert.Equal(t, "SCRIPT", node.Source)
|
||||||
assert.Equal(t, bannerID, result.CreateCookiePattern.CookieBanner.ID)
|
assert.Equal(t, bannerID, result.CreateTrackerPattern.CookieBanner.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with PREFIX match type", func(t *testing.T) {
|
t.Run("with PREFIX match type", func(t *testing.T) {
|
||||||
@@ -110,9 +110,9 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
@@ -126,8 +126,8 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
CreateCookiePattern struct {
|
CreateTrackerPattern struct {
|
||||||
CookiePatternEdge struct {
|
TrackerPatternEdge struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
@@ -135,8 +135,8 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
} `json:"cookiePatternEdge"`
|
} `json:"trackerPatternEdge"`
|
||||||
} `json:"createCookiePattern"`
|
} `json:"createTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
@@ -150,7 +150,7 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
node := result.CreateCookiePattern.CookiePatternEdge.Node
|
node := result.CreateTrackerPattern.TrackerPatternEdge.Node
|
||||||
assert.Equal(t, "_gat_", node.Pattern)
|
assert.Equal(t, "_gat_", node.Pattern)
|
||||||
assert.Equal(t, "PREFIX", node.MatchType)
|
assert.Equal(t, "PREFIX", node.MatchType)
|
||||||
assert.Nil(t, node.MaxAgeSeconds)
|
assert.Nil(t, node.MaxAgeSeconds)
|
||||||
@@ -163,15 +163,15 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
|
|
||||||
factory.CreateCookiePattern(owner, categoryID, factory.Attrs{
|
factory.CreateTrackerPattern(owner, categoryID, factory.Attrs{
|
||||||
"pattern": "duplicate_cookie",
|
"pattern": "duplicate_cookie",
|
||||||
"displayName": "First",
|
"displayName": "First",
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge { node { id } }
|
trackerPatternEdge { node { id } }
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ func TestCookiePattern_Create(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_Update(t *testing.T) {
|
func TestTrackerPattern_Update(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("update displayName and description", func(t *testing.T) {
|
t.Run("update displayName and description", func(t *testing.T) {
|
||||||
@@ -197,15 +197,15 @@ func TestCookiePattern_Update(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID, factory.Attrs{
|
patternID := factory.CreateTrackerPattern(owner, categoryID, factory.Attrs{
|
||||||
"displayName": "Original Name",
|
"displayName": "Original Name",
|
||||||
"description": "Original description",
|
"description": "Original description",
|
||||||
})
|
})
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
displayName
|
displayName
|
||||||
description
|
description
|
||||||
@@ -218,31 +218,31 @@ func TestCookiePattern_Update(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
CookieBanner struct {
|
CookieBanner struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"cookieBanner"`
|
} `json:"cookieBanner"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"displayName": "Updated Name",
|
"displayName": "Updated Name",
|
||||||
"description": "Updated description",
|
"description": "Updated description",
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, patternID, result.UpdateCookiePattern.CookiePattern.ID)
|
assert.Equal(t, patternID, result.UpdateTrackerPattern.TrackerPattern.ID)
|
||||||
assert.Equal(t, "Updated Name", result.UpdateCookiePattern.CookiePattern.DisplayName)
|
assert.Equal(t, "Updated Name", result.UpdateTrackerPattern.TrackerPattern.DisplayName)
|
||||||
assert.Equal(t, "Updated description", result.UpdateCookiePattern.CookiePattern.Description)
|
assert.Equal(t, "Updated description", result.UpdateTrackerPattern.TrackerPattern.Description)
|
||||||
assert.Equal(t, bannerID, result.UpdateCookiePattern.CookieBanner.ID)
|
assert.Equal(t, bannerID, result.UpdateTrackerPattern.CookieBanner.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("update maxAgeSeconds", func(t *testing.T) {
|
t.Run("update maxAgeSeconds", func(t *testing.T) {
|
||||||
@@ -251,12 +251,12 @@ func TestCookiePattern_Update(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
maxAgeSeconds
|
maxAgeSeconds
|
||||||
}
|
}
|
||||||
@@ -265,28 +265,28 @@ func TestCookiePattern_Update(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"maxAgeSeconds": 7200,
|
"maxAgeSeconds": 7200,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, result.UpdateCookiePattern.CookiePattern.MaxAgeSeconds)
|
require.NotNil(t, result.UpdateTrackerPattern.TrackerPattern.MaxAgeSeconds)
|
||||||
assert.Equal(t, 7200, *result.UpdateCookiePattern.CookiePattern.MaxAgeSeconds)
|
assert.Equal(t, 7200, *result.UpdateTrackerPattern.TrackerPattern.MaxAgeSeconds)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_Excluded(t *testing.T) {
|
func TestTrackerPattern_Excluded(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("defaults to false on create", func(t *testing.T) {
|
t.Run("defaults to false on create", func(t *testing.T) {
|
||||||
@@ -297,9 +297,9 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
excluded
|
excluded
|
||||||
@@ -310,14 +310,14 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
CreateCookiePattern struct {
|
CreateTrackerPattern struct {
|
||||||
CookiePatternEdge struct {
|
TrackerPatternEdge struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Excluded bool `json:"excluded"`
|
Excluded bool `json:"excluded"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
} `json:"cookiePatternEdge"`
|
} `json:"trackerPatternEdge"`
|
||||||
} `json:"createCookiePattern"`
|
} `json:"createTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
@@ -331,7 +331,7 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.False(t, result.CreateCookiePattern.CookiePatternEdge.Node.Excluded)
|
assert.False(t, result.CreateTrackerPattern.TrackerPatternEdge.Node.Excluded)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("can be set to true via update", func(t *testing.T) {
|
t.Run("can be set to true via update", func(t *testing.T) {
|
||||||
@@ -340,12 +340,12 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
excluded
|
excluded
|
||||||
}
|
}
|
||||||
@@ -354,23 +354,23 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Excluded bool `json:"excluded"`
|
Excluded bool `json:"excluded"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"excluded": true,
|
"excluded": true,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.True(t, result.UpdateCookiePattern.CookiePattern.Excluded)
|
assert.True(t, result.UpdateTrackerPattern.TrackerPattern.Excluded)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("can be toggled back to false", func(t *testing.T) {
|
t.Run("can be toggled back to false", func(t *testing.T) {
|
||||||
@@ -379,12 +379,12 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
const updateQuery = `
|
const updateQuery = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
excluded
|
excluded
|
||||||
}
|
}
|
||||||
@@ -393,35 +393,35 @@ func TestCookiePattern_Excluded(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Excluded bool `json:"excluded"`
|
Excluded bool `json:"excluded"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(updateQuery, map[string]any{
|
err := owner.Execute(updateQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"excluded": true,
|
"excluded": true,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.True(t, result.UpdateCookiePattern.CookiePattern.Excluded)
|
assert.True(t, result.UpdateTrackerPattern.TrackerPattern.Excluded)
|
||||||
|
|
||||||
err = owner.Execute(updateQuery, map[string]any{
|
err = owner.Execute(updateQuery, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"excluded": false,
|
"excluded": false,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.False(t, result.UpdateCookiePattern.CookiePattern.Excluded)
|
assert.False(t, result.UpdateTrackerPattern.TrackerPattern.Excluded)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_Delete(t *testing.T) {
|
func TestTrackerPattern_Delete(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
@@ -430,12 +430,12 @@ func TestCookiePattern_Delete(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation DeleteCookiePattern($input: DeleteCookiePatternInput!) {
|
mutation DeleteTrackerPattern($input: DeleteTrackerPatternInput!) {
|
||||||
deleteCookiePattern(input: $input) {
|
deleteTrackerPattern(input: $input) {
|
||||||
deletedCookiePatternId
|
deletedTrackerPatternId
|
||||||
cookieBanner {
|
cookieBanner {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -444,25 +444,25 @@ func TestCookiePattern_Delete(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
DeleteCookiePattern struct {
|
DeleteTrackerPattern struct {
|
||||||
DeletedCookiePatternID string `json:"deletedCookiePatternId"`
|
DeletedTrackerPatternID string `json:"deletedTrackerPatternId"`
|
||||||
CookieBanner struct {
|
CookieBanner struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"cookieBanner"`
|
} `json:"cookieBanner"`
|
||||||
} `json:"deleteCookiePattern"`
|
} `json:"deleteTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{"cookiePatternId": patternID},
|
"input": map[string]any{"trackerPatternId": patternID},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, patternID, result.DeleteCookiePattern.DeletedCookiePatternID)
|
assert.Equal(t, patternID, result.DeleteTrackerPattern.DeletedTrackerPatternID)
|
||||||
assert.Equal(t, bannerID, result.DeleteCookiePattern.CookieBanner.ID)
|
assert.Equal(t, bannerID, result.DeleteTrackerPattern.CookieBanner.ID)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_MoveToCategory(t *testing.T) {
|
func TestTrackerPattern_MoveToCategory(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
@@ -472,12 +472,12 @@ func TestCookiePattern_MoveToCategory(t *testing.T) {
|
|||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "cat-a-move"})
|
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "cat-a-move"})
|
||||||
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "cat-b-move"})
|
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "cat-b-move"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryA)
|
patternID := factory.CreateTrackerPattern(owner, categoryA)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation MoveCookiePatternToCategory($input: MoveCookiePatternToCategoryInput!) {
|
mutation MoveTrackerPatternToCategory($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
cookieCategory {
|
cookieCategory {
|
||||||
id
|
id
|
||||||
@@ -491,30 +491,30 @@ func TestCookiePattern_MoveToCategory(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
MoveCookiePatternToCategory struct {
|
MoveTrackerPatternToCategory struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
CookieCategory struct {
|
CookieCategory struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"cookieCategory"`
|
} `json:"cookieCategory"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
CookieBanner struct {
|
CookieBanner struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"cookieBanner"`
|
} `json:"cookieBanner"`
|
||||||
} `json:"moveCookiePatternToCategory"`
|
} `json:"moveTrackerPatternToCategory"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{
|
err := owner.Execute(query, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"targetCookieCategoryId": categoryB,
|
"targetCookieCategoryId": categoryB,
|
||||||
},
|
},
|
||||||
}, &result)
|
}, &result)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, patternID, result.MoveCookiePatternToCategory.CookiePattern.ID)
|
assert.Equal(t, patternID, result.MoveTrackerPatternToCategory.TrackerPattern.ID)
|
||||||
assert.Equal(t, categoryB, result.MoveCookiePatternToCategory.CookiePattern.CookieCategory.ID)
|
assert.Equal(t, categoryB, result.MoveTrackerPatternToCategory.TrackerPattern.CookieCategory.ID)
|
||||||
assert.Equal(t, bannerID, result.MoveCookiePatternToCategory.CookieBanner.ID)
|
assert.Equal(t, bannerID, result.MoveTrackerPatternToCategory.CookieBanner.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("cross-banner mismatch error", func(t *testing.T) {
|
t.Run("cross-banner mismatch error", func(t *testing.T) {
|
||||||
@@ -525,18 +525,18 @@ func TestCookiePattern_MoveToCategory(t *testing.T) {
|
|||||||
banner2 := factory.CreateCookieBanner(owner)
|
banner2 := factory.CreateCookieBanner(owner)
|
||||||
category1 := factory.CreateCookieCategory(owner, banner1, factory.Attrs{"slug": "cat-x-mismatch"})
|
category1 := factory.CreateCookieCategory(owner, banner1, factory.Attrs{"slug": "cat-x-mismatch"})
|
||||||
category2 := factory.CreateCookieCategory(owner, banner2, factory.Attrs{"slug": "cat-y-mismatch"})
|
category2 := factory.CreateCookieCategory(owner, banner2, factory.Attrs{"slug": "cat-y-mismatch"})
|
||||||
patternID := factory.CreateCookiePattern(owner, category1)
|
patternID := factory.CreateTrackerPattern(owner, category1)
|
||||||
|
|
||||||
_, err := owner.Do(`
|
_, err := owner.Do(`
|
||||||
mutation MoveCookiePatternToCategory($input: MoveCookiePatternToCategoryInput!) {
|
mutation MoveTrackerPatternToCategory($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern { id }
|
trackerPattern { id }
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"targetCookieCategoryId": category2,
|
"targetCookieCategoryId": category2,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -544,23 +544,23 @@ func TestCookiePattern_MoveToCategory(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_List(t *testing.T) {
|
func TestTrackerPattern_List(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("via category cookiePatterns connection", func(t *testing.T) {
|
t.Run("via category trackerPatterns connection", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
factory.CreateCookiePattern(owner, categoryID)
|
factory.CreateTrackerPattern(owner, categoryID)
|
||||||
factory.CreateCookiePattern(owner, categoryID)
|
factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
query($id: ID!) {
|
query($id: ID!) {
|
||||||
node(id: $id) {
|
node(id: $id) {
|
||||||
... on CookieCategory {
|
... on CookieCategory {
|
||||||
cookiePatterns(first: 10) {
|
trackerPatterns(first: 10) {
|
||||||
totalCount
|
totalCount
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
@@ -581,7 +581,7 @@ func TestCookiePattern_List(t *testing.T) {
|
|||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
CookiePatterns struct {
|
TrackerPatterns struct {
|
||||||
TotalCount int `json:"totalCount"`
|
TotalCount int `json:"totalCount"`
|
||||||
Edges []struct {
|
Edges []struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
@@ -594,18 +594,18 @@ func TestCookiePattern_List(t *testing.T) {
|
|||||||
HasNextPage bool `json:"hasNextPage"`
|
HasNextPage bool `json:"hasNextPage"`
|
||||||
HasPreviousPage bool `json:"hasPreviousPage"`
|
HasPreviousPage bool `json:"hasPreviousPage"`
|
||||||
} `json:"pageInfo"`
|
} `json:"pageInfo"`
|
||||||
} `json:"cookiePatterns"`
|
} `json:"trackerPatterns"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := owner.Execute(query, map[string]any{"id": categoryID}, &result)
|
err := owner.Execute(query, map[string]any{"id": categoryID}, &result)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 2, result.Node.CookiePatterns.TotalCount)
|
assert.Equal(t, 2, result.Node.TrackerPatterns.TotalCount)
|
||||||
assert.Len(t, result.Node.CookiePatterns.Edges, 2)
|
assert.Len(t, result.Node.TrackerPatterns.Edges, 2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCookiePattern_RBAC(t *testing.T) {
|
func TestTrackerPattern_RBAC(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("viewer cannot create pattern", func(t *testing.T) {
|
t.Run("viewer cannot create pattern", func(t *testing.T) {
|
||||||
@@ -617,9 +617,9 @@ func TestCookiePattern_RBAC(t *testing.T) {
|
|||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
|
|
||||||
_, err := viewer.Do(`
|
_, err := viewer.Do(`
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge { node { id } }
|
trackerPatternEdge { node { id } }
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,7 +632,7 @@ func TestCookiePattern_RBAC(t *testing.T) {
|
|||||||
"description": "Should fail",
|
"description": "Should fail",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
testutil.RequireForbiddenError(t, err, "viewer should not be able to create cookie pattern")
|
testutil.RequireForbiddenError(t, err, "viewer should not be able to create tracker pattern")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("viewer cannot update pattern", func(t *testing.T) {
|
t.Run("viewer cannot update pattern", func(t *testing.T) {
|
||||||
@@ -642,22 +642,22 @@ func TestCookiePattern_RBAC(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
_, err := viewer.Do(`
|
_, err := viewer.Do(`
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern { id }
|
trackerPattern { id }
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"displayName": "Updated by Viewer",
|
"displayName": "Updated by Viewer",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
testutil.RequireForbiddenError(t, err, "viewer should not be able to update cookie pattern")
|
testutil.RequireForbiddenError(t, err, "viewer should not be able to update tracker pattern")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("viewer cannot delete pattern", func(t *testing.T) {
|
t.Run("viewer cannot delete pattern", func(t *testing.T) {
|
||||||
@@ -667,19 +667,19 @@ func TestCookiePattern_RBAC(t *testing.T) {
|
|||||||
|
|
||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
categoryID := factory.CreateCookieCategory(owner, bannerID)
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryID)
|
patternID := factory.CreateTrackerPattern(owner, categoryID)
|
||||||
|
|
||||||
_, err := viewer.Do(`
|
_, err := viewer.Do(`
|
||||||
mutation DeleteCookiePattern($input: DeleteCookiePatternInput!) {
|
mutation DeleteTrackerPattern($input: DeleteTrackerPatternInput!) {
|
||||||
deleteCookiePattern(input: $input) {
|
deleteTrackerPattern(input: $input) {
|
||||||
deletedCookiePatternId
|
deletedTrackerPatternId
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{"cookiePatternId": patternID},
|
"input": map[string]any{"trackerPatternId": patternID},
|
||||||
})
|
})
|
||||||
testutil.RequireForbiddenError(t, err, "viewer should not be able to delete cookie pattern")
|
testutil.RequireForbiddenError(t, err, "viewer should not be able to delete tracker pattern")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("viewer cannot move pattern", func(t *testing.T) {
|
t.Run("viewer cannot move pattern", func(t *testing.T) {
|
||||||
@@ -690,21 +690,21 @@ func TestCookiePattern_RBAC(t *testing.T) {
|
|||||||
bannerID := factory.CreateCookieBanner(owner)
|
bannerID := factory.CreateCookieBanner(owner)
|
||||||
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "rbac-move-a"})
|
categoryA := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "rbac-move-a"})
|
||||||
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "rbac-move-b"})
|
categoryB := factory.CreateCookieCategory(owner, bannerID, factory.Attrs{"slug": "rbac-move-b"})
|
||||||
patternID := factory.CreateCookiePattern(owner, categoryA)
|
patternID := factory.CreateTrackerPattern(owner, categoryA)
|
||||||
|
|
||||||
_, err := viewer.Do(`
|
_, err := viewer.Do(`
|
||||||
mutation MoveCookiePatternToCategory($input: MoveCookiePatternToCategoryInput!) {
|
mutation MoveTrackerPatternToCategory($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern { id }
|
trackerPattern { id }
|
||||||
cookieBanner { id }
|
cookieBanner { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, map[string]any{
|
`, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": patternID,
|
"trackerPatternId": patternID,
|
||||||
"targetCookieCategoryId": categoryB,
|
"targetCookieCategoryId": categoryB,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
testutil.RequireForbiddenError(t, err, "viewer should not be able to move cookie pattern")
|
testutil.RequireForbiddenError(t, err, "viewer should not be able to move tracker pattern")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1343,7 +1343,7 @@ func CreateCookieCategory(c *testutil.Client, bannerID string, attrs ...Attrs) s
|
|||||||
return result.CreateCookieCategory.CookieCategoryEdge.Node.ID
|
return result.CreateCookieCategory.CookieCategoryEdge.Node.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateCookiePattern(c *testutil.Client, categoryID string, attrs ...Attrs) string {
|
func CreateTrackerPattern(c *testutil.Client, categoryID string, attrs ...Attrs) string {
|
||||||
c.T.Helper()
|
c.T.Helper()
|
||||||
|
|
||||||
var a Attrs
|
var a Attrs
|
||||||
@@ -1352,9 +1352,9 @@ func CreateCookiePattern(c *testutil.Client, categoryID string, attrs ...Attrs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation($input: CreateCookiePatternInput!) {
|
mutation($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node { id }
|
node { id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1363,27 +1363,28 @@ func CreateCookiePattern(c *testutil.Client, categoryID string, attrs ...Attrs)
|
|||||||
|
|
||||||
input := map[string]any{
|
input := map[string]any{
|
||||||
"cookieCategoryId": categoryID,
|
"cookieCategoryId": categoryID,
|
||||||
|
"trackerType": a.getString("trackerType", "COOKIE"),
|
||||||
"pattern": a.getString("pattern", gofakeit.LetterN(8)+"_cookie"),
|
"pattern": a.getString("pattern", gofakeit.LetterN(8)+"_cookie"),
|
||||||
"matchType": a.getString("matchType", "EXACT"),
|
"matchType": a.getString("matchType", "EXACT"),
|
||||||
"displayName": a.getString("displayName", SafeName("Pattern")),
|
"displayName": a.getString("displayName", SafeName("Pattern")),
|
||||||
"description": a.getString("description", "Test cookie pattern"),
|
"description": a.getString("description", "Test tracker pattern"),
|
||||||
}
|
}
|
||||||
if _, ok := a["maxAgeSeconds"]; ok {
|
if _, ok := a["maxAgeSeconds"]; ok {
|
||||||
input["maxAgeSeconds"] = a.getInt("maxAgeSeconds", 0)
|
input["maxAgeSeconds"] = a.getInt("maxAgeSeconds", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
CreateCookiePattern struct {
|
CreateTrackerPattern struct {
|
||||||
CookiePatternEdge struct {
|
TrackerPatternEdge struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
} `json:"cookiePatternEdge"`
|
} `json:"trackerPatternEdge"`
|
||||||
} `json:"createCookiePattern"`
|
} `json:"createTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.Execute(query, map[string]any{"input": input}, &result)
|
err := c.Execute(query, map[string]any{"input": input}, &result)
|
||||||
require.NoError(c.T, err, "createCookiePattern mutation failed")
|
require.NoError(c.T, err, "createTrackerPattern mutation failed")
|
||||||
|
|
||||||
return result.CreateCookiePattern.CookiePatternEdge.Node.ID
|
return result.CreateTrackerPattern.TrackerPatternEdge.Node.ID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,11 +116,6 @@ export class Probo implements INodeType {
|
|||||||
value: 'cookieConsentRecord',
|
value: 'cookieConsentRecord',
|
||||||
description: 'View cookie consent records',
|
description: 'View cookie consent records',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'Cookie Pattern',
|
|
||||||
value: 'cookiePattern',
|
|
||||||
description: 'Manage cookie patterns',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'Data',
|
name: 'Data',
|
||||||
value: 'datum',
|
value: 'datum',
|
||||||
@@ -206,6 +201,11 @@ export class Probo implements INodeType {
|
|||||||
value: 'tia',
|
value: 'tia',
|
||||||
description: 'Manage transfer impact assessments',
|
description: 'Manage transfer impact assessments',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Tracker Pattern',
|
||||||
|
value: 'trackerPattern',
|
||||||
|
description: 'Manage tracker patterns',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Trust Center',
|
name: 'Trust Center',
|
||||||
value: 'trustCenter',
|
value: 'trustCenter',
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import * as control from './control';
|
|||||||
import * as cookieBanner from './cookieBanner';
|
import * as cookieBanner from './cookieBanner';
|
||||||
import * as cookieCategory from './cookieCategory';
|
import * as cookieCategory from './cookieCategory';
|
||||||
import * as cookieConsentRecord from './cookieConsentRecord';
|
import * as cookieConsentRecord from './cookieConsentRecord';
|
||||||
import * as cookiePattern from './cookiePattern';
|
import * as trackerPattern from './trackerPattern';
|
||||||
import * as datum from './datum';
|
import * as datum from './datum';
|
||||||
import * as document from './document';
|
import * as document from './document';
|
||||||
import * as dpia from './dpia';
|
import * as dpia from './dpia';
|
||||||
@@ -63,7 +63,7 @@ export const resources: Record<string, ResourceModule> = {
|
|||||||
cookieBanner: cookieBanner as ResourceModule,
|
cookieBanner: cookieBanner as ResourceModule,
|
||||||
cookieCategory: cookieCategory as ResourceModule,
|
cookieCategory: cookieCategory as ResourceModule,
|
||||||
cookieConsentRecord: cookieConsentRecord as ResourceModule,
|
cookieConsentRecord: cookieConsentRecord as ResourceModule,
|
||||||
cookiePattern: cookiePattern as ResourceModule,
|
trackerPattern: trackerPattern as ResourceModule,
|
||||||
datum: datum as ResourceModule,
|
datum: datum as ResourceModule,
|
||||||
document: document as ResourceModule,
|
document: document as ResourceModule,
|
||||||
dpia: dpia as ResourceModule,
|
dpia: dpia as ResourceModule,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -36,12 +36,12 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The cookie name pattern to match',
|
description: 'The tracker name pattern to match',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -50,7 +50,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'options',
|
type: 'options',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -65,7 +65,7 @@ export const description: INodeProperties[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: 'EXACT',
|
default: 'EXACT',
|
||||||
description: 'How the pattern should be matched against cookie names',
|
description: 'How the pattern should be matched against tracker names',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -74,12 +74,12 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The display name for the cookie pattern',
|
description: 'The display name for the tracker pattern',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -88,12 +88,12 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The description of the cookie pattern',
|
description: 'The description of the tracker pattern',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['create'],
|
operation: ['create'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -123,9 +123,9 @@ export async function execute(
|
|||||||
const maxAgeSeconds = this.getNodeParameter('maxAgeSeconds', itemIndex, 0) as number;
|
const maxAgeSeconds = this.getNodeParameter('maxAgeSeconds', itemIndex, 0) as number;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation CreateCookiePattern($input: CreateCookiePatternInput!) {
|
mutation CreateTrackerPattern($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
@@ -17,17 +17,17 @@ import { proboApiRequest } from '../../GenericFunctions';
|
|||||||
|
|
||||||
export const description: INodeProperties[] = [
|
export const description: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Cookie Pattern ID',
|
displayName: 'Tracker Pattern ID',
|
||||||
name: 'cookiePatternId',
|
name: 'trackerPatternId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['delete'],
|
operation: ['delete'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The ID of the cookie pattern to delete',
|
description: 'The ID of the tracker pattern to delete',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -36,12 +36,12 @@ export async function execute(
|
|||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const cookiePatternId = this.getNodeParameter('cookiePatternId', itemIndex) as string;
|
const trackerPatternId = this.getNodeParameter('trackerPatternId', itemIndex) as string;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation DeleteCookiePattern($input: DeleteCookiePatternInput!) {
|
mutation DeleteTrackerPattern($input: DeleteTrackerPatternInput!) {
|
||||||
deleteCookiePattern(input: $input) {
|
deleteTrackerPattern(input: $input) {
|
||||||
deletedCookiePatternId
|
deletedTrackerPatternId
|
||||||
cookieBanner {
|
cookieBanner {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -50,7 +50,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, { input: { cookiePatternId } });
|
const responseData = await proboApiRequest.call(this, query, { input: { trackerPatternId } });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
json: responseData,
|
json: responseData,
|
||||||
@@ -17,17 +17,17 @@ import { proboApiRequest } from '../../GenericFunctions';
|
|||||||
|
|
||||||
export const description: INodeProperties[] = [
|
export const description: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Cookie Pattern ID',
|
displayName: 'Tracker Pattern ID',
|
||||||
name: 'cookiePatternId',
|
name: 'trackerPatternId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['get'],
|
operation: ['get'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The ID of the cookie pattern',
|
description: 'The ID of the tracker pattern',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -36,12 +36,12 @@ export async function execute(
|
|||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const cookiePatternId = this.getNodeParameter('cookiePatternId', itemIndex) as string;
|
const trackerPatternId = this.getNodeParameter('trackerPatternId', itemIndex) as string;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
query GetCookiePattern($cookiePatternId: ID!) {
|
query GetTrackerPattern($trackerPatternId: ID!) {
|
||||||
node(id: $cookiePatternId) {
|
node(id: $trackerPatternId) {
|
||||||
... on CookiePattern {
|
... on TrackerPattern {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
matchType
|
matchType
|
||||||
@@ -58,7 +58,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, { cookiePatternId });
|
const responseData = await proboApiRequest.call(this, query, { trackerPatternId });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
json: responseData,
|
json: responseData,
|
||||||
@@ -22,7 +22,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['getAll'],
|
operation: ['getAll'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -36,7 +36,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['getAll'],
|
operation: ['getAll'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -49,7 +49,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['getAll'],
|
operation: ['getAll'],
|
||||||
returnAll: [false],
|
returnAll: [false],
|
||||||
},
|
},
|
||||||
@@ -71,10 +71,10 @@ export async function execute(
|
|||||||
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
|
const limit = this.getNodeParameter('limit', itemIndex, 50) as number;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
query GetCookiePatterns($cookieCategoryId: ID!, $first: Int, $after: CursorKey) {
|
query GetTrackerPatterns($cookieCategoryId: ID!, $first: Int, $after: CursorKey) {
|
||||||
node(id: $cookieCategoryId) {
|
node(id: $cookieCategoryId) {
|
||||||
... on CookieCategory {
|
... on CookieCategory {
|
||||||
cookiePatterns(first: $first, after: $after) {
|
trackerPatterns(first: $first, after: $after) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
@@ -100,21 +100,21 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cookiePatterns = await proboApiRequestAllItems.call(
|
const trackerPatterns = await proboApiRequestAllItems.call(
|
||||||
this,
|
this,
|
||||||
query,
|
query,
|
||||||
{ cookieCategoryId },
|
{ cookieCategoryId },
|
||||||
(response) => {
|
(response) => {
|
||||||
const data = response?.data as IDataObject | undefined;
|
const data = response?.data as IDataObject | undefined;
|
||||||
const node = data?.node as IDataObject | undefined;
|
const node = data?.node as IDataObject | undefined;
|
||||||
return node?.cookiePatterns as IDataObject | undefined;
|
return node?.trackerPatterns as IDataObject | undefined;
|
||||||
},
|
},
|
||||||
returnAll,
|
returnAll,
|
||||||
limit,
|
limit,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
json: { cookiePatterns },
|
json: { trackerPatterns },
|
||||||
pairedItem: { item: itemIndex },
|
pairedItem: { item: itemIndex },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -28,45 +28,45 @@ export const description: INodeProperties[] = [
|
|||||||
noDataExpression: true,
|
noDataExpression: true,
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'Create',
|
name: 'Create',
|
||||||
value: 'create',
|
value: 'create',
|
||||||
description: 'Create a new cookie pattern',
|
description: 'Create a new tracker pattern',
|
||||||
action: 'Create a cookie pattern',
|
action: 'Create a tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Delete',
|
name: 'Delete',
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
description: 'Delete a cookie pattern',
|
description: 'Delete a tracker pattern',
|
||||||
action: 'Delete a cookie pattern',
|
action: 'Delete a tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Get',
|
name: 'Get',
|
||||||
value: 'get',
|
value: 'get',
|
||||||
description: 'Get a cookie pattern',
|
description: 'Get a tracker pattern',
|
||||||
action: 'Get a cookie pattern',
|
action: 'Get a tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Get Many',
|
name: 'Get Many',
|
||||||
value: 'getAll',
|
value: 'getAll',
|
||||||
description: 'Get many cookie patterns',
|
description: 'Get many tracker patterns',
|
||||||
action: 'Get many cookie patterns',
|
action: 'Get many tracker patterns',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Move',
|
name: 'Move',
|
||||||
value: 'move',
|
value: 'move',
|
||||||
description: 'Move a cookie pattern to a different category',
|
description: 'Move a tracker pattern to a different category',
|
||||||
action: 'Move a cookie pattern',
|
action: 'Move a tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Update',
|
name: 'Update',
|
||||||
value: 'update',
|
value: 'update',
|
||||||
description: 'Update an existing cookie pattern',
|
description: 'Update an existing tracker pattern',
|
||||||
action: 'Update a cookie pattern',
|
action: 'Update a tracker pattern',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: 'create',
|
default: 'create',
|
||||||
@@ -17,17 +17,17 @@ import { proboApiRequest } from '../../GenericFunctions';
|
|||||||
|
|
||||||
export const description: INodeProperties[] = [
|
export const description: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Cookie Pattern ID',
|
displayName: 'Tracker Pattern ID',
|
||||||
name: 'cookiePatternId',
|
name: 'trackerPatternId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['move'],
|
operation: ['move'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The ID of the cookie pattern to move',
|
description: 'The ID of the tracker pattern to move',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['move'],
|
operation: ['move'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -50,13 +50,13 @@ export async function execute(
|
|||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const cookiePatternId = this.getNodeParameter('cookiePatternId', itemIndex) as string;
|
const trackerPatternId = this.getNodeParameter('trackerPatternId', itemIndex) as string;
|
||||||
const targetCookieCategoryId = this.getNodeParameter('targetCookieCategoryId', itemIndex) as string;
|
const targetCookieCategoryId = this.getNodeParameter('targetCookieCategoryId', itemIndex) as string;
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation MoveCookiePatternToCategory($input: MoveCookiePatternToCategoryInput!) {
|
mutation MoveTrackerPatternToCategory($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
matchType
|
matchType
|
||||||
@@ -77,7 +77,7 @@ export async function execute(
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const responseData = await proboApiRequest.call(this, query, {
|
const responseData = await proboApiRequest.call(this, query, {
|
||||||
input: { cookiePatternId, targetCookieCategoryId },
|
input: { trackerPatternId, targetCookieCategoryId },
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -17,17 +17,17 @@ import { proboApiRequest } from '../../GenericFunctions';
|
|||||||
|
|
||||||
export const description: INodeProperties[] = [
|
export const description: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
displayName: 'Cookie Pattern ID',
|
displayName: 'Tracker Pattern ID',
|
||||||
name: 'cookiePatternId',
|
name: 'trackerPatternId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The ID of the cookie pattern to update',
|
description: 'The ID of the tracker pattern to update',
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -36,12 +36,12 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The display name for the cookie pattern',
|
description: 'The display name for the tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Excluded',
|
displayName: 'Excluded',
|
||||||
@@ -49,7 +49,7 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'options',
|
type: 'options',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -68,7 +68,7 @@ export const description: INodeProperties[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Whether the cookie pattern is excluded from the banner',
|
description: 'Whether the tracker pattern is excluded from the banner',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Description',
|
displayName: 'Description',
|
||||||
@@ -76,12 +76,12 @@ export const description: INodeProperties[] = [
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description: 'The description of the cookie pattern',
|
description: 'The description of the tracker pattern',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Additional Fields',
|
displayName: 'Additional Fields',
|
||||||
@@ -91,7 +91,7 @@ export const description: INodeProperties[] = [
|
|||||||
default: {},
|
default: {},
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
resource: ['cookiePattern'],
|
resource: ['trackerPattern'],
|
||||||
operation: ['update'],
|
operation: ['update'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -114,7 +114,7 @@ export async function execute(
|
|||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
): Promise<INodeExecutionData> {
|
): Promise<INodeExecutionData> {
|
||||||
const cookiePatternId = this.getNodeParameter('cookiePatternId', itemIndex) as string;
|
const trackerPatternId = this.getNodeParameter('trackerPatternId', itemIndex) as string;
|
||||||
const displayName = this.getNodeParameter('displayName', itemIndex, '') as string;
|
const displayName = this.getNodeParameter('displayName', itemIndex, '') as string;
|
||||||
const excluded = this.getNodeParameter('excluded', itemIndex, '') as string;
|
const excluded = this.getNodeParameter('excluded', itemIndex, '') as string;
|
||||||
const patternDescription = this.getNodeParameter('patternDescription', itemIndex, '') as string;
|
const patternDescription = this.getNodeParameter('patternDescription', itemIndex, '') as string;
|
||||||
@@ -123,9 +123,9 @@ export async function execute(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const query = `
|
const query = `
|
||||||
mutation UpdateCookiePattern($input: UpdateCookiePatternInput!) {
|
mutation UpdateTrackerPattern($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
matchType
|
matchType
|
||||||
@@ -145,7 +145,7 @@ export async function execute(
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const input: Record<string, unknown> = { cookiePatternId };
|
const input: Record<string, unknown> = { trackerPatternId };
|
||||||
if (displayName) input.displayName = displayName;
|
if (displayName) input.displayName = displayName;
|
||||||
if (excluded) input.excluded = excluded === 'true';
|
if (excluded) input.excluded = excluded === 'true';
|
||||||
if (patternDescription) input.description = patternDescription;
|
if (patternDescription) input.description = patternDescription;
|
||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/cmd/control"
|
"go.probo.inc/probo/pkg/cmd/control"
|
||||||
cookiebanner "go.probo.inc/probo/pkg/cmd/cookie-banner"
|
cookiebanner "go.probo.inc/probo/pkg/cmd/cookie-banner"
|
||||||
cookiecategory "go.probo.inc/probo/pkg/cmd/cookie-category"
|
cookiecategory "go.probo.inc/probo/pkg/cmd/cookie-category"
|
||||||
cookiepattern "go.probo.inc/probo/pkg/cmd/cookie-pattern"
|
|
||||||
"go.probo.inc/probo/pkg/cmd/datum"
|
"go.probo.inc/probo/pkg/cmd/datum"
|
||||||
"go.probo.inc/probo/pkg/cmd/document"
|
"go.probo.inc/probo/pkg/cmd/document"
|
||||||
"go.probo.inc/probo/pkg/cmd/dpia"
|
"go.probo.inc/probo/pkg/cmd/dpia"
|
||||||
@@ -48,6 +47,7 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/cmd/soa"
|
"go.probo.inc/probo/pkg/cmd/soa"
|
||||||
"go.probo.inc/probo/pkg/cmd/task"
|
"go.probo.inc/probo/pkg/cmd/task"
|
||||||
"go.probo.inc/probo/pkg/cmd/tia"
|
"go.probo.inc/probo/pkg/cmd/tia"
|
||||||
|
trackerpattern "go.probo.inc/probo/pkg/cmd/tracker-pattern"
|
||||||
trustcenter "go.probo.inc/probo/pkg/cmd/trust-center"
|
trustcenter "go.probo.inc/probo/pkg/cmd/trust-center"
|
||||||
"go.probo.inc/probo/pkg/cmd/user"
|
"go.probo.inc/probo/pkg/cmd/user"
|
||||||
"go.probo.inc/probo/pkg/cmd/vendormgmt"
|
"go.probo.inc/probo/pkg/cmd/vendormgmt"
|
||||||
@@ -99,7 +99,7 @@ func NewCmdRoot(f *cmdutil.Factory) *cobra.Command {
|
|||||||
cmd.AddCommand(control.NewCmdControl(f))
|
cmd.AddCommand(control.NewCmdControl(f))
|
||||||
cmd.AddCommand(cookiebanner.NewCmdCookieBanner(f))
|
cmd.AddCommand(cookiebanner.NewCmdCookieBanner(f))
|
||||||
cmd.AddCommand(cookiecategory.NewCmdCookieCategory(f))
|
cmd.AddCommand(cookiecategory.NewCmdCookieCategory(f))
|
||||||
cmd.AddCommand(cookiepattern.NewCmdCookiePattern(f))
|
cmd.AddCommand(trackerpattern.NewCmdTrackerPattern(f))
|
||||||
cmd.AddCommand(datum.NewCmdDatum(f))
|
cmd.AddCommand(datum.NewCmdDatum(f))
|
||||||
cmd.AddCommand(document.NewCmdDocument(f))
|
cmd.AddCommand(document.NewCmdDocument(f))
|
||||||
cmd.AddCommand(dpia.NewCmdDPIA(f))
|
cmd.AddCommand(dpia.NewCmdDPIA(f))
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const createMutation = `
|
const createMutation = `
|
||||||
mutation($input: CreateCookiePatternInput!) {
|
mutation($input: CreateTrackerPatternInput!) {
|
||||||
createCookiePattern(input: $input) {
|
createTrackerPattern(input: $input) {
|
||||||
cookiePatternEdge {
|
trackerPatternEdge {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
@@ -42,15 +42,15 @@ mutation($input: CreateCookiePatternInput!) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
type createResponse struct {
|
type createResponse struct {
|
||||||
CreateCookiePattern struct {
|
CreateTrackerPattern struct {
|
||||||
CookiePatternEdge struct {
|
TrackerPatternEdge struct {
|
||||||
Node struct {
|
Node struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
} `json:"cookiePatternEdge"`
|
} `json:"trackerPatternEdge"`
|
||||||
} `json:"createCookiePattern"`
|
} `json:"createTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
||||||
@@ -65,7 +65,7 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a new cookie pattern",
|
Short: "Create a new tracker pattern",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := f.Config()
|
cfg, err := f.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -87,7 +87,7 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
if f.IOStreams.IsInteractive() {
|
if f.IOStreams.IsInteractive() {
|
||||||
if flagPattern == "" {
|
if flagPattern == "" {
|
||||||
if err := huh.NewInput().Title("Cookie pattern").Value(&flagPattern).Run(); err != nil {
|
if err := huh.NewInput().Title("Tracker pattern").Value(&flagPattern).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,8 +142,8 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
return fmt.Errorf("cannot parse response: %w", err)
|
return fmt.Errorf("cannot parse response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := resp.CreateCookiePattern.CookiePatternEdge.Node
|
p := resp.CreateTrackerPattern.TrackerPatternEdge.Node
|
||||||
_, _ = fmt.Fprintf(f.IOStreams.Out, "Created cookie pattern %s (%s)\n", p.ID, p.DisplayName)
|
_, _ = fmt.Fprintf(f.IOStreams.Out, "Created tracker pattern %s (%s)\n", p.ID, p.DisplayName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -151,7 +151,7 @@ func NewCmdCreate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd.Flags().StringVar(&flagCategoryID, "category-id", "", "Cookie category ID (required)")
|
cmd.Flags().StringVar(&flagCategoryID, "category-id", "", "Cookie category ID (required)")
|
||||||
_ = cmd.MarkFlagRequired("category-id")
|
_ = cmd.MarkFlagRequired("category-id")
|
||||||
cmd.Flags().StringVar(&flagPattern, "pattern", "", "Cookie pattern (required)")
|
cmd.Flags().StringVar(&flagPattern, "pattern", "", "Tracker pattern (required)")
|
||||||
cmd.Flags().StringVar(&flagMatchType, "match-type", "", "Match type: EXACT or PREFIX (required)")
|
cmd.Flags().StringVar(&flagMatchType, "match-type", "", "Match type: EXACT or PREFIX (required)")
|
||||||
cmd.Flags().StringVar(&flagDisplayName, "display-name", "", "Display name (required)")
|
cmd.Flags().StringVar(&flagDisplayName, "display-name", "", "Display name (required)")
|
||||||
cmd.Flags().StringVar(&flagDescription, "description", "", "Description")
|
cmd.Flags().StringVar(&flagDescription, "description", "", "Description")
|
||||||
@@ -24,9 +24,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const deleteMutation = `
|
const deleteMutation = `
|
||||||
mutation($input: DeleteCookiePatternInput!) {
|
mutation($input: DeleteTrackerPatternInput!) {
|
||||||
deleteCookiePattern(input: $input) {
|
deleteTrackerPattern(input: $input) {
|
||||||
deletedCookiePatternId
|
deletedTrackerPatternId
|
||||||
cookieBanner {
|
cookieBanner {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -39,15 +39,15 @@ func NewCmdDelete(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delete <id>",
|
Use: "delete <id>",
|
||||||
Short: "Delete a cookie pattern",
|
Short: "Delete a tracker pattern",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if !flagYes {
|
if !flagYes {
|
||||||
if !f.IOStreams.IsInteractive() {
|
if !f.IOStreams.IsInteractive() {
|
||||||
return fmt.Errorf("cannot delete cookie pattern: confirmation required, use --yes to confirm")
|
return fmt.Errorf("cannot delete tracker pattern: confirmation required, use --yes to confirm")
|
||||||
}
|
}
|
||||||
var confirmed bool
|
var confirmed bool
|
||||||
if err := huh.NewConfirm().Title(fmt.Sprintf("Delete cookie pattern %s?", args[0])).Value(&confirmed).Run(); err != nil {
|
if err := huh.NewConfirm().Title(fmt.Sprintf("Delete tracker pattern %s?", args[0])).Value(&confirmed).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !confirmed {
|
if !confirmed {
|
||||||
@@ -74,13 +74,13 @@ func NewCmdDelete(f *cmdutil.Factory) *cobra.Command {
|
|||||||
)
|
)
|
||||||
|
|
||||||
_, err = client.Do(deleteMutation, map[string]any{
|
_, err = client.Do(deleteMutation, map[string]any{
|
||||||
"input": map[string]any{"cookiePatternId": args[0]},
|
"input": map[string]any{"trackerPatternId": args[0]},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = fmt.Fprintf(f.IOStreams.Out, "Deleted cookie pattern %s\n", args[0])
|
_, _ = fmt.Fprintf(f.IOStreams.Out, "Deleted tracker pattern %s\n", args[0])
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -28,13 +28,14 @@ query($id: ID!, $first: Int, $after: CursorKey) {
|
|||||||
node(id: $id) {
|
node(id: $id) {
|
||||||
__typename
|
__typename
|
||||||
... on CookieCategory {
|
... on CookieCategory {
|
||||||
cookiePatterns(first: $first, after: $after) {
|
trackerPatterns(first: $first, after: $after) {
|
||||||
totalCount
|
totalCount
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
matchType
|
matchType
|
||||||
|
trackerType
|
||||||
displayName
|
displayName
|
||||||
source
|
source
|
||||||
excluded
|
excluded
|
||||||
@@ -51,10 +52,11 @@ query($id: ID!, $first: Int, $after: CursorKey) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
type cookiePattern struct {
|
type trackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
MatchType string `json:"matchType"`
|
MatchType string `json:"matchType"`
|
||||||
|
TrackerType string `json:"trackerType"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
Excluded bool `json:"excluded"`
|
Excluded bool `json:"excluded"`
|
||||||
@@ -70,7 +72,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List cookie patterns in a category",
|
Short: "List tracker patterns in a category",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
@@ -103,11 +105,11 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
listQuery,
|
listQuery,
|
||||||
variables,
|
variables,
|
||||||
flagLimit,
|
flagLimit,
|
||||||
func(data json.RawMessage) (*api.Connection[cookiePattern], error) {
|
func(data json.RawMessage) (*api.Connection[trackerPattern], error) {
|
||||||
var resp struct {
|
var resp struct {
|
||||||
Node *struct {
|
Node *struct {
|
||||||
Typename string `json:"__typename"`
|
Typename string `json:"__typename"`
|
||||||
CookiePatterns api.Connection[cookiePattern] `json:"cookiePatterns"`
|
TrackerPatterns api.Connection[trackerPattern] `json:"trackerPatterns"`
|
||||||
} `json:"node"`
|
} `json:"node"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, &resp); err != nil {
|
if err := json.Unmarshal(data, &resp); err != nil {
|
||||||
@@ -119,7 +121,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
if resp.Node.Typename != "CookieCategory" {
|
if resp.Node.Typename != "CookieCategory" {
|
||||||
return nil, fmt.Errorf("expected CookieCategory node, got %s", resp.Node.Typename)
|
return nil, fmt.Errorf("expected CookieCategory node, got %s", resp.Node.Typename)
|
||||||
}
|
}
|
||||||
return &resp.Node.CookiePatterns, nil
|
return &resp.Node.TrackerPatterns, nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -131,7 +133,7 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(patterns) == 0 {
|
if len(patterns) == 0 {
|
||||||
_, _ = fmt.Fprintln(f.IOStreams.Out, "No cookie patterns found.")
|
_, _ = fmt.Fprintln(f.IOStreams.Out, "No tracker patterns found.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,14 +147,14 @@ func NewCmdList(f *cmdutil.Factory) *cobra.Command {
|
|||||||
if p.LastMatchedAt != nil {
|
if p.LastMatchedAt != nil {
|
||||||
lastMatched = cmdutil.FormatTime(*p.LastMatchedAt)
|
lastMatched = cmdutil.FormatTime(*p.LastMatchedAt)
|
||||||
}
|
}
|
||||||
rows = append(rows, []string{p.ID, p.Pattern, p.MatchType, p.DisplayName, p.Source, excluded, lastMatched})
|
rows = append(rows, []string{p.ID, p.Pattern, p.MatchType, p.TrackerType, p.DisplayName, p.Source, excluded, lastMatched})
|
||||||
}
|
}
|
||||||
|
|
||||||
t := cmdutil.NewTable("ID", "PATTERN", "MATCH TYPE", "DISPLAY NAME", "SOURCE", "EXCLUDED", "LAST MATCHED").Rows(rows...)
|
t := cmdutil.NewTable("ID", "PATTERN", "MATCH TYPE", "TRACKER TYPE", "DISPLAY NAME", "SOURCE", "EXCLUDED", "LAST MATCHED").Rows(rows...)
|
||||||
_, _ = fmt.Fprintln(f.IOStreams.Out, t)
|
_, _ = fmt.Fprintln(f.IOStreams.Out, t)
|
||||||
|
|
||||||
if totalCount > len(patterns) {
|
if totalCount > len(patterns) {
|
||||||
_, _ = fmt.Fprintf(f.IOStreams.ErrOut, "\nShowing %d of %d cookie patterns\n", len(patterns), totalCount)
|
_, _ = fmt.Fprintf(f.IOStreams.ErrOut, "\nShowing %d of %d tracker patterns\n", len(patterns), totalCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -24,9 +24,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const moveMutation = `
|
const moveMutation = `
|
||||||
mutation($input: MoveCookiePatternToCategoryInput!) {
|
mutation($input: MoveTrackerPatternToCategoryInput!) {
|
||||||
moveCookiePatternToCategory(input: $input) {
|
moveTrackerPatternToCategory(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
cookieCategory {
|
cookieCategory {
|
||||||
id
|
id
|
||||||
@@ -41,15 +41,15 @@ mutation($input: MoveCookiePatternToCategoryInput!) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
type moveResponse struct {
|
type moveResponse struct {
|
||||||
MoveCookiePatternToCategory struct {
|
MoveTrackerPatternToCategory struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
CookieCategory struct {
|
CookieCategory struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
} `json:"cookieCategory"`
|
} `json:"cookieCategory"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"moveCookiePatternToCategory"`
|
} `json:"moveTrackerPatternToCategory"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdMove(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdMove(f *cmdutil.Factory) *cobra.Command {
|
||||||
@@ -57,7 +57,7 @@ func NewCmdMove(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "move <id>",
|
Use: "move <id>",
|
||||||
Short: "Move a cookie pattern to a different category",
|
Short: "Move a tracker pattern to a different category",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := f.Config()
|
cfg, err := f.Config()
|
||||||
@@ -80,7 +80,7 @@ func NewCmdMove(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
data, err := client.Do(moveMutation, map[string]any{
|
data, err := client.Do(moveMutation, map[string]any{
|
||||||
"input": map[string]any{
|
"input": map[string]any{
|
||||||
"cookiePatternId": args[0],
|
"trackerPatternId": args[0],
|
||||||
"targetCookieCategoryId": flagTargetCategoryID,
|
"targetCookieCategoryId": flagTargetCategoryID,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -93,8 +93,8 @@ func NewCmdMove(f *cmdutil.Factory) *cobra.Command {
|
|||||||
return fmt.Errorf("cannot parse response: %w", err)
|
return fmt.Errorf("cannot parse response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := resp.MoveCookiePatternToCategory.CookiePattern
|
p := resp.MoveTrackerPatternToCategory.TrackerPattern
|
||||||
_, _ = fmt.Fprintf(f.IOStreams.Out, "Moved cookie pattern %s to category %s\n", p.ID, p.CookieCategory.Name)
|
_, _ = fmt.Fprintf(f.IOStreams.Out, "Moved tracker pattern %s to category %s\n", p.ID, p.CookieCategory.Name)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -12,23 +12,23 @@
|
|||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
package cookiepattern
|
package trackerpattern
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.probo.inc/probo/pkg/cmd/cmdutil"
|
"go.probo.inc/probo/pkg/cmd/cmdutil"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/create"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/create"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/delete"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/delete"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/list"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/list"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/move"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/move"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/update"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/update"
|
||||||
"go.probo.inc/probo/pkg/cmd/cookie-pattern/view"
|
"go.probo.inc/probo/pkg/cmd/tracker-pattern/view"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdCookiePattern(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdTrackerPattern(f *cmdutil.Factory) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "cookie-pattern <command>",
|
Use: "tracker-pattern <command>",
|
||||||
Short: "Manage cookie patterns",
|
Short: "Manage tracker patterns",
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(list.NewCmdList(f))
|
cmd.AddCommand(list.NewCmdList(f))
|
||||||
@@ -24,9 +24,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const updateMutation = `
|
const updateMutation = `
|
||||||
mutation($input: UpdateCookiePatternInput!) {
|
mutation($input: UpdateTrackerPatternInput!) {
|
||||||
updateCookiePattern(input: $input) {
|
updateTrackerPattern(input: $input) {
|
||||||
cookiePattern {
|
trackerPattern {
|
||||||
id
|
id
|
||||||
displayName
|
displayName
|
||||||
}
|
}
|
||||||
@@ -38,12 +38,12 @@ mutation($input: UpdateCookiePatternInput!) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
type updateResponse struct {
|
type updateResponse struct {
|
||||||
UpdateCookiePattern struct {
|
UpdateTrackerPattern struct {
|
||||||
CookiePattern struct {
|
TrackerPattern struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
} `json:"cookiePattern"`
|
} `json:"trackerPattern"`
|
||||||
} `json:"updateCookiePattern"`
|
} `json:"updateTrackerPattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command {
|
func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command {
|
||||||
@@ -56,7 +56,7 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "update <id>",
|
Use: "update <id>",
|
||||||
Short: "Update a cookie pattern",
|
Short: "Update a tracker pattern",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := f.Config()
|
cfg, err := f.Config()
|
||||||
@@ -77,7 +77,7 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
cmdutil.TokenRefreshOption(cfg, host, hc),
|
cmdutil.TokenRefreshOption(cfg, host, hc),
|
||||||
)
|
)
|
||||||
|
|
||||||
input := map[string]any{"cookiePatternId": args[0]}
|
input := map[string]any{"trackerPatternId": args[0]}
|
||||||
|
|
||||||
if cmd.Flags().Changed("display-name") {
|
if cmd.Flags().Changed("display-name") {
|
||||||
input["displayName"] = flagDisplayName
|
input["displayName"] = flagDisplayName
|
||||||
@@ -106,8 +106,8 @@ func NewCmdUpdate(f *cmdutil.Factory) *cobra.Command {
|
|||||||
return fmt.Errorf("cannot parse response: %w", err)
|
return fmt.Errorf("cannot parse response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := resp.UpdateCookiePattern.CookiePattern
|
p := resp.UpdateTrackerPattern.TrackerPattern
|
||||||
_, _ = fmt.Fprintf(f.IOStreams.Out, "Updated cookie pattern %s (%s)\n", p.ID, p.DisplayName)
|
_, _ = fmt.Fprintf(f.IOStreams.Out, "Updated tracker pattern %s (%s)\n", p.ID, p.DisplayName)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -28,10 +28,11 @@ const viewQuery = `
|
|||||||
query($id: ID!) {
|
query($id: ID!) {
|
||||||
node(id: $id) {
|
node(id: $id) {
|
||||||
__typename
|
__typename
|
||||||
... on CookiePattern {
|
... on TrackerPattern {
|
||||||
id
|
id
|
||||||
pattern
|
pattern
|
||||||
matchType
|
matchType
|
||||||
|
trackerType
|
||||||
displayName
|
displayName
|
||||||
maxAgeSeconds
|
maxAgeSeconds
|
||||||
description
|
description
|
||||||
@@ -51,6 +52,7 @@ type viewResponse struct {
|
|||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
MatchType string `json:"matchType"`
|
MatchType string `json:"matchType"`
|
||||||
|
TrackerType string `json:"trackerType"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
MaxAgeSeconds *int `json:"maxAgeSeconds"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
@@ -67,7 +69,7 @@ func NewCmdView(f *cmdutil.Factory) *cobra.Command {
|
|||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "view <id>",
|
Use: "view <id>",
|
||||||
Short: "View a cookie pattern",
|
Short: "View a tracker pattern",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := cmdutil.ValidateOutputFlag(flagOutput); err != nil {
|
if err := cmdutil.ValidateOutputFlag(flagOutput); err != nil {
|
||||||
@@ -102,8 +104,8 @@ func NewCmdView(f *cmdutil.Factory) *cobra.Command {
|
|||||||
return fmt.Errorf("cannot parse response: %w", err)
|
return fmt.Errorf("cannot parse response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.Node == nil || resp.Node.Typename != "CookiePattern" {
|
if resp.Node == nil || resp.Node.Typename != "TrackerPattern" {
|
||||||
return fmt.Errorf("cookie pattern %s not found", args[0])
|
return fmt.Errorf("tracker pattern %s not found", args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if *flagOutput == cmdutil.OutputJSON {
|
if *flagOutput == cmdutil.OutputJSON {
|
||||||
@@ -120,6 +122,7 @@ func NewCmdView(f *cmdutil.Factory) *cobra.Command {
|
|||||||
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("ID:"), v.ID)
|
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("ID:"), v.ID)
|
||||||
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Pattern:"), v.Pattern)
|
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Pattern:"), v.Pattern)
|
||||||
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Match Type:"), v.MatchType)
|
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Match Type:"), v.MatchType)
|
||||||
|
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Tracker Type:"), v.TrackerType)
|
||||||
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Source:"), v.Source)
|
_, _ = fmt.Fprintf(out, "%s%s\n", label.Render("Source:"), v.Source)
|
||||||
_, _ = fmt.Fprintf(out, "%s%v\n", label.Render("Excluded:"), v.Excluded)
|
_, _ = fmt.Fprintf(out, "%s%v\n", label.Render("Excluded:"), v.Excluded)
|
||||||
if v.MaxAgeSeconds != nil {
|
if v.MaxAgeSeconds != nil {
|
||||||
@@ -32,7 +32,7 @@ var (
|
|||||||
ErrCookieNotFound = errors.New("cookie not found")
|
ErrCookieNotFound = errors.New("cookie not found")
|
||||||
ErrCategoriesBannerMismatch = errors.New("source and target categories belong to different banners")
|
ErrCategoriesBannerMismatch = errors.New("source and target categories belong to different banners")
|
||||||
ErrPostHogConsentKindInvalid = errors.New("PostHog consent can only be enabled on normal categories")
|
ErrPostHogConsentKindInvalid = errors.New("PostHog consent can only be enabled on normal categories")
|
||||||
ErrCookiePatternNotFound = errors.New("cookie pattern not found")
|
ErrTrackerPatternNotFound = errors.New("tracker pattern not found")
|
||||||
ErrPatternAlreadyExists = errors.New("a pattern with this name already exists in this banner")
|
ErrPatternAlreadyExists = errors.New("a pattern with this name already exists in this banner")
|
||||||
ErrSamePatternCategoryMove = errors.New("source and target cookie categories must be different")
|
ErrSamePatternCategoryMove = errors.New("source and target cookie categories must be different")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -84,33 +84,6 @@ type (
|
|||||||
Rank int
|
Rank int
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateCookiePatternRequest struct {
|
|
||||||
CookieCategoryID gid.GID
|
|
||||||
Pattern string
|
|
||||||
MatchType coredata.CookiePatternMatchType
|
|
||||||
DisplayName string
|
|
||||||
MaxAgeSeconds *int
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateCookiePatternRequest struct {
|
|
||||||
CookiePatternID gid.GID
|
|
||||||
DisplayName *string
|
|
||||||
MaxAgeSeconds **int
|
|
||||||
Description *string
|
|
||||||
Excluded *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
MoveCookiePatternToCategoryRequest struct {
|
|
||||||
CookiePatternID gid.GID
|
|
||||||
TargetCookieCategoryID gid.GID
|
|
||||||
}
|
|
||||||
|
|
||||||
MoveCookiePatternToCategoryResult struct {
|
|
||||||
CookiePattern *coredata.CookiePattern
|
|
||||||
Banner *coredata.CookieBanner
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateCookieConsentRecordRequest struct {
|
CreateCookieConsentRecordRequest struct {
|
||||||
CookieBannerID gid.GID
|
CookieBannerID gid.GID
|
||||||
Version int
|
Version int
|
||||||
@@ -159,6 +132,17 @@ type (
|
|||||||
Resources []DetectedResourceItem
|
Resources []DetectedResourceItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateTrackerPatternRequest struct {
|
||||||
|
CookieCategoryID gid.GID
|
||||||
|
TrackerType coredata.TrackerType
|
||||||
|
Pattern string
|
||||||
|
MatchType coredata.TrackerPatternMatchType
|
||||||
|
DisplayName string
|
||||||
|
MaxAgeSeconds *int
|
||||||
|
Description string
|
||||||
|
Source *coredata.CookieSource
|
||||||
|
}
|
||||||
|
|
||||||
UpdateTrackerPatternRequest struct {
|
UpdateTrackerPatternRequest struct {
|
||||||
TrackerPatternID gid.GID
|
TrackerPatternID gid.GID
|
||||||
DisplayName *string
|
DisplayName *string
|
||||||
@@ -266,46 +250,6 @@ func (r *ReorderCookieCategoryRequest) Validate() error {
|
|||||||
return v.Error()
|
return v.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CreateCookiePatternRequest) Validate() error {
|
|
||||||
v := validator.New()
|
|
||||||
|
|
||||||
v.Check(r.CookieCategoryID, "cookie_category_id", validator.Required(), validator.GID(coredata.CookieCategoryEntityType))
|
|
||||||
v.Check(r.Pattern, "pattern", validator.Required(), validator.SafeTextNoNewLine(255))
|
|
||||||
v.Check(string(r.MatchType), "match_type", validator.Required(), validator.OneOfSlice(
|
|
||||||
func() []string {
|
|
||||||
types := coredata.CookiePatternMatchTypes()
|
|
||||||
s := make([]string, len(types))
|
|
||||||
for i, t := range types {
|
|
||||||
s[i] = string(t)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}(),
|
|
||||||
))
|
|
||||||
v.Check(r.DisplayName, "display_name", validator.Required(), validator.SafeTextNoNewLine(255))
|
|
||||||
v.Check(r.Description, "description", validator.SafeText(1000))
|
|
||||||
|
|
||||||
return v.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *UpdateCookiePatternRequest) Validate() error {
|
|
||||||
v := validator.New()
|
|
||||||
|
|
||||||
v.Check(r.CookiePatternID, "cookie_pattern_id", validator.Required(), validator.GID(coredata.CookiePatternEntityType))
|
|
||||||
v.Check(r.DisplayName, "display_name", validator.SafeTextNoNewLine(255))
|
|
||||||
v.Check(r.Description, "description", validator.SafeText(1000))
|
|
||||||
|
|
||||||
return v.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *MoveCookiePatternToCategoryRequest) Validate() error {
|
|
||||||
v := validator.New()
|
|
||||||
|
|
||||||
v.Check(r.CookiePatternID, "cookie_pattern_id", validator.Required(), validator.GID(coredata.CookiePatternEntityType))
|
|
||||||
v.Check(r.TargetCookieCategoryID, "target_cookie_category_id", validator.Required(), validator.GID(coredata.CookieCategoryEntityType))
|
|
||||||
|
|
||||||
return v.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *CreateCookieConsentRecordRequest) Validate() error {
|
func (r *CreateCookieConsentRecordRequest) Validate() error {
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
|
|
||||||
@@ -373,6 +317,27 @@ func (r *UpsertCookieBannerTranslationRequest) Validate() error {
|
|||||||
return v.Error()
|
return v.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *CreateTrackerPatternRequest) Validate() error {
|
||||||
|
v := validator.New()
|
||||||
|
|
||||||
|
v.Check(r.CookieCategoryID, "cookie_category_id", validator.Required(), validator.GID(coredata.CookieCategoryEntityType))
|
||||||
|
v.Check(r.Pattern, "pattern", validator.Required(), validator.SafeTextNoNewLine(255))
|
||||||
|
v.Check(string(r.MatchType), "match_type", validator.Required(), validator.OneOfSlice(
|
||||||
|
func() []string {
|
||||||
|
types := coredata.TrackerPatternMatchTypes()
|
||||||
|
s := make([]string, len(types))
|
||||||
|
for i, t := range types {
|
||||||
|
s[i] = string(t)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}(),
|
||||||
|
))
|
||||||
|
v.Check(r.DisplayName, "display_name", validator.Required(), validator.SafeTextNoNewLine(255))
|
||||||
|
v.Check(r.Description, "description", validator.SafeText(1000))
|
||||||
|
|
||||||
|
return v.Error()
|
||||||
|
}
|
||||||
|
|
||||||
func CanonicalizeOrigin(raw string) string {
|
func CanonicalizeOrigin(raw string) string {
|
||||||
u, err := url.Parse(raw)
|
u, err := url.Parse(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -473,7 +438,7 @@ func (s *Service) ensureDraftVersionForBanner(
|
|||||||
tx,
|
tx,
|
||||||
scope,
|
scope,
|
||||||
bannerID,
|
bannerID,
|
||||||
coredata.NewCookiePatternFilter(nil, nil, new(false)),
|
coredata.NewTrackerPatternFilter(nil, nil, new(false)),
|
||||||
nil,
|
nil,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, fmt.Errorf("cannot load tracker patterns: %w", err)
|
return nil, fmt.Errorf("cannot load tracker patterns: %w", err)
|
||||||
@@ -550,17 +515,18 @@ func (s *Service) CreateCookieBanner(
|
|||||||
|
|
||||||
if dc.Kind == coredata.CookieCategoryKindNecessary {
|
if dc.Kind == coredata.CookieCategoryKindNecessary {
|
||||||
consentMaxAge := req.ConsentExpiryDays * 86400
|
consentMaxAge := req.ConsentExpiryDays * 86400
|
||||||
consentPattern := &coredata.CookiePattern{
|
consentPattern := &coredata.TrackerPattern{
|
||||||
ID: gid.New(scope.GetTenantID(), coredata.CookiePatternEntityType),
|
ID: gid.New(scope.GetTenantID(), coredata.TrackerPatternEntityType),
|
||||||
OrganizationID: banner.OrganizationID,
|
OrganizationID: banner.OrganizationID,
|
||||||
CookieBannerID: banner.ID,
|
CookieBannerID: banner.ID,
|
||||||
CookieCategoryID: category.ID,
|
CookieCategoryID: category.ID,
|
||||||
|
TrackerType: coredata.TrackerTypeCookie,
|
||||||
Pattern: "probo_consent",
|
Pattern: "probo_consent",
|
||||||
MatchType: coredata.CookiePatternMatchTypeExact,
|
MatchType: coredata.TrackerPatternMatchTypeExact,
|
||||||
DisplayName: "probo_consent",
|
DisplayName: "probo_consent",
|
||||||
MaxAgeSeconds: &consentMaxAge,
|
MaxAgeSeconds: &consentMaxAge,
|
||||||
Description: "Stores your cookie consent preferences for this website.",
|
Description: "Stores your cookie consent preferences for this website.",
|
||||||
Source: coredata.CookieSourceScript,
|
Source: new(coredata.CookieSourceScript),
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
@@ -1156,442 +1122,6 @@ func (s *Service) CountCookieCategoriesForBanner(
|
|||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetCookiePattern(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
cookiePatternID gid.GID,
|
|
||||||
) (*coredata.CookiePattern, error) {
|
|
||||||
var pattern coredata.CookiePattern
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
|
||||||
if err := pattern.LoadByID(ctx, conn, scope, cookiePatternID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCookiePatternNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pattern, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CreateCookiePattern(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
req CreateCookiePatternRequest,
|
|
||||||
) (*coredata.CookiePattern, error) {
|
|
||||||
if err := req.Validate(); err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var pattern *coredata.CookiePattern
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
var category coredata.CookieCategory
|
|
||||||
if err := category.LoadByID(ctx, tx, scope, req.CookieCategoryID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCategoryNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load cookie category: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
pattern = &coredata.CookiePattern{
|
|
||||||
ID: gid.New(scope.GetTenantID(), coredata.CookiePatternEntityType),
|
|
||||||
OrganizationID: category.OrganizationID,
|
|
||||||
CookieBannerID: category.CookieBannerID,
|
|
||||||
CookieCategoryID: category.ID,
|
|
||||||
Pattern: req.Pattern,
|
|
||||||
MatchType: req.MatchType,
|
|
||||||
DisplayName: req.DisplayName,
|
|
||||||
MaxAgeSeconds: req.MaxAgeSeconds,
|
|
||||||
Description: req.Description,
|
|
||||||
Source: coredata.CookieSourceScript,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := pattern.Insert(ctx, tx, scope); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
|
||||||
return ErrPatternAlreadyExists
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot insert cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tp := &coredata.TrackerPattern{
|
|
||||||
ID: gid.New(scope.GetTenantID(), coredata.TrackerPatternEntityType),
|
|
||||||
OrganizationID: category.OrganizationID,
|
|
||||||
CookieBannerID: category.CookieBannerID,
|
|
||||||
CookieCategoryID: category.ID,
|
|
||||||
TrackerType: coredata.TrackerTypeCookie,
|
|
||||||
Pattern: req.Pattern,
|
|
||||||
MatchType: req.MatchType,
|
|
||||||
DisplayName: req.DisplayName,
|
|
||||||
MaxAgeSeconds: req.MaxAgeSeconds,
|
|
||||||
Description: req.Description,
|
|
||||||
Source: new(coredata.CookieSourceScript),
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
if _, err := tp.InsertIfNotExists(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, category.CookieBannerID); err != nil {
|
|
||||||
return fmt.Errorf("cannot ensure draft version: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pattern, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) UpdateCookiePattern(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
req UpdateCookiePatternRequest,
|
|
||||||
) (*coredata.CookiePattern, error) {
|
|
||||||
if err := req.Validate(); err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var pattern coredata.CookiePattern
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, req.CookiePatternID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCookiePatternNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
displayNameChanged := req.DisplayName != nil && *req.DisplayName != pattern.DisplayName
|
|
||||||
maxAgeChanged := req.MaxAgeSeconds != nil && !ptrEqual(*req.MaxAgeSeconds, pattern.MaxAgeSeconds)
|
|
||||||
descChanged := req.Description != nil && *req.Description != pattern.Description
|
|
||||||
excludedChanged := req.Excluded != nil && *req.Excluded != pattern.Excluded
|
|
||||||
|
|
||||||
if !displayNameChanged && !maxAgeChanged && !descChanged && !excludedChanged {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A pattern that was excluded and stays excluded is invisible to visitors,
|
|
||||||
// so any field updates do not affect the published snapshot. We persist
|
|
||||||
// the row but skip the version bump.
|
|
||||||
staysExcluded := pattern.Excluded && (req.Excluded == nil || *req.Excluded)
|
|
||||||
|
|
||||||
if req.DisplayName != nil {
|
|
||||||
pattern.DisplayName = *req.DisplayName
|
|
||||||
}
|
|
||||||
if req.MaxAgeSeconds != nil {
|
|
||||||
pattern.MaxAgeSeconds = *req.MaxAgeSeconds
|
|
||||||
}
|
|
||||||
if req.Description != nil {
|
|
||||||
pattern.Description = *req.Description
|
|
||||||
}
|
|
||||||
if req.Excluded != nil {
|
|
||||||
pattern.Excluded = *req.Excluded
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern.UpdatedAt = time.Now()
|
|
||||||
|
|
||||||
if err := pattern.Update(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot update cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var tp coredata.TrackerPattern
|
|
||||||
if err := tp.LoadByBannerIDTypeAndPattern(ctx, tx, scope, pattern.CookieBannerID, coredata.TrackerTypeCookie, pattern.Pattern); err != nil {
|
|
||||||
if !errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if req.DisplayName != nil {
|
|
||||||
tp.DisplayName = *req.DisplayName
|
|
||||||
}
|
|
||||||
if req.MaxAgeSeconds != nil {
|
|
||||||
tp.MaxAgeSeconds = *req.MaxAgeSeconds
|
|
||||||
}
|
|
||||||
if req.Description != nil {
|
|
||||||
tp.Description = *req.Description
|
|
||||||
}
|
|
||||||
if req.Excluded != nil {
|
|
||||||
tp.Excluded = *req.Excluded
|
|
||||||
}
|
|
||||||
tp.UpdatedAt = time.Now()
|
|
||||||
if err := tp.Update(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot update tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !staysExcluded {
|
|
||||||
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, pattern.CookieBannerID); err != nil {
|
|
||||||
return fmt.Errorf("cannot ensure draft version: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pattern, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) DeleteCookiePattern(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
cookiePatternID gid.GID,
|
|
||||||
) error {
|
|
||||||
return s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
var pattern coredata.CookiePattern
|
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, cookiePatternID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCookiePatternNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wasExcluded := pattern.Excluded
|
|
||||||
|
|
||||||
if err := pattern.Delete(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot delete cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var tp coredata.TrackerPattern
|
|
||||||
if err := tp.LoadByBannerIDTypeAndPattern(ctx, tx, scope, pattern.CookieBannerID, coredata.TrackerTypeCookie, pattern.Pattern); err != nil {
|
|
||||||
if !errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := tp.Delete(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot delete tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !wasExcluded {
|
|
||||||
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, pattern.CookieBannerID); err != nil {
|
|
||||||
return fmt.Errorf("cannot ensure draft version: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) MoveCookiePatternToCategory(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
req MoveCookiePatternToCategoryRequest,
|
|
||||||
) (*MoveCookiePatternToCategoryResult, error) {
|
|
||||||
if err := req.Validate(); err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var result MoveCookiePatternToCategoryResult
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, tx pg.Tx) error {
|
|
||||||
var pattern coredata.CookiePattern
|
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, req.CookiePatternID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCookiePatternNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var target coredata.CookieCategory
|
|
||||||
if err := target.LoadByID(ctx, tx, scope, req.TargetCookieCategoryID); err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return ErrCategoryNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot load target cookie category: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if pattern.CookieCategoryID == target.ID {
|
|
||||||
return ErrSamePatternCategoryMove
|
|
||||||
}
|
|
||||||
|
|
||||||
if pattern.CookieBannerID != target.CookieBannerID {
|
|
||||||
return ErrCategoriesBannerMismatch
|
|
||||||
}
|
|
||||||
|
|
||||||
wasExcluded := pattern.Excluded
|
|
||||||
|
|
||||||
pattern.CookieCategoryID = target.ID
|
|
||||||
pattern.UpdatedAt = time.Now()
|
|
||||||
|
|
||||||
if err := pattern.Update(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot update cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var tp coredata.TrackerPattern
|
|
||||||
if err := tp.LoadByBannerIDTypeAndPattern(ctx, tx, scope, pattern.CookieBannerID, coredata.TrackerTypeCookie, pattern.Pattern); err != nil {
|
|
||||||
if !errors.Is(err, coredata.ErrResourceNotFound) {
|
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tp.CookieCategoryID = target.ID
|
|
||||||
tp.UpdatedAt = time.Now()
|
|
||||||
if err := tp.Update(ctx, tx, scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot update tracker pattern: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var banner coredata.CookieBanner
|
|
||||||
if err := banner.LoadByID(ctx, tx, scope, pattern.CookieBannerID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load cookie banner: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !wasExcluded {
|
|
||||||
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, pattern.CookieBannerID); err != nil {
|
|
||||||
return fmt.Errorf("cannot ensure draft version: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.CookiePattern = &pattern
|
|
||||||
result.Banner = &banner
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) ListCookiePatternsForCategory(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
categoryID gid.GID,
|
|
||||||
cursor *page.Cursor[coredata.CookiePatternOrderField],
|
|
||||||
) (coredata.CookiePatterns, error) {
|
|
||||||
var patterns coredata.CookiePatterns
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
|
||||||
if err := patterns.LoadByCookieCategoryID(ctx, conn, scope, categoryID, cursor); err != nil {
|
|
||||||
return fmt.Errorf("cannot list cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return patterns, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CountCookiePatternsForCategory(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
categoryID gid.GID,
|
|
||||||
) (int, error) {
|
|
||||||
var count int
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
|
||||||
var patterns coredata.CookiePatterns
|
|
||||||
var err error
|
|
||||||
|
|
||||||
count, err = patterns.CountByCookieCategoryID(ctx, conn, scope, categoryID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot count cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) ListUncategorisedCookiePatterns(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
bannerID gid.GID,
|
|
||||||
cursor *page.Cursor[coredata.CookiePatternOrderField],
|
|
||||||
filter *coredata.CookiePatternFilter,
|
|
||||||
) (coredata.CookiePatterns, error) {
|
|
||||||
var patterns coredata.CookiePatterns
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
|
||||||
if err := patterns.LoadUncategorisedByCookieBannerID(ctx, conn, scope, bannerID, cursor, filter); err != nil {
|
|
||||||
return fmt.Errorf("cannot list uncategorised cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return patterns, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CountUncategorisedCookiePatterns(
|
|
||||||
ctx context.Context,
|
|
||||||
scope coredata.Scoper,
|
|
||||||
bannerID gid.GID,
|
|
||||||
filter *coredata.CookiePatternFilter,
|
|
||||||
) (int, error) {
|
|
||||||
var count int
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(ctx context.Context, conn pg.Querier) error {
|
|
||||||
var patterns coredata.CookiePatterns
|
|
||||||
var err error
|
|
||||||
|
|
||||||
count, err = patterns.CountUncategorisedByCookieBannerID(ctx, conn, scope, bannerID, filter)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot count uncategorised cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) CountCookiesForPattern(
|
func (s *Service) CountCookiesForPattern(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
scope coredata.Scoper,
|
scope coredata.Scoper,
|
||||||
@@ -1777,9 +1307,9 @@ func (s *Service) DeleteCookieCategory(
|
|||||||
return fmt.Errorf("cannot load uncategorised cookie category: %w", err)
|
return fmt.Errorf("cannot load uncategorised cookie category: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var patterns coredata.CookiePatterns
|
var patterns coredata.TrackerPatterns
|
||||||
if err := patterns.MoveToCategoryByCookieCategoryID(ctx, tx, scope, category.ID, uncategorised.ID); err != nil {
|
if err := patterns.MoveToCategoryByCookieCategoryID(ctx, tx, scope, category.ID, uncategorised.ID); err != nil {
|
||||||
return fmt.Errorf("cannot move cookie patterns to uncategorised: %w", err)
|
return fmt.Errorf("cannot move tracker patterns to uncategorised: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := category.Delete(ctx, tx, scope); err != nil {
|
if err := category.Delete(ctx, tx, scope); err != nil {
|
||||||
@@ -2513,7 +2043,7 @@ func (s *Service) reportDetectedTracker(
|
|||||||
CookieCategoryID: uncategorisedID,
|
CookieCategoryID: uncategorisedID,
|
||||||
TrackerType: info.TrackerType,
|
TrackerType: info.TrackerType,
|
||||||
Pattern: info.Identifier,
|
Pattern: info.Identifier,
|
||||||
MatchType: coredata.CookiePatternMatchTypeExact,
|
MatchType: coredata.TrackerPatternMatchTypeExact,
|
||||||
DisplayName: info.Identifier,
|
DisplayName: info.Identifier,
|
||||||
Description: "",
|
Description: "",
|
||||||
MaxAgeSeconds: info.MaxAgeSeconds,
|
MaxAgeSeconds: info.MaxAgeSeconds,
|
||||||
@@ -2558,6 +2088,114 @@ func (s *Service) reportDetectedTracker(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) CreateTrackerPattern(
|
||||||
|
ctx context.Context,
|
||||||
|
scope coredata.Scoper,
|
||||||
|
req CreateTrackerPatternRequest,
|
||||||
|
) (*coredata.TrackerPattern, error) {
|
||||||
|
if err := req.Validate(); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var pattern *coredata.TrackerPattern
|
||||||
|
|
||||||
|
err := s.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(ctx context.Context, tx pg.Tx) error {
|
||||||
|
var category coredata.CookieCategory
|
||||||
|
if err := category.LoadByID(ctx, tx, scope, req.CookieCategoryID); err != nil {
|
||||||
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
|
return ErrCategoryNotFound
|
||||||
|
}
|
||||||
|
return fmt.Errorf("cannot load cookie category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
pattern = &coredata.TrackerPattern{
|
||||||
|
ID: gid.New(scope.GetTenantID(), coredata.TrackerPatternEntityType),
|
||||||
|
OrganizationID: category.OrganizationID,
|
||||||
|
CookieBannerID: category.CookieBannerID,
|
||||||
|
CookieCategoryID: category.ID,
|
||||||
|
TrackerType: req.TrackerType,
|
||||||
|
Pattern: req.Pattern,
|
||||||
|
MatchType: req.MatchType,
|
||||||
|
DisplayName: req.DisplayName,
|
||||||
|
MaxAgeSeconds: req.MaxAgeSeconds,
|
||||||
|
Description: req.Description,
|
||||||
|
Source: req.Source,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pattern.Insert(ctx, tx, scope); err != nil {
|
||||||
|
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||||
|
return ErrPatternAlreadyExists
|
||||||
|
}
|
||||||
|
return fmt.Errorf("cannot insert tracker pattern: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pattern.Excluded && pattern.TrackerType == coredata.TrackerTypeCookie {
|
||||||
|
if _, err := s.ensureDraftVersionForBanner(ctx, tx, scope, pattern.CookieBannerID); err != nil {
|
||||||
|
return fmt.Errorf("cannot ensure draft version: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pattern, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) ListTrackerPatternsForCategory(
|
||||||
|
ctx context.Context,
|
||||||
|
scope coredata.Scoper,
|
||||||
|
categoryID gid.GID,
|
||||||
|
cursor *page.Cursor[coredata.TrackerPatternOrderField],
|
||||||
|
) (coredata.TrackerPatterns, error) {
|
||||||
|
var patterns coredata.TrackerPatterns
|
||||||
|
|
||||||
|
err := s.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(ctx context.Context, conn pg.Querier) error {
|
||||||
|
return patterns.LoadByCookieCategoryID(ctx, conn, scope, categoryID, cursor)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot list tracker patterns for category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return patterns, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) CountTrackerPatternsForCategory(
|
||||||
|
ctx context.Context,
|
||||||
|
scope coredata.Scoper,
|
||||||
|
categoryID gid.GID,
|
||||||
|
) (int, error) {
|
||||||
|
var count int
|
||||||
|
|
||||||
|
err := s.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(ctx context.Context, conn pg.Querier) error {
|
||||||
|
var patterns coredata.TrackerPatterns
|
||||||
|
var err error
|
||||||
|
|
||||||
|
count, err = patterns.CountByCookieCategoryID(ctx, conn, scope, categoryID)
|
||||||
|
return err
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot count tracker patterns for category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) GetTrackerPattern(
|
func (s *Service) GetTrackerPattern(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
scope coredata.Scoper,
|
scope coredata.Scoper,
|
||||||
@@ -2570,7 +2208,7 @@ func (s *Service) GetTrackerPattern(
|
|||||||
func(ctx context.Context, conn pg.Querier) error {
|
func(ctx context.Context, conn pg.Querier) error {
|
||||||
if err := pattern.LoadByID(ctx, conn, scope, trackerPatternID); err != nil {
|
if err := pattern.LoadByID(ctx, conn, scope, trackerPatternID); err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
return ErrCookiePatternNotFound
|
return ErrTrackerPatternNotFound
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
@@ -2597,7 +2235,7 @@ func (s *Service) UpdateTrackerPattern(
|
|||||||
func(ctx context.Context, tx pg.Tx) error {
|
func(ctx context.Context, tx pg.Tx) error {
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, req.TrackerPatternID); err != nil {
|
if err := pattern.LoadByID(ctx, tx, scope, req.TrackerPatternID); err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
return ErrCookiePatternNotFound
|
return ErrTrackerPatternNotFound
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
@@ -2659,7 +2297,7 @@ func (s *Service) DeleteTrackerPattern(
|
|||||||
var pattern coredata.TrackerPattern
|
var pattern coredata.TrackerPattern
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, trackerPatternID); err != nil {
|
if err := pattern.LoadByID(ctx, tx, scope, trackerPatternID); err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
return ErrCookiePatternNotFound
|
return ErrTrackerPatternNotFound
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
@@ -2694,7 +2332,7 @@ func (s *Service) MoveTrackerPatternToCategory(
|
|||||||
var pattern coredata.TrackerPattern
|
var pattern coredata.TrackerPattern
|
||||||
if err := pattern.LoadByID(ctx, tx, scope, req.TrackerPatternID); err != nil {
|
if err := pattern.LoadByID(ctx, tx, scope, req.TrackerPatternID); err != nil {
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
return ErrCookiePatternNotFound
|
return ErrTrackerPatternNotFound
|
||||||
}
|
}
|
||||||
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
return fmt.Errorf("cannot load tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
@@ -2752,8 +2390,8 @@ func (s *Service) ListUncategorisedTrackerPatterns(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
scope coredata.Scoper,
|
scope coredata.Scoper,
|
||||||
bannerID gid.GID,
|
bannerID gid.GID,
|
||||||
cursor *page.Cursor[coredata.CookiePatternOrderField],
|
cursor *page.Cursor[coredata.TrackerPatternOrderField],
|
||||||
filter *coredata.CookiePatternFilter,
|
filter *coredata.TrackerPatternFilter,
|
||||||
) (coredata.TrackerPatterns, error) {
|
) (coredata.TrackerPatterns, error) {
|
||||||
var patterns coredata.TrackerPatterns
|
var patterns coredata.TrackerPatterns
|
||||||
|
|
||||||
@@ -2778,7 +2416,7 @@ func (s *Service) CountUncategorisedTrackerPatterns(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
scope coredata.Scoper,
|
scope coredata.Scoper,
|
||||||
bannerID gid.GID,
|
bannerID gid.GID,
|
||||||
filter *coredata.CookiePatternFilter,
|
filter *coredata.TrackerPatternFilter,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
var count int
|
var count int
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func (h *patternAnalysisHandler) Process(ctx context.Context, banner coredata.Co
|
|||||||
tx,
|
tx,
|
||||||
scope,
|
scope,
|
||||||
banner.ID,
|
banner.ID,
|
||||||
coredata.NewCookiePatternFilter(new(coredata.CookiePatternMatchTypeExact), nil, new(false)),
|
coredata.NewTrackerPatternFilter(new(coredata.TrackerPatternMatchTypeExact), nil, new(false)),
|
||||||
nil,
|
nil,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return fmt.Errorf("cannot load exact patterns: %w", err)
|
return fmt.Errorf("cannot load exact patterns: %w", err)
|
||||||
@@ -121,7 +121,7 @@ func (h *patternAnalysisHandler) Process(ctx context.Context, banner coredata.Co
|
|||||||
CookieCategoryID: key.categoryID,
|
CookieCategoryID: key.categoryID,
|
||||||
TrackerType: key.trackerType,
|
TrackerType: key.trackerType,
|
||||||
Pattern: key.prefix,
|
Pattern: key.prefix,
|
||||||
MatchType: coredata.CookiePatternMatchTypePrefix,
|
MatchType: coredata.TrackerPatternMatchTypePrefix,
|
||||||
DisplayName: key.prefix + "*",
|
DisplayName: key.prefix + "*",
|
||||||
MaxAgeSeconds: maxAge,
|
MaxAgeSeconds: maxAge,
|
||||||
Description: "",
|
Description: "",
|
||||||
@@ -139,7 +139,7 @@ func (h *patternAnalysisHandler) Process(ctx context.Context, banner coredata.Co
|
|||||||
return fmt.Errorf("cannot load existing prefix pattern %q: %w", key.prefix, err)
|
return fmt.Errorf("cannot load existing prefix pattern %q: %w", key.prefix, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if prefixPattern.CookieCategoryID != key.categoryID || prefixPattern.MatchType != coredata.CookiePatternMatchTypePrefix {
|
if prefixPattern.CookieCategoryID != key.categoryID || prefixPattern.MatchType != coredata.TrackerPatternMatchTypePrefix {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ func (h *patternAnalysisHandler) adoptUncategorisedPatterns(
|
|||||||
tx,
|
tx,
|
||||||
scope,
|
scope,
|
||||||
banner.ID,
|
banner.ID,
|
||||||
coredata.NewCookiePatternFilter(new(coredata.CookiePatternMatchTypePrefix), nil, new(false)),
|
coredata.NewTrackerPatternFilter(new(coredata.TrackerPatternMatchTypePrefix), nil, new(false)),
|
||||||
nil,
|
nil,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return false, fmt.Errorf("cannot load prefix patterns: %w", err)
|
return false, fmt.Errorf("cannot load prefix patterns: %w", err)
|
||||||
@@ -333,14 +333,14 @@ func (h *patternAnalysisHandler) adoptUncategorisedPatterns(
|
|||||||
return len(prefixPatterns[i].Pattern) > len(prefixPatterns[j].Pattern)
|
return len(prefixPatterns[i].Pattern) > len(prefixPatterns[j].Pattern)
|
||||||
})
|
})
|
||||||
|
|
||||||
exactMatchType := coredata.CookiePatternMatchTypeExact
|
exactMatchType := coredata.TrackerPatternMatchTypeExact
|
||||||
var uncategorisedExact coredata.TrackerPatterns
|
var uncategorisedExact coredata.TrackerPatterns
|
||||||
if err := uncategorisedExact.LoadAllByCookieBannerID(
|
if err := uncategorisedExact.LoadAllByCookieBannerID(
|
||||||
ctx,
|
ctx,
|
||||||
tx,
|
tx,
|
||||||
scope,
|
scope,
|
||||||
banner.ID,
|
banner.ID,
|
||||||
coredata.NewCookiePatternFilter(&exactMatchType, &uncategorised.ID, new(false)),
|
coredata.NewTrackerPatternFilter(&exactMatchType, &uncategorised.ID, new(false)),
|
||||||
nil,
|
nil,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return false, fmt.Errorf("cannot load uncategorised exact patterns: %w", err)
|
return false, fmt.Errorf("cannot load uncategorised exact patterns: %w", err)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func TestFindMergeGroups(t *testing.T) {
|
|||||||
return &coredata.TrackerPattern{
|
return &coredata.TrackerPattern{
|
||||||
Pattern: name,
|
Pattern: name,
|
||||||
TrackerType: coredata.TrackerTypeCookie,
|
TrackerType: coredata.TrackerTypeCookie,
|
||||||
MatchType: coredata.CookiePatternMatchTypeExact,
|
MatchType: coredata.TrackerPatternMatchTypeExact,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,794 +0,0 @@
|
|||||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
package coredata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"maps"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
"go.probo.inc/probo/pkg/gid"
|
|
||||||
"go.probo.inc/probo/pkg/page"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CookiePattern struct {
|
|
||||||
ID gid.GID `db:"id"`
|
|
||||||
OrganizationID gid.GID `db:"organization_id"`
|
|
||||||
CookieBannerID gid.GID `db:"cookie_banner_id"`
|
|
||||||
CookieCategoryID gid.GID `db:"cookie_category_id"`
|
|
||||||
Pattern string `db:"pattern"`
|
|
||||||
MatchType CookiePatternMatchType `db:"match_type"`
|
|
||||||
DisplayName string `db:"display_name"`
|
|
||||||
MaxAgeSeconds *int `db:"max_age_seconds"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
Source CookieSource `db:"source"`
|
|
||||||
Excluded bool `db:"excluded"`
|
|
||||||
LastMatchedAt *time.Time `db:"last_matched_at"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
CookiePatterns []*CookiePattern
|
|
||||||
)
|
|
||||||
|
|
||||||
func (cp *CookiePattern) CursorKey(field CookiePatternOrderField) page.CursorKey {
|
|
||||||
switch field {
|
|
||||||
case CookiePatternOrderFieldCreatedAt:
|
|
||||||
return page.NewCursorKey(cp.ID, cp.CreatedAt)
|
|
||||||
case CookiePatternOrderFieldName:
|
|
||||||
return page.NewCursorKey(cp.ID, cp.DisplayName)
|
|
||||||
case CookiePatternOrderFieldLastMatchedAt:
|
|
||||||
if cp.LastMatchedAt == nil {
|
|
||||||
return page.NewCursorKey(cp.ID, time.Time{})
|
|
||||||
}
|
|
||||||
return page.NewCursorKey(cp.ID, *cp.LastMatchedAt)
|
|
||||||
case CookiePatternOrderFieldUpdatedAt:
|
|
||||||
return page.NewCursorKey(cp.ID, cp.UpdatedAt)
|
|
||||||
case CookiePatternOrderFieldSource:
|
|
||||||
return page.NewCursorKey(cp.ID, string(cp.Source))
|
|
||||||
}
|
|
||||||
|
|
||||||
panic(fmt.Sprintf("unsupported order by: %s", field))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) AuthorizationAttributes(ctx context.Context, conn pg.Querier) (map[string]string, error) {
|
|
||||||
q := `SELECT organization_id FROM cookie_patterns WHERE id = $1 LIMIT 1;`
|
|
||||||
|
|
||||||
var organizationID gid.GID
|
|
||||||
if err := conn.QueryRow(ctx, q, cp.ID).Scan(&organizationID); err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return nil, ErrResourceNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("cannot query cookie pattern authorization attributes: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]string{"organization_id": organizationID.String()}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) LoadByID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookiePatternID gid.GID,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND id = @cookie_pattern_id
|
|
||||||
LIMIT 1;
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"cookie_pattern_id": cookiePatternID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return ErrResourceNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot collect cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cp = pattern
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) LoadByBannerIDAndPattern(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
pattern string,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_banner_id = @cookie_banner_id
|
|
||||||
AND pattern = @pattern
|
|
||||||
LIMIT 1;
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"cookie_banner_id": cookieBannerID,
|
|
||||||
"pattern": pattern,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return ErrResourceNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot collect cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cp = p
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) FindMatchingPattern(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
cookieName string,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_banner_id = @cookie_banner_id
|
|
||||||
AND (
|
|
||||||
(match_type = @match_type_prefix AND starts_with(@cookie_name, pattern))
|
|
||||||
OR (match_type = @match_type_exact AND pattern = @cookie_name)
|
|
||||||
)
|
|
||||||
ORDER BY
|
|
||||||
CASE WHEN match_type = @match_type_exact AND pattern = @cookie_name THEN 0
|
|
||||||
WHEN match_type = @match_type_prefix THEN 1
|
|
||||||
ELSE 2
|
|
||||||
END,
|
|
||||||
LENGTH(pattern) DESC
|
|
||||||
LIMIT 1;
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"cookie_banner_id": cookieBannerID,
|
|
||||||
"cookie_name": cookieName,
|
|
||||||
"match_type_prefix": CookiePatternMatchTypePrefix,
|
|
||||||
"match_type_exact": CookiePatternMatchTypeExact,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pattern, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, pgx.ErrNoRows) {
|
|
||||||
return ErrResourceNotFound
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot collect cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cp = pattern
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) LoadByCookieCategoryID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieCategoryID gid.GID,
|
|
||||||
cursor *page.Cursor[CookiePatternOrderField],
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_category_id = @cookie_category_id
|
|
||||||
AND %s
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"cookie_category_id": cookieCategoryID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
maps.Copy(args, cursor.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
patterns, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot collect cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cps = patterns
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) CountByCookieCategoryID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieCategoryID gid.GID,
|
|
||||||
) (int, error) {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
COUNT(id)
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_category_id = @cookie_category_id
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"cookie_category_id": cookieCategoryID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
row := conn.QueryRow(ctx, q, args)
|
|
||||||
|
|
||||||
var count int
|
|
||||||
if err := row.Scan(&count); err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot scan count: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) LoadAllByCookieBannerID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
filter *CookiePatternFilter,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_banner_id = @cookie_banner_id
|
|
||||||
AND %s
|
|
||||||
ORDER BY
|
|
||||||
created_at ASC, id ASC;
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment(), filter.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"cookie_banner_id": cookieBannerID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
maps.Copy(args, filter.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
patterns, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot collect cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cps = patterns
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) Insert(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
INSERT INTO cookie_patterns (
|
|
||||||
id,
|
|
||||||
tenant_id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
) VALUES (
|
|
||||||
@id,
|
|
||||||
@tenant_id,
|
|
||||||
@organization_id,
|
|
||||||
@cookie_banner_id,
|
|
||||||
@cookie_category_id,
|
|
||||||
@pattern,
|
|
||||||
@match_type,
|
|
||||||
@display_name,
|
|
||||||
@max_age_seconds,
|
|
||||||
@description,
|
|
||||||
@source,
|
|
||||||
@excluded,
|
|
||||||
@last_matched_at,
|
|
||||||
@created_at,
|
|
||||||
@updated_at
|
|
||||||
)
|
|
||||||
`
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"id": cp.ID,
|
|
||||||
"tenant_id": scope.GetTenantID(),
|
|
||||||
"organization_id": cp.OrganizationID,
|
|
||||||
"cookie_banner_id": cp.CookieBannerID,
|
|
||||||
"cookie_category_id": cp.CookieCategoryID,
|
|
||||||
"pattern": cp.Pattern,
|
|
||||||
"match_type": cp.MatchType,
|
|
||||||
"display_name": cp.DisplayName,
|
|
||||||
"max_age_seconds": cp.MaxAgeSeconds,
|
|
||||||
"description": cp.Description,
|
|
||||||
"source": cp.Source,
|
|
||||||
"excluded": cp.Excluded,
|
|
||||||
"last_matched_at": cp.LastMatchedAt,
|
|
||||||
"created_at": cp.CreatedAt,
|
|
||||||
"updated_at": cp.UpdatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
if pgErr, ok := errors.AsType[*pgconn.PgError](err); ok {
|
|
||||||
if pgErr.Code == "23505" && pgErr.ConstraintName == "idx_cookie_patterns_unique_pattern_per_banner" {
|
|
||||||
return ErrResourceAlreadyExists
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot insert cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) InsertIfNotExists(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
) (bool, error) {
|
|
||||||
q := `
|
|
||||||
INSERT INTO cookie_patterns (
|
|
||||||
id,
|
|
||||||
tenant_id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
) VALUES (
|
|
||||||
@id,
|
|
||||||
@tenant_id,
|
|
||||||
@organization_id,
|
|
||||||
@cookie_banner_id,
|
|
||||||
@cookie_category_id,
|
|
||||||
@pattern,
|
|
||||||
@match_type,
|
|
||||||
@display_name,
|
|
||||||
@max_age_seconds,
|
|
||||||
@description,
|
|
||||||
@source,
|
|
||||||
@excluded,
|
|
||||||
@last_matched_at,
|
|
||||||
@created_at,
|
|
||||||
@updated_at
|
|
||||||
)
|
|
||||||
ON CONFLICT (cookie_banner_id, pattern) DO NOTHING
|
|
||||||
`
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"id": cp.ID,
|
|
||||||
"tenant_id": scope.GetTenantID(),
|
|
||||||
"organization_id": cp.OrganizationID,
|
|
||||||
"cookie_banner_id": cp.CookieBannerID,
|
|
||||||
"cookie_category_id": cp.CookieCategoryID,
|
|
||||||
"pattern": cp.Pattern,
|
|
||||||
"match_type": cp.MatchType,
|
|
||||||
"display_name": cp.DisplayName,
|
|
||||||
"max_age_seconds": cp.MaxAgeSeconds,
|
|
||||||
"description": cp.Description,
|
|
||||||
"source": cp.Source,
|
|
||||||
"excluded": cp.Excluded,
|
|
||||||
"last_matched_at": cp.LastMatchedAt,
|
|
||||||
"created_at": cp.CreatedAt,
|
|
||||||
"updated_at": cp.UpdatedAt,
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("cannot insert cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.RowsAffected() > 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) Update(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
UPDATE cookie_patterns
|
|
||||||
SET
|
|
||||||
cookie_category_id = @cookie_category_id,
|
|
||||||
display_name = @display_name,
|
|
||||||
max_age_seconds = @max_age_seconds,
|
|
||||||
description = @description,
|
|
||||||
excluded = @excluded,
|
|
||||||
updated_at = @updated_at
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND id = @id
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"id": cp.ID,
|
|
||||||
"cookie_category_id": cp.CookieCategoryID,
|
|
||||||
"display_name": cp.DisplayName,
|
|
||||||
"max_age_seconds": cp.MaxAgeSeconds,
|
|
||||||
"description": cp.Description,
|
|
||||||
"excluded": cp.Excluded,
|
|
||||||
"updated_at": cp.UpdatedAt,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
result, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
if pgErr, ok := errors.AsType[*pgconn.PgError](err); ok {
|
|
||||||
if pgErr.Code == "23505" && pgErr.ConstraintName == "idx_cookie_patterns_unique_pattern_per_banner" {
|
|
||||||
return ErrResourceAlreadyExists
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("cannot update cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected() == 0 {
|
|
||||||
return ErrResourceNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cp *CookiePattern) Delete(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
DELETE FROM cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND id = @id
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"id": cp.ID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
_, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot delete cookie pattern: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) RefreshLastMatchedAtByCookieBannerID(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
UPDATE cookie_patterns
|
|
||||||
SET
|
|
||||||
last_matched_at = sub.max_detected
|
|
||||||
FROM (
|
|
||||||
SELECT cookie_pattern_id, MAX(last_detected_at) AS max_detected
|
|
||||||
FROM cookies
|
|
||||||
WHERE %[1]s AND cookie_banner_id = @cookie_banner_id
|
|
||||||
GROUP BY cookie_pattern_id
|
|
||||||
) sub
|
|
||||||
WHERE
|
|
||||||
cookie_patterns.id = sub.cookie_pattern_id
|
|
||||||
AND %[1]s
|
|
||||||
AND cookie_patterns.cookie_banner_id = @cookie_banner_id
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{"cookie_banner_id": cookieBannerID}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
_, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot refresh last_matched_at for banner patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) LoadUncategorisedByCookieBannerID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
cursor *page.Cursor[CookiePatternOrderField],
|
|
||||||
filter *CookiePatternFilter,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
organization_id,
|
|
||||||
cookie_banner_id,
|
|
||||||
cookie_category_id,
|
|
||||||
pattern,
|
|
||||||
match_type,
|
|
||||||
display_name,
|
|
||||||
max_age_seconds,
|
|
||||||
description,
|
|
||||||
source,
|
|
||||||
excluded,
|
|
||||||
last_matched_at,
|
|
||||||
created_at,
|
|
||||||
updated_at
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_banner_id = @cookie_banner_id
|
|
||||||
AND cookie_category_id = (
|
|
||||||
SELECT id FROM cookie_categories
|
|
||||||
WHERE cookie_banner_id = @cookie_banner_id
|
|
||||||
AND kind = @category_kind
|
|
||||||
AND %s
|
|
||||||
LIMIT 1
|
|
||||||
)
|
|
||||||
AND %s
|
|
||||||
AND %s
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment(), scope.SQLFragment(), filter.SQLFragment(), cursor.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"cookie_banner_id": cookieBannerID,
|
|
||||||
"category_kind": CookieCategoryKindUncategorised,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
maps.Copy(args, filter.SQLArguments())
|
|
||||||
maps.Copy(args, cursor.SQLArguments())
|
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot query uncategorised cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
patterns, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[CookiePattern])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot collect uncategorised cookie patterns: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
*cps = patterns
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) CountUncategorisedByCookieBannerID(
|
|
||||||
ctx context.Context,
|
|
||||||
conn pg.Querier,
|
|
||||||
scope Scoper,
|
|
||||||
cookieBannerID gid.GID,
|
|
||||||
filter *CookiePatternFilter,
|
|
||||||
) (int, error) {
|
|
||||||
q := `
|
|
||||||
SELECT
|
|
||||||
COUNT(id)
|
|
||||||
FROM
|
|
||||||
cookie_patterns
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_banner_id = @cookie_banner_id
|
|
||||||
AND cookie_category_id = (
|
|
||||||
SELECT id FROM cookie_categories
|
|
||||||
WHERE cookie_banner_id = @cookie_banner_id
|
|
||||||
AND kind = @category_kind
|
|
||||||
AND %s
|
|
||||||
LIMIT 1
|
|
||||||
)
|
|
||||||
AND %s
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment(), scope.SQLFragment(), filter.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"cookie_banner_id": cookieBannerID,
|
|
||||||
"category_kind": CookieCategoryKindUncategorised,
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
maps.Copy(args, filter.SQLArguments())
|
|
||||||
|
|
||||||
row := conn.QueryRow(ctx, q, args)
|
|
||||||
|
|
||||||
var count int
|
|
||||||
if err := row.Scan(&count); err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot scan count: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cps *CookiePatterns) MoveToCategoryByCookieCategoryID(
|
|
||||||
ctx context.Context,
|
|
||||||
tx pg.Tx,
|
|
||||||
scope Scoper,
|
|
||||||
sourceCategoryID gid.GID,
|
|
||||||
targetCategoryID gid.GID,
|
|
||||||
) error {
|
|
||||||
q := `
|
|
||||||
UPDATE cookie_patterns
|
|
||||||
SET
|
|
||||||
cookie_category_id = @target_category_id,
|
|
||||||
updated_at = @updated_at
|
|
||||||
WHERE
|
|
||||||
%s
|
|
||||||
AND cookie_category_id = @source_category_id
|
|
||||||
`
|
|
||||||
|
|
||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
|
||||||
"source_category_id": sourceCategoryID,
|
|
||||||
"target_category_id": targetCategoryID,
|
|
||||||
"updated_at": time.Now(),
|
|
||||||
}
|
|
||||||
maps.Copy(args, scope.SQLArguments())
|
|
||||||
|
|
||||||
_, err := tx.Exec(ctx, q, args)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("cannot move cookie patterns to category: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
package coredata
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type CookiePatternOrderField string
|
|
||||||
|
|
||||||
const (
|
|
||||||
CookiePatternOrderFieldCreatedAt CookiePatternOrderField = "CREATED_AT"
|
|
||||||
CookiePatternOrderFieldName CookiePatternOrderField = "NAME"
|
|
||||||
CookiePatternOrderFieldLastMatchedAt CookiePatternOrderField = "LAST_MATCHED_AT"
|
|
||||||
CookiePatternOrderFieldUpdatedAt CookiePatternOrderField = "UPDATED_AT"
|
|
||||||
CookiePatternOrderFieldSource CookiePatternOrderField = "SOURCE"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p CookiePatternOrderField) Column() string {
|
|
||||||
switch p {
|
|
||||||
case CookiePatternOrderFieldCreatedAt:
|
|
||||||
return "created_at"
|
|
||||||
case CookiePatternOrderFieldName:
|
|
||||||
return "display_name"
|
|
||||||
case CookiePatternOrderFieldLastMatchedAt:
|
|
||||||
return "COALESCE(last_matched_at, '0001-01-01T00:00:00Z'::timestamptz)"
|
|
||||||
case CookiePatternOrderFieldUpdatedAt:
|
|
||||||
return "updated_at"
|
|
||||||
case CookiePatternOrderFieldSource:
|
|
||||||
return "source"
|
|
||||||
}
|
|
||||||
panic(fmt.Sprintf("unsupported order by: %s", p))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p CookiePatternOrderField) IsValid() bool {
|
|
||||||
switch p {
|
|
||||||
case CookiePatternOrderFieldCreatedAt,
|
|
||||||
CookiePatternOrderFieldName,
|
|
||||||
CookiePatternOrderFieldLastMatchedAt,
|
|
||||||
CookiePatternOrderFieldUpdatedAt,
|
|
||||||
CookiePatternOrderFieldSource:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p CookiePatternOrderField) String() string {
|
|
||||||
return string(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *CookiePatternOrderField) UnmarshalText(text []byte) error {
|
|
||||||
*p = CookiePatternOrderField(text)
|
|
||||||
if !p.IsValid() {
|
|
||||||
return fmt.Errorf("%s is not a valid CookiePatternOrderField", string(text))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p CookiePatternOrderField) MarshalText() ([]byte, error) {
|
|
||||||
return []byte(p.String()), nil
|
|
||||||
}
|
|
||||||
@@ -111,7 +111,7 @@ const (
|
|||||||
CookieEntityType uint16 = 85
|
CookieEntityType uint16 = 85
|
||||||
CookieBannerTranslationEntityType uint16 = 86
|
CookieBannerTranslationEntityType uint16 = 86
|
||||||
AgentRunEntityType uint16 = 87
|
AgentRunEntityType uint16 = 87
|
||||||
CookiePatternEntityType uint16 = 88
|
_ uint16 = 88 // CookiePatternEntityType - removed
|
||||||
TrackerPatternEntityType uint16 = 89
|
TrackerPatternEntityType uint16 = 89
|
||||||
DetectedTrackerEntityType uint16 = 90
|
DetectedTrackerEntityType uint16 = 90
|
||||||
)
|
)
|
||||||
@@ -282,8 +282,6 @@ func NewEntityFromID(id gid.GID) (any, bool) {
|
|||||||
return &CookieBannerTranslation{ID: id}, true
|
return &CookieBannerTranslation{ID: id}, true
|
||||||
case AgentRunEntityType:
|
case AgentRunEntityType:
|
||||||
return &AgentRun{ID: id}, true
|
return &AgentRun{ID: id}, true
|
||||||
case CookiePatternEntityType:
|
|
||||||
return &CookiePattern{ID: id}, true
|
|
||||||
case TrackerPatternEntityType:
|
case TrackerPatternEntityType:
|
||||||
return &TrackerPattern{ID: id}, true
|
return &TrackerPattern{ID: id}, true
|
||||||
case DetectedTrackerEntityType:
|
case DetectedTrackerEntityType:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type (
|
|||||||
CookieCategoryID gid.GID `db:"cookie_category_id"`
|
CookieCategoryID gid.GID `db:"cookie_category_id"`
|
||||||
TrackerType TrackerType `db:"tracker_type"`
|
TrackerType TrackerType `db:"tracker_type"`
|
||||||
Pattern string `db:"pattern"`
|
Pattern string `db:"pattern"`
|
||||||
MatchType CookiePatternMatchType `db:"match_type"`
|
MatchType TrackerPatternMatchType `db:"match_type"`
|
||||||
DisplayName string `db:"display_name"`
|
DisplayName string `db:"display_name"`
|
||||||
Description string `db:"description"`
|
Description string `db:"description"`
|
||||||
Excluded bool `db:"excluded"`
|
Excluded bool `db:"excluded"`
|
||||||
@@ -50,20 +50,20 @@ type (
|
|||||||
TrackerPatterns []*TrackerPattern
|
TrackerPatterns []*TrackerPattern
|
||||||
)
|
)
|
||||||
|
|
||||||
func (tp *TrackerPattern) CursorKey(field CookiePatternOrderField) page.CursorKey {
|
func (tp *TrackerPattern) CursorKey(field TrackerPatternOrderField) page.CursorKey {
|
||||||
switch field {
|
switch field {
|
||||||
case CookiePatternOrderFieldCreatedAt:
|
case TrackerPatternOrderFieldCreatedAt:
|
||||||
return page.NewCursorKey(tp.ID, tp.CreatedAt)
|
return page.NewCursorKey(tp.ID, tp.CreatedAt)
|
||||||
case CookiePatternOrderFieldName:
|
case TrackerPatternOrderFieldName:
|
||||||
return page.NewCursorKey(tp.ID, tp.DisplayName)
|
return page.NewCursorKey(tp.ID, tp.DisplayName)
|
||||||
case CookiePatternOrderFieldLastMatchedAt:
|
case TrackerPatternOrderFieldLastMatchedAt:
|
||||||
if tp.LastMatchedAt == nil {
|
if tp.LastMatchedAt == nil {
|
||||||
return page.NewCursorKey(tp.ID, time.Time{})
|
return page.NewCursorKey(tp.ID, time.Time{})
|
||||||
}
|
}
|
||||||
return page.NewCursorKey(tp.ID, *tp.LastMatchedAt)
|
return page.NewCursorKey(tp.ID, *tp.LastMatchedAt)
|
||||||
case CookiePatternOrderFieldUpdatedAt:
|
case TrackerPatternOrderFieldUpdatedAt:
|
||||||
return page.NewCursorKey(tp.ID, tp.UpdatedAt)
|
return page.NewCursorKey(tp.ID, tp.UpdatedAt)
|
||||||
case CookiePatternOrderFieldSource:
|
case TrackerPatternOrderFieldSource:
|
||||||
if tp.Source == nil {
|
if tp.Source == nil {
|
||||||
return page.NewCursorKey(tp.ID, "")
|
return page.NewCursorKey(tp.ID, "")
|
||||||
}
|
}
|
||||||
@@ -254,8 +254,8 @@ LIMIT 1;
|
|||||||
"cookie_banner_id": cookieBannerID,
|
"cookie_banner_id": cookieBannerID,
|
||||||
"tracker_type": trackerType,
|
"tracker_type": trackerType,
|
||||||
"identifier": identifier,
|
"identifier": identifier,
|
||||||
"match_type_prefix": CookiePatternMatchTypePrefix,
|
"match_type_prefix": TrackerPatternMatchTypePrefix,
|
||||||
"match_type_exact": CookiePatternMatchTypeExact,
|
"match_type_exact": TrackerPatternMatchTypeExact,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
@@ -504,7 +504,7 @@ func (tps *TrackerPatterns) LoadAllByCookieBannerID(
|
|||||||
conn pg.Querier,
|
conn pg.Querier,
|
||||||
scope Scoper,
|
scope Scoper,
|
||||||
cookieBannerID gid.GID,
|
cookieBannerID gid.GID,
|
||||||
filter *CookiePatternFilter,
|
filter *TrackerPatternFilter,
|
||||||
trackerType *TrackerType,
|
trackerType *TrackerType,
|
||||||
) error {
|
) error {
|
||||||
trackerTypeFragment := "TRUE"
|
trackerTypeFragment := "TRUE"
|
||||||
@@ -605,8 +605,8 @@ func (tps *TrackerPatterns) LoadUncategorisedByCookieBannerID(
|
|||||||
conn pg.Querier,
|
conn pg.Querier,
|
||||||
scope Scoper,
|
scope Scoper,
|
||||||
cookieBannerID gid.GID,
|
cookieBannerID gid.GID,
|
||||||
cursor *page.Cursor[CookiePatternOrderField],
|
cursor *page.Cursor[TrackerPatternOrderField],
|
||||||
filter *CookiePatternFilter,
|
filter *TrackerPatternFilter,
|
||||||
) error {
|
) error {
|
||||||
q := `
|
q := `
|
||||||
SELECT
|
SELECT
|
||||||
@@ -671,7 +671,7 @@ func (tps *TrackerPatterns) CountUncategorisedByCookieBannerID(
|
|||||||
conn pg.Querier,
|
conn pg.Querier,
|
||||||
scope Scoper,
|
scope Scoper,
|
||||||
cookieBannerID gid.GID,
|
cookieBannerID gid.GID,
|
||||||
filter *CookiePatternFilter,
|
filter *TrackerPatternFilter,
|
||||||
) (int, error) {
|
) (int, error) {
|
||||||
q := `
|
q := `
|
||||||
SELECT
|
SELECT
|
||||||
@@ -709,3 +709,120 @@ WHERE
|
|||||||
|
|
||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tps *TrackerPatterns) LoadByCookieCategoryID(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Querier,
|
||||||
|
scope Scoper,
|
||||||
|
cookieCategoryID gid.GID,
|
||||||
|
cursor *page.Cursor[TrackerPatternOrderField],
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
organization_id,
|
||||||
|
cookie_banner_id,
|
||||||
|
cookie_category_id,
|
||||||
|
tracker_type,
|
||||||
|
pattern,
|
||||||
|
match_type,
|
||||||
|
display_name,
|
||||||
|
description,
|
||||||
|
excluded,
|
||||||
|
max_age_seconds,
|
||||||
|
source,
|
||||||
|
last_matched_at,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM
|
||||||
|
tracker_patterns
|
||||||
|
WHERE
|
||||||
|
%s
|
||||||
|
AND cookie_category_id = @cookie_category_id
|
||||||
|
AND %s
|
||||||
|
`
|
||||||
|
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.StrictNamedArgs{"cookie_category_id": cookieCategoryID}
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
maps.Copy(args, cursor.SQLArguments())
|
||||||
|
|
||||||
|
rows, err := conn.Query(ctx, q, args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot query tracker patterns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
patterns, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[TrackerPattern])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot collect tracker patterns: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*tps = patterns
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tps *TrackerPatterns) CountByCookieCategoryID(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Querier,
|
||||||
|
scope Scoper,
|
||||||
|
cookieCategoryID gid.GID,
|
||||||
|
) (int, error) {
|
||||||
|
q := `
|
||||||
|
SELECT
|
||||||
|
COUNT(id)
|
||||||
|
FROM
|
||||||
|
tracker_patterns
|
||||||
|
WHERE
|
||||||
|
%s
|
||||||
|
AND cookie_category_id = @cookie_category_id
|
||||||
|
`
|
||||||
|
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.StrictNamedArgs{"cookie_category_id": cookieCategoryID}
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
row := conn.QueryRow(ctx, q, args)
|
||||||
|
|
||||||
|
var count int
|
||||||
|
if err := row.Scan(&count); err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot scan count: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return count, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tps *TrackerPatterns) MoveToCategoryByCookieCategoryID(
|
||||||
|
ctx context.Context,
|
||||||
|
tx pg.Tx,
|
||||||
|
scope Scoper,
|
||||||
|
sourceCategoryID gid.GID,
|
||||||
|
targetCategoryID gid.GID,
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
UPDATE tracker_patterns
|
||||||
|
SET
|
||||||
|
cookie_category_id = @target_category_id,
|
||||||
|
updated_at = @updated_at
|
||||||
|
WHERE
|
||||||
|
%s
|
||||||
|
AND cookie_category_id = @source_category_id
|
||||||
|
`
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.StrictNamedArgs{
|
||||||
|
"source_category_id": sourceCategoryID,
|
||||||
|
"target_category_id": targetCategoryID,
|
||||||
|
"updated_at": time.Now(),
|
||||||
|
}
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
_, err := tx.Exec(ctx, q, args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot move tracker patterns to category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,37 +19,37 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CookiePatternFilter struct {
|
type TrackerPatternFilter struct {
|
||||||
matchType *CookiePatternMatchType
|
matchType *TrackerPatternMatchType
|
||||||
cookieCategoryID *gid.GID
|
cookieCategoryID *gid.GID
|
||||||
excluded *bool
|
excluded *bool
|
||||||
query *string
|
query *string
|
||||||
source *CookieSource
|
source *CookieSource
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCookiePatternFilter(
|
func NewTrackerPatternFilter(
|
||||||
matchType *CookiePatternMatchType,
|
matchType *TrackerPatternMatchType,
|
||||||
cookieCategoryID *gid.GID,
|
cookieCategoryID *gid.GID,
|
||||||
excluded *bool,
|
excluded *bool,
|
||||||
) *CookiePatternFilter {
|
) *TrackerPatternFilter {
|
||||||
return &CookiePatternFilter{
|
return &TrackerPatternFilter{
|
||||||
matchType: matchType,
|
matchType: matchType,
|
||||||
cookieCategoryID: cookieCategoryID,
|
cookieCategoryID: cookieCategoryID,
|
||||||
excluded: excluded,
|
excluded: excluded,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *CookiePatternFilter) WithQuery(query *string) *CookiePatternFilter {
|
func (f *TrackerPatternFilter) WithQuery(query *string) *TrackerPatternFilter {
|
||||||
f.query = query
|
f.query = query
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *CookiePatternFilter) WithSource(source *CookieSource) *CookiePatternFilter {
|
func (f *TrackerPatternFilter) WithSource(source *CookieSource) *TrackerPatternFilter {
|
||||||
f.source = source
|
f.source = source
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *CookiePatternFilter) SQLFragment() string {
|
func (f *TrackerPatternFilter) SQLFragment() string {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return "TRUE"
|
return "TRUE"
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ func (f *CookiePatternFilter) SQLFragment() string {
|
|||||||
)`
|
)`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *CookiePatternFilter) SQLArguments() pgx.StrictNamedArgs {
|
func (f *TrackerPatternFilter) SQLArguments() pgx.StrictNamedArgs {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return pgx.StrictNamedArgs{}
|
return pgx.StrictNamedArgs{}
|
||||||
}
|
}
|
||||||
@@ -19,25 +19,25 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CookiePatternMatchType string
|
type TrackerPatternMatchType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CookiePatternMatchTypeExact CookiePatternMatchType = "EXACT"
|
TrackerPatternMatchTypeExact TrackerPatternMatchType = "EXACT"
|
||||||
CookiePatternMatchTypePrefix CookiePatternMatchType = "PREFIX"
|
TrackerPatternMatchTypePrefix TrackerPatternMatchType = "PREFIX"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CookiePatternMatchTypes() []CookiePatternMatchType {
|
func TrackerPatternMatchTypes() []TrackerPatternMatchType {
|
||||||
return []CookiePatternMatchType{
|
return []TrackerPatternMatchType{
|
||||||
CookiePatternMatchTypeExact,
|
TrackerPatternMatchTypeExact,
|
||||||
CookiePatternMatchTypePrefix,
|
TrackerPatternMatchTypePrefix,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m CookiePatternMatchType) String() string {
|
func (m TrackerPatternMatchType) String() string {
|
||||||
return string(m)
|
return string(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CookiePatternMatchType) Scan(value any) error {
|
func (m *TrackerPatternMatchType) Scan(value any) error {
|
||||||
var v string
|
var v string
|
||||||
switch val := value.(type) {
|
switch val := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
@@ -45,26 +45,26 @@ func (m *CookiePatternMatchType) Scan(value any) error {
|
|||||||
case []byte:
|
case []byte:
|
||||||
v = string(val)
|
v = string(val)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported type for CookiePatternMatchType: %T", value)
|
return fmt.Errorf("unsupported type for TrackerPatternMatchType: %T", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch CookiePatternMatchType(v) {
|
switch TrackerPatternMatchType(v) {
|
||||||
case CookiePatternMatchTypeExact:
|
case TrackerPatternMatchTypeExact:
|
||||||
*m = CookiePatternMatchTypeExact
|
*m = TrackerPatternMatchTypeExact
|
||||||
case CookiePatternMatchTypePrefix:
|
case TrackerPatternMatchTypePrefix:
|
||||||
*m = CookiePatternMatchTypePrefix
|
*m = TrackerPatternMatchTypePrefix
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid CookiePatternMatchType value: %q", v)
|
return fmt.Errorf("invalid TrackerPatternMatchType value: %q", v)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m CookiePatternMatchType) Value() (driver.Value, error) {
|
func (m TrackerPatternMatchType) Value() (driver.Value, error) {
|
||||||
switch m {
|
switch m {
|
||||||
case CookiePatternMatchTypeExact,
|
case TrackerPatternMatchTypeExact,
|
||||||
CookiePatternMatchTypePrefix:
|
TrackerPatternMatchTypePrefix:
|
||||||
return string(m), nil
|
return string(m), nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid CookiePatternMatchType: %s", m)
|
return nil, fmt.Errorf("invalid TrackerPatternMatchType: %s", m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
71
pkg/coredata/tracker_pattern_order_field.go
Normal file
71
pkg/coredata/tracker_pattern_order_field.go
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package coredata
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type TrackerPatternOrderField string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TrackerPatternOrderFieldCreatedAt TrackerPatternOrderField = "CREATED_AT"
|
||||||
|
TrackerPatternOrderFieldName TrackerPatternOrderField = "NAME"
|
||||||
|
TrackerPatternOrderFieldLastMatchedAt TrackerPatternOrderField = "LAST_MATCHED_AT"
|
||||||
|
TrackerPatternOrderFieldUpdatedAt TrackerPatternOrderField = "UPDATED_AT"
|
||||||
|
TrackerPatternOrderFieldSource TrackerPatternOrderField = "SOURCE"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p TrackerPatternOrderField) Column() string {
|
||||||
|
switch p {
|
||||||
|
case TrackerPatternOrderFieldCreatedAt:
|
||||||
|
return "created_at"
|
||||||
|
case TrackerPatternOrderFieldName:
|
||||||
|
return "display_name"
|
||||||
|
case TrackerPatternOrderFieldLastMatchedAt:
|
||||||
|
return "COALESCE(last_matched_at, '0001-01-01T00:00:00Z'::timestamptz)"
|
||||||
|
case TrackerPatternOrderFieldUpdatedAt:
|
||||||
|
return "updated_at"
|
||||||
|
case TrackerPatternOrderFieldSource:
|
||||||
|
return "source"
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("unsupported order by: %s", p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p TrackerPatternOrderField) IsValid() bool {
|
||||||
|
switch p {
|
||||||
|
case TrackerPatternOrderFieldCreatedAt,
|
||||||
|
TrackerPatternOrderFieldName,
|
||||||
|
TrackerPatternOrderFieldLastMatchedAt,
|
||||||
|
TrackerPatternOrderFieldUpdatedAt,
|
||||||
|
TrackerPatternOrderFieldSource:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p TrackerPatternOrderField) String() string {
|
||||||
|
return string(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *TrackerPatternOrderField) UnmarshalText(text []byte) error {
|
||||||
|
*p = TrackerPatternOrderField(text)
|
||||||
|
if !p.IsValid() {
|
||||||
|
return fmt.Errorf("%s is not a valid TrackerPatternOrderField", string(text))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p TrackerPatternOrderField) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(p.String()), nil
|
||||||
|
}
|
||||||
@@ -403,12 +403,12 @@ const (
|
|||||||
ActionCookieUpdate = "core:cookie:update"
|
ActionCookieUpdate = "core:cookie:update"
|
||||||
ActionCookieDelete = "core:cookie:delete"
|
ActionCookieDelete = "core:cookie:delete"
|
||||||
|
|
||||||
// CookiePattern actions
|
// TrackerPattern actions
|
||||||
ActionCookiePatternGet = "core:cookie-pattern:get"
|
ActionTrackerPatternGet = "core:tracker-pattern:get"
|
||||||
ActionCookiePatternList = "core:cookie-pattern:list"
|
ActionTrackerPatternList = "core:tracker-pattern:list"
|
||||||
ActionCookiePatternCreate = "core:cookie-pattern:create"
|
ActionTrackerPatternCreate = "core:tracker-pattern:create"
|
||||||
ActionCookiePatternUpdate = "core:cookie-pattern:update"
|
ActionTrackerPatternUpdate = "core:tracker-pattern:update"
|
||||||
ActionCookiePatternDelete = "core:cookie-pattern:delete"
|
ActionTrackerPatternDelete = "core:tracker-pattern:delete"
|
||||||
|
|
||||||
// CookieConsentRecord actions
|
// CookieConsentRecord actions
|
||||||
ActionCookieConsentRecordList = "core:cookie-consent-record:list"
|
ActionCookieConsentRecordList = "core:cookie-consent-record:list"
|
||||||
|
|||||||
@@ -177,54 +177,18 @@ func (r *cookieBannerResolver) ConsentRecords(ctx context.Context, obj *types.Co
|
|||||||
return types.NewCookieConsentRecordConnection(p, r, obj.ID, coredataFilter), nil
|
return types.NewCookieConsentRecordConnection(p, r, obj.ID, coredataFilter), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UncategorisedPatterns is the resolver for the uncategorisedPatterns field.
|
|
||||||
func (r *cookieBannerResolver) UncategorisedPatterns(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookiePatternOrderBy, filter *types.CookiePatternFilter) (*types.CookiePatternConnection, error) {
|
|
||||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookiePatternList); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.CookiePatternOrderField]{
|
|
||||||
Field: coredata.CookiePatternOrderFieldName,
|
|
||||||
Direction: page.OrderDirectionAsc,
|
|
||||||
}
|
|
||||||
if orderBy != nil {
|
|
||||||
pageOrderBy = page.OrderBy[coredata.CookiePatternOrderField]{
|
|
||||||
Field: orderBy.Field,
|
|
||||||
Direction: orderBy.Direction,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
|
||||||
|
|
||||||
coredataFilter := coredata.NewCookiePatternFilter(nil, nil, nil)
|
|
||||||
if filter != nil {
|
|
||||||
coredataFilter = coredataFilter.WithQuery(filter.Query).WithSource(filter.Source)
|
|
||||||
}
|
|
||||||
|
|
||||||
patterns, err := r.cookieBanner.ListUncategorisedCookiePatterns(ctx, scope, obj.ID, cursor, coredataFilter)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot list uncategorised cookie patterns", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
p := page.NewPage(patterns, cursor)
|
|
||||||
|
|
||||||
return types.NewCookiePatternConnectionWithFilter(p, r, obj.ID, coredataFilter), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UncategorisedTrackerPatterns is the resolver for the uncategorisedTrackerPatterns field.
|
// UncategorisedTrackerPatterns is the resolver for the uncategorisedTrackerPatterns field.
|
||||||
func (r *cookieBannerResolver) UncategorisedTrackerPatterns(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerPatternOrderBy, filter *types.TrackerPatternFilter) (*types.TrackerPatternConnection, error) {
|
func (r *cookieBannerResolver) UncategorisedTrackerPatterns(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerPatternOrderBy, filter *types.TrackerPatternFilter) (*types.TrackerPatternConnection, error) {
|
||||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookiePatternList); err != nil {
|
if err := r.authorize(ctx, obj.ID, probo.ActionTrackerPatternList); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.CookiePatternOrderField]{
|
pageOrderBy := page.OrderBy[coredata.TrackerPatternOrderField]{
|
||||||
Field: coredata.CookiePatternOrderFieldName,
|
Field: coredata.TrackerPatternOrderFieldName,
|
||||||
Direction: page.OrderDirectionAsc,
|
Direction: page.OrderDirectionAsc,
|
||||||
}
|
}
|
||||||
if orderBy != nil {
|
if orderBy != nil {
|
||||||
pageOrderBy = page.OrderBy[coredata.CookiePatternOrderField]{
|
pageOrderBy = page.OrderBy[coredata.TrackerPatternOrderField]{
|
||||||
Field: orderBy.Field,
|
Field: orderBy.Field,
|
||||||
Direction: orderBy.Direction,
|
Direction: orderBy.Direction,
|
||||||
}
|
}
|
||||||
@@ -233,7 +197,7 @@ func (r *cookieBannerResolver) UncategorisedTrackerPatterns(ctx context.Context,
|
|||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||||
|
|
||||||
coredataFilter := coredata.NewCookiePatternFilter(nil, nil, nil)
|
coredataFilter := coredata.NewTrackerPatternFilter(nil, nil, nil)
|
||||||
if filter != nil {
|
if filter != nil {
|
||||||
coredataFilter = coredataFilter.WithQuery(filter.Query).WithSource(filter.Source)
|
coredataFilter = coredataFilter.WithQuery(filter.Query).WithSource(filter.Source)
|
||||||
}
|
}
|
||||||
@@ -338,18 +302,18 @@ func (r *cookieCategoryResolver) CookieBanner(ctx context.Context, obj *types.Co
|
|||||||
return types.NewCookieBanner(banner), nil
|
return types.NewCookieBanner(banner), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CookiePatterns is the resolver for the cookiePatterns field.
|
// TrackerPatterns is the resolver for the trackerPatterns field.
|
||||||
func (r *cookieCategoryResolver) CookiePatterns(ctx context.Context, obj *types.CookieCategory, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookiePatternOrderBy) (*types.CookiePatternConnection, error) {
|
func (r *cookieCategoryResolver) TrackerPatterns(ctx context.Context, obj *types.CookieCategory, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TrackerPatternOrderBy) (*types.TrackerPatternConnection, error) {
|
||||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookiePatternList); err != nil {
|
if err := r.authorize(ctx, obj.ID, probo.ActionTrackerPatternList); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pageOrderBy := page.OrderBy[coredata.CookiePatternOrderField]{
|
pageOrderBy := page.OrderBy[coredata.TrackerPatternOrderField]{
|
||||||
Field: coredata.CookiePatternOrderFieldCreatedAt,
|
Field: coredata.TrackerPatternOrderFieldCreatedAt,
|
||||||
Direction: page.OrderDirectionAsc,
|
Direction: page.OrderDirectionAsc,
|
||||||
}
|
}
|
||||||
if orderBy != nil {
|
if orderBy != nil {
|
||||||
pageOrderBy = page.OrderBy[coredata.CookiePatternOrderField]{
|
pageOrderBy = page.OrderBy[coredata.TrackerPatternOrderField]{
|
||||||
Field: orderBy.Field,
|
Field: orderBy.Field,
|
||||||
Direction: orderBy.Direction,
|
Direction: orderBy.Direction,
|
||||||
}
|
}
|
||||||
@@ -358,15 +322,15 @@ func (r *cookieCategoryResolver) CookiePatterns(ctx context.Context, obj *types.
|
|||||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||||
|
|
||||||
patterns, err := r.cookieBanner.ListCookiePatternsForCategory(ctx, scope, obj.ID, cursor)
|
patterns, err := r.cookieBanner.ListTrackerPatternsForCategory(ctx, scope, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.logger.ErrorCtx(ctx, "cannot list cookie patterns", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot list tracker patterns", log.Error(err))
|
||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := page.NewPage(patterns, cursor)
|
p := page.NewPage(patterns, cursor)
|
||||||
|
|
||||||
return types.NewCookiePatternConnection(p, r, obj.ID), nil
|
return types.NewTrackerPatternConnection(p, r, obj.ID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permission is the resolver for the permission field.
|
// Permission is the resolver for the permission field.
|
||||||
@@ -391,74 +355,6 @@ func (r *cookieCategoryConnectionResolver) TotalCount(ctx context.Context, obj *
|
|||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CookieCategory is the resolver for the cookieCategory field.
|
|
||||||
func (r *cookiePatternResolver) CookieCategory(ctx context.Context, obj *types.CookiePattern) (*types.CookieCategory, error) {
|
|
||||||
if err := r.authorize(ctx, obj.CookieCategory.ID, probo.ActionCookieCategoryGet); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
loaders := dataloader.FromContext(ctx)
|
|
||||||
|
|
||||||
category, err := loaders.CookieCategory.Load(ctx, obj.CookieCategory.ID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, coredata.ErrResourceNotFound) || errors.Is(err, dataloadgen.ErrNotFound) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get cookie category", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return types.NewCookieCategory(category), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CookieCount is the resolver for the cookieCount field.
|
|
||||||
func (r *cookiePatternResolver) CookieCount(ctx context.Context, obj *types.CookiePattern) (int, error) {
|
|
||||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookiePatternGet); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
|
||||||
|
|
||||||
count, err := r.cookieBanner.CountCookiesForPattern(ctx, scope, obj.ID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot count cookies for pattern", log.Error(err))
|
|
||||||
return 0, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Permission is the resolver for the permission field.
|
|
||||||
func (r *cookiePatternResolver) Permission(ctx context.Context, obj *types.CookiePattern, action string) (bool, error) {
|
|
||||||
return r.Resolver.Permission(ctx, obj, action)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TotalCount is the resolver for the totalCount field.
|
|
||||||
func (r *cookiePatternConnectionResolver) TotalCount(ctx context.Context, obj *types.CookiePatternConnection) (int, error) {
|
|
||||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionCookiePatternList); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
|
||||||
|
|
||||||
switch obj.Resolver.(type) {
|
|
||||||
case *cookieBannerResolver:
|
|
||||||
count, err := r.cookieBanner.CountUncategorisedCookiePatterns(ctx, scope, obj.ParentID, obj.Filter)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot count uncategorised cookie patterns", log.Error(err))
|
|
||||||
return 0, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
return count, nil
|
|
||||||
default:
|
|
||||||
count, err := r.cookieBanner.CountCookiePatternsForCategory(ctx, scope, obj.ParentID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot count cookie patterns", log.Error(err))
|
|
||||||
return 0, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateCookieBanner is the resolver for the createCookieBanner field.
|
// CreateCookieBanner is the resolver for the createCookieBanner field.
|
||||||
func (r *mutationResolver) CreateCookieBanner(ctx context.Context, input types.CreateCookieBannerInput) (*types.CreateCookieBannerPayload, error) {
|
func (r *mutationResolver) CreateCookieBanner(ctx context.Context, input types.CreateCookieBannerInput) (*types.CreateCookieBannerPayload, error) {
|
||||||
if err := r.authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate); err != nil {
|
if err := r.authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate); err != nil {
|
||||||
@@ -819,180 +715,6 @@ func (r *mutationResolver) ReorderCookieCategory(ctx context.Context, input type
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCookiePattern is the resolver for the createCookiePattern field.
|
|
||||||
func (r *mutationResolver) CreateCookiePattern(ctx context.Context, input types.CreateCookiePatternInput) (*types.CreateCookiePatternPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookiePatternCreate); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
|
||||||
|
|
||||||
pattern, err := r.cookieBanner.CreateCookiePattern(
|
|
||||||
ctx,
|
|
||||||
scope,
|
|
||||||
cookiebanner.CreateCookiePatternRequest{
|
|
||||||
CookieCategoryID: input.CookieCategoryID,
|
|
||||||
Pattern: input.Pattern,
|
|
||||||
MatchType: input.MatchType,
|
|
||||||
DisplayName: input.DisplayName,
|
|
||||||
MaxAgeSeconds: input.MaxAgeSeconds,
|
|
||||||
Description: input.Description,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, cookiebanner.ErrPatternAlreadyExists) {
|
|
||||||
return nil, gqlutils.Conflict(ctx, err)
|
|
||||||
}
|
|
||||||
if errors.Is(err, cookiebanner.ErrCategoryNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
||||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot create cookie pattern", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
bannerScope := coredata.NewScopeFromObjectID(pattern.CookieBannerID)
|
|
||||||
banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, pattern.CookieBannerID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.CreateCookiePatternPayload{
|
|
||||||
CookiePatternEdge: types.NewCookiePatternEdge(pattern, coredata.CookiePatternOrderFieldCreatedAt),
|
|
||||||
CookieBanner: types.NewCookieBanner(banner),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateCookiePattern is the resolver for the updateCookiePattern field.
|
|
||||||
func (r *mutationResolver) UpdateCookiePattern(ctx context.Context, input types.UpdateCookiePatternInput) (*types.UpdateCookiePatternPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.CookiePatternID, probo.ActionCookiePatternUpdate); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookiePatternID)
|
|
||||||
|
|
||||||
pattern, err := r.cookieBanner.UpdateCookiePattern(
|
|
||||||
ctx,
|
|
||||||
scope,
|
|
||||||
cookiebanner.UpdateCookiePatternRequest{
|
|
||||||
CookiePatternID: input.CookiePatternID,
|
|
||||||
DisplayName: input.DisplayName,
|
|
||||||
MaxAgeSeconds: gqlutils.UnwrapOmittable(input.MaxAgeSeconds),
|
|
||||||
Description: input.Description,
|
|
||||||
Excluded: input.Excluded,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, cookiebanner.ErrCookiePatternNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
||||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot update cookie pattern", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
bannerScope := coredata.NewScopeFromObjectID(pattern.CookieBannerID)
|
|
||||||
banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, pattern.CookieBannerID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.UpdateCookiePatternPayload{
|
|
||||||
CookiePattern: types.NewCookiePattern(pattern),
|
|
||||||
CookieBanner: types.NewCookieBanner(banner),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteCookiePattern is the resolver for the deleteCookiePattern field.
|
|
||||||
func (r *mutationResolver) DeleteCookiePattern(ctx context.Context, input types.DeleteCookiePatternInput) (*types.DeleteCookiePatternPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.CookiePatternID, probo.ActionCookiePatternDelete); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookiePatternID)
|
|
||||||
|
|
||||||
pattern, err := r.cookieBanner.GetCookiePattern(ctx, scope, input.CookiePatternID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, cookiebanner.ErrCookieNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get cookie pattern", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
bannerID := pattern.CookieBannerID
|
|
||||||
|
|
||||||
err = r.cookieBanner.DeleteCookiePattern(ctx, scope, input.CookiePatternID)
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, cookiebanner.ErrCookiePatternNotFound) {
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot delete cookie pattern", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
bannerScope := coredata.NewScopeFromObjectID(bannerID)
|
|
||||||
banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, bannerID)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.DeleteCookiePatternPayload{
|
|
||||||
DeletedCookiePatternID: input.CookiePatternID,
|
|
||||||
CookieBanner: types.NewCookieBanner(banner),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MoveCookiePatternToCategory is the resolver for the moveCookiePatternToCategory field.
|
|
||||||
func (r *mutationResolver) MoveCookiePatternToCategory(ctx context.Context, input types.MoveCookiePatternToCategoryInput) (*types.MoveCookiePatternToCategoryPayload, error) {
|
|
||||||
if err := r.authorize(ctx, input.CookiePatternID, probo.ActionCookiePatternUpdate); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := r.authorize(ctx, input.TargetCookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookiePatternID)
|
|
||||||
|
|
||||||
result, err := r.cookieBanner.MoveCookiePatternToCategory(
|
|
||||||
ctx,
|
|
||||||
scope,
|
|
||||||
cookiebanner.MoveCookiePatternToCategoryRequest{
|
|
||||||
CookiePatternID: input.CookiePatternID,
|
|
||||||
TargetCookieCategoryID: input.TargetCookieCategoryID,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
switch {
|
|
||||||
case errors.Is(err, cookiebanner.ErrCategoryNotFound):
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
case errors.Is(err, cookiebanner.ErrCookiePatternNotFound):
|
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
|
||||||
case errors.Is(err, cookiebanner.ErrCategoriesBannerMismatch):
|
|
||||||
return nil, gqlutils.NotFoundf(ctx, "cookie pattern or target category not found")
|
|
||||||
default:
|
|
||||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
|
||||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
|
||||||
}
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot move cookie pattern to category", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &types.MoveCookiePatternToCategoryPayload{
|
|
||||||
CookiePattern: types.NewCookiePattern(result.CookiePattern),
|
|
||||||
CookieBanner: types.NewCookieBanner(result.Banner),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpsertCookieBannerTranslation is the resolver for the upsertCookieBannerTranslation field.
|
// UpsertCookieBannerTranslation is the resolver for the upsertCookieBannerTranslation field.
|
||||||
func (r *mutationResolver) UpsertCookieBannerTranslation(ctx context.Context, input types.UpsertCookieBannerTranslationInput) (*types.UpsertCookieBannerTranslationPayload, error) {
|
func (r *mutationResolver) UpsertCookieBannerTranslation(ctx context.Context, input types.UpsertCookieBannerTranslationInput) (*types.UpsertCookieBannerTranslationPayload, error) {
|
||||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil {
|
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil {
|
||||||
@@ -1033,9 +755,64 @@ func (r *mutationResolver) UpsertCookieBannerTranslation(ctx context.Context, in
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateTrackerPattern is the resolver for the createTrackerPattern field.
|
||||||
|
func (r *mutationResolver) CreateTrackerPattern(ctx context.Context, input types.CreateTrackerPatternInput) (*types.CreateTrackerPatternPayload, error) {
|
||||||
|
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternCreate); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||||
|
|
||||||
|
trackerType := coredata.TrackerTypeCookie
|
||||||
|
if input.TrackerType != nil {
|
||||||
|
trackerType = *input.TrackerType
|
||||||
|
}
|
||||||
|
|
||||||
|
var description string
|
||||||
|
if input.Description != nil {
|
||||||
|
description = *input.Description
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern, err := r.cookieBanner.CreateTrackerPattern(
|
||||||
|
ctx,
|
||||||
|
scope,
|
||||||
|
cookiebanner.CreateTrackerPatternRequest{
|
||||||
|
CookieCategoryID: input.CookieCategoryID,
|
||||||
|
TrackerType: trackerType,
|
||||||
|
Pattern: input.Pattern,
|
||||||
|
MatchType: input.MatchType,
|
||||||
|
DisplayName: input.DisplayName,
|
||||||
|
MaxAgeSeconds: input.MaxAgeSeconds,
|
||||||
|
Description: description,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, cookiebanner.ErrPatternAlreadyExists) {
|
||||||
|
return nil, gqlutils.Conflictf(ctx, "a pattern with this name already exists in this banner")
|
||||||
|
}
|
||||||
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||||
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||||
|
}
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot create tracker pattern", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
bannerScope := coredata.NewScopeFromObjectID(pattern.CookieBannerID)
|
||||||
|
banner, err := r.cookieBanner.GetCookieBanner(ctx, bannerScope, pattern.CookieBannerID)
|
||||||
|
if err != nil {
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot get cookie banner", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.CreateTrackerPatternPayload{
|
||||||
|
TrackerPatternEdge: types.NewTrackerPatternEdge(pattern, coredata.TrackerPatternOrderFieldCreatedAt),
|
||||||
|
CookieBanner: types.NewCookieBanner(banner),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateTrackerPattern is the resolver for the updateTrackerPattern field.
|
// UpdateTrackerPattern is the resolver for the updateTrackerPattern field.
|
||||||
func (r *mutationResolver) UpdateTrackerPattern(ctx context.Context, input types.UpdateTrackerPatternInput) (*types.UpdateTrackerPatternPayload, error) {
|
func (r *mutationResolver) UpdateTrackerPattern(ctx context.Context, input types.UpdateTrackerPatternInput) (*types.UpdateTrackerPatternPayload, error) {
|
||||||
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionCookiePatternUpdate); err != nil {
|
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,7 +830,7 @@ func (r *mutationResolver) UpdateTrackerPattern(ctx context.Context, input types
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, cookiebanner.ErrCookiePatternNotFound) {
|
if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) {
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
}
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot update tracker pattern", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot update tracker pattern", log.Error(err))
|
||||||
@@ -1075,7 +852,7 @@ func (r *mutationResolver) UpdateTrackerPattern(ctx context.Context, input types
|
|||||||
|
|
||||||
// DeleteTrackerPattern is the resolver for the deleteTrackerPattern field.
|
// DeleteTrackerPattern is the resolver for the deleteTrackerPattern field.
|
||||||
func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types.DeleteTrackerPatternInput) (*types.DeleteTrackerPatternPayload, error) {
|
func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types.DeleteTrackerPatternInput) (*types.DeleteTrackerPatternPayload, error) {
|
||||||
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionCookiePatternDelete); err != nil {
|
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternDelete); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,7 +860,7 @@ func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types
|
|||||||
|
|
||||||
pattern, err := r.cookieBanner.GetTrackerPattern(ctx, scope, input.TrackerPatternID)
|
pattern, err := r.cookieBanner.GetTrackerPattern(ctx, scope, input.TrackerPatternID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, cookiebanner.ErrCookiePatternNotFound) {
|
if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) {
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
}
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot get tracker pattern", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot get tracker pattern", log.Error(err))
|
||||||
@@ -1093,7 +870,7 @@ func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types
|
|||||||
bannerID := pattern.CookieBannerID
|
bannerID := pattern.CookieBannerID
|
||||||
|
|
||||||
if err := r.cookieBanner.DeleteTrackerPattern(ctx, scope, input.TrackerPatternID); err != nil {
|
if err := r.cookieBanner.DeleteTrackerPattern(ctx, scope, input.TrackerPatternID); err != nil {
|
||||||
if errors.Is(err, cookiebanner.ErrCookiePatternNotFound) {
|
if errors.Is(err, cookiebanner.ErrTrackerPatternNotFound) {
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
}
|
}
|
||||||
r.logger.ErrorCtx(ctx, "cannot delete tracker pattern", log.Error(err))
|
r.logger.ErrorCtx(ctx, "cannot delete tracker pattern", log.Error(err))
|
||||||
@@ -1115,7 +892,7 @@ func (r *mutationResolver) DeleteTrackerPattern(ctx context.Context, input types
|
|||||||
|
|
||||||
// MoveTrackerPatternToCategory is the resolver for the moveTrackerPatternToCategory field.
|
// MoveTrackerPatternToCategory is the resolver for the moveTrackerPatternToCategory field.
|
||||||
func (r *mutationResolver) MoveTrackerPatternToCategory(ctx context.Context, input types.MoveTrackerPatternToCategoryInput) (*types.MoveTrackerPatternToCategoryPayload, error) {
|
func (r *mutationResolver) MoveTrackerPatternToCategory(ctx context.Context, input types.MoveTrackerPatternToCategoryInput) (*types.MoveTrackerPatternToCategoryPayload, error) {
|
||||||
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionCookiePatternUpdate); err != nil {
|
if err := r.authorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,7 +914,7 @@ func (r *mutationResolver) MoveTrackerPatternToCategory(ctx context.Context, inp
|
|||||||
switch {
|
switch {
|
||||||
case errors.Is(err, cookiebanner.ErrCategoryNotFound):
|
case errors.Is(err, cookiebanner.ErrCategoryNotFound):
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
case errors.Is(err, cookiebanner.ErrCookiePatternNotFound):
|
case errors.Is(err, cookiebanner.ErrTrackerPatternNotFound):
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
return nil, gqlutils.NotFound(ctx, err)
|
||||||
case errors.Is(err, cookiebanner.ErrCategoriesBannerMismatch):
|
case errors.Is(err, cookiebanner.ErrCategoriesBannerMismatch):
|
||||||
return nil, gqlutils.NotFoundf(ctx, "tracker pattern or target category not found")
|
return nil, gqlutils.NotFoundf(ctx, "tracker pattern or target category not found")
|
||||||
@@ -1195,7 +972,7 @@ func (r *trackerPatternResolver) Permission(ctx context.Context, obj *types.Trac
|
|||||||
func (r *trackerPatternConnectionResolver) TotalCount(ctx context.Context, obj *types.TrackerPatternConnection) (int, error) {
|
func (r *trackerPatternConnectionResolver) TotalCount(ctx context.Context, obj *types.TrackerPatternConnection) (int, error) {
|
||||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
||||||
|
|
||||||
filter := coredata.NewCookiePatternFilter(nil, nil, nil)
|
filter := coredata.NewTrackerPatternFilter(nil, nil, nil)
|
||||||
if obj.Filter != nil {
|
if obj.Filter != nil {
|
||||||
filter = filter.WithQuery(obj.Filter.Query).WithSource(obj.Filter.Source)
|
filter = filter.WithQuery(obj.Filter.Query).WithSource(obj.Filter.Source)
|
||||||
}
|
}
|
||||||
@@ -1230,14 +1007,6 @@ func (r *Resolver) CookieCategoryConnection() schema.CookieCategoryConnectionRes
|
|||||||
return &cookieCategoryConnectionResolver{r}
|
return &cookieCategoryConnectionResolver{r}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CookiePattern returns schema.CookiePatternResolver implementation.
|
|
||||||
func (r *Resolver) CookiePattern() schema.CookiePatternResolver { return &cookiePatternResolver{r} }
|
|
||||||
|
|
||||||
// CookiePatternConnection returns schema.CookiePatternConnectionResolver implementation.
|
|
||||||
func (r *Resolver) CookiePatternConnection() schema.CookiePatternConnectionResolver {
|
|
||||||
return &cookiePatternConnectionResolver{r}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrackerPattern returns schema.TrackerPatternResolver implementation.
|
// TrackerPattern returns schema.TrackerPatternResolver implementation.
|
||||||
func (r *Resolver) TrackerPattern() schema.TrackerPatternResolver { return &trackerPatternResolver{r} }
|
func (r *Resolver) TrackerPattern() schema.TrackerPatternResolver { return &trackerPatternResolver{r} }
|
||||||
|
|
||||||
@@ -1251,7 +1020,5 @@ type cookieBannerConnectionResolver struct{ *Resolver }
|
|||||||
type cookieBannerVersionResolver struct{ *Resolver }
|
type cookieBannerVersionResolver struct{ *Resolver }
|
||||||
type cookieCategoryResolver struct{ *Resolver }
|
type cookieCategoryResolver struct{ *Resolver }
|
||||||
type cookieCategoryConnectionResolver struct{ *Resolver }
|
type cookieCategoryConnectionResolver struct{ *Resolver }
|
||||||
type cookiePatternResolver struct{ *Resolver }
|
|
||||||
type cookiePatternConnectionResolver struct{ *Resolver }
|
|
||||||
type trackerPatternResolver struct{ *Resolver }
|
type trackerPatternResolver struct{ *Resolver }
|
||||||
type trackerPatternConnectionResolver struct{ *Resolver }
|
type trackerPatternConnectionResolver struct{ *Resolver }
|
||||||
|
|||||||
@@ -151,15 +151,6 @@ type CookieBanner implements Node {
|
|||||||
filter: CookieConsentRecordFilter
|
filter: CookieConsentRecordFilter
|
||||||
): CookieConsentRecordConnection @goField(forceResolver: true)
|
): CookieConsentRecordConnection @goField(forceResolver: true)
|
||||||
|
|
||||||
uncategorisedPatterns(
|
|
||||||
first: Int
|
|
||||||
after: CursorKey
|
|
||||||
last: Int
|
|
||||||
before: CursorKey
|
|
||||||
orderBy: CookiePatternOrder
|
|
||||||
filter: CookiePatternFilter
|
|
||||||
): CookiePatternConnection @goField(forceResolver: true)
|
|
||||||
|
|
||||||
uncategorisedTrackerPatterns(
|
uncategorisedTrackerPatterns(
|
||||||
first: Int
|
first: Int
|
||||||
after: CursorKey
|
after: CursorKey
|
||||||
@@ -194,13 +185,13 @@ type CookieCategory implements Node {
|
|||||||
gcmConsentTypes: [String!]!
|
gcmConsentTypes: [String!]!
|
||||||
posthogConsent: Boolean!
|
posthogConsent: Boolean!
|
||||||
|
|
||||||
cookiePatterns(
|
trackerPatterns(
|
||||||
first: Int
|
first: Int
|
||||||
after: CursorKey
|
after: CursorKey
|
||||||
last: Int
|
last: Int
|
||||||
before: CursorKey
|
before: CursorKey
|
||||||
orderBy: CookiePatternOrder
|
orderBy: TrackerPatternOrder
|
||||||
): CookiePatternConnection @goField(forceResolver: true)
|
): TrackerPatternConnection @goField(forceResolver: true)
|
||||||
|
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
@@ -208,98 +199,52 @@ type CookieCategory implements Node {
|
|||||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CookiePatternMatchType
|
enum TrackerPatternMatchType
|
||||||
@goModel(
|
@goModel(
|
||||||
model: "go.probo.inc/probo/pkg/coredata.CookiePatternMatchType"
|
model: "go.probo.inc/probo/pkg/coredata.TrackerPatternMatchType"
|
||||||
) {
|
) {
|
||||||
EXACT
|
EXACT
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternMatchTypeExact"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternMatchTypeExact"
|
||||||
)
|
)
|
||||||
PREFIX
|
PREFIX
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternMatchTypePrefix"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternMatchTypePrefix"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CookiePatternOrderField
|
enum TrackerPatternOrderField
|
||||||
@goModel(
|
@goModel(
|
||||||
model: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderField"
|
model: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderField"
|
||||||
) {
|
) {
|
||||||
CREATED_AT
|
CREATED_AT
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderFieldCreatedAt"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderFieldCreatedAt"
|
||||||
)
|
)
|
||||||
NAME
|
NAME
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderFieldName"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderFieldName"
|
||||||
)
|
)
|
||||||
LAST_MATCHED_AT
|
LAST_MATCHED_AT
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderFieldLastMatchedAt"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderFieldLastMatchedAt"
|
||||||
)
|
)
|
||||||
UPDATED_AT
|
UPDATED_AT
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderFieldUpdatedAt"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderFieldUpdatedAt"
|
||||||
)
|
)
|
||||||
SOURCE
|
SOURCE
|
||||||
@goEnum(
|
@goEnum(
|
||||||
value: "go.probo.inc/probo/pkg/coredata.CookiePatternOrderFieldSource"
|
value: "go.probo.inc/probo/pkg/coredata.TrackerPatternOrderFieldSource"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
input CookiePatternOrder
|
|
||||||
@goModel(
|
|
||||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookiePatternOrderBy"
|
|
||||||
) {
|
|
||||||
direction: OrderDirection!
|
|
||||||
field: CookiePatternOrderField!
|
|
||||||
}
|
|
||||||
|
|
||||||
input CookiePatternFilter {
|
|
||||||
query: String
|
|
||||||
source: CookieSource
|
|
||||||
}
|
|
||||||
|
|
||||||
type CookiePattern implements Node {
|
|
||||||
id: ID!
|
|
||||||
cookieCategory: CookieCategory @goField(forceResolver: true)
|
|
||||||
trackerType: TrackerType!
|
|
||||||
pattern: String!
|
|
||||||
matchType: CookiePatternMatchType!
|
|
||||||
displayName: String!
|
|
||||||
maxAgeSeconds: Int
|
|
||||||
description: String!
|
|
||||||
source: CookieSource
|
|
||||||
excluded: Boolean!
|
|
||||||
cookieCount: Int! @goField(forceResolver: true)
|
|
||||||
lastMatchedAt: Datetime
|
|
||||||
createdAt: Datetime!
|
|
||||||
updatedAt: Datetime!
|
|
||||||
|
|
||||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
type CookiePatternConnection
|
|
||||||
@goModel(
|
|
||||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookiePatternConnection"
|
|
||||||
) {
|
|
||||||
totalCount: Int! @goField(forceResolver: true)
|
|
||||||
edges: [CookiePatternEdge!]!
|
|
||||||
pageInfo: PageInfo!
|
|
||||||
}
|
|
||||||
|
|
||||||
type CookiePatternEdge {
|
|
||||||
cursor: CursorKey!
|
|
||||||
node: CookiePattern!
|
|
||||||
}
|
|
||||||
|
|
||||||
type TrackerPattern implements Node {
|
type TrackerPattern implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
cookieCategory: CookieCategory @goField(forceResolver: true)
|
cookieCategory: CookieCategory @goField(forceResolver: true)
|
||||||
trackerType: TrackerType!
|
trackerType: TrackerType!
|
||||||
pattern: String!
|
pattern: String!
|
||||||
matchType: CookiePatternMatchType!
|
matchType: TrackerPatternMatchType!
|
||||||
displayName: String!
|
displayName: String!
|
||||||
maxAgeSeconds: Int
|
maxAgeSeconds: Int
|
||||||
description: String!
|
description: String!
|
||||||
@@ -332,7 +277,7 @@ input TrackerPatternOrder
|
|||||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrackerPatternOrderBy"
|
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrackerPatternOrderBy"
|
||||||
) {
|
) {
|
||||||
direction: OrderDirection!
|
direction: OrderDirection!
|
||||||
field: CookiePatternOrderField!
|
field: TrackerPatternOrderField!
|
||||||
}
|
}
|
||||||
|
|
||||||
input TrackerPatternFilter
|
input TrackerPatternFilter
|
||||||
@@ -426,21 +371,12 @@ extend type Mutation {
|
|||||||
reorderCookieCategory(
|
reorderCookieCategory(
|
||||||
input: ReorderCookieCategoryInput!
|
input: ReorderCookieCategoryInput!
|
||||||
): ReorderCookieCategoryPayload!
|
): ReorderCookieCategoryPayload!
|
||||||
createCookiePattern(
|
|
||||||
input: CreateCookiePatternInput!
|
|
||||||
): CreateCookiePatternPayload!
|
|
||||||
updateCookiePattern(
|
|
||||||
input: UpdateCookiePatternInput!
|
|
||||||
): UpdateCookiePatternPayload!
|
|
||||||
deleteCookiePattern(
|
|
||||||
input: DeleteCookiePatternInput!
|
|
||||||
): DeleteCookiePatternPayload!
|
|
||||||
moveCookiePatternToCategory(
|
|
||||||
input: MoveCookiePatternToCategoryInput!
|
|
||||||
): MoveCookiePatternToCategoryPayload!
|
|
||||||
upsertCookieBannerTranslation(
|
upsertCookieBannerTranslation(
|
||||||
input: UpsertCookieBannerTranslationInput!
|
input: UpsertCookieBannerTranslationInput!
|
||||||
): UpsertCookieBannerTranslationPayload!
|
): UpsertCookieBannerTranslationPayload!
|
||||||
|
createTrackerPattern(
|
||||||
|
input: CreateTrackerPatternInput!
|
||||||
|
): CreateTrackerPatternPayload!
|
||||||
updateTrackerPattern(
|
updateTrackerPattern(
|
||||||
input: UpdateTrackerPatternInput!
|
input: UpdateTrackerPatternInput!
|
||||||
): UpdateTrackerPatternPayload!
|
): UpdateTrackerPatternPayload!
|
||||||
@@ -558,53 +494,6 @@ type ReorderCookieCategoryPayload {
|
|||||||
cookieBanner: CookieBanner!
|
cookieBanner: CookieBanner!
|
||||||
}
|
}
|
||||||
|
|
||||||
input CreateCookiePatternInput {
|
|
||||||
cookieCategoryId: ID!
|
|
||||||
trackerType: TrackerType
|
|
||||||
pattern: String!
|
|
||||||
matchType: CookiePatternMatchType!
|
|
||||||
displayName: String!
|
|
||||||
maxAgeSeconds: Int
|
|
||||||
description: String!
|
|
||||||
}
|
|
||||||
|
|
||||||
input UpdateCookiePatternInput {
|
|
||||||
cookiePatternId: ID!
|
|
||||||
displayName: String
|
|
||||||
maxAgeSeconds: Int @goField(omittable: true)
|
|
||||||
description: String
|
|
||||||
excluded: Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
input DeleteCookiePatternInput {
|
|
||||||
cookiePatternId: ID!
|
|
||||||
}
|
|
||||||
|
|
||||||
input MoveCookiePatternToCategoryInput {
|
|
||||||
cookiePatternId: ID!
|
|
||||||
targetCookieCategoryId: ID!
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateCookiePatternPayload {
|
|
||||||
cookiePatternEdge: CookiePatternEdge!
|
|
||||||
cookieBanner: CookieBanner!
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateCookiePatternPayload {
|
|
||||||
cookiePattern: CookiePattern!
|
|
||||||
cookieBanner: CookieBanner!
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteCookiePatternPayload {
|
|
||||||
deletedCookiePatternId: ID!
|
|
||||||
cookieBanner: CookieBanner!
|
|
||||||
}
|
|
||||||
|
|
||||||
type MoveCookiePatternToCategoryPayload {
|
|
||||||
cookiePattern: CookiePattern!
|
|
||||||
cookieBanner: CookieBanner!
|
|
||||||
}
|
|
||||||
|
|
||||||
input UpsertCookieBannerTranslationInput {
|
input UpsertCookieBannerTranslationInput {
|
||||||
cookieBannerId: ID!
|
cookieBannerId: ID!
|
||||||
language: String!
|
language: String!
|
||||||
@@ -616,6 +505,16 @@ type UpsertCookieBannerTranslationPayload {
|
|||||||
cookieBanner: CookieBanner!
|
cookieBanner: CookieBanner!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input CreateTrackerPatternInput {
|
||||||
|
cookieCategoryId: ID!
|
||||||
|
trackerType: TrackerType
|
||||||
|
pattern: String!
|
||||||
|
matchType: TrackerPatternMatchType!
|
||||||
|
displayName: String!
|
||||||
|
maxAgeSeconds: Int
|
||||||
|
description: String
|
||||||
|
}
|
||||||
|
|
||||||
input UpdateTrackerPatternInput {
|
input UpdateTrackerPatternInput {
|
||||||
trackerPatternId: ID!
|
trackerPatternId: ID!
|
||||||
displayName: String
|
displayName: String
|
||||||
@@ -633,6 +532,11 @@ input MoveTrackerPatternToCategoryInput {
|
|||||||
targetCookieCategoryId: ID!
|
targetCookieCategoryId: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateTrackerPatternPayload {
|
||||||
|
trackerPatternEdge: TrackerPatternEdge!
|
||||||
|
cookieBanner: CookieBanner!
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateTrackerPatternPayload {
|
type UpdateTrackerPatternPayload {
|
||||||
trackerPattern: TrackerPattern!
|
trackerPattern: TrackerPattern!
|
||||||
cookieBanner: CookieBanner!
|
cookieBanner: CookieBanner!
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||||
// copyright notice and this permission notice appear in all copies.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
||||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
||||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
||||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
// PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
|
|
||||||
package types
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.probo.inc/probo/pkg/coredata"
|
|
||||||
"go.probo.inc/probo/pkg/gid"
|
|
||||||
"go.probo.inc/probo/pkg/page"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CookiePatternOrderBy OrderBy[coredata.CookiePatternOrderField]
|
|
||||||
|
|
||||||
CookiePatternConnection struct {
|
|
||||||
TotalCount int
|
|
||||||
Edges []*CookiePatternEdge
|
|
||||||
PageInfo PageInfo
|
|
||||||
|
|
||||||
Resolver any
|
|
||||||
ParentID gid.GID
|
|
||||||
Filter *coredata.CookiePatternFilter
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCookiePatternConnection(
|
|
||||||
p *page.Page[*coredata.CookiePattern, coredata.CookiePatternOrderField],
|
|
||||||
parentType any,
|
|
||||||
parentID gid.GID,
|
|
||||||
) *CookiePatternConnection {
|
|
||||||
edges := make([]*CookiePatternEdge, len(p.Data))
|
|
||||||
|
|
||||||
for i := range edges {
|
|
||||||
edges[i] = NewCookiePatternEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &CookiePatternConnection{
|
|
||||||
Edges: edges,
|
|
||||||
PageInfo: *NewPageInfo(p),
|
|
||||||
|
|
||||||
Resolver: parentType,
|
|
||||||
ParentID: parentID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCookiePatternConnectionWithFilter(
|
|
||||||
p *page.Page[*coredata.CookiePattern, coredata.CookiePatternOrderField],
|
|
||||||
parentType any,
|
|
||||||
parentID gid.GID,
|
|
||||||
filter *coredata.CookiePatternFilter,
|
|
||||||
) *CookiePatternConnection {
|
|
||||||
conn := NewCookiePatternConnection(p, parentType, parentID)
|
|
||||||
conn.Filter = filter
|
|
||||||
return conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCookiePatternEdge(cp *coredata.CookiePattern, orderBy coredata.CookiePatternOrderField) *CookiePatternEdge {
|
|
||||||
return &CookiePatternEdge{
|
|
||||||
Cursor: cp.CursorKey(orderBy),
|
|
||||||
Node: NewCookiePattern(cp),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCookiePattern(cp *coredata.CookiePattern) *CookiePattern {
|
|
||||||
return &CookiePattern{
|
|
||||||
ID: cp.ID,
|
|
||||||
CookieCategory: &CookieCategory{
|
|
||||||
ID: cp.CookieCategoryID,
|
|
||||||
CookieBanner: &CookieBanner{
|
|
||||||
ID: cp.CookieBannerID,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TrackerType: coredata.TrackerTypeCookie,
|
|
||||||
Pattern: cp.Pattern,
|
|
||||||
MatchType: cp.MatchType,
|
|
||||||
DisplayName: cp.DisplayName,
|
|
||||||
MaxAgeSeconds: cp.MaxAgeSeconds,
|
|
||||||
Description: cp.Description,
|
|
||||||
Source: &cp.Source,
|
|
||||||
Excluded: cp.Excluded,
|
|
||||||
LastMatchedAt: cp.LastMatchedAt,
|
|
||||||
CreatedAt: cp.CreatedAt,
|
|
||||||
UpdatedAt: cp.UpdatedAt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTrackerPattern(tp *coredata.TrackerPattern) *CookiePattern {
|
|
||||||
return &CookiePattern{
|
|
||||||
ID: tp.ID,
|
|
||||||
CookieCategory: &CookieCategory{
|
|
||||||
ID: tp.CookieCategoryID,
|
|
||||||
CookieBanner: &CookieBanner{
|
|
||||||
ID: tp.CookieBannerID,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
TrackerType: tp.TrackerType,
|
|
||||||
Pattern: tp.Pattern,
|
|
||||||
MatchType: tp.MatchType,
|
|
||||||
DisplayName: tp.DisplayName,
|
|
||||||
MaxAgeSeconds: tp.MaxAgeSeconds,
|
|
||||||
Description: tp.Description,
|
|
||||||
Source: tp.Source,
|
|
||||||
Excluded: tp.Excluded,
|
|
||||||
LastMatchedAt: tp.LastMatchedAt,
|
|
||||||
CreatedAt: tp.CreatedAt,
|
|
||||||
UpdatedAt: tp.UpdatedAt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
TrackerPatternOrderBy OrderBy[coredata.CookiePatternOrderField]
|
TrackerPatternOrderBy OrderBy[coredata.TrackerPatternOrderField]
|
||||||
|
|
||||||
TrackerPatternConnection struct {
|
TrackerPatternConnection struct {
|
||||||
TotalCount int
|
TotalCount int
|
||||||
@@ -41,7 +41,7 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewTrackerPatternConnection(
|
func NewTrackerPatternConnection(
|
||||||
p *page.Page[*coredata.TrackerPattern, coredata.CookiePatternOrderField],
|
p *page.Page[*coredata.TrackerPattern, coredata.TrackerPatternOrderField],
|
||||||
parentType any,
|
parentType any,
|
||||||
parentID gid.GID,
|
parentID gid.GID,
|
||||||
) *TrackerPatternConnection {
|
) *TrackerPatternConnection {
|
||||||
@@ -61,7 +61,7 @@ func NewTrackerPatternConnection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTrackerPatternConnectionWithFilter(
|
func NewTrackerPatternConnectionWithFilter(
|
||||||
p *page.Page[*coredata.TrackerPattern, coredata.CookiePatternOrderField],
|
p *page.Page[*coredata.TrackerPattern, coredata.TrackerPatternOrderField],
|
||||||
parentType any,
|
parentType any,
|
||||||
parentID gid.GID,
|
parentID gid.GID,
|
||||||
filter *TrackerPatternFilter,
|
filter *TrackerPatternFilter,
|
||||||
@@ -71,7 +71,7 @@ func NewTrackerPatternConnectionWithFilter(
|
|||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTrackerPatternEdge(tp *coredata.TrackerPattern, orderBy coredata.CookiePatternOrderField) *TrackerPatternEdge {
|
func NewTrackerPatternEdge(tp *coredata.TrackerPattern, orderBy coredata.TrackerPatternOrderField) *TrackerPatternEdge {
|
||||||
return &TrackerPatternEdge{
|
return &TrackerPatternEdge{
|
||||||
Cursor: tp.CursorKey(orderBy),
|
Cursor: tp.CursorKey(orderBy),
|
||||||
Node: NewTrackerPatternNode(tp),
|
Node: NewTrackerPatternNode(tp),
|
||||||
|
|||||||
@@ -4941,49 +4941,50 @@ func (r *Resolver) ReorderCookieCategoryTool(ctx context.Context, req *mcp.CallT
|
|||||||
return nil, types.ReorderCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
return nil, types.ReorderCookieCategoryOutput{CookieCategory: types.NewCookieCategory(category)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) ListCookiePatternsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListCookiePatternsInput) (*mcp.CallToolResult, types.ListCookiePatternsOutput, error) {
|
func (r *Resolver) ListTrackerPatternsTool(ctx context.Context, req *mcp.CallToolRequest, input *types.ListTrackerPatternsInput) (*mcp.CallToolResult, types.ListTrackerPatternsOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.CookieCategoryID, probo.ActionCookiePatternList)
|
r.MustAuthorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternList)
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||||
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.CookiePatternOrderField]{Field: coredata.CookiePatternOrderFieldCreatedAt, Direction: page.OrderDirectionAsc})
|
cursor := types.NewCursor(input.Size, input.Cursor, page.OrderBy[coredata.TrackerPatternOrderField]{Field: coredata.TrackerPatternOrderFieldCreatedAt, Direction: page.OrderDirectionAsc})
|
||||||
patterns, err := r.cookieBanner.ListCookiePatternsForCategory(ctx, scope, input.CookieCategoryID, cursor)
|
patterns, err := r.cookieBanner.ListTrackerPatternsForCategory(ctx, scope, input.CookieCategoryID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("cannot list cookie patterns: %w", err))
|
panic(fmt.Errorf("cannot list tracker patterns: %w", err))
|
||||||
}
|
}
|
||||||
p := page.NewPage(patterns, cursor)
|
p := page.NewPage(patterns, cursor)
|
||||||
return nil, types.NewListCookiePatternsOutput(p), nil
|
return nil, types.NewListTrackerPatternsOutput(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) GetCookiePatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetCookiePatternInput) (*mcp.CallToolResult, types.GetCookiePatternOutput, error) {
|
func (r *Resolver) GetTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetTrackerPatternInput) (*mcp.CallToolResult, types.GetTrackerPatternOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.ID, probo.ActionCookiePatternGet)
|
r.MustAuthorize(ctx, input.ID, probo.ActionTrackerPatternGet)
|
||||||
scope := coredata.NewScopeFromObjectID(input.ID)
|
scope := coredata.NewScopeFromObjectID(input.ID)
|
||||||
pattern, err := r.cookieBanner.GetCookiePattern(ctx, scope, input.ID)
|
pattern, err := r.cookieBanner.GetTrackerPattern(ctx, scope, input.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.GetCookiePatternOutput{}, fmt.Errorf("cannot get cookie pattern: %w", err)
|
return nil, types.GetTrackerPatternOutput{}, fmt.Errorf("cannot get tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
return nil, types.GetCookiePatternOutput{CookiePattern: types.NewCookiePattern(pattern)}, nil
|
return nil, types.GetTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) AddCookiePatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddCookiePatternInput) (*mcp.CallToolResult, types.AddCookiePatternOutput, error) {
|
func (r *Resolver) AddTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.AddTrackerPatternInput) (*mcp.CallToolResult, types.AddTrackerPatternOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.CookieCategoryID, probo.ActionCookiePatternCreate)
|
r.MustAuthorize(ctx, input.CookieCategoryID, probo.ActionTrackerPatternCreate)
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||||
pattern, err := r.cookieBanner.CreateCookiePattern(ctx, scope, cookiebanner.CreateCookiePatternRequest{
|
pattern, err := r.cookieBanner.CreateTrackerPattern(ctx, scope, cookiebanner.CreateTrackerPatternRequest{
|
||||||
CookieCategoryID: input.CookieCategoryID,
|
CookieCategoryID: input.CookieCategoryID,
|
||||||
|
TrackerType: coredata.TrackerType(input.TrackerType),
|
||||||
Pattern: input.Pattern,
|
Pattern: input.Pattern,
|
||||||
MatchType: coredata.CookiePatternMatchType(input.MatchType),
|
MatchType: coredata.TrackerPatternMatchType(input.MatchType),
|
||||||
DisplayName: input.DisplayName,
|
DisplayName: input.DisplayName,
|
||||||
MaxAgeSeconds: input.MaxAgeSeconds,
|
MaxAgeSeconds: input.MaxAgeSeconds,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.AddCookiePatternOutput{}, fmt.Errorf("cannot create cookie pattern: %w", err)
|
return nil, types.AddTrackerPatternOutput{}, fmt.Errorf("cannot create tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
return nil, types.AddCookiePatternOutput{CookiePattern: types.NewCookiePattern(pattern)}, nil
|
return nil, types.AddTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) UpdateCookiePatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateCookiePatternInput) (*mcp.CallToolResult, types.UpdateCookiePatternOutput, error) {
|
func (r *Resolver) UpdateTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateTrackerPatternInput) (*mcp.CallToolResult, types.UpdateTrackerPatternOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.ID, probo.ActionCookiePatternUpdate)
|
r.MustAuthorize(ctx, input.ID, probo.ActionTrackerPatternUpdate)
|
||||||
scope := coredata.NewScopeFromObjectID(input.ID)
|
scope := coredata.NewScopeFromObjectID(input.ID)
|
||||||
updateReq := cookiebanner.UpdateCookiePatternRequest{CookiePatternID: input.ID}
|
updateReq := cookiebanner.UpdateTrackerPatternRequest{TrackerPatternID: input.ID}
|
||||||
if v := UnwrapOmittable(input.DisplayName); v != nil && *v != nil {
|
if v := UnwrapOmittable(input.DisplayName); v != nil && *v != nil {
|
||||||
updateReq.DisplayName = *v
|
updateReq.DisplayName = *v
|
||||||
}
|
}
|
||||||
@@ -4997,33 +4998,33 @@ func (r *Resolver) UpdateCookiePatternTool(ctx context.Context, req *mcp.CallToo
|
|||||||
if v := UnwrapOmittable(input.Excluded); v != nil && *v != nil {
|
if v := UnwrapOmittable(input.Excluded); v != nil && *v != nil {
|
||||||
updateReq.Excluded = *v
|
updateReq.Excluded = *v
|
||||||
}
|
}
|
||||||
pattern, err := r.cookieBanner.UpdateCookiePattern(ctx, scope, updateReq)
|
pattern, err := r.cookieBanner.UpdateTrackerPattern(ctx, scope, updateReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.UpdateCookiePatternOutput{}, fmt.Errorf("cannot update cookie pattern: %w", err)
|
return nil, types.UpdateTrackerPatternOutput{}, fmt.Errorf("cannot update tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
return nil, types.UpdateCookiePatternOutput{CookiePattern: types.NewCookiePattern(pattern)}, nil
|
return nil, types.UpdateTrackerPatternOutput{TrackerPattern: types.NewTrackerPattern(pattern)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) DeleteCookiePatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteCookiePatternInput) (*mcp.CallToolResult, types.DeleteCookiePatternOutput, error) {
|
func (r *Resolver) DeleteTrackerPatternTool(ctx context.Context, req *mcp.CallToolRequest, input *types.DeleteTrackerPatternInput) (*mcp.CallToolResult, types.DeleteTrackerPatternOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.ID, probo.ActionCookiePatternDelete)
|
r.MustAuthorize(ctx, input.ID, probo.ActionTrackerPatternDelete)
|
||||||
scope := coredata.NewScopeFromObjectID(input.ID)
|
scope := coredata.NewScopeFromObjectID(input.ID)
|
||||||
if err := r.cookieBanner.DeleteCookiePattern(ctx, scope, input.ID); err != nil {
|
if err := r.cookieBanner.DeleteTrackerPattern(ctx, scope, input.ID); err != nil {
|
||||||
return nil, types.DeleteCookiePatternOutput{}, fmt.Errorf("cannot delete cookie pattern: %w", err)
|
return nil, types.DeleteTrackerPatternOutput{}, fmt.Errorf("cannot delete tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
return nil, types.DeleteCookiePatternOutput{DeletedID: input.ID}, nil
|
return nil, types.DeleteTrackerPatternOutput{DeletedID: input.ID}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) MoveCookiePatternToCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.MoveCookiePatternToCategoryInput) (*mcp.CallToolResult, types.MoveCookiePatternToCategoryOutput, error) {
|
func (r *Resolver) MoveTrackerPatternToCategoryTool(ctx context.Context, req *mcp.CallToolRequest, input *types.MoveTrackerPatternToCategoryInput) (*mcp.CallToolResult, types.MoveTrackerPatternToCategoryOutput, error) {
|
||||||
r.MustAuthorize(ctx, input.CookiePatternID, probo.ActionCookiePatternUpdate)
|
r.MustAuthorize(ctx, input.TrackerPatternID, probo.ActionTrackerPatternUpdate)
|
||||||
scope := coredata.NewScopeFromObjectID(input.CookiePatternID)
|
scope := coredata.NewScopeFromObjectID(input.TrackerPatternID)
|
||||||
result, err := r.cookieBanner.MoveCookiePatternToCategory(ctx, scope, cookiebanner.MoveCookiePatternToCategoryRequest{
|
result, err := r.cookieBanner.MoveTrackerPatternToCategory(ctx, scope, cookiebanner.MoveTrackerPatternToCategoryRequest{
|
||||||
CookiePatternID: input.CookiePatternID,
|
TrackerPatternID: input.TrackerPatternID,
|
||||||
TargetCookieCategoryID: input.TargetCookieCategoryID,
|
TargetCookieCategoryID: input.TargetCookieCategoryID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, types.MoveCookiePatternToCategoryOutput{}, fmt.Errorf("cannot move cookie pattern: %w", err)
|
return nil, types.MoveTrackerPatternToCategoryOutput{}, fmt.Errorf("cannot move tracker pattern: %w", err)
|
||||||
}
|
}
|
||||||
return nil, types.MoveCookiePatternToCategoryOutput{CookiePattern: types.NewCookiePattern(result.CookiePattern)}, nil
|
return nil, types.MoveTrackerPatternToCategoryOutput{TrackerPattern: types.NewTrackerPattern(result.TrackerPattern)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) PublishCookieBannerVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishCookieBannerVersionInput) (*mcp.CallToolResult, types.PublishCookieBannerVersionOutput, error) {
|
func (r *Resolver) PublishCookieBannerVersionTool(ctx context.Context, req *mcp.CallToolRequest, input *types.PublishCookieBannerVersionInput) (*mcp.CallToolResult, types.PublishCookieBannerVersionOutput, error) {
|
||||||
|
|||||||
@@ -9132,13 +9132,14 @@ components:
|
|||||||
format: date-time
|
format: date-time
|
||||||
description: Last update timestamp
|
description: Last update timestamp
|
||||||
|
|
||||||
CookiePattern:
|
TrackerPattern:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
- organization_id
|
- organization_id
|
||||||
- cookie_banner_id
|
- cookie_banner_id
|
||||||
- cookie_category_id
|
- cookie_category_id
|
||||||
|
- tracker_type
|
||||||
- pattern
|
- pattern
|
||||||
- match_type
|
- match_type
|
||||||
- display_name
|
- display_name
|
||||||
@@ -9150,7 +9151,7 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Cookie pattern ID
|
description: Tracker pattern ID
|
||||||
organization_id:
|
organization_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Organization ID
|
description: Organization ID
|
||||||
@@ -9160,9 +9161,13 @@ components:
|
|||||||
cookie_category_id:
|
cookie_category_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
description: Cookie category ID
|
description: Cookie category ID
|
||||||
|
tracker_type:
|
||||||
|
type: string
|
||||||
|
enum: [COOKIE, LOCAL_STORAGE, SESSION_STORAGE, PIXEL]
|
||||||
|
description: Type of tracker
|
||||||
pattern:
|
pattern:
|
||||||
type: string
|
type: string
|
||||||
description: Cookie name pattern
|
description: Tracker name pattern
|
||||||
match_type:
|
match_type:
|
||||||
type: string
|
type: string
|
||||||
enum: [EXACT, PREFIX]
|
enum: [EXACT, PREFIX]
|
||||||
@@ -9630,7 +9635,7 @@ components:
|
|||||||
cookie_category:
|
cookie_category:
|
||||||
$ref: "#/components/schemas/CookieCategory"
|
$ref: "#/components/schemas/CookieCategory"
|
||||||
|
|
||||||
ListCookiePatternsInput:
|
ListTrackerPatternsInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_category_id
|
- cookie_category_id
|
||||||
@@ -9642,19 +9647,19 @@ components:
|
|||||||
cursor:
|
cursor:
|
||||||
$ref: "#/components/schemas/CursorKey"
|
$ref: "#/components/schemas/CursorKey"
|
||||||
|
|
||||||
ListCookiePatternsOutput:
|
ListTrackerPatternsOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_patterns
|
- tracker_patterns
|
||||||
properties:
|
properties:
|
||||||
next_cursor:
|
next_cursor:
|
||||||
$ref: "#/components/schemas/CursorKey"
|
$ref: "#/components/schemas/CursorKey"
|
||||||
cookie_patterns:
|
tracker_patterns:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/CookiePattern"
|
$ref: "#/components/schemas/TrackerPattern"
|
||||||
|
|
||||||
GetCookiePatternInput:
|
GetTrackerPatternInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
@@ -9662,18 +9667,19 @@ components:
|
|||||||
id:
|
id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
|
|
||||||
GetCookiePatternOutput:
|
GetTrackerPatternOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_pattern
|
- tracker_pattern
|
||||||
properties:
|
properties:
|
||||||
cookie_pattern:
|
tracker_pattern:
|
||||||
$ref: "#/components/schemas/CookiePattern"
|
$ref: "#/components/schemas/TrackerPattern"
|
||||||
|
|
||||||
AddCookiePatternInput:
|
AddTrackerPatternInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_category_id
|
- cookie_category_id
|
||||||
|
- tracker_type
|
||||||
- pattern
|
- pattern
|
||||||
- match_type
|
- match_type
|
||||||
- display_name
|
- display_name
|
||||||
@@ -9681,6 +9687,9 @@ components:
|
|||||||
properties:
|
properties:
|
||||||
cookie_category_id:
|
cookie_category_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
|
tracker_type:
|
||||||
|
type: string
|
||||||
|
enum: [COOKIE, LOCAL_STORAGE, SESSION_STORAGE, PIXEL]
|
||||||
pattern:
|
pattern:
|
||||||
type: string
|
type: string
|
||||||
match_type:
|
match_type:
|
||||||
@@ -9693,15 +9702,15 @@ components:
|
|||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
AddCookiePatternOutput:
|
AddTrackerPatternOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_pattern
|
- tracker_pattern
|
||||||
properties:
|
properties:
|
||||||
cookie_pattern:
|
tracker_pattern:
|
||||||
$ref: "#/components/schemas/CookiePattern"
|
$ref: "#/components/schemas/TrackerPattern"
|
||||||
|
|
||||||
UpdateCookiePatternInput:
|
UpdateTrackerPatternInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
@@ -9729,15 +9738,15 @@ components:
|
|||||||
- "null"
|
- "null"
|
||||||
go.probo.inc/mcpgen/omittable: true
|
go.probo.inc/mcpgen/omittable: true
|
||||||
|
|
||||||
UpdateCookiePatternOutput:
|
UpdateTrackerPatternOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_pattern
|
- tracker_pattern
|
||||||
properties:
|
properties:
|
||||||
cookie_pattern:
|
tracker_pattern:
|
||||||
$ref: "#/components/schemas/CookiePattern"
|
$ref: "#/components/schemas/TrackerPattern"
|
||||||
|
|
||||||
DeleteCookiePatternInput:
|
DeleteTrackerPatternInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- id
|
- id
|
||||||
@@ -9745,7 +9754,7 @@ components:
|
|||||||
id:
|
id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
|
|
||||||
DeleteCookiePatternOutput:
|
DeleteTrackerPatternOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- deleted_id
|
- deleted_id
|
||||||
@@ -9753,24 +9762,24 @@ components:
|
|||||||
deleted_id:
|
deleted_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
|
|
||||||
MoveCookiePatternToCategoryInput:
|
MoveTrackerPatternToCategoryInput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_pattern_id
|
- tracker_pattern_id
|
||||||
- target_cookie_category_id
|
- target_cookie_category_id
|
||||||
properties:
|
properties:
|
||||||
cookie_pattern_id:
|
tracker_pattern_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
target_cookie_category_id:
|
target_cookie_category_id:
|
||||||
$ref: "#/components/schemas/GID"
|
$ref: "#/components/schemas/GID"
|
||||||
|
|
||||||
MoveCookiePatternToCategoryOutput:
|
MoveTrackerPatternToCategoryOutput:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- cookie_pattern
|
- tracker_pattern
|
||||||
properties:
|
properties:
|
||||||
cookie_pattern:
|
tracker_pattern:
|
||||||
$ref: "#/components/schemas/CookiePattern"
|
$ref: "#/components/schemas/TrackerPattern"
|
||||||
|
|
||||||
PublishCookieBannerVersionInput:
|
PublishCookieBannerVersionInput:
|
||||||
type: object
|
type: object
|
||||||
@@ -12019,57 +12028,57 @@ tools:
|
|||||||
$ref: "#/components/schemas/ReorderCookieCategoryInput"
|
$ref: "#/components/schemas/ReorderCookieCategoryInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/ReorderCookieCategoryOutput"
|
$ref: "#/components/schemas/ReorderCookieCategoryOutput"
|
||||||
- name: listCookiePatterns
|
- name: listTrackerPatterns
|
||||||
description: List all cookie patterns for a category
|
description: List all tracker patterns for a category
|
||||||
hints:
|
hints:
|
||||||
readonly: true
|
readonly: true
|
||||||
idempotent: true
|
idempotent: true
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/ListCookiePatternsInput"
|
$ref: "#/components/schemas/ListTrackerPatternsInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/ListCookiePatternsOutput"
|
$ref: "#/components/schemas/ListTrackerPatternsOutput"
|
||||||
- name: getCookiePattern
|
- name: getTrackerPattern
|
||||||
description: Get a cookie pattern by ID
|
description: Get a tracker pattern by ID
|
||||||
hints:
|
hints:
|
||||||
readonly: true
|
readonly: true
|
||||||
idempotent: true
|
idempotent: true
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/GetCookiePatternInput"
|
$ref: "#/components/schemas/GetTrackerPatternInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/GetCookiePatternOutput"
|
$ref: "#/components/schemas/GetTrackerPatternOutput"
|
||||||
- name: addCookiePattern
|
- name: addTrackerPattern
|
||||||
description: Create a new cookie pattern for a category
|
description: Create a new tracker pattern for a category
|
||||||
hints:
|
hints:
|
||||||
readonly: false
|
readonly: false
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/AddCookiePatternInput"
|
$ref: "#/components/schemas/AddTrackerPatternInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/AddCookiePatternOutput"
|
$ref: "#/components/schemas/AddTrackerPatternOutput"
|
||||||
- name: updateCookiePattern
|
- name: updateTrackerPattern
|
||||||
description: Update an existing cookie pattern
|
description: Update an existing tracker pattern
|
||||||
hints:
|
hints:
|
||||||
readonly: false
|
readonly: false
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/UpdateCookiePatternInput"
|
$ref: "#/components/schemas/UpdateTrackerPatternInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/UpdateCookiePatternOutput"
|
$ref: "#/components/schemas/UpdateTrackerPatternOutput"
|
||||||
- name: deleteCookiePattern
|
- name: deleteTrackerPattern
|
||||||
description: Delete a cookie pattern
|
description: Delete a tracker pattern
|
||||||
hints:
|
hints:
|
||||||
readonly: false
|
readonly: false
|
||||||
destructive: true
|
destructive: true
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/DeleteCookiePatternInput"
|
$ref: "#/components/schemas/DeleteTrackerPatternInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/DeleteCookiePatternOutput"
|
$ref: "#/components/schemas/DeleteTrackerPatternOutput"
|
||||||
- name: moveCookiePatternToCategory
|
- name: moveTrackerPatternToCategory
|
||||||
description: Move a cookie pattern to a different category
|
description: Move a tracker pattern to a different category
|
||||||
hints:
|
hints:
|
||||||
readonly: false
|
readonly: false
|
||||||
inputSchema:
|
inputSchema:
|
||||||
$ref: "#/components/schemas/MoveCookiePatternToCategoryInput"
|
$ref: "#/components/schemas/MoveTrackerPatternToCategoryInput"
|
||||||
outputSchema:
|
outputSchema:
|
||||||
$ref: "#/components/schemas/MoveCookiePatternToCategoryOutput"
|
$ref: "#/components/schemas/MoveTrackerPatternToCategoryOutput"
|
||||||
- name: publishCookieBannerVersion
|
- name: publishCookieBannerVersion
|
||||||
description: Publish the current draft version of a cookie banner
|
description: Publish the current draft version of a cookie banner
|
||||||
hints:
|
hints:
|
||||||
|
|||||||
@@ -19,18 +19,24 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/page"
|
"go.probo.inc/probo/pkg/page"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCookiePattern(p *coredata.CookiePattern) *CookiePattern {
|
func NewTrackerPattern(p *coredata.TrackerPattern) *TrackerPattern {
|
||||||
return &CookiePattern{
|
var source TrackerPatternSource
|
||||||
|
if p.Source != nil {
|
||||||
|
source = TrackerPatternSource(*p.Source)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TrackerPattern{
|
||||||
ID: p.ID,
|
ID: p.ID,
|
||||||
OrganizationID: p.OrganizationID,
|
OrganizationID: p.OrganizationID,
|
||||||
CookieBannerID: p.CookieBannerID,
|
CookieBannerID: p.CookieBannerID,
|
||||||
CookieCategoryID: p.CookieCategoryID,
|
CookieCategoryID: p.CookieCategoryID,
|
||||||
|
TrackerType: TrackerPatternTrackerType(p.TrackerType),
|
||||||
Pattern: p.Pattern,
|
Pattern: p.Pattern,
|
||||||
MatchType: CookiePatternMatchType(p.MatchType),
|
MatchType: TrackerPatternMatchType(p.MatchType),
|
||||||
DisplayName: p.DisplayName,
|
DisplayName: p.DisplayName,
|
||||||
MaxAgeSeconds: p.MaxAgeSeconds,
|
MaxAgeSeconds: p.MaxAgeSeconds,
|
||||||
Description: p.Description,
|
Description: p.Description,
|
||||||
Source: CookiePatternSource(p.Source),
|
Source: source,
|
||||||
Excluded: p.Excluded,
|
Excluded: p.Excluded,
|
||||||
LastMatchedAt: p.LastMatchedAt,
|
LastMatchedAt: p.LastMatchedAt,
|
||||||
CreatedAt: p.CreatedAt,
|
CreatedAt: p.CreatedAt,
|
||||||
@@ -38,10 +44,10 @@ func NewCookiePattern(p *coredata.CookiePattern) *CookiePattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListCookiePatternsOutput(pg *page.Page[*coredata.CookiePattern, coredata.CookiePatternOrderField]) ListCookiePatternsOutput {
|
func NewListTrackerPatternsOutput(pg *page.Page[*coredata.TrackerPattern, coredata.TrackerPatternOrderField]) ListTrackerPatternsOutput {
|
||||||
patterns := make([]*CookiePattern, 0, len(pg.Data))
|
patterns := make([]*TrackerPattern, 0, len(pg.Data))
|
||||||
for _, p := range pg.Data {
|
for _, p := range pg.Data {
|
||||||
patterns = append(patterns, NewCookiePattern(p))
|
patterns = append(patterns, NewTrackerPattern(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextCursor *page.CursorKey
|
var nextCursor *page.CursorKey
|
||||||
@@ -50,8 +56,8 @@ func NewListCookiePatternsOutput(pg *page.Page[*coredata.CookiePattern, coredata
|
|||||||
nextCursor = &cursorKey
|
nextCursor = &cursorKey
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListCookiePatternsOutput{
|
return ListTrackerPatternsOutput{
|
||||||
NextCursor: nextCursor,
|
NextCursor: nextCursor,
|
||||||
CookiePatterns: patterns,
|
TrackerPatterns: patterns,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user