Prevent Email Spam after using reCaptcha - php

All,
I've got a form on my page that I use to send emails. On the form page I have the following code:
<input type="text" name="Name" id="your_name" class="contact_form_input_text">
<input type="text" name="Email_Address" id="your_email" class="contact_form_input_text">
<input type="text" name="fill_me_out" id="fill_me_out">
<input type="button" value="Send" id="submit_contact_form_button">
The first text box is a lamecaptcha and I check it on the PHP side to make sure that it wasn't filled out. I also hide it using some JS with this:
jQuery(function(){
jQuery("#fill_me_out").hide();
});
I then have the following form validation before my page submits using jQuery validator:
jQuery("#contact_form").validate({
rules: {
Email_Address: {
required: true,
email: true
},
Name: {
required: true
}
},
messages: {
Email_Address: {
required: "Please enter an email address!",
email: "Please enter a valid email address!"
},
Name: {
required: "Please enter your Name!"
}
}
});
jQuery("#submit_contact_form_button").click(function(event) {
if (jQuery("#contact_form").valid()) {
challengeField = jQuery("input#recaptcha_challenge_field").val();
responseField = jQuery("input#recaptcha_response_field").val();
var html = jQuery.ajax({
type: "POST",
url: site_url + "ajax.recaptcha.php",
data: "recaptcha_challenge_field=" + challengeField + "&recaptcha_response_field=" + responseField,
async: false
}).responseText;
if(html == "success")
{
//$("#captchaStatus").html(" ");
// Uncomment the following line in your application
//return true;
jQuery("#contact_form").submit();
}else{
jQuery("#captchaStatus").html("Your captcha is incorrect. Please try again");
Recaptcha.reload();
return false;
}
}
return false;
});
If everything is filled out correctly the page then submits. I have the following check to check the lame captcha:
$lamecaptcha_check = $_POST['fill_me_out'];
if($lamecaptcha_check!=""){
echo '[box style="alert"]Why are you trying to spam us? It could be because you don\'t have Javascript enabled and filled out an incorrect box![/box]';
}else{
//Send the form using mail
}
To submit the form is a button and not a submit so it has to go through the jquery validation to do even be submitted. Somehow I'm still getting blank email messages to come through. Does anyone know anything else I can possibly do to prevent spam/blank email messages? I was thinking I should check the variables on the back end to make sure they are not blank but the form shouldn't even be submitted unless there are some values so I require a valid email address on the initial page. Any ideas are appreciated!
Thanks!

Just because you have a submit button go through jQuery to work, doesn't mean the form can't be submitted otherwise.
A spambot would probably examine the HTML of your form, look at the different fields, and then just send a POST request with the relevant information. It will not evaluate your jQuery.
If you want to do something like this, set the form's action="javascript:;", then update it in your jQuery to the actual value right before submitting.

Related

Remote validation in jquery validation not returning

I have tried to get this to work and have been unsuccessful, I have tried 18 different ways all produced the same result. I have double checked and triple check everything. NOTHING HAS WORKED! I have validation done server side as a fall back if jquery does not work. the validation part works fine its the cheeking if exists that is not working required is working.
My form field
<div class="col-sm-12">
<label>Name</label>
<input type="text" class="form-control" autocomplete="off" name="name" id="name" value="<?php echo isset($_POST['name']) ? $_POST['name'] : '' ?>">
</div>
My jquery vaidate function
$(function() {
$("form[name='register']").validate({
rules: {
name: {
required: true,
name: true,
remote: {
url: "../includes/check.php",
type: "post",
data: {
name: function() {
return $( "#name" ).val();
}
}
}
},
email: {
required: true,
email: true
},
password: {
required: true,
minlength: 5
}
},
messages: {
name: {
required: "Please enter your name",
minlength: "Name must be at least 4 characters long",
remote: "The name entered is unavailable"
},
password: {
required: "Please provide a password",
minlength: "Your password must be at least 5 characters long"
},
email: "Please enter a valid email address"
},
submitHandler: function(form) {
form.submit();
}
});
});
My query script
include("db.php");
if(isset($_POST['name'])) {
$name = $_POST['name'];
$db = dbconnect();
$stmt = $db->prepare("SELECT Name FROM users WHERE Name = ?");
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows == 1){
echo 'true';
}else{
echo 'false';
}
}
The problem is not directly related to the remote validation.
You just need to remove
name: true,
from your validation options. This option does not exist in jQuery Validate - there is no validation metod called "name" - and causes a Javascript error when jQuery validate tries to use it:
Cannot read property 'call' of undefined. Exception occurred when checking element name, check the 'name' method.
This means that the "remote" validation never executes because the script crashes before it gets to it.
See https://jsfiddle.net/09djba33/10/ to see the broken functionality - open the Developer Tools and submit the form (with the name field completed), and watch the error message appear in the console.
and https://jsfiddle.net/09djba33/12/ to see the "remote" method working correctly without that spurious option.
P.S. This is why, in the comments, I kept asking you to check what was happening to your ajax request, by looking in the browser tools... :-)
From reading the docs https://jqueryvalidation.org/remote-method/ you can see that while using remote, you need to send data to your server side script because you are using post method. Do it in this way :
remote: {
url: "../includes/check.php",
type: "post"
data: {
username: function () {
return $('#username').val();
}
},

JQuery Validation Plugin: Use remote with delay

I am using the remote method from the jQuery validation plugin which makes an ajax call. The remote function is activated each time a key is pressed in the input field. I would like to add a delay, so that the ajax request is only trigged when the user stopped pressing a key for some miliseconds.
This problem was posed in 2012 at GitHub but was closed by the developer in 2015:
I'm sorry for the lack of activity on this issue. Instead of leaving
it open any longer, I decided to close old issues without trying to
address them, to longer give the false impression that it will get
addressed eventually.
In the discussion forum, the user lohfu proposed the following solution:
$.validator.methods._remote = $.validator.methods.remote;
var timer = 0;
$.validator.methods.remote = function () {
clearTimeout(timer);
var args = arguments;
timer = setTimeout(function() {
$.validator.methods._remote.apply(this, args);
}.bind(this), 500);
return "pending";
};
However, there are two main problems:
It does not work. If I add the delay and the remote function returns false, then the form gets still submitted.
When I enter something in the input filed which causes an error by the remote function it correctly gets class="error" assigned. If I now select a different input, the class="error" switches to class="valid", although the error message is still present and the error message is still shown. The same happens when I press submit.
Here is a minimal example:
HTML
<form action="test.php" method= "POST" id="form">
Name: <input type="text" name="name"><br>
Email: <input type="email" name="email"><br>
<input type="submit">
</form>
JS
$("#form").validate({
rules: {
name: "required",
email: {
required: true,
email: true,
remote: {
url: "ajax.php",
type: "post"
}
}
},
messages: {
email: {
remote: "Email already exists"
}
}
});
ajax.php
<?php
header('Content-Type: application/json');
$valid = null;
echo json_encode($valid);
This form should never be submitted, because the ajax.php always returns false. However, entering a name and a valid email will submit the form, despite the fact that the error "Email already exists" is shown.
Does the following fiddle work as expected?
You can change the url into true or false instead:
url: '/echo/js/?js=[null|true|false]',
https://jsfiddle.net/ww0zh9jm/2/
..you have to ad the external resources (Fiddle removes them):
https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
https://ajax.aspnetcdn.com/ajax/jquery.validate/1.15.0/jquery.validate.min.js

Print PHP message to form through Ajax/Jquery

I have a jquery/bootstrap form. My php is checking against the database if an email address is already in use.
If the email address is in use, the following is called but to a new window.
echo'<p class="error">An account already exists for this email address. Please use a different email address</p>';
This all works fine but now I want the error message to show up on the Jquery form. I can't seem to wrap my head around how to do this.
I know I have to use this handler, but I don't know where to put the error message or how this code knows which error message to read from the php. Additionally, I would like the error message to show up next to the email field of the form
$(document).ready(function() {
$('#form').submit(function() {
$.ajax({
type: 'POST',
url: "process.php",
data: dataString,
success: function() {
}
})
return false;
});
});
Processing the error message can be performed in the success property. The function can accept a data argument (the response from process.php).
success: function(data){
//does data contain p.error?
//get the contents of p.error, display it on the current page
//for example:
if( $(data).find("p.error.name").length ){
//process name error here
nameError = $(data).find("p.error.name").text();
console.log(nameError);
}
if( $(data).find("p.error.email").length ){
//process email error here
emailError = $(data).find("p.error.email").text();
console.log(emailError);
}
}
The success function defined above assumes process.php looks something like this:
<div>
<p class="error name">Please enter a name.</p>
<p class="error email">Your email address is invalid.</p>
<!-- some other stuff here -->
</div>

No Ajax response even though PHP file set up correctly

I have a simple sign up mailing list form. It sends the user's email address to a store-address.php file. I use jQuery's ajax object to send a request to the php file and then receive a response.
The problem is I am not getting a response from the php file. I tried setting the cache to false in the request. I also tried send the information through the URL like so:
http://www.fifthtribe.com/inc/store-address.php?ajax=true&cache=false&email=test4%40gmail.com
When I do it that way it works and gives me a reponse. But when I do it through ajax it doesn't give me a response. This is from Firebug:
And here's snippets from my code:
HTML:
<div id="mlist">
<form id="mlist_form" method="POST" action="">
<input type="text" id="email" name="email" placeholder="Email" />
<input type="submit" id="submit_btn" value="Join" />
</form>
<div id="response"></div>
</div>
JQuery:
/* Add to mailing list */
$("#mlist_form").submit( function(e){
//$('#response').append('<div id="thanks-mce"><div id="mce-arrow"></div>Thanks for signing up!</div>');
var email = escape( $('#email').val() );
e.preventDefault();
data = {
"ajax" : "true",
"email" : email,
"cache" : "false"
}
$.ajax({
type: "POST",
url: 'inc/store-address.php',
data: data,
success: function( msg ){
// successfully signed up
$('#response').html( msg );
$('#email').val('');
},
error: function( err ){
// error while signing up
$('#response').html('Error: Is your email correct?');
}
});
return false;
});
PHP:
function storeAddress(){
// Validation
if(!$_GET['email']){ return "No email address provided"; }
if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*$/i", $_GET['email'])) {
return "Email address is invalid";
}
require_once('MCAPI.class.php');
// grab an API Key from http://admin.mailchimp.com/account/api/
$api = new MCAPI('xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us4');
// grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
// Click the "settings" link for the list - the Unique Id is at the bottom of that page.
$list_id = "xxxxxxxx";
if($api->listSubscribe($list_id, $_GET['email'], '') === true) {
// It worked!
return 'Success! Check your email to confirm sign up.';
}else{
// An error ocurred, return error message
return 'Error: ' . $api->errorMessage;
}
}
// If being called via ajax, autorun the function
if($_GET['ajax']){ echo storeAddress(); }
?>
You realize that your PHP script is using GET method but your jQuery code is using the POST method right?
If the information is being posted to PHP, PHP will need to use $_POST to retrieve it. This explains why the URL method using $_GET works but the jQuery POST doesn't.
Good luck!
It looks like you're using $_GET instead of $_POST. Try echoing out the contents of $_REQUEST to see what that holds.
Debug your script!
Place an alert in the success and error parts of your script and then you will know whether the AJAX is working.
If not, you can then work your way up the document and see where the problem is.
In addition, the error here is quite simple. You are using $_GET in PHP and you are POSTING your data using AJAX, this will not show an error. Although the PHP document will not process your request because it is not being fed any parameters.

