Not able to know when user is identified as a bot in google invisible captcha on client side - invisible-recaptcha

I am following Programmatically invoke challenge process for identifying a user as human or bot.
below is my captcha div in html.
<div class="g-recaptcha"
data-sitekey="<site_key>"
data-callback="onSubmit"
data-size="invisible">
</div>
and i have data callback function in my html script tag:
var onSubmit = function(token){
// do next processing with token
}
data callback gets invoked every time when google identifies a user as human successfully.
it does not get invoked when google identifies a user as a bot.
but i want to know when google identifies user a bot in above similar way on clicking a button?
because when i click on a button, i programmatically invoke challenge by grecaptcha.execute() so this happens:
1) if user is validated as human , data-callback is called and i do my next processing with token.but
2) if user is not validated as human, data-callback is not called and nothing happens on click and i stay on same page.
i expect acknowledgment here in second case so that i can decide further processing.
please help me in this.

Related

How to update a field in a database via email?

When a user subscribes to news from the site, he receives a welcome letter in his mail with a question, does he really want to subscribe to news?
Also in the letter there is a button that confirms his consent to the newsletter.
How can I make it so that when I click this button from an email, the values ​​​​in my database are updated?
This is my mail form welcome.blade.php
Welcome, User
<form action="{{route('welcome', $data->hash)}} method="POST">#csrf
<button type="submit">Click me</button>
</form>
Controller
public function welcome($hash) {
\DB::table('config')->where('hash', $hash)->update(['agree' => 1]);
Route
Route::post('welcome', 'WelcomeController#welcome')->name('welcome')
Embedding forms in emails is not allowed/recommended. It is a security risk. Email clients will simply warn the recipients of potential danger and will disable the form.
You need to add a link to your application in the email content.
click me
When a user will click on the URL below route will hit.
Route::get('/add-consent/{token}', 'WelcomeController#welcome')->name('welcome');
In the action identify user based on token and perform the action.
public function welcome($token) {
// Identify user based on token and perform the action...
\DB::table('config')->where('hash', $token)->update(['agree' => 1]);
}

Slack Modal views: expand the stack to more than 3 before final submission

I'm working on a slack bot that have more than 3 modals until I submit it to process.. According to slack docs, the view stack is limit to 3 so I though that I cloud just close the oldest one and free a slot for a new one.. not sure if that make sense (Im actually trying to limit the whole experience to those 3 modals)... in this case goes like this:
Slash command --> views.open (open modal step1 to user and send a null response).
The user submit step1 modal and I trigger a push response operation with the next modal (step2).
idem ... showing modal step3 with a review of the values (I store them using Object Store -Mulesoft)..
this submit with do some process on the data from the step1 and step2 modals and response with a IM to the user with the result
On the 2nd step I tried to trigger a POST to views.push but the trigger ID from the submission is not valid, have to be the trigger id from a block action according to slack.
On step 1 and 2 modals I replace the word SUBMIT with NEXT and only on the final one it say SUBMIT.
One thing... I know that by not closing the views I can close and sort of "go back".. which I will loose if I expand the stack..
I tried to trigger another POST on views.open with a null response for while the response from that POST is good (ok: true)... on the UI... I get the error "We had some trouble connecting. Try again?" on the "step1" modal..
Anyone have any ideas on how can I close modal from the bottom of the view stack so I can add a new one and so on? I know the use case may not be the best (slack apps should make thins easier not form after form..) but just want to know if it can be done).
Thanks!
Well... I have come a long way since I posted this... I ended up using JS but one thing that I want to share if you are on the same situation is that as long you responde the SUBMIT with an sync acknowledgment (is easier in js) the modal will close and then you can send/open another one and so on...

Google reCaptcha Verification

