Name
global.PwdWFRequestProcessor
Description
No description available
Script
var PwdWFRequestProcessor = Class.create();
PwdWFRequestProcessor.prototype = {
TYPE_INFO: "Info",
TYPE_WARNING: "Warning",
TYPE_ERROR: "Error",
RESET_PASSWORD_ACTION : "1",
STAGE_RESET: "Reset",
COMPLETED_WITH_SUCCESS: 1,
COMPLETED_WITH_FAILURE: -1,
PENDING: 3,
MASTER_WORKFLOW: "Pwd Reset - Master",
responseMsg: null,
history: [],
activity: [],
wfResult: {
pass: false,
message: ""
},
initialize: function() {},
validatePassword: function(processId, newPwd, userName) {
var credMgr = new SNC.PwdCredentialStoreManager();
var credId = credMgr.getCredentialStoreIdByProcessId(processId);
var isPasswordPolicyEnabled = credMgr.getEnablePasswordPolicy(processId);
var result = {
"isPwdValid": false,
"errorMessage": gs.getMessage("Invalid password")
};
if (isPasswordPolicyEnabled) {
var passwordPolicyId = credMgr.getPasswordPolicyId(processId);
var jsonResponse = SNC.PasswordPolicyEvaluator.isValidPwdPerPolicyWithMessage(newPwd, passwordPolicyId, userName);
var validationResponse = JSON.parse(jsonResponse);
if (validationResponse.success == true) {
result.isPwdValid = true;
result.errorMessage = "";
} else {
result.errorMessage = gs.getMessage("Invalid password - {0}", validationResponse.message);
}
} else {
var credGr = new GlideRecord('pwd_cred_store');
if (credGr.get(credId)) {
var pwdRule = credGr.getValue('pwd_rule');
var pwdRuleCall = pwdRule + '\nisPasswordValid(password);';
credGr.setValue('pwd_rule', pwdRuleCall);
var vars = {
'password': newPwd
};
var evaluator = new GlideScopedEvaluator();
var isPwdValid = evaluator.evaluateScript(credGr, 'pwd_rule', vars);
if (isPwdValid) {
result.isPwdValid = true;
result.errorMessage = "";
}
}
}
return JSON.stringify(result);
},
startWorkflow: function(sysparm_request_id, sysparm_new_password, isSecure) {
var LOG_ID = "[PwdAjaxWFRequestProcessor:startWorkflow] ";
var ctxId = "";
var trackingMgr = new SNC.PwdTrackingManager();
var requestId = sysparm_request_id;
var newPasswd = sysparm_new_password;
var historyCheckErrorMessage = gs.getMessage("You used that password recently. Choose a different password.");
var pwdFlowHelper = new PwdFlowHelper();
// Retrieve request by request id
var requestVerified = trackingMgr.requestVerified(requestId);
try {
// return error if the request is not verified:
if (!requestVerified) {
var requestMsg = "Could not verify request: " + requestId;
trackingMgr.createActivity(PwdConstants.TYPE_WARNING, PwdConstants.STAGE_RESET, requestMsg, requestId);
var reqMsg = gs.getMessage("{0} Could not verify request: {1}", [LOG_ID, requestId]);
this._setResponseMessage("failure", reqMsg, requestId);
return this.responseMsg;
}
var processId = trackingMgr.getProcessIdByRequestId(requestId);
var acceptsPassword = false;
var gr = new GlideRecord("pwd_process");
if (gr.get(processId))
acceptsPassword = !gr.cred_store.type.use_flow || gr.cred_store.type.password_delivery_mechanism == '' || gr.cred_store.type.password_delivery_mechanism == '0';
var encryptedPassword;
this._updateRequestAction(processId, requestId);
// If the cred store does not accept password then skip the encryption logic
if (acceptsPassword) {
// auto-generate new password, if needed
if (gs.nil(newPasswd)) {
newPasswd = new SNC.PwdProcessManager().generatePasswordByProcessId(processId);
// Fail workflow if we get an empty response
if (typeof(newPasswd) == 'undefined' || newPasswd == null || newPasswd == '') {
var passwordMsg = 'Empty password generated';
trackingMgr.createActivity(PwdConstants.TYPE_WARNING, PwdConstants.STAGE_RESET, passwordMsg, requestId);
var genPasswordMsg = gs.getMessage("{0} Empty password generated", LOG_ID);
this._setResponseMessage("failure", genPasswordMsg, requestId);
return this.responseMsg;
}
gs.getSession().putProperty('temp_password', newPasswd);
}
encryptedPassword = newPasswd;
if (isSecure == null || isSecure == false) {
encryptedPassword = new PasswordResetUtil().encryptWithKMFModule(encryptedPassword);
}
}
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, "Starting Password Reset Master Subflow", requestId);
var outputs = pwdFlowHelper.startMasterSubFlow(requestId, encryptedPassword, '', this.RESET_PASSWORD_ACTION);
if (outputs.is_flow == false && outputs.context_id) {
ctxId = outputs.context_id.sys_id;
}
if (outputs.is_flow == true && outputs.status != 'Error') {
if (outputs.status == "Success") {
trackingMgr.updateRequestStatus(requestId, this.COMPLETED_WITH_SUCCESS);
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, "Flow Completed Successfully", requestId);
} else {
gs.getSession().putProperty('async_pwd_request', 'true');
trackingMgr.updateRequestStatus(requestId, this.PENDING);
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, "Password Reset request is Pending with external system", requestId);
}
}
if (outputs.is_flow == false && outputs.context_id == undefined) {
var errorMsg = "Failed to start password reset process";
trackingMgr.createActivity(PwdConstants.TYPE_ERROR, PwdConstants.STAGE_RESET, errorMsg, requestId);
responseErrorMsg = gs.getMessage("{0} Failed to start workflow process", [LOG_ID]);
this._setResponseMessage("failure", responseErrorMsg, requestId);
return this.responseMsg;
} else if (outputs.is_flow == true && outputs.status == 'Error') {
if(outputs.error_message != historyCheckErrorMessage)
trackingMgr.updateRequestStatus(requestId, this.COMPLETED_WITH_FAILURE);
trackingMgr.createActivity(PwdConstants.TYPE_ERROR, PwdConstants.STAGE_RESET, 'Password reset failed', requestId);
this._setResponseMessage("failure", outputs.error_message, requestId);
return this.responseMsg;
}
//Invalidate the token for the user if he/she is resetting the password through a URL
var request = new GlideRecord("pwd_reset_request");
if (request.get(requestId))
SNC.PasswordResetUtil.invalidateTokenForUser(request.user, '');
if (!outputs.is_flow || outputs.status == "Success")
this._setResponseMessage("success", "The request has been successfully completed", ctxId);
else
this._setResponseMessage("pending", "The request has been successfully submitted and is pending with the external system", ctxId);
return this.responseMsg;
} catch (error) {
var exceptionMsg = gs.getMessage("Exception: {0}", error);
trackingMgr.createActivity(PwdConstants.TYPE_ERROR, PwdConstants.STAGE_RESET, exceptionMsg, requestId);
var responseExceptionMsg = gs.getMessage("{0} Exception: {1}", [LOG_ID, error]);
this._setResponseMessage("failure", responseExceptionMsg, ctxId);
return this.responseMsg;
}
},
runPostProcessor: function(requestId, processId, status) {
var LOG_ID = "[PwdWFRequestProcessor:runPostProcessor] ";
var trackingMgr = new SNC.PwdTrackingManager();
var gr = new GlideRecord('pwd_process');
if (!gr.get(processId))
return false;
if (!gs.nil(gr.post_processor)) {
var postProcessorId = gr.post_processor;
var postProcessorName = gr.post_processor.name;
try {
var params = new SNC.PwdExtensionScriptParameter();
params.resetRequestId = requestId;
params.wfSuccess = status == "true" ? true : false;
var postResetExtension = new SNC.PwdExtensionScript(postProcessorId);
var infoMsg = "Starting post-processor script: " + postProcessorName;
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, infoMsg, requestId);
postResetExtension.process(params);
} catch (error) {
var exceptionMsg = gs.getMessage("Error while executing post-processor script: {0}. Error:{1}", [postProcessorName, error]);
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, exceptionMsg, requestId);
var responseExceptionMsg = gs.getMessage("{0} Error while executing post-processor script {1}. Error: {2}",
[LOG_ID, postProcessorName, error]);
return false;
}
var successMsg = gs.getMessage("Completed post-processor script: {0}", postProcessorName);
trackingMgr.createActivity(PwdConstants.TYPE_INFO, PwdConstants.STAGE_RESET, successMsg, requestId);
var responseSuccessMsg = gs.getMessage("{0} Completed post-processor script: {1}", [LOG_ID, postProcessorName]);
return true;
}
},
buildWorkflowDetails: function(contextId) {
var gr = new GlideRecord('wf_history');
gr.addQuery('context', contextId);
gr.orderBy('activity_index');
gr.addJoinQuery('wf_activity', 'activity', 'sys_id');
gr.query();
while (gr.next()) {
var historyDetails = {};
var activity = gr.getValue('activity');
this.getWorkFlowActivity(activity);
historyDetails.activity_result = gr.getValue('result');
historyDetails.fault_description = gr.getValue('fault_description');
historyDetails.activity_index = gr.getValue('activity_index');
historyDetails.sys_id = gr.getValue('sys_id');
this.history.push(historyDetails);
}
},
getWorkFlowActivity: function(activityId) {
var gr = new GlideRecord('wf_activity');
if (gr.get(activityId)) {
var activityDetials = {};
activityDetials.name = gr.getValue('name');
this.activity.push(activityDetials);
}
},
getErrrorMessage: function(executionResult, contextId) {
this.buildWorkflowDetails(contextId);
var allActivitiesSucceeded = true;
// An array of obj representing the state of an activity
var allActivitiesObj = [];
// Grab all the activities in the workflow and build an array of objects
for (var i = 0; i < this.history.length; i++) {
var tmp = {};
tmp.name = this.activity[i].name;
tmp.index = this.history[i].activity_index;
tmp.result = this.history[i].activity_result;
if (tmp.result == undefined) {
tmp.result = "";
}
tmp.faultDescription = this.history[i].fault_description;
if (tmp.faultDescription == undefined) {
tmp.faultDescription = "";
}
allActivitiesObj.push(tmp);
}
// Iterate through activity history list to find the first error
allActivitiesObj.sort(function(a, b) {
return b.index - a.index;
});
var failingActivityObj = {};
for (var j in allActivitiesObj) {
var activity = allActivitiesObj[j];
if (activity.result == undefined)
continue;
if (activity.result.match(/failure/i)) {
allActivitiesSucceeded = false;
// Check if faultDescription is an json object. If so, this was created via SNC.PwdWorkflowManager().creatError().
try {
failingActivityObj = eval("(" + activity.faultDescription + ")");
} catch (e) {
//The faultDescription was created manually, and not via new SNC.PwdWorkflowManager().getErrorJSONString(...)
failingActivityObj.message = activity.faultDescription;
failingActivityObj.isFatal = true;
}
break;
}
}
var wfGeneralStatus = executionResult.status;
var message = executionResult.message;
var value = executionResult.value;
if (!wfGeneralStatus.match(/success/i) || (!allActivitiesSucceeded)) {
//Check failure via by workflow result
this.wfResult.pass = false;
this.wfResult.message = failingActivityObj.message || "Password reset request failed.";
} else { //pass
this.wfResult.pass = true;
}
return this.wfResult;
},
_setResponseMessage: function(status, msg, value) {
this.responseMsg = {
"status": status,
"message": msg,
"value": value
};
},
//------------------------------------------------------------------------------------------------------------------
// Starts a new workflow and returns the new workflow sys Id.
//------------------------------------------------------------------------------------------------------------------
_startWorkflow: function(requestId, newPasswd) {
var workflowName = this.MASTER_WORKFLOW;
var wf = new Workflow();
var workflowId = wf.getWorkflowFromName(workflowName);
var request = new GlideRecord("pwd_reset_request");
var getRequest = request.get(requestId);
var gr = wf.startFlow(workflowId, request, 'update', {
u_request_id: requestId,
u_new_password: newPasswd
});
gr.next();
var ctxId = gr.getValue('sys_id');
return ctxId;
},
_updateRequestAction: function(processId, requestId) {
var processSupportsUnlock = 0;
var proc = new GlideRecord('pwd_process');
if (proc.get(processId)) {
processSupportsUnlock = proc.getValue('unlock_account');
}
var value = '1'; // Reset Password
var gr = new GlideRecord('pwd_reset_request');
if (gr.get(requestId)) {
var lockState = gr.getValue('lock_state');
if (processSupportsUnlock == '1' && lockState == '1') {
value = '3'; // Reset and Unlock
}
gr.setValue('action_type', value);
gr.update();
}
},
type: 'PwdWFRequestProcessor'
};
Sys ID
f2b47c0b67100200a5a0f3b457415afd