Merge pull request #897 from Safelite/feature/digital/SSR-1473
SSR-1473 RSA Auth
This commit is contained in:
commit
23d7f736b5
2 changed files with 93 additions and 99 deletions
|
|
@ -4,18 +4,12 @@ export function validateISSClientTag(clientTag) {
|
|||
const store = useMainStore();
|
||||
|
||||
return store.validateClientTag(clientTag)
|
||||
.then(
|
||||
(response) => response,
|
||||
() => null
|
||||
);
|
||||
.then((response) => response.data, () => null);
|
||||
}
|
||||
|
||||
export function validateISSClientSignature(clientTag, token, signature) {
|
||||
const store = useMainStore();
|
||||
|
||||
return store.validateClientSignature(clientTag, token, signature)
|
||||
.then(
|
||||
(response) => response,
|
||||
() => null
|
||||
);
|
||||
.then((response) => response.data, () => null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,54 +36,54 @@ export default {
|
|||
async mounted() {
|
||||
const queryStringParams = this.parseQueryParms();
|
||||
|
||||
const { isAuthorized, clientData } = await this.validateClientTagOnEntry(queryStringParams);
|
||||
const { isAuthorized, clientData, decryptedParams } = await this.validateClientTagOnEntry(queryStringParams);
|
||||
|
||||
this.unauthorized = !isAuthorized;
|
||||
|
||||
if (isAuthorized) {
|
||||
this.populateISSConfigValues(clientData);
|
||||
|
||||
try {
|
||||
// Check cookie
|
||||
const issCookie = getISSCookie();
|
||||
if (issCookie !== null && issCookie.VehicleMake && issCookie.VehicleModel) {
|
||||
const clientParentAccountNumber = clientData.parentAccountNumber;
|
||||
const cookieParentAccountNumber = issCookie.ReferralParentAccountNumber;
|
||||
|
||||
if (clientParentAccountNumber === cookieParentAccountNumber) {
|
||||
const savedSessionTimeStamp = new Date(issCookie.SavedSessionTimeoutDate);
|
||||
const isSavedSessionTimedOut = new Date(new Date().toUTCString()) > savedSessionTimeStamp;
|
||||
|
||||
if (!isSavedSessionTimedOut) {
|
||||
this.mainStore.issConfig.enableContinueFromCookie = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateOrCreateISSCookie(true);
|
||||
}
|
||||
} catch {
|
||||
updateOrCreateISSCookie(true);
|
||||
}
|
||||
|
||||
if (clientData.parameters?.length > 0) {
|
||||
const finalParams = this.combineClientParameters(clientData.parameters, queryStringParams);
|
||||
this.populateStoreItemsFromParams(finalParams);
|
||||
}
|
||||
|
||||
this.mainStore.applicationUser.coverageAttempts = 0;
|
||||
if (
|
||||
applicationConfig.CURRENT_ENVIRONMENT === 'Localhost'
|
||||
|| applicationConfig.CURRENT_ENVIRONMENT === 'Dev'
|
||||
|| applicationConfig.CURRENT_ENVIRONMENT === 'SysTest'
|
||||
) {
|
||||
this.navigateForward();
|
||||
} else {
|
||||
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
|
||||
window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`;
|
||||
}
|
||||
} else {
|
||||
if (!isAuthorized) {
|
||||
// Remove the loading animation if client tag validation fails so users can see the Unauthorized Access message.
|
||||
showIssLoadingModal(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.populateISSConfigValues(clientData);
|
||||
|
||||
try {
|
||||
// Check cookie
|
||||
const issCookie = getISSCookie();
|
||||
if (issCookie !== null && issCookie.VehicleMake && issCookie.VehicleModel) {
|
||||
const clientParentAccountNumber = clientData.parentAccountNumber;
|
||||
const cookieParentAccountNumber = issCookie.ReferralParentAccountNumber;
|
||||
|
||||
if (clientParentAccountNumber === cookieParentAccountNumber) {
|
||||
const savedSessionTimeStamp = new Date(issCookie.SavedSessionTimeoutDate);
|
||||
const isSavedSessionTimedOut = new Date(new Date().toUTCString()) > savedSessionTimeStamp;
|
||||
|
||||
if (!isSavedSessionTimedOut) {
|
||||
this.mainStore.issConfig.enableContinueFromCookie = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateOrCreateISSCookie(true);
|
||||
}
|
||||
} catch {
|
||||
updateOrCreateISSCookie(true);
|
||||
}
|
||||
|
||||
if (clientData.parameters?.length > 0) {
|
||||
const finalParams = this.combineClientParameters(clientData.parameters, {...queryStringParams, ...decryptedParams});
|
||||
this.populateStoreItemsFromParams(finalParams);
|
||||
}
|
||||
|
||||
this.mainStore.applicationUser.coverageAttempts = 0;
|
||||
if (
|
||||
applicationConfig.CURRENT_ENVIRONMENT === 'Localhost'
|
||||
|| applicationConfig.CURRENT_ENVIRONMENT === 'Dev'
|
||||
|| applicationConfig.CURRENT_ENVIRONMENT === 'SysTest'
|
||||
) {
|
||||
this.navigateForward();
|
||||
} else {
|
||||
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
|
||||
window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`;
|
||||
}
|
||||
},
|
||||
methods:
|
||||
|
|
@ -95,46 +95,51 @@ export default {
|
|||
);
|
||||
},
|
||||
parseQueryParms() {
|
||||
// Dump the query string parameters into an array. Remove casing on the key for easy compare.
|
||||
const queryStringParams = [];
|
||||
|
||||
// Dump the query string parameters into an object
|
||||
if (this.$route?.query) {
|
||||
Object.keys(this.$route.query).forEach((param) => {
|
||||
queryStringParams[param.toLowerCase()] = this.$route.query[param];
|
||||
});
|
||||
return Object.fromEntries(Object.entries(this.$route?.query).map(([key, value]) => [key.toLowerCase(), value]));
|
||||
}
|
||||
|
||||
return queryStringParams;
|
||||
return {};
|
||||
},
|
||||
async validateClientTagOnEntry(queryStringParams) {
|
||||
const clientTag = queryStringParams.clienttag;
|
||||
const clientTagPresent = !!clientTag;
|
||||
let authorized = false;
|
||||
if (!clientTag) {
|
||||
return { isAuthorized: false };
|
||||
}
|
||||
|
||||
const resp = await validateISSClientTag(clientTag);
|
||||
if (!resp) {
|
||||
return { isAuthorized: false };
|
||||
}
|
||||
|
||||
let isAuthorized = false;
|
||||
let clientData = null;
|
||||
const decryptedParams = {};
|
||||
|
||||
if (clientTagPresent) {
|
||||
const resp = await validateISSClientTag(clientTag);
|
||||
|
||||
if (resp?.data.active && resp?.data.accountName.length > 0) {
|
||||
if (resp.data.authentication === 'RSAToken') {
|
||||
const { token, signature } = queryStringParams;
|
||||
const vsigResp = await validateISSClientSignature(clientTag, token, signature);
|
||||
|
||||
this.mainStore.issConfig.isAuthenticated = vsigResp?.data?.valid ?? false;
|
||||
if (this.mainStore.issConfig.isAuthenticated) {
|
||||
authorized = true;
|
||||
if (resp.active && resp.accountName.length > 0) {
|
||||
if (resp.authentication.startsWith('RSAToken')) {
|
||||
const { token, signature } = queryStringParams;
|
||||
const vsigResp = await validateISSClientSignature(clientTag, token, signature);
|
||||
if (resp.authentication.includes('EncParams')) {
|
||||
const params = new URLSearchParams(vsigResp.decryptedData);
|
||||
for (const [key, value] of params) {
|
||||
decryptedParams[key.toLowerCase()] = value;
|
||||
}
|
||||
} else {
|
||||
authorized = true;
|
||||
}
|
||||
|
||||
if (authorized) {
|
||||
clientData = resp.data;
|
||||
}
|
||||
isAuthorized = vsigResp?.valid ?? false;
|
||||
this.mainStore.issConfig.isAuthenticated = isAuthorized;
|
||||
} else {
|
||||
isAuthorized = true;
|
||||
}
|
||||
|
||||
if (isAuthorized) {
|
||||
clientData = resp;
|
||||
}
|
||||
}
|
||||
|
||||
return { isAuthorized: authorized, clientData };
|
||||
return { isAuthorized, clientData, decryptedParams };
|
||||
},
|
||||
populateISSConfigValues(data) {
|
||||
this.mainStore.issConfig.clientName = data.accountName;
|
||||
|
|
@ -169,22 +174,17 @@ export default {
|
|||
}
|
||||
},
|
||||
combineClientParameters(configParams, queryStringParams) {
|
||||
const finalParams = [];
|
||||
const finalParams = {};
|
||||
|
||||
try {
|
||||
const clientParams = JSON.parse(configParams);
|
||||
|
||||
Object.keys(clientParams).forEach((cparam) => {
|
||||
const cname = clientParams[cparam].toLowerCase();
|
||||
|
||||
Object.keys(queryStringParams).forEach((qsparam) => {
|
||||
const qsname = qsparam.toLowerCase();
|
||||
|
||||
if (cname === qsname) {
|
||||
finalParams[cname] = queryStringParams[cname];
|
||||
}
|
||||
});
|
||||
});
|
||||
for (const clientParam of clientParams) {
|
||||
const paramName = clientParam.toLowerCase();
|
||||
const value = queryStringParams[paramName];
|
||||
if (value) {
|
||||
finalParams[paramName] = value;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
window.console.error(`Error combining client parameters: ${e}`);
|
||||
}
|
||||
|
|
@ -193,12 +193,9 @@ export default {
|
|||
},
|
||||
populateStoreItemsFromParams(params) {
|
||||
// Populate store items from parameters.
|
||||
|
||||
Object.keys(params).forEach((param) => {
|
||||
const name = param.toLowerCase();
|
||||
const value = params[param];
|
||||
|
||||
switch (name) {
|
||||
for (const [key, value] of Object.entries(params)) {
|
||||
switch (key.toLowerCase()) {
|
||||
case 'policynbr':
|
||||
case 'policynumber':
|
||||
this.mainStore.order.policy.policyNumber = value;
|
||||
this.mainStore.issConfig.disabledFields.policyNumber = true;
|
||||
|
|
@ -209,16 +206,19 @@ export default {
|
|||
this.mainStore.issConfig.disabledFields.policyZipCode = true;
|
||||
break;
|
||||
|
||||
case 'dateofloss':
|
||||
case 'lossdate':
|
||||
// NOTE: May need some date parsing logic in here depending on client.
|
||||
// NOTE: May need some date parsing logic in here depending on client.
|
||||
this.mainStore.order.policy.dateOfLoss = value;
|
||||
this.mainStore.issConfig.disabledFields.dateOfLoss = true;
|
||||
break;
|
||||
|
||||
case 'returnurl':
|
||||
case 'successreturnurl':
|
||||
this.mainStore.issConfig.successReturnURL = value;
|
||||
break;
|
||||
|
||||
case 'returnurl2':
|
||||
case 'failurereturnurl':
|
||||
this.mainStore.issConfig.failureReturnURL = value;
|
||||
break;
|
||||
|
|
@ -230,7 +230,7 @@ export default {
|
|||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue