Skip to content

Conversation

@tvandort
Copy link
Contributor

@tvandort tvandort commented Nov 11, 2025

Ticket ENG-1841

Description Of Changes

Allows the Fides consent cookie to be written with a suffix.

Set fides_cookie_suffix to apply the suffix. Fides will read and write from the newly named cookie allowing vendor segmentation of consent.

Code Changes

  • Allows fides_cookie_suffix setting to be set.
  • Allows cookie to have suffix.

Steps to Confirm

  1. Set up fides.js to serve an experience. Easier if you choose an experience with a banner
  2. Get the banner and save your consent settings
  3. In your url set https://localhost?fides_cookie_suffix=example_company
  4. You should see the banner resurface
  5. Save consent preferences
  6. Check that the saved cookie has your suffix
  7. Reload the page with the suffix, you should have no banner
  8. Reload the page without a suffix, you should have no banner

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

@vercel
Copy link

vercel bot commented Nov 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
fides-plus-nightly Ignored Ignored Preview Nov 13, 2025 4:10pm
fides-privacy-center Ignored Ignored Nov 13, 2025 4:10pm

Comment on lines +102 to +106
config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;
Copy link
Contributor Author

@tvandort tvandort Nov 12, 2025

Choose a reason for hiding this comment

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

Make it clearer that this order needs to be maintained before calling getFidesConsentCookie. I think the order these were called before was "potentially buggy" in the sense that it wasn't refactor friendly.

Can I get the type system to cooperate in expressing this by adding some "overriden" string like type flag to the merged object?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is possible but too ambitious for right now. Maybe later unless someone else has a good idea.

@tvandort tvandort force-pushed the ENG-1841 branch 2 times, most recently from 959e286 to 688a8a9 Compare November 12, 2025 22:33
@tvandort tvandort marked this pull request as ready for review November 12, 2025 22:40
@tvandort tvandort requested a review from a team as a code owner November 12, 2025 22:40
@tvandort tvandort requested review from gilluminate and removed request for a team November 12, 2025 22:40
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 12, 2025

Greptile Overview

Greptile Summary

This PR implements cookie suffix support for Fides consent cookies, allowing vendor segmentation by enabling different consent cookies based on a fides_cookie_suffix query parameter or window override.

Key Changes

  • Added fidesCookieSuffix option that can be set via query param (?fides_cookie_suffix=example_company), window object, or cookie
  • Cookie operations now use fides_consent_{suffix} instead of just fides_consent when suffix is provided
  • All cookie read/write operations updated to thread the suffix parameter through the codebase
  • Comprehensive test coverage added for suffix functionality

Critical Issue Found

Config merge timing bug in clients/fides-js/src/fides.ts:99-111: The config merge that applies optionsOverrides (including fidesCookieSuffix) happens AFTER the getFidesConsentCookie() call during migration check. This means the suffix won't be available when checking for migrated consent, causing the feature to fail when suffix is provided via query param or window overrides.

Other Issues

Potential DOM rendering bug: The Cypress test at clients/privacy-center/cypress/e2e/fides-js/consent-banner-cookie-suffix.cy.ts:278-289 contains a workaround comment indicating that after multiple page reloads with different cookie suffixes, the modal renders without its outer container wrapper. This suggests a component lifecycle/cleanup issue that should be investigated separately.

Confidence Score: 2/5

  • This PR has a critical logic bug that will break the feature when suffix is provided via query params or window overrides
  • The config merge timing issue is a blocking bug that prevents the feature from working correctly in the most common use case (runtime configuration). While the core implementation is solid and well-tested, this initialization order bug must be fixed before merge.
  • Pay close attention to clients/fides-js/src/fides.ts - the config merge must happen before the migration check

Important Files Changed

File Analysis

Filename Score Overview
clients/fides-js/src/lib/cookie.ts 4/5 Implements cookie suffix logic by adding getConsentCookieName() helper and updating all cookie operations to accept suffix parameter. Implementation is clean but has one critical bug in the config merge timing.
clients/fides-js/src/fides.ts 2/5 Critical bug: Config merge moved after getFidesConsentCookie() call, but the suffix won't be available yet. The migration check happens before options overrides are applied to config.
clients/privacy-center/cypress/e2e/fides-js/consent-banner-cookie-suffix.cy.ts 4/5 Thorough e2e tests covering suffix behavior. Contains workaround comment for DOM rendering bug after multiple reloads with different suffixes (lines 278-289).

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

