aryehraber / statamic-captcha

Statamic Addon that protects your Statamic forms using a Captcha service.
MIT License
11 stars 8 forks source link

Captcha error checking via AJAX #36

Closed sjclark closed 2 years ago

sjclark commented 2 years ago

Hey @aryehraber - this is definitely more a bug on my end rather than something specific to your script; but thought I'd file a bug to see if you might be able to point me in the right direction. 😂

I'm trying to utilise Statamic Captcha with Statamic Peak - which does its form processing via Javascript. Essentially statamic peak works by processing the form via AJAX, which is super handy as you can have forms on statically cached pages.

For the relevant code see here: https://github.com/studio1902/statamic-peak/blob/main/resources/views/page_builder/_form.antlers.html#L79 - it requires that you handle errors external to the normal form error loop by displaying them client side via alpine.

Out of the box the captcha seems to work perfectly with the sole exception of not throwing errors. With a normal statamic install the Captcha errors come through within the normal error loop, but I just cannot seem to find them when going via the AJAX method.

Say for a simple form like this....

Screen Shot 2022-03-19 at 4 24 55 pm

I'd get back all fields except the Captcha in the errors array

Screen Shot 2022-03-19 at 4 24 39 pm

Just grabbing this via...

Screen Shot 2022-03-19 at 4 29 58 pm

Would you have any idea how I would be able to get access to Captcha validation via ajax, or is it likely something I'd have to do client-side? Had a cursory look around the code and it seems to hook into the normal Exception code... so feel like I'm missing something obvious?

Again, this isn't really a bug with Captcha (more with me!) so feel free to delete if you feel like this is out of scope!

👍

aryehraber commented 2 years ago

Hi @sjclark, no worries regarding opening this issue 👍

In theory, from what you’ve explained and shown in your screenshot, it should all Just Work™.

One small caveat: Captchas errors will never show until the main form fields all pass validation, Statamic doesn’t send the submission to Form Listeners (i.e. Captcha) until the form can successfully be submitted.

If you’re not seeing the form fail via Captcha then make sure the captcha config is setup correctly to verify this form.

If that fails, I can try and take a closer look at Peak. I’ve been meaning to create a demo of sorts to show Captcha working via JS so using Peak might be a good idea.

sjclark commented 2 years ago

😮 OOOOOOOoooo! You've already got me heading in the correct path - didn't know all the other fields had to validate before Captcha would be checked. Tried submitting it with everything EXCEPT the captcha and it seems to be coming through! Will have a further wangjangling of my code and see if I can get it hooked up!

Screen Shot 2022-03-19 at 4 58 02 pm

Will report back!

aryehraber commented 2 years ago

Hmm, on second thought, there might be some addition work needed to get Captcha to play nice over Ajax. I always forget about that, but you essentially need to trigger Captcha via the form submit and then have Captcha perform the real submit to Statamic once the verification from Google has taken place.

Is your site public on GitHub for me to play around with, or should I take a look at the default Peak install (being close to your setup)?

sjclark commented 2 years ago

So in other words.... my code was correct the entire time! I just didn't know it checked it after all the other fields! I'm not sure why I spent hours trying to figure this out instead of asking you!

Screen Shot 2022-03-19 at 5 04 43 pm

But thank you so much! @aryehraber

I've actually been vaguely documenting my attempts if helpful: https://astronautnz.notion.site/Setup-a-Statamic-form-to-Send-via-JS-9300baeff0a34f2fadf3489e1f121031

sjclark commented 2 years ago

Ooops, missed your last message, I'm not using Peak itself but functionally all my code is all based on peak so thats probably the easiest setup 😄

aryehraber commented 2 years ago

Ok cool, will see if I can find some time to get a simple setup going. I have Captcha working on my company’s website which also uses Alpine so hopefully won’t be too tricky.

sjclark commented 2 years ago

😄 The link above basically has everything you'd need to get it to work at this stage (and the basis is 99% Peak). Really the only change in the end was outputting the error specific to captcha (as its not the in the default fields loop). <span class="text-sm text-red-600" x-text="errors.captcha"></span> or something similar Thanks again @aryehraber 🔥

aryehraber commented 2 years ago

@sjclark Oh right, it’s actually working as expected now? Also performing a successful form submission (after completing the Captcha check)?

If so, then all good and glad it worked out 💪

sjclark commented 2 years ago

@aryehraber yep it works perfectly 💯

  1. Submitting the form with missing required fields shows errors for those (but not Captcha)
  2. Submitting everything correctly EXCEPT the captcha then yields a Captcha failed
  3. Submitting everything correctly INCLUDING the captcha then successfully sends the form (just added a wee bit more detail to my document as well)

EDIT: Should also say I did this all with Captcha V2, no idea if it works with V3 🤷‍♂️

aryehraber commented 2 years ago

Great! 🚀

I think I got mixed up with Invisible Captcha, which needs the additional code to trigger Captcha before submitting the form “for real”. But makes sense your use case works as expected 👍

sjclark commented 2 years ago

@aryehraber something curious I did note was that via AJAX g-recaptcha-response gets saved as a field for form submissions. Completely inconsequential (for my purposes at least), but thought I'd mention out of interest 🙂 Screen Shot 2022-03-28 at 4 52 48 pm

aryehraber commented 2 years ago

Haha what?!?! I didn’t even know that was possible if a field isn’t defined in the Formset. Maybe it’s a Statamic bug, or otherwise a new feature I wasn’t aware of. Either way, thanks for the heads up!