Merge branch 'develop' into dependabot/npm_and_yarn/launch-editor-2.14.1

This commit is contained in:
Jeremy-Z 2026-06-08 12:40:52 -04:00 committed by GitHub
commit 0f87777e72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 88 additions and 14 deletions

View file

@ -113,7 +113,10 @@ describe('entry-page.vue', () => {
parentAccountNumber: 'P', parentAccountNumber: 'P',
styleSheet: '', styleSheet: '',
coverageEnabled: true, coverageEnabled: true,
siteType: '' siteType: '',
clientFlags: JSON.stringify({
EncryptedParametersPattern: 'foo=(?<foo>[^&]+)&from=(?<from>[^&]+)'
})
}; };
const decryptedData = 'foo=bar&from=yesterday'; const decryptedData = 'foo=bar&from=yesterday';
jest.spyOn(clientAuthHelper, 'validateISSClientTag').mockResolvedValueOnce(resp); jest.spyOn(clientAuthHelper, 'validateISSClientTag').mockResolvedValueOnce(resp);
@ -221,4 +224,20 @@ describe('entry-page.vue', () => {
expect(wrapper.vm.mainStore.issConfig.successReturnURL).toBe('http://success'); expect(wrapper.vm.mainStore.issConfig.successReturnURL).toBe('http://success');
expect(wrapper.vm.mainStore.issConfig.failureReturnURL).toBe('http://fail'); expect(wrapper.vm.mainStore.issConfig.failureReturnURL).toBe('http://fail');
}); });
test('does not populate date of loss when dateofloss is not ISO formatted', () => {
const mainInitialState = {
issConfig: { disabledFields: { dateOfLoss: false } },
order: { policy: { dateOfLoss: '2021-12-31' } }
};
const params = {
dateofloss: 'not-a-date'
};
const { wrapper } = getMountedComponent(mainInitialState);
wrapper.vm.populateStoreItemsFromParams(params);
expect(wrapper.vm.mainStore.order.policy.dateOfLoss).toBe('2021-12-31');
expect(wrapper.vm.mainStore.issConfig.disabledFields.dateOfLoss).toBe(false);
});
}); });

View file

@ -130,15 +130,30 @@ export default {
let isAuthorized = false; let isAuthorized = false;
let clientData = null; let clientData = null;
const decryptedParams = {}; const decryptedParams = {};
const encryptedParametersPattern = this.mainStore.issConfig.encryptedParametersPattern;
if (resp.active && resp.accountName.length > 0) { if (resp.active && resp.accountName.length > 0) {
if (resp.authentication.startsWith('RSAToken')) { if (resp.authentication.startsWith('RSAToken')) {
const { token, signature } = queryStringParams; const { token, signature } = queryStringParams;
const vsigResp = await validateISSClientSignature(clientTag, token, signature); const vsigResp = await validateISSClientSignature(clientTag, token, signature);
if (resp.authentication.includes('EncParams')) {
const params = new URLSearchParams(vsigResp.decryptedData); // Encrypted params only populated if the authentication type includes EncParams and we have a pattern to pull them out of the decrypted data.
for (const [key, value] of params) { // Try/Catch is here to ensure that any issues with populating these parameters does not impact the overall authentication/authorization of the client.
decryptedParams[key.toLowerCase()] = value; // They can fallback to manually entering the data on the webpage.
if (resp.authentication.includes('EncParams') && encryptedParametersPattern) {
try {
const encryptedParametersPatternRegex = RegExp(encryptedParametersPattern);
const match = vsigResp.decryptedData.match(encryptedParametersPatternRegex);
if ( match?.groups ) {
const params = match.groups;
for (const [key, value] of Object.entries(params)) {
decryptedParams[key.toLowerCase()] = value;
}
}
}
catch ( error ) {
global.$logger.logError(`[Entry Page] Unable to populate encrypted parameters: ${error} - Client Tag: ${clientTag} - Token: ${token} - Signature: ${signature}`);
} }
} }
@ -197,6 +212,10 @@ export default {
if (clientFlags.EnableNoCompQuote) { if (clientFlags.EnableNoCompQuote) {
this.mainStore.issConfig.enableNoCompQuote = true; this.mainStore.issConfig.enableNoCompQuote = true;
} }
if ( clientFlags.EncryptedParametersPattern != null ) {
this.mainStore.issConfig.encryptedParametersPattern = clientFlags.EncryptedParametersPattern;
}
} }
}, },
combineClientParameters(configParams, queryStringParams) { combineClientParameters(configParams, queryStringParams) {
@ -234,9 +253,13 @@ export default {
case 'dateofloss': case 'dateofloss':
case 'lossdate': case 'lossdate':
// NOTE: May need some date parsing logic in here depending on client. const formattedDate = this.formatToYYYYMMDD(value);
this.mainStore.order.policy.dateOfLoss = value;
this.mainStore.issConfig.disabledFields.dateOfLoss = true; // Only set this if it formatted correctly.
if ( formattedDate ) {
this.mainStore.order.policy.dateOfLoss = formattedDate;
this.mainStore.issConfig.disabledFields.dateOfLoss = true;
}
break; break;
case 'returnurl': case 'returnurl':
@ -257,9 +280,31 @@ export default {
default: default:
} }
} }
},
formatToYYYYMMDD(dateString) {
try {
if (!dateString) {
return null;
}
// Avoid any UTC / local time issues by always treating the output as UTC.
const date = new Date(dateString);
if (Number.isNaN(date.getTime())) {
return null;
}
const year = date.getUTCFullYear();
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
const day = String(date.getUTCDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
} catch ( error ) {
global.$logger.logError(`[Entry Page] Error formatting date string: ${error} - Input: ${dateString}`);
return null;
}
} }
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View file

@ -95,15 +95,23 @@ export default {
async logCustomEvent(category, action, label, value) { async logCustomEvent(category, action, label, value) {
const store = useMainStore(); const store = useMainStore();
const issConfig = store.issConfig;
const currentPageName = this.getPageNameByQueryString(); const currentPageName = this.getPageNameByQueryString();
//await this.validateSession(); //await this.validateSession();
const submittedOrder = store.getSubmittedOrder();
const hasSubmittedOrder = store.hasSubmittedOrder();
const order = hasSubmittedOrder ? submittedOrder : store.order;
// Use parentaccount on order, use parentaccount on issconfig as fallback.
const parentAccountNumber = (order.parentAccountNumber ?? issConfig.parentAccountNumber);
const payload = { const payload = {
userId: getUserIdValue(), userId: getUserIdValue(),
sessionKey: getSessionKeyValue(), sessionKey: getSessionKeyValue(),
pageName: currentPageName, pageName: currentPageName,
referralSequenceNumber: store.order.referralSequenceNumber, referralSequenceNumber: order.referralSequenceNumber,
parentAccountNumber: store.order.parentAccountNumber ?? 0, parentAccountNumber: parentAccountNumber,
sessionId: getSessionIdValue(), sessionId: getSessionIdValue(),
category, category,
action, action,

View file

@ -2596,7 +2596,7 @@ export const useMainStore = defineStore({
} }
); );
}, },
async logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser }) { async logCustomEvent({ userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser, referralSequenceNumber, parentAccountNumber }) {
if (pageName == null || pageName.length === 0) { pageName = 'none'; } if (pageName == null || pageName.length === 0) { pageName = 'none'; }
const payload = { const payload = {
@ -2610,7 +2610,9 @@ export const useMainStore = defineStore({
label, label,
value, value,
shouldUseSessionId, shouldUseSessionId,
experimentsForUser experimentsForUser,
referralSequenceNumber,
parentAccountNumber
}; };
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({