I'm a little confused by the opening paragraph of this article: https://developers.google.com/recaptcha/docs/verify
When you use the third method to validate (i.e. the `data-callback' attribute), does this mean that there's no longer a need to POST to https://www.google.com/recaptcha/api/siteverify from the back end? Is this essentially a 100% client-side captcha?
It means you would post with ajax and when you get your callback if its successful or not then you can have a Javascript function to allow the submit/post or whatever action you need to do. I use the callback to allow the login button to submit and if it has not been completed then the button remains disabled. You will still need to submit your challenge to google so they can verify if it is successful. Here is a simplified example.
<div class="g-recaptcha" id="login" data-callback="captcha_filled"
data-expired-callback="captcha_expired" data-sitekey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"></div>
function captcha_filled() {
$("#submitLogin").prop('disabled', false);
}

Google Chrome Extension - How can I include a content script more than once?

I've been working on Chrome Extension for a website for the past couple of days. It's coming along really nicely but I've encountered a problem that you might be able to help with.
Here's an outline of what the extension does (this functionality is complete):
A user can enter their username and password into the extensions popup - and verify their user account for the particular website
When a user browses http://twitter.com a content script is dynamically included that manipulates the DOM to include an extra button next to each tweet displayed.
When a user clicks this button they are presented with a dialog box
I've made a lot of progress but here is my problem:
When a user visits Twitter the content script is activated and all tweets on the page get my new button - but if the user then clicks 'More...' and dynamically loads the next 20 tweets... these new additions to the page DOM do not get affected by the content script (because it is already loaded).
I could add an event listener to the 'More...' button so it then triggers the original content script again (and adds the new button) but i would have to predict the length of twitter's ajax request response.
I can't tap into their Ajax request that pulls in more tweets and call my addCurateButton() function once the request is complete.
What do you think is the best solution? (if there is one)
What you want to do is to re-execute your content-script every time the DOM is changed. Luckily there is an event for that. Have a look at the mutation event called DOMNodeInserted.
Rewrite your content script so that it attaches an event listener to the body of the DOM for the DOMNodeInserted event. See the example below:
var isActive = false;
/* Your function that injects your buttons */
var inject = function() {
if (isActive) {
console.log('INFO: Injection already active');
return;
}
try {
isActive = true;
//inject your buttons here
//for the sake of the example I just put an alert here.
alert("Hello. The DOM just changed.");
} catch(e) {
console.error("ERROR: " + e.toString());
} finally {
isActive = false;
}
};
document.body.addEventListener("DOMNodeInserted", inject, false);
The last line will add the event listener. When a page loads the event is triggered quite often so you should define a boolean (e.g. var isActive), that you initialize to false. Whenever the inject function is run check whether isActive == true and then abort the injection to not execute it too often at the same time.
Interacting with Ajax is probably the hardest thing to coax a content script to do, but I think you’re on the right track. There are a couple different approaches I’ve taken to solving this problem. In your case, though, I think a combination of the two approaches (which I’ll explain last) would be best.
Attach event listeners to the DOM to detect relevant changes. This solution is what you’ve suggested and introduces the race condition.
Continuously inspect the DOM for changes from inside a loop (preferably one executed with setInterval). This solution would be effective, but relatively inefficient.
The best-of-both-worlds approach would be to initiate the inspection loop only after the more button is pressed. This solution would both avoid the timing issue and be efficient.
You can attach an event-handler on the button, or link that is used for fetching more results. Then attach a function to it such that whenever the button is clicked, your extension removes all the buttons from DOM and starts over inserting them, or check weather your button exists in that particular class of DOM element or not and attach a button if it doesn't.

Hot to implement grails server-side-triggered dialog, or how to break out of update region after AJAX call

In grails, I use the mechanism below in order to implement what I'd call a conditional server-side-triggered dialog: When a form is submitted, data must first be processed by a controller. Based on the outcome, there must either be a) a modal Yes/No confirmation in front of the "old" screen or b) a redirect to a new controller/view replacing the "old" screen (no confirmation required).
So here's my current approach:
In the originating view, I have a <g:formRemote name="requestForm" url="[controller:'test', action:'testRequest']", update:"dummyRegion"> and a
<span id="dummyRegion"> which is hidden by CSS
When submitting the form, the test controller checks if a confirmation is necessary and if so, renders a template with a yui-based dialog including Yes No buttons in front of the old screen (which works fine because the dialog "comes from" the dummyRegion, not overwriting the page). When Yes is pressed, the right other controller & action is called and the old screen is replaced, if No is pressed, the dialog is cancelled and the "old" screen is shown again without the dialog. Works well until here.
When submitting the form and test controller sees that NO confirmation is necessary, I would usually directly redirect to the right other controller & action. But the problem is that the corresponding view of that controller does not appear because it is rendered in the invisble dummyRegion as well. So I currently use a GSP template including a javascript redirect which I render instead. However a javascript redirect is often not allowed by the browser and I think it's not a clean solution.
So (finally ;-) my question is: How do I get a controller redirect to cause the corresponding view to "break out" of my AJAX dummyRegion, replacing the whole screen again?
Or: Do you have a better approach for what I have in mind? But please note that I cannot check on the client side whether the confirmation is necessary, there needs to be a server call! Also I'd like to avoid that the whole page has to be refreshed just for the confirmation dialog to pop up (which would also be possible without AJAX).
Thanks for any hints!
I know, it's not an "integrated" solution, but have you considered to do this "manually" with some JS library of your choice (my personal choice would be jQuery, but any other of the established libraries should do the trick)? This way you wouldn't depend on any update "region", but could do whatever you want (such as updating any DOM element) in the response handler of the AJAX request.
Just a thought. My personal experience is that the "built-in" AJAX/JS stuff in Grails often lacks some flexibility and I've always been better off just doing everything in plain jQuery.
This sounds like a good use-case for using web flows. If you want to show Form A, do some kind of check, and then either move onto NextScreen or show a Dialog that later redirects to NextScreen, then you could accomplish this with a flow:
def shoppingCartFlow = {
showFormA {
on("submit") {
if(needToShowDialog())return
}.to "showNextScreen"
on("return").to "showDialog"
}
showDialog {
on("submit").to "showNextScreen"
}
showNextScreen {
redirect(controller:"nextController", action:"nextAction")
}
}
Then you create a showDialog.gsp that pops up the dialog.
--EDIT--
But, you want an Ajax response to the first form submit, which WebFlow does not support. This tutorial, though, will teach you how to Ajaxify your web flow.

Resources