Using OOTB-style Constraints in AEM on a Custom Form Component | Community
Skip to main content
andrewh9285432
June 29, 2018

Using OOTB-style Constraints in AEM on a Custom Form Component

  • June 29, 2018
  • 1 reply
  • 3528 views

I'm trying to validate a custom recaptcha component using constraints in the same way the OOTB Form Elements do.  I'm having trouble figuring out how to connect the custom component to it's servervalidation.jsp though.

I need help getting to the point where submitting a form with the custom constraint selected causes the captcha/servervalidations.jsp to validate.  It currently allows an undone captcha to be submitted.

I have my component:

(I made a lot of edits to the captcha.jsp for brevity here since it's not really the point and I may have messed it up, so if there's syntax errors in that file don't worry about it.)

captcha.jsp

    <%@include file="/apps/codebase/global.jsp" %>

  

    <div class="captcha-wrap">

      <div id="recaptcha${properties.reCaptchaId}" class="g-recaptcha"></div>  

    <script>

  

        /* Renders captchas.  Runs @ async defer (callback on recaptcha src script in 'basepage/footer.jsp') */

        function recaptchaCallback() {

          var cC = $('.g-recaptcha').length;  // captcha count

          if ( cC >= 1 && cC <= 6) {   // recaptcha1 loads when cC is 1-6

            grecaptcha.render('recaptcha1', {

              'sitekey' : '<PUBLIC_KEY>'

            });

          }

          if ( cC >= 2 && cC <=  6) {

            grecaptcha.render('recaptcha2', {

              'sitekey' : '<PUBLIC_KEY>'

            });

          }

          /* Additional if statements for rendering 1 to 6 captchas on the same page */

  

    </script>

This script renders the captcha:

footer.jsp

    <script src="https://www.google.com/recaptcha/api.js?onload=recaptchaCallback&render=explicit" defer></script>

Here is my dialog with the OOTB captcha constraint tab included

dialog.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"

        jcr:primaryType="cq:Dialog"

        title="Captcha Configuration"

        xtype="dialog">

        <items

            jcr:primaryType="cq:Widget"

            xtype="tabpanel">

            <items jcr:primaryType="cq:WidgetCollection">

                <tab0

                    jcr:primaryType="cq:Panel"

                    title="Captcha">

                    <items jcr:primaryType="cq:WidgetCollection">

                        <reCaptchaId

                        jcr:primaryType="cq:Widget"

                        fieldDescription="Must be 1, 2, 3, 4, 5 or 6. Must go in order, i.e. don't only have a 1, 2, and 4 on the page or it won't work. Will not work with 7+ either."

                        fieldLabel="ReCaptcha ID"

                        name="./reCaptchaId"

                        xtype="textfield" />

                    </items>

                </tab0>

            <tab1

               jcr:primaryType="nt:unstructured"

               title="Constraints"

               xtype="panel">

               <items jcr:primaryType="cq:WidgetCollection">

                    <required

                         jcr:primaryType="cq:Widget"

                         fieldLabel="Required"

                         inputValue="true"

                         name="./required"

                         type="checkbox"

                         xtype="selection"/>

                   <requiredMessage

                         jcr:primaryType="cq:Widget"             

                         fieldLabel="Required Message"

                         name="./requiredMessage"

                         xtype="textarea"/>

                    <constraintType

                         jcr:primaryType="cq:Widget"

                         fieldLabel="Constraint"

                         name="./constraintType"

                         options="/etc/designs/codebase/options/constraints.json"

                         type="select"

                         xtype="selection"/>

                   <constraintMessage

                        jcr:primaryType="cq:Widget"

                        fieldLabel="Constraint Message"

                        name="./constraintMessage"

                        xtype="textarea"/>

                </items>

             </tab1> 

            </items>

        </items>

    </jcr:root>

And here is the json referenced:

constraints.json

    [

         {"value":"","text":"None"},

         {"value":"codebase/components/content/formelements/constraints/captcha","text":"Captcha"}

    ]

Which brings me to the constraint file itself.  My problem is that I cannot get this file to actually validate against the captcha.jsp file.  So it has not been debugged and may be full of java errors for all I know.

This file is a combination of the OOTB file found at /libs/foundation/components/form/captcha/servervalidation.jsp<br>

and the captcha validation solution found here: Server side validation for reCAPTCHA V2 or Invisible reCAPTCHA with Java (Servlet) - Code Review Stack Exchange

codebase/components/content/formelements/constraints/captcha/servervalidation.jsp

    <%@page session="false" %><%

    %><%@page import="java.io.BufferedReader,

    java.io.InputStream;

                    java.text.ParsePosition,

        java.io.InputStreamReader,

    java.net.URL,

    java.nio.charset.Charset,

    org.json.JSONObject,

                    com.day.cq.wcm.foundation.forms.FieldHelper,

                    com.day.cq.wcm.foundation.forms.FieldDescription,

                    com.day.cq.wcm.foundation.forms.FormsHelper,

                    com.day.cq.wcm.foundation.forms.ValidationInfo"%><%

    %><%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>

  

    <sling:defineObjects/><%

  

        // Get field description and force its name

        FieldDescription desc = FieldHelper.getConstraintFieldDescription(slingRequest);

        desc.setName(":cq:recaptcha");

  

        // Check if a value has been provided

        if (FieldHelper.checkRequired(slingRequest, desc)) {

            final String response = request.getParameter("g-recaptcha-response");

            final String secretKey = "<PRIVATE_KEY>";

  

    private static boolean isCaptchaValid(String secretKey, String response) {

        try {

            String url = "https://www.google.com/recaptcha/api/siteverify?"

                    + "secret=" + secretKey

                    + "&response=" + response;

            InputStream res = new URL(url).openStream();

            BufferedReader rd = new BufferedReader(new InputStreamReader(res, Charset.forName("UTF-8")));

  

            StringBuilder sb = new StringBuilder();

            int cp;

            while ((cp = rd.read()) != -1) {

                sb.append((char) cp);

            }

            String jsonText = sb.toString();

            res.close();

  

            JSONObject json = new JSONObject(jsonText);

            return json.getBoolean("success");

        } catch (Exception e) {

            return false;

        }

    }

            if (!isCaptchaValid("<PRIVATE_KEY>", request.getParameter("g-recaptcha-response"))) {

                ValidationInfo.addConstraintError(slingRequest, desc);

            }

        }

  

    %>

How can I get this captcha constraint `servervalidation.jsp` file to actually work? Currently the captcha can be submitted uncompleted and no validation stops it.

I do notice some form parameters in the `_cq_editConfig.xml` of the OOTB components, and that's the only thing I notice that I haven't copied to try to get this constraint to work. But that's because I'm not sure how it works.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

1 reply

smacdonald2008
Level 10
June 29, 2018

We have an article on building a custom ReCaphc here - Scott's Digital Community: Adding Google reCAPTCHA to an AEM web site

andrewh9285432
June 29, 2018

smacdonald2008 unless I'm misunderstanding something that article is out of date.  I did that entire tutorial before and it only verifies the deprecated reCaptcha V1 while just rendering the v2 underneath it.  That's why I'm trying to get a custom constraint to work.  I'm certainly open to other paths but I don't think that works, and update would be appreciated.

If you look at the article, rendering the v2 under v1 makes no sense and there's no verification set up for v2.  No js alerts either like there is for v1. And they only verify v1 in the video.  v1 is fully deprecated at of 3/31/2018, it no longer loads in the page at all.

smacdonald2008
Level 10
June 29, 2018

Do you think this custom constraint path could work?  Or do you know if developers can make custom constraints for custom components?  I'm having trouble finding anything online about recaptcha v2 and AEM because everyone just reblogs the article that you posted.  Any other suggestions would be helpful, I need this validated server-side.


Its been nearly 2 years since that was written. I have not looked at the new version. I will talk to internal ppl and see if we can update that article to use the newest one.