From f7b452351dba0afc7d10a03a9d4faa107d32cbf7 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 10 Nov 2025 12:50:10 -0500 Subject: [PATCH] Organization + Delete Cookies + Send Pageview request --- public/static/error/index.html | 253 +++++++++++++++++++++++++-------- 1 file changed, 190 insertions(+), 63 deletions(-) diff --git a/public/static/error/index.html b/public/static/error/index.html index a4c141f85..53bb9fc08 100644 --- a/public/static/error/index.html +++ b/public/static/error/index.html @@ -114,7 +114,7 @@ body { debug: true, }, { - name: 'Test', + name: 'SysTest', hostName: 'www-test2.safelite.com', apiHostname: 'digitalapi.test.safelite.io', debug: true, @@ -142,83 +142,178 @@ body { return match; } + function getExperimentSettingsFromVuex(vuexData) { + const experiments = vuexData?.applicationUser?.experiments; + + if(experiments) { + return experiments + .filter((e) => !!e.isActive) + .map((e) => e.settings) + .reduce((prev, next) => Object.assign(prev, next), {}) ?? {}; + } + + return {}; + } + + function extractDataFromVuex(existingVuexData) { + let bailoutInfo = []; + let headerInfo = []; + + try { + // =============== Collect diagnostic data: + bailoutInfo = []; + + // App & Site Name + bailoutInfo.push({ name: 'App Name', value: 'FixMyGlass' }); + bailoutInfo.push({ name: 'Site Name', value: 'SafeliteDotcom' }); + + // Not included (yet) from heritage: + // - Site ID + // - Code + // - Module + // - Page + + bailoutInfo.push({ name: 'Timestamp', value: `${new Date()}` }); + + // - URL + // - Server + + const sessionId = getCookieValueByName('sid'); + bailoutInfo.push({ name: 'Session Id', value: sessionId }); + + const userAgent = window.navigator.userAgent; + bailoutInfo.push({ name: 'User Agent', value: userAgent }); + + // - IP + // - Session Log Sequence Number + + bailoutInfo.push({ name: 'Referral Seq Number', value: existingVuexData.order?.referralSequenceNumber }); + bailoutInfo.push({ name: 'Referral Number', value: existingVuexData.order?.referralNumber }); + bailoutInfo.push({ name: 'Referral Date', value: existingVuexData.order?.referralDate }); + bailoutInfo.push({ name: 'Referral Provider Number', value: existingVuexData.order?.serviceLocation?.provider?.providerNumber }); + bailoutInfo.push({ name: 'Referral CTU', value: existingVuexData.order?.serviceLocation?.provider?.address?.zipCodeCtu }); + + // - Referral Insured Zip + // - Referral Insured Service Zip + + bailoutInfo.push({ name: 'Referral CarID', value: existingVuexData.order?.vehicle?.carId }); + + const vehicle = existingVuexData.order?.vehicle; + const vehicleString = vehicle?.year + ? `${vehicle.year} ${vehicle.make} ${vehicle.model} - ${vehicle.style}` + : null; + bailoutInfo.push({ name: 'Referral Vehicle', value: vehicleString }); + bailoutInfo.push({ name: 'Work Order Number', value: existingVuexData.order?.workOrderNumber }); + bailoutInfo.push({ name: 'Work Order ID', value: existingVuexData.order?.workOrderId }); + bailoutInfo.push({ name: 'Parent Account Number', value: existingVuexData.order?.payment?.parentAccountNumber }); + + const environmentData = getCurrentEnvironmentData(); + const userIdCookieName = `FunnelUserId-${environmentData?.name}`; + bailoutInfo.push({ name: 'User Id', value: getCookieValueByName(userIdCookieName) }); + + // - Parent Account Name + // - Client GUID + + // =============== Collect header data: + headerInfo = []; + + headerInfo.push({ name: 'X-Experiment-Data', value: JSON.stringify(getExperimentSettingsFromVuex(existingVuexData)) }); + headerInfo.push({ name: 'X-Application-Name', value: 'FixMyGlass' }); + + const sessionKeyCookieName = `FunnelSessionKey-${environmentData?.name}`; + + headerInfo.push({ name: 'X-Session-Sequence-Number', value: getCookieValueByName(sessionKeyCookieName) }); + headerInfo.push({ name: 'X-Referral-Sequence-Number', value: existingVuexData?.order?.referralSequenceNumber }); + headerInfo.push({ name: 'X-Enterprise-Order-Number', value: existingVuexData?.order?.eon }); + headerInfo.push({ name: 'log-enabled', value: existingVuexData?.applicationUser?.loggingOption ?? false }); + } finally { + return { + headerInfo: headerInfo, + bailoutInfo: bailoutInfo + }; + } + } + + function generateRequestHeader(headerInfo) { + let headers = {}; + + headerInfo.forEach( + keyPair => { + headers[keyPair.name] = keyPair.value; + } + ); + + headers['X-Transaction-Id'] = crypto.randomUUID(); + + headers['Content-Type'] = 'application/json'; + + return headers; + } + + function getFieldWithName(info, name) { + const match = info?.find( + (row) => row.name === name + ); + + return match?.value; + } + + function clearApplicationData() { + window.localStorage.removeItem('vuex'); + + const environmentData = getCurrentEnvironmentData(); + const cookieNames = [ + `FunnelUserId-${environmentData?.name}`, + `FunnelSessionKey-${environmentData?.name}`, + `FunnelSessionInfo-${environmentData?.name}`, + `sid`, + `dxdev`, + ]; + + cookieNames.forEach( + (cookieName) => { + let cookieToAdd = `${cookieName}=undefined; path=/; domain=${environmentData.hostName}; max-age=0`; + document.cookie = cookieToAdd; + } + ) + } + window.onload = async () => { // =============== Check for session info: const existingVuexDataJSON = window.localStorage.getItem('vuex'); const existingVuexData = existingVuexDataJSON ? JSON.parse(existingVuexDataJSON) : null; const existingBailoutInfoJSON = window.sessionStorage.getItem('bailoutInfo'); const existingBailoutInfo = existingBailoutInfoJSON ? JSON.parse(existingBailoutInfoJSON) : null; + const existingHeaderInfoJSON = window.sessionStorage.getItem('headerInfo'); + const existingHeaderInfo = existingHeaderInfoJSON ? JSON.parse(existingHeaderInfoJSON) : null; console.log(`================ VUEX DATA`); console.log(existingVuexData); console.log(`================ PRIOR BAILOUT DATA`); console.log(existingBailoutInfo); + console.log(`================ PRIOR HEADER DATA`); + console.log(existingHeaderInfo); let bailoutInfo = null; + let headerInfo = null; if(existingVuexData) { - try { - // =============== Collect diagnostic data: - bailoutInfo = []; + const results = extractDataFromVuex(existingVuexData); + bailoutInfo = results.bailoutInfo; + headerInfo = results.headerInfo; - // App & Site Name - bailoutInfo.push({ name: 'App Name', value: 'FixMyGlass' }); - bailoutInfo.push({ name: 'Site Name', value: 'SafeliteDotcom' }); + clearApplicationData(); - // Not included (yet) from heritage: - // - Site ID - // - Code - // - Module - // - Page - - bailoutInfo.push({ name: 'Timestamp', value: `${new Date()}` }); - - // - URL - // - Server - - const sessionId = getCookieValueByName('sid'); - bailoutInfo.push({ name: 'Session Id', value: sessionId }); - - const userAgent = window.navigator.userAgent; - bailoutInfo.push({ name: 'User Agent', value: userAgent }); - - // - IP - // - Session Log Sequence Number - - bailoutInfo.push({ name: 'Referral Seq Number', value: existingVuexData.order?.referralSequenceNumber }); - bailoutInfo.push({ name: 'Referral Number', value: existingVuexData.order?.referralNumber }); - bailoutInfo.push({ name: 'Referral Date', value: existingVuexData.order?.referralDate }); - bailoutInfo.push({ name: 'Referral Provider Number', value: existingVuexData.order?.serviceLocation?.provider?.providerNumber }); - bailoutInfo.push({ name: 'Referral CTU', value: existingVuexData.order?.serviceLocation?.provider?.address?.zipCodeCtu }); - - // - Referral Insured Zip - // - Referral Insured Service Zip - - bailoutInfo.push({ name: 'Referral CarID', value: existingVuexData.order?.vehicle?.carId }); - - const vehicle = existingVuexData.order?.vehicle; - const vehicleString = vehicle?.year - ? `${vehicle.year} ${vehicle.make} ${vehicle.model} - ${vehicle.style}` - : null; - bailoutInfo.push({ name: 'Referral Vehicle', value: vehicleString }); - bailoutInfo.push({ name: 'Work Order Number', value: existingVuexData.order?.workOrderNumber }); - bailoutInfo.push({ name: 'Work Order ID', value: existingVuexData.order?.workOrderId }); - bailoutInfo.push({ name: 'Parent Account Number', value: existingVuexData.order?.payment?.parentAccountNumber }); - - // - Parent Account Name - // - Client GUID - } finally { - // If any information gathered, write to session storage. - if(bailoutInfo) { - window.sessionStorage.setItem('bailoutInfo', JSON.stringify(bailoutInfo)); - } - - // Then *always* clear vuex data. - window.localStorage.removeItem('vuex'); + if(bailoutInfo) { + window.sessionStorage.setItem('bailoutInfo', JSON.stringify(bailoutInfo)); } - } else if(existingBailoutInfo) { - // Proceed with prior data. - bailoutInfo = existingBailoutInfo; + + if(headerInfo) { + window.sessionStorage.setItem('headerInfo', JSON.stringify(headerInfo)); + } + } else { + bailoutInfo = existingBailoutInfo ?? []; + headerInfo = existingHeaderInfo ?? []; } const environmentInfo = getCurrentEnvironmentData(); @@ -275,11 +370,11 @@ body { ); const entryString = `User encountered bailout page.\n${new Date()}\n${infoString ?? 'No information recoverable'}`; + const headers = generateRequestHeader(headerInfo); + const request = new Request(endpointUrl, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, + headers: headers, body: JSON.stringify({ entry: entryString, }), @@ -292,6 +387,38 @@ body { console.error(`=== ERROR SENDING LOGGING`); console.error(e); } + + try { + const endpointUrl = `https://${apiHostname}/analytics/api/v1/analytics/log-page-view`; + + const headers = generateRequestHeader(headerInfo); + + const payload = { + AppName: "FixMyGlass", + action: "", + applicationName: "FixMyGlassNextGen", + event: "ENTRY", + experimentsForUser: [], + pageName: "static-error", + parentAccountNumber: getFieldWithName(bailoutInfo, 'Parent Account Number') ?? 0, + referralSequenceNumber: getFieldWithName(bailoutInfo, 'Referral Seq Number'), + sessionId: getFieldWithName(bailoutInfo, 'Session Id'), + sessionKey: getFieldWithName(headerInfo, 'X-Session-Sequence-Number'), + shouldUseSessionId: false, + userId: getFieldWithName(bailoutInfo, 'User Id'), + }; + + const request = new Request(endpointUrl, { + method: 'POST', + headers: headers, + body: JSON.stringify(payload), + }); + + const response = await fetch(request); + } catch(e) { + console.error(`=== ERROR SENDING PAGEVIEW`); + console.error(e); + } } };