import { cookieNames, cookieExpirations } from '@/constants/cookie-names'; import applicationConfig from '@/constants/application-config'; import { useMainStore } from '@/store'; /** * @function isLocalhost */ function isLocalhost() { // eslint-disable-next-line no-restricted-globals return location.hostname.includes('localhost'); } /** * @function getCookieValueByName * @param {string} name * @summary * Gets cookie value by name, returns empty string if not found. */ function getCookieValueByName(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) { return parts.pop().split(';').shift(); } return ''; } /* Gets current domain without the subdomain for cookie. */ function getDomainWithoutSubdomain() { // eslint-disable-next-line no-restricted-globals const url = location.hostname; if (isLocalhost()) { return 'localhost'; } const urlParts = url.split('.'); return `.${urlParts .slice(0) .slice(-(urlParts.length === 4 ? 3 : 2)) .join('.')}`; } /* Gets cookie domain value. Localhost will be empty "". */ export function getCookieDomainValue() { return isLocalhost() ? '' : `domain=${getDomainWithoutSubdomain()};`; } /* Used to create a cookie. `useDefaultISSCookieAttributes` will set the path and domain to our defaults */ function createOrUpdateCookie( key, value = '', { useDefaultISSCookieAttributes = true, maxAge, isSecure = true } ) { let cookieToAdd = `${key}=${value}; `; if (useDefaultISSCookieAttributes) { cookieToAdd += `path=${applicationConfig.COOKIE_PATH}; ${getCookieDomainValue()} `; } if (isSecure && !isLocalhost()) { cookieToAdd += 'secure; '; } if (!Number.isNaN(maxAge)) { cookieToAdd += `max-age=${maxAge};`; } document.cookie = cookieToAdd; } /* Gets the current instance of the ISS cookie. Returns null if cookie isn't valid JSON. */ export function getISSCookie() { const cookieJson = document.cookie ?.split('; ') ?.find((row) => row.startsWith(`${cookieNames.ISS_SESSION_INFO}=`)) ?.split('=')[1]; try { return JSON.parse(cookieJson); } catch (error) { return null; } } /* Used to set properties on the ISS cookie. Takes an object with properties to set. Will overwrite existing properties. */ function setISSCookieProperties(properties) { if (typeof properties === 'object') { const cookie = getISSCookie(); if (cookie !== null) { Object.keys(properties).forEach((key) => { cookie[key] = properties[key]; }); } const cookieValueJson = JSON.stringify(cookie ?? {}); createOrUpdateCookie(cookieNames.ISS_SESSION_INFO, cookieValueJson, {}); } } /* Will update the cookie if present, or create a new one if not. */ export function updateOrCreateISSCookie() { const store = useMainStore(); // Set up cookie with all the props. setISSCookieProperties({ LastTouched: new Date().toUTCString(), SavedSessionTimeoutDate: store.applicationUser.savedSessionTimeout, ShouldResetState: false, ReferralNumber: store.order.referralNumber, ReferralDate: store.order.referralDate, ReferralCorrelationId: store.order.referralCorrelationId, ReferralParentAccountNumber: store.order.parentAccountNumber, SavedSessionId: store.applicationUser.savedSessionId }); } /* Removes cookie from browser. */ export function deleteISSCookie() { createOrUpdateCookie(cookieNames.ISS_SESSION_INFO, undefined, { maxAge: 0 }); } /* Gets value of dxdev cookie, and then extracts "did" value from it. Returns empty string if cookie not found or "did" string not present. */ export function getDeviceIdValue() { // Sometimes these cookie contains more than the device ID. const cookieValue = getCookieValueByName(cookieNames.DXDEV); const cookieValuesSplit = cookieValue.split('='); // If this is the only value, just use that. if (cookieValuesSplit.length === 2 && cookieValuesSplit[0] === 'did') { return cookieValuesSplit[1]; } const cookieValueMatch = cookieValue.match('^did=[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}'); if (cookieValueMatch) { return cookieValueMatch[0].split('=')[1]; } return '00000000-0000-0000-0000-000000000000'; } /* Gets value of skey cookie, returns 0 if not found. */ export function getSessionKeyValue() { const cookieValue = getCookieValueByName(cookieNames.SESSION_KEY); if (cookieValue) { return cookieValue; } return 0; } /* Gets value of skey cookie, returns 0 if not found. */ export function getSessionIdValue() { const cookieValue = getCookieValueByName(cookieNames.SESSION_ID); if (cookieValue) { return cookieValue; } return '00000000-0000-0000-0000-000000000000'; } /* Updates session ID cookie with new expiration date */ export function updateSessionIdCookie() { createOrUpdateCookie(cookieNames.SESSION_ID, getSessionIdValue(), { maxAge: 60 * 30 }); } export function setCookieProperties( properties, { useDefaultISSCookieAttributes = true, maxAge, isSecure } ) { if (typeof properties === 'object') { Object.keys(properties).forEach((key) => { createOrUpdateCookie(key, properties[key], { useDefaultISSCookieAttributes, maxAge, isSecure }); }); } } 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 } ); } }