From 09be7d8ed67f267fa386510ccb6ea604ab888ba9 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Mon, 22 Apr 2024 11:05:23 -0400 Subject: [PATCH] Cookie and Id updates Taken from FMG. --- src/constants/cookie-names.js | 12 ++++- src/helpers/cookie-helper.js | 84 ++++++++++++++++++++++++++++++++- src/helpers/date-helper.js | 12 +++++ src/helpers/unit-test-helper.js | 2 +- src/mixins/analytics-mixin.js | 52 ++++++++++---------- 5 files changed, 133 insertions(+), 29 deletions(-) diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js index df42423f..9ee326f4 100644 --- a/src/constants/cookie-names.js +++ b/src/constants/cookie-names.js @@ -1,4 +1,5 @@ import applicationConfig from '@/constants/application-config.js'; +import { convertToSeconds } from '@/helpers/date-helper.js'; /** * @module cookieNames @@ -8,6 +9,8 @@ import applicationConfig from '@/constants/application-config.js'; */ const cookieNames = Object.freeze({ ISS_SESSION_INFO: `ISSSessionInfo-${applicationConfig.CURRENT_ENVIRONMENT}`, + ISS_SESSION_KEY: `ISSSessionKey-${applicationConfig.CURRENT_ENVIRONMENT}`, + ISS_USER_ID: `ISSUserId-${applicationConfig.CURRENT_ENVIRONMENT}`, // Existing Safelite.com cookies DXDEV: 'dxdev', @@ -15,4 +18,11 @@ const cookieNames = Object.freeze({ SESSION_KEY: 'skey' }); -export default cookieNames; +const cookieExpirations = Object.freeze({ + SESSION_ID: convertToSeconds({ minutes: 30 }), + DXDEV: convertToSeconds({ years: 1 }), + ISS_USER_ID: convertToSeconds({ weeks: 1 }), + ISS_SESSION_KEY: convertToSeconds({ minutes: 30 }) +}); + +export { cookieNames, cookieExpirations }; diff --git a/src/helpers/cookie-helper.js b/src/helpers/cookie-helper.js index 18546702..9b5107ad 100644 --- a/src/helpers/cookie-helper.js +++ b/src/helpers/cookie-helper.js @@ -1,4 +1,4 @@ -import cookieNames from '@/constants/cookie-names'; +import { cookieNames, cookieExpirations } from '@/constants/cookie-names'; import applicationConfig from '@/constants/application-config'; import { useMainStore } from '@/store'; @@ -206,3 +206,85 @@ export function setCookieProperties( }); } } + +export function isCookieSet(name) { + const val = getCookieValueByName(name); + + return !!val; +} + +export function regenerateDeviceId() { + if (!isCookieSet(cookieNames.DXDEV)) { + setCookieProperties( + { + [cookieNames.DXDEV]: `did=${crypto.randomUUID()}` + }, + { maxAge: cookieExpirations.DXDEV } + ); + } +} + +export function regenerateUserId() { + if (!isCookieSet(cookieNames.ISS_USER_ID)) { + setCookieProperties( + { + [cookieNames.ISS_USER_ID]: crypto.randomUUID() + }, + { maxAge: cookieExpirations.ISS_USER_ID } + ); + } +} + +export function getUserIdValue() { + const cookieValue = getCookieValueByName(cookieNames.ISS_USER_ID); + + if (cookieValue) { + return cookieValue; + } + + return '00000000-0000-0000-0000-000000000000'; +} + +export function areAllSessionCookiesSet() { + return ( + isCookieSet(cookieNames.SESSION_ID) + && isCookieSet(cookieNames.DXDEV) + && isCookieSet(cookieNames.ISS_SESSION_KEY) + && isCookieSet(cookieNames.ISS_USER_ID) + ); +} + +export function refreshCookieExpiration(name, expirationTime) { + if (isCookieSet(name)) { + createOrUpdateCookie(name, getCookieValueByName(name), { maxAge: expirationTime }); + } +} + +export function refreshSessionExpiration() { + refreshCookieExpiration(cookieNames.SESSION_ID, cookieExpirations.SESSION_ID); + refreshCookieExpiration(cookieNames.DXDEV, cookieExpirations.DXDEV); + refreshCookieExpiration(cookieNames.ISS_USER_ID, cookieExpirations.ISS_USER_ID); + refreshCookieExpiration(cookieNames.ISS_SESSION_KEY, cookieExpirations.ISS_SESSION_KEY); +} + +export function setSessionIdIfUnset(value) { + if (!isCookieSet(cookieNames.SESSION_ID)) { + setCookieProperties( + { + [cookieNames.SESSION_ID]: value + }, + { maxAge: cookieExpirations.SESSION_ID } + ); + } +} + +export function setSessionKeyIfUnset(value) { + if (!isCookieSet(cookieNames.ISS_SESSION_KEY)) { + setCookieProperties( + { + [cookieNames.ISS_SESSION_KEY]: value + }, + { maxAge: cookieExpirations.ISS_SESSION_KEY } + ); + } +} diff --git a/src/helpers/date-helper.js b/src/helpers/date-helper.js index 70f598a6..c1ef3093 100644 --- a/src/helpers/date-helper.js +++ b/src/helpers/date-helper.js @@ -173,3 +173,15 @@ export function shortTimeString(date) { // Return undefined if the input is not a valid date object ? date.toLocaleTimeString('en-us', { hour: 'numeric', minute: 'numeric', hour12: true }) : undefined; } + +export function convertToSeconds({ years, months, weeks, days, hours, minutes, seconds }) { + let total = seconds ?? 0; + total += (minutes ?? 0) * 60; + total += (hours ?? 0) * 60 * 60; + total += (days ?? 0) * 24 * 60 * 60; + total += (weeks ?? 0) * 7 * 24 * 60 * 60; + total += (months ?? 0) * 30 * 24 * 60 * 60; + total += (years ?? 0) * 365 * 24 * 60 * 60; + + return total; +} diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index ac3a2694..3395b574 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -4,7 +4,7 @@ import { createTestingPinia } from '@pinia/testing'; import navigationScenarios from '@/router/router-constants/navigation-scenarios.js'; import vehicleCategories from '@/constants/vehicle-categories.js'; import issPageValues from '@/router/router-constants/issPage-values'; -import cookieNames from '@/constants/cookie-names'; +import { cookieNames } from '@/constants/cookie-names'; import { Form } from 'vee-validate'; import baseMixin from '@/mixins/base-mixin'; import { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 0d780c81..4ae25f38 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -1,9 +1,16 @@ +/* eslint-disable import/no-cycle */ import { - setCookieProperties, + areAllSessionCookiesSet, getDeviceIdValue, getSessionIdValue, - getSessionKeyValue + getSessionKeyValue, + getUserIdValue, + regenerateUserId, + regenerateDeviceId, + setSessionIdIfUnset, + setSessionKeyIfUnset } from '@/helpers/cookie-helper'; +import applicationConfig from '@/constants/application-config'; import queryStrings from '@/constants/query-strings'; import { experimentSettings } from '@/constants/experiments'; import { @@ -14,7 +21,6 @@ import { GaEvents, ValueToLogTypes } from '@/constants/analytics'; -import cookieNames from '@/constants/cookie-names'; import { useMainStore } from '@/store'; function pushToDataLayerIfDefined(data) { @@ -151,42 +157,36 @@ export default { }, async initSession() { - const sid = getSessionIdValue(); - const skey = getSessionKeyValue(); + regenerateDeviceId(); + regenerateUserId(); + + const deviceId = getDeviceIdValue(); // cookieNames.DXDEV + const userId = getUserIdValue(); // cookieNames.ISS_USER_ID + const sid = getSessionIdValue(); // cookieNames.SESSION_ID + // const skey = getSessionKeyValue(); + const referrer = applicationConfig.CURRENT_ENVIRONMENT !== 'Localhost' ? document.referrer : null; const payload = { - userId: getDeviceIdValue(), + deviceId, + referrer, sessionId: sid, - userAgent: navigator.userAgent, - referrer: document.referrer + userId, + userAgent: navigator.userAgent }; const response = await useMainStore().initializeSession(payload); if (response?.data) { - if (response?.data.sessionKey && skey === 0) { - setCookieProperties( - { [cookieNames.SESSION_KEY]: response?.data.sessionKey }, - { - useDefaultFunnelCookieAttributes: false - } - ); + if (response?.data.sessionKey) { + setSessionKeyIfUnset(response.data.sessionKey); } - if (response?.data.sessionId && sid === '00000000-0000-0000-0000-000000000000') { - setCookieProperties( - { [cookieNames.SESSION_ID]: response?.data.sessionId }, - { - maxAge: 60 * 30 // 30 minutes - } - ); + if (response?.data.sessionId) { + setSessionIdIfUnset(response.data.sessionId); } } }, noSession() { - return ( - getSessionKeyValue() === 0 - || getSessionIdValue() === '00000000-0000-0000-0000-000000000000' - ); + return !areAllSessionCookiesSet(); } }, computed: {