Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add single cookie consent API #3854

Merged
merged 7 commits into from Mar 8, 2024
Merged

Add single cookie consent API #3854

merged 7 commits into from Mar 8, 2024

Conversation

andysellick
Copy link
Contributor

@andysellick andysellick commented Feb 6, 2024

What / why

Adds code for the single consent cookie API to allow cookie preferences to be shared across GOV.UK.

Supersedes #3829

How this works

The single consent API should take control of the setting of cookies relating to cookie consent. Fortunately it sets exactly the same cookies as we do now:

  • cookies_preferences_set indicating that a user preference has been made
  • cookies_policy showing the preferences chosen (set by default to no consent)

Testing scenarios

There are two main things to test - when the consent API is enabled, and when it is not. When it is not enabled (by default) everything should work as normal. This means:

  • a users first visit should set the cookies_policy to reject all but essential cookies, and no other cookies
  • when they choose a preference (accept/reject/custom), this should be reflected in the cookies_policy cookie, and the cookies_preferences_set cookie should also be set
  • the page at /help/cookies should reflect the contents of the cookies_policy cookie, and allow it to be changed

When the consent API is enabled, the behaviour should be similar but the consent API code should set these cookies, not our code. Additionally:

  • no cookies are set until the user makes a choice
  • when the user chooses a cookie preference (accept/reject/custom), the consent API code makes an XMLHttpRequest to the consent API
  • if this is successful, it sets a gov_singleconsent_uid cookie, containing the users randomly generated anonymous ID
  • if this fails (e.g. timeout), this cookie is not set and the consent preferences are all set to reject
  • on any following pages, the consent API code will not attempt to reconnect to the API, and leave user consent as rejected

Testing locally

Check out this branch and run yarn install to get the single consent API code.

To make testing easier and keep the gem compatible with applications that do not need the single consent API, it is disabled by default. It is enabled by setting window.GOVUK.useSingleConsentApi = true. For the purposes of testing this can be set in your local static.

You'll need to run frontend (it renders the cookies page) running locally through docker with a local static, both pointed at this branch of the components gem. You'll need to modify config/initializers/content_security_policy.rb in frontend so that the CSP allows JS to make requests to the consent API. The staging URL has changed during development, is currently https://gds-single-consent-staging.app/.

GovukContentSecurityPolicy.configure do |policy|
  policy.connect_src(*policy.connect_src, "<staging url>")
end

You can test the scenario of arriving at GOV.UK having set cookie preferences on another site by either:

  • using a URL of the form: https://www.gov.uk?gov_singleconsent_uid=<id>. You can get the value for id by from the gov_singleconsent_uid cookie (after it has been successfully set)
  • accept cookies and let the consent api set the gov_singleconsent_uid cookie, then delete all other cookies (this wouldn't happen in real life, but it's an easy way of simulating the consent api already being initialised)

To test link decoration going from GOV.UK to a participating site you can use the consent API staging site https://gds-single-consent-staging.app/ (this is why the staging URL is both the API interface and an actual website). Do the following:

  • modify a page in frontend to have a link to the staging site
  • in the components gem code, open node_modules/govuk-single-consent/dist/singleconsent.iife.js and modify the function (origins) code around line 357 to include the following line before setting addUIDtoCrossOriginLinks:
origins.push('https://gds-single-consent-staging.app') // or whatever the staging URL is
  • click on the link
  • the link should be automatically decorated with a URL parameter, will immediately disappear when the page has loaded, so you can check it's worked by comparing the cookie settings on the staging site with what you set on your local site. You can also scroll to the bottom of the staging site and click on the Cookies link to change your preferences, then go back to your local site to confirm that changing preferences works both ways.

Cumulative Layout Shift impact

Broadly - no impact. I suspect this is mostly due to recent changes to hide the banner by default and when JS is disabled.

All tests run locally to account for differences in local and production, however testable scores on production are the same. Testing carried out locally on frontend, homepage.

Desktop

Without consent api With consent api
accept all cookies - 0 accept all cookies - 0
reject all cookies - 0 reject all cookies - 0
no cookie preference made - 0.31 no cookie preference made - 0.31
(not available) with only a valid govuk_consent_id cookie (to force the consent api call) - 0

Mobile

Without consent api With consent api
accept all cookies - 0.003 accept all cookies - 0.003
reject all cookies - 0.003 reject all cookies - 0.003
no cookie preference made - 0.486 no cookie preference made - 0.486
(not available) with only a valid govuk_consent_id cookie (to force the consent api call) - 0.003

Visual Changes

None.

Trello card: https://trello.com/c/dmlTAzKB/140-implement-single-consent-api

@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 6, 2024 09:55 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 6, 2024 10:50 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 6, 2024 16:10 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 6, 2024 16:12 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 7, 2024 09:56 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 7, 2024 10:03 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 7, 2024 11:25 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 7, 2024 17:29 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 12:53 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 13:10 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 13:12 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 13:13 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 13:24 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 14:09 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 15:37 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 February 8, 2024 15:44 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 4, 2024 12:25 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 5, 2024 14:42 Inactive
@govuk-ci govuk-ci had a problem deploying to components-gem-pr-3854 March 5, 2024 14:48 Failure
@govuk-ci govuk-ci had a problem deploying to components-gem-pr-3854 March 5, 2024 14:48 Failure
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 5, 2024 14:55 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 5, 2024 15:21 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 6, 2024 11:54 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 6, 2024 11:55 Inactive
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 6, 2024 12:06 Inactive
- adds code to include and manage our use of the single consent API code
- init is called by the cookie banner code on every page, which determines which API endpoint to use (staging or prod) and creates the GovSingleConsent object
- useConsentApi is called across the code to check whether or not to use the consent API, this will be set in static
- the default callback for the consent object checks the returned response and if the user has consented, triggers the cookie-consent event, which will initialise analytics and hide the cookie banner
- setPreferences allows user consent to be set through the API
- use load analytics environment list for consent API URL
- update the cookie banner component JS to use the single consent API code
- stores an internal variable to check whether or not to use the consent API
- if false, behaviour should be as normal
- if true, should yield setting of consent cookies entirely to the consent API code
- update cookie banner tests accordingly
- updates the JavaScript for the cookie settings page to use the single consent API code
- stores an internal variable to check whether or not to use the consent API
- if false, behaviour should be as normal
- if true, should yield setting of consent cookies entirely to the consent API code
- note that this code sends its own callback function for the consent API, which sets the initial form values on page load, this means that any delay in the API call will result in these fields being unfilled until it responds
- previously the consent cookie was always set (to reject all cookies) prior to user choice
- now that we're not doing that, the code that turns links to Youtube videos in govspeak content into embedded videos was checking for the consent cookie, not finding it, and defaulting to... true.
- this meant that videos were appearing on a page before users had consented to cookies
- setting the default value to false seems to be the simplest way to fix this. Videos still initialise automatically as before once cookies are consented to
- now that the domain config contains information about more than just analytics, it feels like it should be separated out for clarity
- updated docs and tests accordingly
@govuk-ci govuk-ci temporarily deployed to components-gem-pr-3854 March 8, 2024 10:01 Inactive
@andysellick andysellick changed the title [DO NOT MERGE] Add single cookie consent API Add single cookie consent API Mar 8, 2024
Copy link
Contributor

@AshGDS AshGDS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work 👍

@andysellick andysellick merged commit 385edf6 into main Mar 8, 2024
12 checks passed
@andysellick andysellick deleted the single-consent-api branch March 8, 2024 12:37
@andysellick andysellick mentioned this pull request Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants