Make cookie banner origin immutable after creation
Origin is a fundamental identity property of a banner tied to consent records for a specific site. Changing it would break the audit trail and violate GDPR consent specificity requirements. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -40,7 +40,6 @@ const updateBannerMutation = graphql`
|
|||||||
cookieBanner {
|
cookieBanner {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
origin
|
|
||||||
privacyPolicyUrl
|
privacyPolicyUrl
|
||||||
consentExpiryDays
|
consentExpiryDays
|
||||||
consentMode
|
consentMode
|
||||||
@@ -68,7 +67,6 @@ export function BannerSettingsForm({ cookieBannerKey }: BannerSettingsFormProps)
|
|||||||
const [updateBanner, isUpdating] = useMutation<BannerSettingsFormMutation>(updateBannerMutation);
|
const [updateBanner, isUpdating] = useMutation<BannerSettingsFormMutation>(updateBannerMutation);
|
||||||
|
|
||||||
const [name, setName] = useState(banner.name);
|
const [name, setName] = useState(banner.name);
|
||||||
const [origin, setOrigin] = useState(banner.origin);
|
|
||||||
const [privacyPolicyUrl, setPrivacyPolicyUrl] = useState(banner.privacyPolicyUrl);
|
const [privacyPolicyUrl, setPrivacyPolicyUrl] = useState(banner.privacyPolicyUrl);
|
||||||
const [consentExpiryDays, setConsentExpiryDays] = useState(String(banner.consentExpiryDays));
|
const [consentExpiryDays, setConsentExpiryDays] = useState(String(banner.consentExpiryDays));
|
||||||
const [consentMode, setConsentMode] = useState(banner.consentMode);
|
const [consentMode, setConsentMode] = useState(banner.consentMode);
|
||||||
@@ -82,7 +80,6 @@ export function BannerSettingsForm({ cookieBannerKey }: BannerSettingsFormProps)
|
|||||||
input: {
|
input: {
|
||||||
cookieBannerId: banner.id,
|
cookieBannerId: banner.id,
|
||||||
name,
|
name,
|
||||||
origin,
|
|
||||||
privacyPolicyUrl,
|
privacyPolicyUrl,
|
||||||
consentExpiryDays: parseInt(consentExpiryDays, 10),
|
consentExpiryDays: parseInt(consentExpiryDays, 10),
|
||||||
consentMode: consentMode,
|
consentMode: consentMode,
|
||||||
@@ -108,7 +105,7 @@ export function BannerSettingsForm({ cookieBannerKey }: BannerSettingsFormProps)
|
|||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<Field label={__("Origin URL")}>
|
<Field label={__("Origin URL")}>
|
||||||
<Input value={origin} onChange={e => setOrigin(e.target.value)} required />
|
<Input value={banner.origin} disabled />
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
<Field label={__("Privacy Policy URL")}>
|
<Field label={__("Privacy Policy URL")}>
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ type (
|
|||||||
UpdateCookieBannerRequest struct {
|
UpdateCookieBannerRequest struct {
|
||||||
CookieBannerID gid.GID
|
CookieBannerID gid.GID
|
||||||
Name *string
|
Name *string
|
||||||
Origin *string
|
|
||||||
PrivacyPolicyURL *string
|
PrivacyPolicyURL *string
|
||||||
ConsentExpiryDays *int
|
ConsentExpiryDays *int
|
||||||
ConsentMode *coredata.CookieConsentMode
|
ConsentMode *coredata.CookieConsentMode
|
||||||
@@ -175,7 +174,6 @@ func (r *UpdateCookieBannerRequest) Validate() error {
|
|||||||
|
|
||||||
v.Check(r.CookieBannerID, "cookie_banner_id", validator.Required(), validator.GID(coredata.CookieBannerEntityType))
|
v.Check(r.CookieBannerID, "cookie_banner_id", validator.Required(), validator.GID(coredata.CookieBannerEntityType))
|
||||||
v.Check(r.Name, "name", validator.SafeTextNoNewLine(255))
|
v.Check(r.Name, "name", validator.SafeTextNoNewLine(255))
|
||||||
v.Check(r.Origin, "origin", validator.Origin())
|
|
||||||
v.Check(r.PrivacyPolicyURL, "privacy_policy_url", validator.URL())
|
v.Check(r.PrivacyPolicyURL, "privacy_policy_url", validator.URL())
|
||||||
v.Check(r.ConsentExpiryDays, "consent_expiry_days", validator.Min(1))
|
v.Check(r.ConsentExpiryDays, "consent_expiry_days", validator.Min(1))
|
||||||
v.Check(r.ConsentMode, "consent_mode", validator.OneOfSlice(coredata.CookieConsentModes()))
|
v.Check(r.ConsentMode, "consent_mode", validator.OneOfSlice(coredata.CookieConsentModes()))
|
||||||
@@ -775,9 +773,6 @@ func (s *Service) UpdateCookieBanner(
|
|||||||
if req.Name != nil {
|
if req.Name != nil {
|
||||||
banner.Name = *req.Name
|
banner.Name = *req.Name
|
||||||
}
|
}
|
||||||
if req.Origin != nil {
|
|
||||||
banner.Origin = CanonicalizeOrigin(*req.Origin)
|
|
||||||
}
|
|
||||||
if req.PrivacyPolicyURL != nil {
|
if req.PrivacyPolicyURL != nil {
|
||||||
banner.PrivacyPolicyURL = *req.PrivacyPolicyURL
|
banner.PrivacyPolicyURL = *req.PrivacyPolicyURL
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -392,7 +392,6 @@ func (b *CookieBanner) Update(
|
|||||||
UPDATE cookie_banners
|
UPDATE cookie_banners
|
||||||
SET
|
SET
|
||||||
name = @name,
|
name = @name,
|
||||||
origin = @origin,
|
|
||||||
state = @state,
|
state = @state,
|
||||||
privacy_policy_url = @privacy_policy_url,
|
privacy_policy_url = @privacy_policy_url,
|
||||||
consent_expiry_days = @consent_expiry_days,
|
consent_expiry_days = @consent_expiry_days,
|
||||||
@@ -410,7 +409,6 @@ WHERE
|
|||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": b.ID,
|
"id": b.ID,
|
||||||
"name": b.Name,
|
"name": b.Name,
|
||||||
"origin": b.Origin,
|
|
||||||
"state": b.State,
|
"state": b.State,
|
||||||
"privacy_policy_url": b.PrivacyPolicyURL,
|
"privacy_policy_url": b.PrivacyPolicyURL,
|
||||||
"consent_expiry_days": b.ConsentExpiryDays,
|
"consent_expiry_days": b.ConsentExpiryDays,
|
||||||
|
|||||||
@@ -269,7 +269,6 @@ func (r *mutationResolver) UpdateCookieBanner(ctx context.Context, input types.U
|
|||||||
cookiebanner.UpdateCookieBannerRequest{
|
cookiebanner.UpdateCookieBannerRequest{
|
||||||
CookieBannerID: input.CookieBannerID,
|
CookieBannerID: input.CookieBannerID,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Origin: input.Origin,
|
|
||||||
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||||
ConsentExpiryDays: input.ConsentExpiryDays,
|
ConsentExpiryDays: input.ConsentExpiryDays,
|
||||||
ConsentMode: input.ConsentMode,
|
ConsentMode: input.ConsentMode,
|
||||||
@@ -280,9 +279,6 @@ func (r *mutationResolver) UpdateCookieBanner(ctx context.Context, input types.U
|
|||||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||||
return nil, gqlutils.NotFound(ctx, err)
|
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 {
|
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,7 +274,6 @@ input CreateCookieBannerInput {
|
|||||||
input UpdateCookieBannerInput {
|
input UpdateCookieBannerInput {
|
||||||
cookieBannerId: ID!
|
cookieBannerId: ID!
|
||||||
name: String
|
name: String
|
||||||
origin: String
|
|
||||||
privacyPolicyUrl: String
|
privacyPolicyUrl: String
|
||||||
consentExpiryDays: Int
|
consentExpiryDays: Int
|
||||||
consentMode: CookieConsentMode
|
consentMode: CookieConsentMode
|
||||||
|
|||||||
Reference in New Issue
Block a user