Adding a Google reCaptcha to a record Producer on the Service Portal
Hello Community,
I had client asking me to add Google reCaptcha on their Record Producer on the Service Portal and allowing anonymous users to submit Incidents. However, they wanted to disable the Submit button on the page if they are NOT verified by the reCaptcha or they NOT authenticated.
There's also an interesting article by Göran on adding reCaptcha in the Portal.
I wanted to keep the solution simple allowing both anonymous and authenticated users to use the same page.
If the Captcha token is expired or the answer is wrong it must disable the Submit button again, until the user passes the reCaptcha validation.
1. Create a reCaptcha Widget, give it an id and the following:
- Body HTML; the submit Button visbility is based on the captach Response :
<!-- Begin Captcha code -->
<!-- This widget is in place to force non-athenticated users to pass Captcha validation, it works in correlation with Widget "udes-widget-sc-cat-item-v2"
The Submit button on the Page will remain disabled until it validates the Captcha response. Alternatively You can broadcast an event between the widgets to disable/enable the Submit Button, although Not recommended -->
<div ng-if="!data.logged_in">
<script></script>
<!--
<script>
function checkCap() {
alert(grecaptcha.getResponse());
}
</script>
-->
<body>
<div class="g-recaptcha" data-sitekey="{{data.sitekey}}" data-callback="captchaCallback" data-expired-callback="captchaExpiredCallback"></div>
<!-- Enlever le commentaire ici si vous voulez tester votre clé <input type="button" value="Test" onClick="checkCap()" /> -->
<script>
function captchaCallback() {
document.getElementById("submit-udes-button").disabled = false;
//captchaClientCallback();
}
function captchaExpiredCallback() {
document.getElementById("submit-udes-button").disabled = true;
}
</script>
</body>
</div>
<!-- End of Captcha code -->
(function() {
data.sitekey = gs.getProperty('property of your API Captacha V2 Key');
data.logged_in = gs.isLoggedIn();
})();
function($rootScope) {
//return MyAlert;
captchaClientCallback = function() {
//return MyAlert;
var c = this;
//console.log("Successfuly validated by Google reCaptcha");
var passedCaptcha = true;
$rootScope.$broadcast('customEvent', passedCaptcha);
//}
};
}
2. Clone the Widget "widget-sc-cat-item-v2" this widget will be used on the sc_cat_item page which is showing the record Producer form, or any record producer of choice. On the Cloned Widget :
- Modifying the following HTML part on line 181 from this code:
<div class="form-group m-b-xs" ng-if="c.options.native_mobile != 'true'">
<button sp-ellipsis-tooltip sp-ellipsis-tooltip-title="{{submitButtonMsg}} ng-if="::c.showOrderNowButton()" tabindex="0" name="submit" id="submit-btn" ng-disabled="disableControls()" ng-click="triggerOnSubmit()" class="btn btn-primary btn-block text-overflow-ellipsis">{{submitButtonMsg}}</button>
<span ng-if="submitting" style="padding-left:4px">${Submitting...}</span>
<span ng-if="validating" style="padding-left:4px">${Validating...}</span>
</div>
- We want to add an ID to the button element, so it will look like this:
<div class="form-group m-b-xs" ng-if="c.options.native_mobile != 'true'">
<button id="submit-udes-button" ng-if="::c.showOrderNowButton()" tabindex="0" name="submit" ng-disabled="disableControls()" ng-click="triggerOnSubmit()" class="btn btn-primary btn-block">{{submitButtonMsg}}</button>
<span ng-if="submitting" style="padding-left:4px">${Submitting...}</span>
<span ng-if="validating" style="padding-left:4px">${Validating...}</span>
</div>
- On the Server script, add the following code before anything to check if the user is authenticated
//Check if user is logged and and Hide Submit Button
// See disableControls function in Client Side
var loggedIn = gs.isLoggedIn();
data.logged_in = true;
if (!loggedIn)
data.logged_in = false;
var localInput = input; //to safeguard pullution of "input" via BR or other scripts
- Client Control: on line 12 modify the code to the following, by adding logged in validation to disable the button:
$scope.disableControls = function(){
return $scope.submitting || $scope.submitted || c.data.isPreview || !c.data.logged_in;
}
3. Position your Widgets on the page and make sure it is Public and so is your Portal:
And here is the Final Product:
If the user is not authenticated and have not passed the Captacha Validation
After passing the reCaptcha validation:
https://www.servicenow.com/community/itsm-articles/adding-a-google-recaptcha-to-a-record-producer-on-the-service/ta-p/2309516