jquery validation plugin and check unique field?

I am currently using jQuery validation plugin with cakephp in my new project.
It's working perfectly untill I need to make unique check to email field through ajax to check with the database..
I didn't know how to make the plugin make a unique validation to email from db.
thanx
I reckon you are refering to using an AJAX call (via the plugin) to check for unique email with the server, yea?
I would suggest using the addMethod of the validation plugin to create a custom validation in which you can make an AJAX call (which will be part of the jQuery core).
There's an SO post on this topic which you can explore:
JQuery Validate Plugin - How to create a simple, custom rule?
Do note that you will have to implement the server-side script yourself.
Here's another article which should be useful (using jQuery and PHP):
Check email already exist – Ajax – Jquery
The syntax is simple
$.validator.addMethod("eventName",
function(value, element) {
// condition returns true or false
}, "Error message to display");
});
Event name is called in the form
<input type="text" name="name" class="eventName" />
Refer this link if any more doubts
jQuery Validate Plugin - How to create a simple custom rule?
If you want to check if the email is unique you can use remote rule.
It is from: http://jqueryvalidation.org/remote-method
Example: Makes the email field required, an email and does a remote request to check if the given address is already taken.
$( "#myform" ).validate({
rules: {
email: {
required: true,
email: true,
remote: "check-email.php"
}
}
});
Example: Makes the email field required, an email and does a remote request to check if the given address is already taken. In addition, the http method is set to “post” and the username is sent alongside the email address.
$( "#myform" ).validate({
rules: {
email: {
required: true,
email: true,
remote: {
url: "check-email.php",
type: "post",
data: {
username: function() {
return $( "#username" ).val();
}
}
}
}
}
});
Try something like
$.validator.addMethod("unique",
function(value, element, params) {
var isUnique = false;
if(value == '')
return isUnique;
id_send= '';
if(params[1] !='')
id_send ='id='+params[1]+'&';
$.ajax({
url: "path"+params[2],
type : 'GET',
async: false,
data: id_send+'field=' + params[0] + "&value=" + value,
dataType: 'json',
cache: true,
success: function(data){
isUnique = data;
}
});
return isUnique;
},
jQuery.validator.format("Value already in use")
);
In the above code:
path is the root path of your application;
params[0] is the name of attribute to check unique;
params[1] is the id of the object, if you want to check in edit too, so exclude himself;
params[2] is the path to the php file that gonna check.
Resulting in something like:
rules:
{
email: {
required: true,
unique:['email', $('#user_id').val(),'uniqueemail.php'],
email: true
},
The PHP uniqueemail.php, search for the value in field email, if return empty or the user with id equals $('#user_id').val() so return true, else return false.
Note that the async attribute is set false, this is a set back but is gonna do the job.

Categories