25 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 99 to +111
// Register any configured consent migration providers
registerDefaultProviders(optionsOverrides);

config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;

// Check for migrated consent from any registered providers
let migratedConsent: NoticeConsent | undefined;

if (!getFidesConsentCookie()) {
if (!getFidesConsentCookie(config.options.fidesCookieSuffix)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: config merge must happen before getFidesConsentCookie() call

The config merge (lines 102-106) now happens AFTER the migration check on line 110, but getFidesConsentCookie(config.options.fidesCookieSuffix) is called before the suffix override is applied to config.options. This means the suffix from query params/window overrides won't be available yet during the migration check.

This ordering issue will cause the feature to fail when users provide fides_cookie_suffix via query param or window.fides_overrides - it will look for the wrong cookie name (without suffix) during migration.

Suggested change
// Register any configured consent migration providers
registerDefaultProviders(optionsOverrides);
config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;
// Check for migrated consent from any registered providers
let migratedConsent: NoticeConsent | undefined;
if (!getFidesConsentCookie()) {
if (!getFidesConsentCookie(config.options.fidesCookieSuffix)) {
// Register any configured consent migration providers
registerDefaultProviders(optionsOverrides);
config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;
// Check for migrated consent from any registered providers
let migratedConsent: NoticeConsent | undefined;
if (!getFidesConsentCookie(config.options.fidesCookieSuffix)) {
const { consent, method } = readConsentFromAnyProvider(optionsOverrides);
if (consent && method) {
migratedConsent = consent;
}
}
/* END THIRD PARTY CONSENT MIGRATION */

Copy link
Contributor Author

Choose a reason for hiding this comment

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

dear reptile,

what?

sincerely,
me

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at your comment, you've identified a critical ordering bug! The issue is that getFidesConsentCookie(config.options.fidesCookieSuffix) is being called on line 111 before the config merge happens on lines 102-106, which means the fidesCookieSuffix from overrides won't be available yet.

Here's the fix to move the config merge before the migration check:

Suggested change
// Register any configured consent migration providers
registerDefaultProviders(optionsOverrides);
config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;
// Check for migrated consent from any registered providers
let migratedConsent: NoticeConsent | undefined;
if (!getFidesConsentCookie()) {
if (!getFidesConsentCookie(config.options.fidesCookieSuffix)) {
// Register any configured consent migration providers
registerDefaultProviders(optionsOverrides);
config = {
...config,
options: { ...config.options, ...overrides.optionsOverrides },
};
this.config = config;
// Check for migrated consent from any registered providers
let migratedConsent: NoticeConsent | undefined;
if (!getFidesConsentCookie(config.options.fidesCookieSuffix)) {
const { consent, method } = readConsentFromAnyProvider(optionsOverrides);
if (consent && method) {
migratedConsent = consent;
}
}

This ensures that any fides_cookie_suffix provided via query params or window.fides_overrides gets applied to the config before we check for existing consent cookies during migration.

Copy link
Contributor Author

@tvandort tvandort Nov 12, 2025

Choose a reason for hiding this comment

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

hello

is the number 111 more or less than the number 102 or 106

thank you in advance

Copy link
Contributor

@gilluminate gilluminate left a comment

Choose a reason for hiding this comment

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

Looks really good overall! Just a couple of minor suggestions for clarity and consistency.

@tvandort tvandort enabled auto-merge November 13, 2025 16:09
@tvandort tvandort added this pull request to the merge queue Nov 13, 2025
Merged via the queue into main with commit 5248dbf Nov 13, 2025
42 of 43 checks passed
@tvandort tvandort deleted the ENG-1841 branch November 13, 2025 16:31
jjdaurora pushed a commit that referenced this pull request Dec 5, 2025
Co-authored-by: Nate Smith <nate@ethyca.com>
Co-authored-by: Jason Gill <jason.gill@ethyca.com>
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.

4 participants