Add UX for cookie banner management
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
463
pkg/server/api/console/v1/cookie_banner_resolvers.go
Normal file
463
pkg/server/api/console/v1/cookie_banner_resolvers.go
Normal file
@@ -0,0 +1,463 @@
|
||||
package console_v1
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver
|
||||
// implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.87
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/cookiebanner"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/probo"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *cookieBannerResolver) Organization(ctx context.Context, obj *types.CookieBanner) (*types.Organization, error) {
|
||||
return obj.Organization, nil
|
||||
}
|
||||
|
||||
// Categories is the resolver for the categories field.
|
||||
func (r *cookieBannerResolver) Categories(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookieCategoryOrderBy) (*types.CookieCategoryConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookieCategoryList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.CookieCategoryOrderField]{
|
||||
Field: coredata.CookieCategoryOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.CookieCategoryOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
categories, err := r.cookieBanner.ListCookieCategoriesForBanner(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list cookie categories", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
p := page.NewPage(categories, cursor)
|
||||
|
||||
return types.NewCookieCategoryConnection(p, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// LatestVersion is the resolver for the latestVersion field.
|
||||
func (r *cookieBannerResolver) LatestVersion(ctx context.Context, obj *types.CookieBanner) (*types.CookieBannerVersion, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerVersionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
cursor := &page.Cursor[coredata.CookieBannerVersionOrderField]{
|
||||
Size: 1,
|
||||
Position: page.Head,
|
||||
OrderBy: page.OrderBy[coredata.CookieBannerVersionOrderField]{
|
||||
Field: coredata.CookieBannerVersionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
},
|
||||
}
|
||||
|
||||
versions, err := r.cookieBanner.ListCookieBannerVersionsForBanner(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot load latest cookie banner version", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
if len(versions) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
v := versions[0]
|
||||
return &types.CookieBannerVersion{
|
||||
ID: v.ID,
|
||||
Version: v.Version,
|
||||
State: string(v.State),
|
||||
CreatedAt: v.CreatedAt,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *cookieBannerResolver) Permission(ctx context.Context, obj *types.CookieBanner, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *cookieBannerConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieBannerConnection) (int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieBannerList); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
||||
|
||||
count, err := r.cookieBanner.CountCookieBannersForOrganization(ctx, scope, obj.ParentID, coredata.NewCookieBannerFilter(nil))
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count cookie banners", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// CookieBanner is the resolver for the cookieBanner field.
|
||||
func (r *cookieCategoryResolver) CookieBanner(ctx context.Context, obj *types.CookieCategory) (*types.CookieBanner, error) {
|
||||
return obj.CookieBanner, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *cookieCategoryResolver) Permission(ctx context.Context, obj *types.CookieCategory, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *cookieCategoryConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieCategoryConnection) (int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieCategoryList); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
||||
|
||||
count, err := r.cookieBanner.CountCookieCategoriesForBanner(ctx, scope, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count cookie categories", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// CreateCookieBanner is the resolver for the createCookieBanner field.
|
||||
func (r *mutationResolver) CreateCookieBanner(ctx context.Context, input types.CreateCookieBannerInput) (*types.CreateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.OrganizationID)
|
||||
|
||||
banner, err := r.cookieBanner.CreateCookieBanner(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.CreateCookieBannerRequest{
|
||||
OrganizationID: input.OrganizationID,
|
||||
Name: input.Name,
|
||||
Origin: input.Origin,
|
||||
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||
ConsentExpiryDays: input.ConsentExpiryDays,
|
||||
ConsentMode: input.ConsentMode,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot create cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCookieBannerPayload{
|
||||
CookieBannerEdge: types.NewCookieBannerEdge(banner, coredata.CookieBannerOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCookieBanner is the resolver for the updateCookieBanner field.
|
||||
func (r *mutationResolver) UpdateCookieBanner(ctx context.Context, input types.UpdateCookieBannerInput) (*types.UpdateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.UpdateCookieBanner(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.UpdateCookieBannerRequest{
|
||||
CookieBannerID: input.CookieBannerID,
|
||||
Name: input.Name,
|
||||
Origin: input.Origin,
|
||||
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||
ConsentExpiryDays: input.ConsentExpiryDays,
|
||||
ConsentMode: input.ConsentMode,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot update cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCookieBanner is the resolver for the deleteCookieBanner field.
|
||||
func (r *mutationResolver) DeleteCookieBanner(ctx context.Context, input types.DeleteCookieBannerInput) (*types.DeleteCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
err := r.cookieBanner.DeleteCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot delete cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCookieBannerPayload{
|
||||
DeletedCookieBannerID: input.CookieBannerID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ActivateCookieBanner is the resolver for the activateCookieBanner field.
|
||||
func (r *mutationResolver) ActivateCookieBanner(ctx context.Context, input types.ActivateCookieBannerInput) (*types.ActivateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerActivate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.ActivateCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrBannerAlreadyActive) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot activate cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.ActivateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeactivateCookieBanner is the resolver for the deactivateCookieBanner field.
|
||||
func (r *mutationResolver) DeactivateCookieBanner(ctx context.Context, input types.DeactivateCookieBannerInput) (*types.DeactivateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDeactivate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.DeactivateCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrBannerAlreadyInactive) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot deactivate cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeactivateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublishCookieBannerVersion is the resolver for the publishCookieBannerVersion field.
|
||||
func (r *mutationResolver) PublishCookieBannerVersion(ctx context.Context, input types.PublishCookieBannerVersionInput) (*types.PublishCookieBannerVersionPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerVersionPublish); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
version, err := r.cookieBanner.PublishCookieBannerVersion(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrNoDraftVersion) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot publish cookie banner version", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.PublishCookieBannerVersionPayload{
|
||||
CookieBannerVersion: &types.CookieBannerVersion{
|
||||
ID: version.ID,
|
||||
Version: version.Version,
|
||||
State: string(version.State),
|
||||
CreatedAt: version.CreatedAt,
|
||||
UpdatedAt: version.UpdatedAt,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateCookieCategory is the resolver for the createCookieCategory field.
|
||||
func (r *mutationResolver) CreateCookieCategory(ctx context.Context, input types.CreateCookieCategoryInput) (*types.CreateCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieCategoryCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
var cookies coredata.CookieItems
|
||||
if input.Cookies != nil {
|
||||
cookies = make(coredata.CookieItems, len(input.Cookies))
|
||||
for i, c := range input.Cookies {
|
||||
cookies[i] = coredata.CookieItem{
|
||||
Name: c.Name,
|
||||
Duration: c.Duration,
|
||||
Description: c.Description,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
category, err := r.cookieBanner.CreateCookieCategory(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.CreateCookieCategoryRequest{
|
||||
CookieBannerID: input.CookieBannerID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
Required: input.Required,
|
||||
Rank: input.Rank,
|
||||
Cookies: cookies,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
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 category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCookieCategoryPayload{
|
||||
CookieCategoryEdge: types.NewCookieCategoryEdge(category, coredata.CookieCategoryOrderFieldRank),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCookieCategory is the resolver for the updateCookieCategory field.
|
||||
func (r *mutationResolver) UpdateCookieCategory(ctx context.Context, input types.UpdateCookieCategoryInput) (*types.UpdateCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||
|
||||
var cookies *coredata.CookieItems
|
||||
if input.Cookies != nil {
|
||||
items := make(coredata.CookieItems, len(input.Cookies))
|
||||
for i, c := range input.Cookies {
|
||||
items[i] = coredata.CookieItem{
|
||||
Name: c.Name,
|
||||
Duration: c.Duration,
|
||||
Description: c.Description,
|
||||
}
|
||||
}
|
||||
cookies = &items
|
||||
}
|
||||
|
||||
category, err := r.cookieBanner.UpdateCookieCategory(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.UpdateCookieCategoryRequest{
|
||||
CookieCategoryID: input.CookieCategoryID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
Rank: input.Rank,
|
||||
Cookies: cookies,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
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 update cookie category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCookieCategoryPayload{
|
||||
CookieCategory: types.NewCookieCategory(category),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCookieCategory is the resolver for the deleteCookieCategory field.
|
||||
func (r *mutationResolver) DeleteCookieCategory(ctx context.Context, input types.DeleteCookieCategoryInput) (*types.DeleteCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||
|
||||
err := r.cookieBanner.DeleteCookieCategory(ctx, scope, input.CookieCategoryID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrCategoryNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrCannotDeleteRequiredCategory) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot delete cookie category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCookieCategoryPayload{
|
||||
DeletedCookieCategoryID: input.CookieCategoryID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CookieBanner returns schema.CookieBannerResolver implementation.
|
||||
func (r *Resolver) CookieBanner() schema.CookieBannerResolver { return &cookieBannerResolver{r} }
|
||||
|
||||
// CookieBannerConnection returns schema.CookieBannerConnectionResolver implementation.
|
||||
func (r *Resolver) CookieBannerConnection() schema.CookieBannerConnectionResolver {
|
||||
return &cookieBannerConnectionResolver{r}
|
||||
}
|
||||
|
||||
// CookieCategory returns schema.CookieCategoryResolver implementation.
|
||||
func (r *Resolver) CookieCategory() schema.CookieCategoryResolver { return &cookieCategoryResolver{r} }
|
||||
|
||||
// CookieCategoryConnection returns schema.CookieCategoryConnectionResolver implementation.
|
||||
func (r *Resolver) CookieCategoryConnection() schema.CookieCategoryConnectionResolver {
|
||||
return &cookieCategoryConnectionResolver{r}
|
||||
}
|
||||
|
||||
type cookieBannerResolver struct{ *Resolver }
|
||||
type cookieBannerConnectionResolver struct{ *Resolver }
|
||||
type cookieCategoryResolver struct{ *Resolver }
|
||||
type cookieCategoryConnectionResolver struct{ *Resolver }
|
||||
Reference in New Issue
Block a user