diff --git a/dotcom-rendering/src/client/userFeatures/user-features.ts b/dotcom-rendering/src/client/userFeatures/user-features.ts index 6648e62e1e1..14c07ac2ab4 100644 --- a/dotcom-rendering/src/client/userFeatures/user-features.ts +++ b/dotcom-rendering/src/client/userFeatures/user-features.ts @@ -4,6 +4,7 @@ * https://github.com/guardian/commercial/blob/1a429d6be05657f20df4ca909df7d01a5c3d7402/src/lib/user-features.ts */ +import { removeCookie } from '@guardian/libs'; import { getAuthStatus, isUserLoggedIn } from '../../lib/identity'; import { AD_FREE_USER_COOKIE } from './cookies/adFree'; import { ALLOW_REJECT_ALL_COOKIE } from './cookies/allowRejectAll'; @@ -36,28 +37,59 @@ const requestNewData = async () => { return syncDataFromUserBenefitsApi(authStatus).then(persistResponse); }; +const USER_BENEFITS_COOKIE_EXPIRATION_IN_DAYS = 30; + /** * Persist the user benefits response to cookies * - * If new cookies are added/removed/edited, update the persistUserBenefitsCookie function in Gateway - * https://github.com/guardian/gateway/blob/252b2b2f24be826da42c6e7c1b1e202594184023/src/server/lib/user-features.ts#L88 - * + * If new cookies are added/removed/edited, update the persistUserBenefitsCookies function in Gateway. * In gateway, the cookies are set after authentication. * + * This code also exist in frontend, so any changes here should be mirrored there. + * * @param {UserBenefits} userBenefitsResponse */ const persistResponse = (userBenefitsResponse: UserBenefits) => { createOrRenewCookie(USER_BENEFITS_EXPIRY_COOKIE); + + // All of these user benefits cookies are now valid for 30 days. Previously + // they were short lived (1-2 days) but this resulted in edge cases where if + // a signed in user didn't visit the site for more than a couple of days + // when they returned their first page view wouldn't reflect their benefits + // (i.e. they would see ads). This is due to a race condition between the + // user benefits refresh and the ads code. However, we don't want to delay + // ads until after the user benefits have been refreshed as that would + // impact performance. So instead, extend the expiry of the cookie. Note: + // this may result in a user getting benefits they no longer have on the + // first returning pageview, but this will be correct from the second page + // view onwards. We think this is OK. This also means we now remove cookies + // if the user benefits response says they no longer have the benefit, + // rather than simply letting the cookie expire. if (userBenefitsResponse.hideSupportMessaging) { - createOrRenewCookie(HIDE_SUPPORT_MESSAGING_COOKIE); + createOrRenewCookie( + HIDE_SUPPORT_MESSAGING_COOKIE, + USER_BENEFITS_COOKIE_EXPIRATION_IN_DAYS, + ); + } else { + removeCookie({ name: HIDE_SUPPORT_MESSAGING_COOKIE }); } + if (userBenefitsResponse.allowRejectAll) { - createOrRenewCookie(ALLOW_REJECT_ALL_COOKIE); + createOrRenewCookie( + ALLOW_REJECT_ALL_COOKIE, + USER_BENEFITS_COOKIE_EXPIRATION_IN_DAYS, + ); + } else { + removeCookie({ name: ALLOW_REJECT_ALL_COOKIE }); } - // Ad free cookie has an expiry of 2 days from now - // See https://github.com/guardian/gateway/blob/52f810a88fa9ce23c6a794916251748718742c3d/src/server/lib/user-features.ts#L111-L115 + if (userBenefitsResponse.adFree) { - createOrRenewCookie(AD_FREE_USER_COOKIE, 2); + createOrRenewCookie( + AD_FREE_USER_COOKIE, + USER_BENEFITS_COOKIE_EXPIRATION_IN_DAYS, + ); + } else { + removeCookie({ name: AD_FREE_USER_COOKIE }); } };