From e15ea5927d766d3996468096177be4966018e46d Mon Sep 17 00:00:00 2001 From: "US\\katie.kroell" Date: Tue, 19 May 2026 11:51:33 -0400 Subject: [PATCH 1/6] update stylesheet naming --- src/styles/client-customizations.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/styles/client-customizations.scss b/src/styles/client-customizations.scss index 0392e5f2..8cb89995 100644 --- a/src/styles/client-customizations.scss +++ b/src/styles/client-customizations.scss @@ -1,8 +1,8 @@ // Each Advanced client with custom colors/styles are defined in this file. -// Begin Liberty Mutual, SafeCo Custom Colors and Styles +// Begin Liberty Mutual, Safeco Custom Colors and Styles .LibertyMutual, -.SafeCo { +.SafecoInsurance { //Define colors for namespaced classes $header-background: #ffd100; $accent-fill: #e6f1f3; // Calendar background @@ -50,7 +50,7 @@ } } -// End Liberty Mutual, SafeCo +// End Liberty Mutual, Safeco From f98a348b735351cf91428b34dc4794933ee04cdc Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Tue, 19 May 2026 13:15:21 -0400 Subject: [PATCH 2/6] Fixes for missing ClientTag value on session log. --- src/layouts/entry-page/entry-page.vue | 2 ++ src/mixins/analytics-mixin.js | 6 ++++++ src/router/index.js | 23 +++++++++++++++++++++++ src/store/index.js | 8 ++++++-- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/layouts/entry-page/entry-page.vue b/src/layouts/entry-page/entry-page.vue index 47031709..8b83f988 100644 --- a/src/layouts/entry-page/entry-page.vue +++ b/src/layouts/entry-page/entry-page.vue @@ -115,6 +115,8 @@ export default { return { isAuthorized: false }; } + this.mainStore.issConfig.clientTag = clientTag; + const resp = await validateISSClientTag(clientTag); if (!resp) { return { isAuthorized: false }; diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 4312d65c..29165735 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -554,7 +554,13 @@ export default { const sid = getSessionIdValue(); // cookieNames.SESSION_ID // const skey = getSessionKeyValue(); const referrer = applicationConfig.CURRENT_ENVIRONMENT !== 'Localhost' ? document.referrer : null; + const store = useMainStore(); + const clientTag = store.issConfig.clientTag; + const siteType = store.issConfig.siteType; + + const payload = { + clientTag, deviceId, referrer, sessionId: sid, diff --git a/src/router/index.js b/src/router/index.js index abbd9061..f5d4517f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,6 +35,19 @@ const routes = [ return await GoToAccessIsDenied(next); } + // This is a quick fix for a prod issue.... better fix will come later. + // This and experiment call for entry-page probably need to be called directly in the mounted + // secion of the entry-page. Can be here for every other page. + if (issPageToUse === issPageValues.ENTRY_PAGE ) + { + const store = useMainStore(); + const queryStringParams = parseQueryParms(to.query); + + if (queryStringParams.clienttag) { + store.issConfig.clientTag = queryStringParams.clienttag; + } + } + await analyticsMixin.methods.validateSession(); // Do not run these for the main entry page - as it is not part of the user flow. @@ -436,6 +449,16 @@ function arePagePrerequisitesValid(component) { return component.default.methods.arePagePrerequisitesValid === undefined || component.default.methods.arePagePrerequisitesValid(); } +// TODO: Put this function some place common. +function parseQueryParms(queryString) { + // Dump the query string parameters into an object + if (queryString) { + return Object.fromEntries(Object.entries(queryString).map(([key, value]) => [key.toLowerCase(), value])); + } + + return {}; +} + // Run SiteEntry and PageEntry triggers for experiments async function runExperiments(nextPage) { const store = useMainStore(); diff --git a/src/store/index.js b/src/store/index.js index 54f97918..ad3c7e40 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -254,6 +254,7 @@ export const getDefaultState = () => ({ clientDisplayName: 'Generic Insurance', // this is the default and will be overridden by the client's name or client display name. clientPossessiveName: 'Generic Insurance\'s', // this is the default and will be overridden by the client's name or client display name converted to possessive or the clients possessive name. clientHeader: {}, + clientTag: '', // ClientTag used by the client to enter the site. styleSheet: '', // Stylesheet used by the client. parentAccountNumber: 0, // Parent account number used by the client. billToAccountNumber: null, @@ -269,7 +270,7 @@ export const getDefaultState = () => ({ policyZipCode: null, dateOfLoss: null }, - siteType: null, + siteType: null, // SiteType / SubType the site is set to (Essential/Advanced). enableNoCompQuote: false } }); @@ -2242,6 +2243,7 @@ export const useMainStore = defineStore({ this.issConfig.clientFullName = 'Generic Insurance'; this.issConfig.clientDisplayName = 'Generic Insurance'; this.issConfig.clientHeader = {}; + this.issConfig.clientTag = ''; this.issConfig.parentAccountNumber = 0; this.issConfig.styleSheet = ''; this.issConfig.isCoverageEnabled = false; @@ -2632,9 +2634,11 @@ export const useMainStore = defineStore({ this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN); this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN); }, - async initializeSession({ userId, sessionId, userAgent, referrer }) { + async initializeSession({ userId, clientTag, siteType, sessionId, userAgent, referrer }) { + //TODO: Add SubType passing ... that is also missing. const payload = { applicationName: applicationConfig.APPLICATION_NAME, + clientTag: clientTag, userId, deviceId: userId, sessionId, From ec5f6f2344bb377ee94b2a1271354eaa1fa2413a Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Tue, 19 May 2026 15:48:17 -0400 Subject: [PATCH 3/6] Fix an issue if mobile only zip has no appts --- src/layouts/schedule-page/schedule-page.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index c76aacce..0fae07bd 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -741,7 +741,7 @@ export default { startDate, endDate, this.selectedAppointmentType, - this.selectedProvider.providerNumber || mobileProviderNumberToUse, + this.selectedProvider?.providerNumber || mobileProviderNumberToUse, this.selectedMobileZipCode ); // ADD API CALL RESULTS TO EXISTING DATE DATA From a37020341f29d7d1736647d6f5f589c8b30ac8e9 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 20 May 2026 13:58:01 -0400 Subject: [PATCH 4/6] Refactored front end entry-page loading and session initialization. --- src/layouts/entry-page/entry-page.vue | 8 ++- src/mixins/analytics-mixin.js | 2 +- src/router/index.js | 81 +++++++++++++++------------ src/store/index.js | 12 ++-- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/layouts/entry-page/entry-page.vue b/src/layouts/entry-page/entry-page.vue index 8b83f988..503827ac 100644 --- a/src/layouts/entry-page/entry-page.vue +++ b/src/layouts/entry-page/entry-page.vue @@ -15,6 +15,7 @@ import { useMainStore } from '@/store'; import showIssLoadingModal from '@/helpers/loading-modal-helper'; import applicationConfig from '@/constants/application-config'; import { toPossessive } from '@/helpers/text-helper'; +import analyticsMixin from '@/mixins/analytics-mixin'; export default { name: 'entry-page', @@ -36,7 +37,6 @@ export default { async mounted() { try { const queryStringParams = this.parseQueryParms(); - const { isAuthorized, clientData, decryptedParams } = await this.validateClientTagOnEntry(queryStringParams); this.unauthorized = !isAuthorized; @@ -46,7 +46,11 @@ export default { return; } + // Populate all the ISS Config values from the service call returns. this.populateISSConfigValues(clientData); + + // Session should only be created / validated on successful client tag validation to avoid unnecessary sessions for unauthorized users. + await analyticsMixin.methods.validateSession(); try { // Check cookie @@ -143,7 +147,7 @@ export default { isAuthorized = true; } - if (isAuthorized) { + if (isAuthorized) { clientData = resp; } } diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 29165735..d3c139c7 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -558,9 +558,9 @@ export default { const clientTag = store.issConfig.clientTag; const siteType = store.issConfig.siteType; - const payload = { clientTag, + siteType: siteType, deviceId, referrer, sessionId: sid, diff --git a/src/router/index.js b/src/router/index.js index f5d4517f..e0f34881 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,30 +35,6 @@ const routes = [ return await GoToAccessIsDenied(next); } - // This is a quick fix for a prod issue.... better fix will come later. - // This and experiment call for entry-page probably need to be called directly in the mounted - // secion of the entry-page. Can be here for every other page. - if (issPageToUse === issPageValues.ENTRY_PAGE ) - { - const store = useMainStore(); - const queryStringParams = parseQueryParms(to.query); - - if (queryStringParams.clienttag) { - store.issConfig.clientTag = queryStringParams.clienttag; - } - } - - await analyticsMixin.methods.validateSession(); - - // Do not run these for the main entry page - as it is not part of the user flow. - if (issPageToUse !== issPageValues.ENTRY_PAGE && issPageToUse !== issPageValues.BAILOUT_PAGE) { - try { - await runExperiments(issPageToUse); - } catch (error) { - console.error('Failed to run experiments during route navigation.', error); - } - } - // Intercept all navigation if a submitted order exists in storage if (useMainStore().hasSubmittedOrder()) { if (to.query.issPage !== issPageValues.ENTRY_PAGE) { @@ -97,15 +73,31 @@ const routes = [ var routeData = []; - try { - routeData = await GetRouteInfoFromPageName(issPageToUse); - } - catch ( error ) { - window.top.location = '/static/error/index.html'; - } + // Only load the routes if we are not on entry-page (this page is the default route and should always be valid) + if ( issPageToUse !== issPageValues.ENTRY_PAGE) { + try { + routeData = await GetRouteInfoFromPageName(issPageToUse); + } + catch ( error ) { + window.top.location = '/static/error/index.html'; + } - if (routeData[0].name.toLowerCase() === 'error') { - throw new Error('Page not found!'); + if (routeData[0].name.toLowerCase() === 'error') { + throw new Error('Page not found!'); + } + } + else { + try { + // Manually create the entry-page route. + routeData.push({ + path: '/', + name: issPageValues.ENTRY_PAGE, + component: lazyLoadComponent(issPageValues.ENTRY_PAGE) + }); + } + catch ( error ) { + window.top.location = '/static/error/index.html'; + } } // Add our dynamic route. @@ -190,14 +182,29 @@ router.afterEach(async (to, from) => { store.clearSaveSessionPromise(); } - const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; - if (from.name !== undefined && !skipSaveSession && !store.hasSubmittedOrder()) { - await saveSession({ bailoutOnError: from.name === issPageValues.ENTRY_PAGE}); - } - if (to.query.issPage !== issPageValues.ENTRY_PAGE) { + await analyticsMixin.methods.validateSession(); + + const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; + if (from.name !== undefined && !skipSaveSession && !store.hasSubmittedOrder()) { + await saveSession({ bailoutOnError: from.name === issPageValues.ENTRY_PAGE}); + } + document.title = routerTitles[to.query.issPage] || 'Safelite Solutions®'; + // Do not run experiments for entry page or the bailout page. + if (to.query.issPage !== issPageValues.BAILOUT_PAGE) { + try { + console.error(`Running experiments for page: ${to.query.issPage}`); + + // Run experiments for page. + await runExperiments(to.query.issPage); + + } catch (error) { + console.error('Failed to run experiments during route navigation.', error); + } + } + // digital consumer logging analyticsMixin.methods.logDigitalConsumer(); diff --git a/src/store/index.js b/src/store/index.js index ad3c7e40..b23f4d47 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2635,10 +2635,10 @@ export const useMainStore = defineStore({ this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN); }, async initializeSession({ userId, clientTag, siteType, sessionId, userAgent, referrer }) { - //TODO: Add SubType passing ... that is also missing. const payload = { applicationName: applicationConfig.APPLICATION_NAME, - clientTag: clientTag, + clientTag: clientTag, + subType: siteType, userId, deviceId: userId, sessionId, @@ -2946,7 +2946,9 @@ export const useMainStore = defineStore({ async validateClientTag(clientTag) { return globalMethods.callHttpClient({ method: endpoints.ValidateClientTag.method, - endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}` + endpoint: `${endpoints.ValidateClientTag.url}/${clientTag}`, + logApiCall: false, + bailoutOnError: false }); }, @@ -2960,7 +2962,9 @@ export const useMainStore = defineStore({ return await globalMethods.callHttpClient({ method: endpoints.ValidateClientSignature.method, endpoint: endpoints.ValidateClientSignature.url, - payload + payload, + logApiCall: false, + bailoutOnError: false }); }, From 71aa3594123830de96854682fa84a4188985ad64 Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Wed, 20 May 2026 15:36:00 -0400 Subject: [PATCH 5/6] Addressed some code review recommendations. --- src/router/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/router/index.js b/src/router/index.js index e0f34881..f6345aa6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -80,6 +80,7 @@ const routes = [ } catch ( error ) { window.top.location = '/static/error/index.html'; + return null; } if (routeData[0].name.toLowerCase() === 'error') { @@ -97,6 +98,7 @@ const routes = [ } catch ( error ) { window.top.location = '/static/error/index.html'; + return null; } } From 1bb496315668f2d5c462631f3781a31f569d234e Mon Sep 17 00:00:00 2001 From: Jeremy-Z Date: Thu, 21 May 2026 11:12:49 -0400 Subject: [PATCH 6/6] Added access-denied as part of the ignore logging / experiment logic. --- src/router/index.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index f6345aa6..1fbe148f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -74,7 +74,10 @@ const routes = [ var routeData = []; // Only load the routes if we are not on entry-page (this page is the default route and should always be valid) - if ( issPageToUse !== issPageValues.ENTRY_PAGE) { + // or the access-denied page (which is an error page) + const shouldGetRouteInfo = (issPageToUse !== issPageValues.ENTRY_PAGE && issPageToUse !== issPageValues.ACCESS_DENIED); + + if (shouldGetRouteInfo) { try { routeData = await GetRouteInfoFromPageName(issPageToUse); } @@ -89,11 +92,11 @@ const routes = [ } else { try { - // Manually create the entry-page route. + // Manually create the page route. routeData.push({ path: '/', - name: issPageValues.ENTRY_PAGE, - component: lazyLoadComponent(issPageValues.ENTRY_PAGE) + name: issPageToUse, + component: lazyLoadComponent(issPageToUse) }); } catch ( error ) { @@ -184,7 +187,13 @@ router.afterEach(async (to, from) => { store.clearSaveSessionPromise(); } - if (to.query.issPage !== issPageValues.ENTRY_PAGE) { + // Do not run base page logic (GA logging, session logging etc..) on the entry page or access denied page. + const shouldRunPageLogic = (to.query.issPage !== issPageValues.ENTRY_PAGE && to.query.issPage !== issPageValues.ACCESS_DENIED); + + if (shouldRunPageLogic) { + // Do not run experiments for the bailout page. + const shouldRunExperiments = (to.query.issPage !== issPageValues.BAILOUT_PAGE); + await analyticsMixin.methods.validateSession(); const skipSaveSession = !!router.options.history.state[routerParams.SKIP_SAVE_SESSION]; @@ -194,11 +203,8 @@ router.afterEach(async (to, from) => { document.title = routerTitles[to.query.issPage] || 'Safelite Solutions®'; - // Do not run experiments for entry page or the bailout page. - if (to.query.issPage !== issPageValues.BAILOUT_PAGE) { + if (shouldRunExperiments) { try { - console.error(`Running experiments for page: ${to.query.issPage}`); - // Run experiments for page. await runExperiments(to.query.issPage);