Validate user with Jelly in UI Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-23-2023 02:13 PM
Hello everyone,
I'm creating a copy of UI Page $pwd_reset_serviceDesk because we need to enhance that to restrict the list of users to show only certain accounts.
The first requirement is to show only accounts active in AD, for that we have a custom field that is populated by LDAP, u_ad_account_status, whose value is either active or inactive.
The second requirement is to show in the dropdown only accounts whose description field contains the current logged in user email.
How should I query and present the user list in the dropdown based on those requirements?
Not sure if I should evaluate (and how) in the HTML section or the client script section:
Full script belows:
HTML:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
<!-- ACTUAL PAGE STARTS HERE -->
<g:macro_invoke macro="$pwd_reset_stylesheet"/>
<g:requires name="scripts/lib/jquery_includes.js" includes="true"/>
<g:macro_invoke macro="$pwd_error_message" error_message="" />
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button class="btn btn-default icon-chevron-left navbar-btn" onclick="goBack();" aria-label="${gs.getMessage('Back')}" title="${gs.getMessage('Back')}"></button>
</div>
</div>
</nav>
<g:macro_invoke macro="$pwd_process_flow" stage="1" />
<h1 class="sr-only">${gs.getMessage('ServiceNow Password Reset Service Desk, step 1 out of 3')}</h1>
<center>
<div class="pwd-reset-box">
<form>
<h2 class="pwd-title">${gs.getMessage('Password Reset Assistance')}</h2>
<h3 class="pwd-subtitle">${gs.getMessage('Select a user, then select a process, and click the "Verify Identity" button.')}</h3>
<div id="user_id_form_group" class="form-group is-required">
<label for="sys_display.ref_sys_user" class="control-label col-sm-3">
<span class="required-marker sn-tooltip-basic"
title="${gs.getMessage('Required')}" data-original-title="${gs.getMessage('Required')}" aria-label="${gs.getMessage('Required')}"></span>
${gs.getMessage('Select user')}
</label>
<span class="col-sm-9">
<j:set var="jvar_user_id" value=""/>
<j:set var="jvar_user_name" value=""/>
<g:evaluate var="jvar_user_has_next" jelly="true">
var renUser = new GlideRecord("sys_user");
renUser.addQuery("sys_id", jelly.sysparm_user);
renUser.query();
renUser.next();
</g:evaluate>
<j:if test="${jvar_user_has_next}">
<j:set var="jvar_user_id" value="$[renUser.sys_id]"/>
<j:set var="jvar_user_name" value="$[renUser.name]"/>
</j:if>
<g:macro_invoke macro="ui_reference" id="ref_sys_user" name="ref_sys_user" table="sys_user" show_popup="true" value="${jvar_user_id}" displayvalue="${jvar_user_name}" onchange="populateProcessSelect();" />
</span>
<span class="col-sm-3"/><span id="error_msg_id" class="help-block col-sm-9"/>
</div>
<div id="process_select_form_group" class="form-group is-required">
<label for="processSelectId" class="control-label col-sm-3">
<span class="required-marker sn-tooltip-basic"
title="${gs.getMessage('Required')}" data-original-title="${gs.getMessage('Required')}" aria-label="${gs.getMessage('Required')}"></span>
${gs.getMessage("Select process")}
</label>
<span class="col-sm-9">
<select id="processSelectId" class="form-control pwd-form-control select2" required="true" aria-required="true" name="processSelectId" onchange="enableVerifyButton();">
<option value="N/A">${gs.getMessage('-- Select a process --')}</option>
</select>
</span>
<span class="col-sm-3"/><span id="error_msg_select" class="help-block col-sm-9"/>
</div>
<input type="hidden" name="sysparm_action" id="sysparm_action" value="password_reset_form" />
<button name="sysverb_pwd_reset" id="sysverb_pwd_reset" class="btn btn-primary btn-pwd-submit" onclick="return verifyIdentity();" aria-label="${gs.getMessage('Verify Identity')}" disabled="disbaled">${gs.getMessage('Verify Identity')}</button>
</form>
<!--
Adding a new CSRF token here. This page does not check whether there's a violation or not because this page
is the starting point.
-->
<g:evaluate var="jvar_csrf_token" jelly="true">
new SNC.PwdSecurityManager().generateSecureToken();
</g:evaluate>
<form id="pwd_master_form" name="pwd_master_form" method="post">
<input type="hidden" id="sysparm_error" name="sysparm_error" value=""/>
<input type="hidden" id="pwd_csrf_token" name="pwd_csrf_token" value="${jvar_csrf_token}"/>
</form>
</div>
</center>
</j:jelly>
Client:
$j('title').text("${gs.getMessage('Password Reset - Service Desk')}");
addLoadEvent(onLoadPopulateProcessSelect);
addLoadEvent(focusOnCorrectField);
function goBack() {
window.history.back();
}
function enableVerifyButton() {
clearErrorMessage();
if(document.getElementById("processSelectId").value == 'N/A')
document.getElementById("sysverb_pwd_reset").disabled = true;
else
document.getElementById("sysverb_pwd_reset").disabled = false;
}
function focusOnCorrectField() {
var user = gel('sys_display.ref_sys_user');
if ((user != undefined) && (user.value == "")) {
user.focus();
return;
}
gel('processSelectId').focus();
}
function onLoadPopulateProcessSelect() {
var fromSysUserForm = gel('ref_sys_user').value;
if (fromSysUserForm.length > 0) {
populateProcessSelect();
}
}
function clearErrorMessage() {
clearFieldError('error_msg_id', 'user_id_form_group');
clearFieldError('error_msg_select', 'process_select_form_group');
}
function populateProcessSelect() {
clearErrorMessage();
var user_id = gel('ref_sys_user').value;
var sel = document.getElementById("processSelectId");
sel.options.length = 1;
if (user_id != "") {
var ga = new GlideAjax('PwdAjaxVerifyIdentityServiceDesk');
ga.addParam('sysparm_name', 'getProcessNamesAsync');
ga.addParam('sysparm_user', user_id);
ga.getXML(function(response) {
var processes = response.responseXML.getElementsByTagName("process");
var numProcesses = processes.length;
for (var i = 0; i < processes.length; i++) {
var name = processes[i].getAttribute("name");
var procSysId = processes[i].getAttribute("procSysId");
sel[i + 1] = new Option(name, procSysId);
}
if (numProcesses == 0) {
displayFieldError("error_msg_select", getMessage('No service-desk processes found for the user selected.'), "process_select_form_group");
}
});
}
}
var wasSubmitted = false;
function verifyIdentity() {
if (wasSubmitted)
return false;
wasSubmitted = true;
clearErrorMessage();
var user_id = gel('ref_sys_user').value;
if ((user_id == undefined) || (user_id == "")) {
displayFieldError("error_msg_id", getMessage("Invalid user"), "user_id_form_group");
wasSubmitted = false;
return false;
}
var sel = document.getElementById("processSelectId");
var procSysId = sel.options[sel.selectedIndex].value;
if (sel.selectedIndex == 0) {
displayFieldError("error_msg_select", getMessage("Invalid selection"), "process_select_form_group");
wasSubmitted = false;
return false;
}
//showPwdLoadingDialog(); //Removing the PopUp as the Call has been made Asynchronous
var ga = new GlideAjax('PwdAjaxVerifyIdentityServiceDesk');
ga.addParam('sysparm_name', 'saveAndProceed');
ga.addParam('sysparm_user_id', user_id);
ga.addParam('sysparm_procSysId', procSysId);
ga.getXML(function(response) {
var result = response.responseXML.getElementsByTagName("result");
var status = result[0].getAttribute("status");
if (!status.match(/success/i)) {
displayFieldError("error_msg_id", status, "user_id_form_group");
} else {
var submitForm = gel('pwd_master_form');
submitForm.action = '$pwd_verify.do';
submitForm.submit();
}
wasSubmitted = false;
});
return false;
}
function isEmailAddress(str) {
var email_pattern = /^\w+(\.\w+)*@\w+(\.\w+)+$/;
return str.match(email_pattern);
}
function errorImage() {
return '<img src="images/outputmsg_error.gifx" alt="Error Message" />';
}
function showPwdLoadingDialog() {
loadingDialog = new GlideModal("pwd_request_in_progress", true);
loadingDialog.setTitle(getMessage('Request in progress'));
loadingDialog.render();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-28-2023 11:13 AM - edited 08-28-2023 01:54 PM
Thanks, Peter.
Yeah, me too. Not even the single quote was accepted because of JS query.
I'm trying to query within the g:evaluate tag, but so far no luck.
EDIT:
Hey @Peter Bodelier , I'm getting very close 😀, see the results:
Now is auto-populating with my elevated account, which is a huge leap!
Here is the change I did:
<g:evaluate var="jvar_user_has_next" jelly="true">
var renUser = new GlideRecord("sys_user");
renUser.addEncodedQuery("user_nameLIKEjavascript:var user = new GlideRecord('sys_user');user.get(gs.getUserID());user.user_name;^sourceLIKEPriv");
renUser.query();
renUser.next();
</g:evaluate>
<j:if test="${jvar_user_has_next}">
<j:set var="jvar_user_id" value="$[renUser.sys_id]"/>
<j:set var="jvar_user_name" value="$[renUser.user_name]"/>
</j:if>
I could pass as Econded Query and the reason it was not working before was because the line:
<j:set var="jvar_user_name" value="$[renUser.user_name]"/>
Was passing the name and not the user_name, name field is blank for our elevated accounts.
Now, the only thing next still missing is to only allow the current logged in user to only see accounts with their user_names in the drop-down or the popup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
08-30-2023 08:51 AM
Everything solved here.
I decided to not use the macro_invoke as it would require customization to the macro ui_reference.
So, I commented that part and added a call for a custom reference and using the dynamic filter (manager IS(dynamic) me):
<g:ui_reference name="ref_sys_user" id="ref_sys_user" query="managerDYNAMIC90d1921e5f510100a9ad2572f2b477fe^sourceLIKEPriv" table="sys_user" show_popup="true" value="${jvar_user_id}" displayvalue="${jvar_user_name}" onchange="populateProcessSelect();" />
<!-- <g:macro_invoke macro="ui_reference" id="ref_sys_user" name="ref_sys_user" table="sys_user" show_popup="true" value="${jvar_user_id}" displayvalue="${jvar_user_name}" onchange="populateProcessSelect();" /> -->
Thanks,