How to verify hCaptcha response and ensure it is filled? - php

I have followed the tutorial here.
hCaptcha appears on my site, but the form can be submitted without attempting it. How can I make it a required field?
I have tried the following to make it required.
<?php
$data = array(
'secret' => "my-secret (should start with 0x..)",
'response' => $_POST['h-captcha-response']
);
$verify = curl_init();
curl_setopt($verify, CURLOPT_URL, "https://hcaptcha.com/siteverify");
curl_setopt($verify, CURLOPT_POST, true);
curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($verify);
var_dump($response);
?>
And also
<?php
if(isset($_POST['h-captcha-response']) && !empty($_POST['h-captcha-response']))
{
$secret = 'your_secret_key';
$verifyResponse = file_get_contents('https://hcaptcha.com/siteverify?secret='.$secret.'&response='.$_POST['h-captcha-response'].'&remoteip='.$_SERVER['REMOTE_ADDR']);
$responseData = json_decode($verifyResponse);
if($responseData->success)
{
$succMsg = 'Your request have submitted successfully.';
}
else
{
$errMsg = 'Robot verification failed, please try again.';
}
}
?>
But I get a Notice: Undefined Index: error. I tried to hide the error by editing php.ini and also by adding
<?php error_reporting (E_ALL ^ E_NOTICE); ?> at the top of my file, but it doesn't work.
When I try to make it required, I get an unexpected end to file error-
$("form").submit(function(event) {
var hcaptchaVal = $('[name=h-captcha-response]').value;
if (hcaptchaVal === "") {
event.preventDefault();
alert("Please complete the hCaptcha");
}
});

There is a hidden field in the DOM that holds the response from the hCaptcha challenge.
Use this code to get the response:
$('[name=h-captcha-response]').val();
$() transforms an elem in a jQuery object and val() is a function from jQuery. jQuery doesn't have value property.

Related

JSON: Update base64 string using url JSON

I'm new to JSON Code. I want to learn about the update function. Currently, I successfully can update data to the database. Below is the code.
<?php
require_once "../config/configPDO.php";
$photo_after = 'kk haha';
$report_id = 1;
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport?taskname=&reportStatus=&photoBefore=&photoAfter=". urlencode($photo_after) . "&reportID=$report_id";
$data = file_get_contents($url);
$json = json_decode($data);
$query = $json->otReportList;
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
the problem is, if the value of $photo_after is base64 string, which is too large string, it will give the error:
1) PHP Warning: file_get_contents.....
2) PHP Notice: Trying to get property 'otReportList' of non-object in C:
BUT
when I change the code to this,
<?php
require_once "../config/configPDO.php";
$photo_after = 'mama kk';
$report_id = 1;
$sql = "UPDATE ot_report SET photo_after ='$photo_after', time_photo_after = GETDATE(), ot_end = '20:30:00' WHERE report_id = '$report_id'";
$query = $conn->prepare($sql);
$query->execute();
if($query){
echo "Data Save!";
}else{
echo "Error!! Not Saved";
}
?>
The data will updated including when the value of $photo_after is in base 64 string.
Can I know what is the problem? Any solution to allow the base64 string update thru json link?
Thanks
// ...
// It's likely that the following line failed
$data = file_get_contents($url);
// ...
If the length of $url is more than 2048 bytes, that could cause file_get_contents($url) to fail. See What is the maximum length of a URL in different browsers?.
Consequent to such failure, you end up with a value of $json which is not an object. Ultimately, the property otReportList would not exist in $json hence the error: ...trying to get property 'otReportList' of non-object in C....
To surmount the URL length limitation, it would be best to embed the value of $photo_after in the request body. As requests made with GET method should not have a body, using POST method would be appropriate.
Below is a conceptual adjustment of your code to send the data with a POST method:
<?php
require_once "../config/configPDO.php";
# You must adapt backend behind this URL to be able to service the
# POST request
$url = "http://172.20.0.45/TGWebService/TGWebService.asmx/ot_maintainReport";
$report_id = 1;
$photo_after = 'very-long-base64-encoding-of-an-image';
$request_content = <<<CONTENT
{
"taskname": $taskname,
"report_id": $report_id,
"photoBefore": $photoBefore,
"photo_after": $photo_after,
"reportStatus": $reportStatus
}
CONTENT;
$request_content_length = strlen($request_content);
# Depending on your server configuration, you may need to set
# $request_headers as an associative array instead of a string.
$request_headers = <<<HEADERS
Content-type: application/json
Content-Length: $request_content_length
HEADERS;
$request_options = array(
'http' => array(
'method' => "POST",
'header' => $request_headers,
'content' => $request_content
)
);
$request_context = stream_context_create($request_options);
$data = file_get_contents($url, false, $request_context);
# The request may fail for whatever reason, you should handle that case.
if (!$data) {
throw new Exception('Request failed, data is invalid');
}
$json = json_decode($data);
$query = $json->otReportList;
if ($query) {
echo "Data Save!";
} else {
echo "Error!! Not Saved";
}
?>
sending a long GET URL is not a good practice. You need to use POST method with cURL. And your webservice should receive the data using post method.
Here's example sending post using PHP:
//
// A very simple PHP example that sends a HTTP POST to a remote site
//
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.example.com/tester.phtml");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"postvar1=value1&postvar2=value2&postvar3=value3");
// In real life you should use something like:
// curl_setopt($ch, CURLOPT_POSTFIELDS,
// http_build_query(array('postvar1' => 'value1')));
// Receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
// Further processing ...
if ($server_output == "OK") { ... } else { ... }
Sample code from: PHP + curl, HTTP POST sample code?
And all output from the webservice will put in the curl_exec() method and from there you can decode the replied json string.

Send form data using cURL and receive JSON validation error from remote API

Due to a few restrictions on my local web server, I am forced to process my comment form data in a remote server using cURL.
What I want to achieve is: send the form data by cURL to the remote validation script, the remote validation script checks user inputs for errors. If there are errors, remote script should send the "specific" error back to the local script. If there are no errors, my remote validation script should send email to me and also output a success message which I should receive in the local file and I will output same to the user filling the form if there is a successful submission or not.
This is a snippet of my local file named Process.php
$Email = $_POST['Email'];
$Comment = $_POST['Comment'];
$ch = curl_init();
$api ="http://RemoteServer.com/Sendmail.php";
$cu = "$api?Email=$Email&Comment=$Comment";
curl_setopt($ch, CURLOPT_URL, $cu);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
Here is also a snippet of my remote file http://RemoteServer.com/Sendmail.php
/**************************************************/
//-- data and error arrays
$errors = array(); // array to hold validation errors
$data = array(); // array to pass back data
/***************************************************/
/*********** CLEAN INPUTS **************************/
// Create function to clean input
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
/******************************************************/
/********************************* VALIDATION ******************************************************/
if ( !empty($_POST)) {
/***************** DEFINE $_POST Data ************************/
$Email = test_input($_POST["Email"]);
$Comment = test_input($_POST["Comment"]);
if (empty($Email)) {
$errors['Error'] = 'Enter your email';
} elseif (!filter_var($Email, FILTER_VALIDATE_EMAIL)) {
$errors['Error'] = 'Invalid email';
} elseif (empty($Comment)) {
$errors['Error'] = 'Enter a comment';
} else {
//Send email to myself and output success
$data['success'] = true;
}
if ( ! empty($errors)) {
// if there are items in our errors array, return those errors
$data['success'] = false;
$data['errors'] = $errors;
} else {
$data['success'] = true;
// if there are no errors process our form, then return a message
}
// return all our data to an AJAX call
echo json_encode($data);
}//--END IF NOT EMPTY POST
else {
$data['success'] = false;
$data['errors'] = $errors;
}
Now, what I hope to achieve is this:
inside my local file Process.php, I should be able to receive the errors from the remote file Sendmail.php and use it this way:
if (errors_from_remote_file) {
//--- Redirect user to error page to notify of form validation errors
header("Location: ./Error.php");
exit();
} else {
//--- Redirect user to Success page if form successfully validated and email sent to me
header("Location: ./Success.php");
exit();
}
At the moment, I have tried
if (isset($_POST))
and if (isset($_GET))
I have both inside my remote file Sendmail.php to retrieve the form data sent by cURL from the local file Process.php and I still can't get the form data.
I really need help on how to retrieve the post data sent from Process.php using cURL to Sendmail.php.
Once this is achieved, I want to also know how I can retrieve the errors from remote file Sendmail.php within my local file Process.php and use it to successfully redirect the user to the next pages depending on the errors or success output in the remote file Sendmail.php
Thanks to everyone.
Thanks to everyone who has responded so far. For the $_POST error, I found out I was missing a semicolon. Once I had it sorted, I was able to retrieve the POST DATA correctly.
As for the JSON result from the Remote File Sendmail.php, I was able to output the errors or success notice by decoding the JSON object and used it to manipulate location to direct the user to upon error or upon success. Here is sample code used in my localfile:
$fp = fopen(dirname(__FILE__).'/errorlog.txt', 'w'); //-- To monitor cURL procedure
$data = array("name"=>"ohidul","age"=>20);
$string = http_build_query($data);
$ch = curl_init("http://RemoteServer.com/Sendmail.php");
curl_setopt($ch, CURLOPT_POST,true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_STDERR, $fp);
curl_exec($ch);
$response = curl_exec($ch);
curl_close($ch);
//-------------DECODE JSON ERROR FROM REMOTE FILE---------------------------------
$RemoteResponse = json_decode($response);
if ($RemoteResponse == "Failed") {
header("Location: ./Error.php");
exit();
} else {
header("Location: ./Success.php");
exit();
}
//---------------------------------------------
I made basic errors by not watching out for the missing semicolon and I also thought it was a long process to read a few tuts on JSON. But, I glanced through a few lines on JSON and I was able to get this done myself. Frustrating initially but I am happy I learnt the hard way by learning on my own.

ReCaptcha returning null values randomly when calling siteverify

I have two php files, the first has a form that gathers payment data then posts to the other file to format a SOAP call to send the payment information to the payment service. The reCaptcha is called in the first file and the returned token is passed to the second file in the post where I call the Google siteverify funtion.
Before processing the payment, I check for the value of success to equal true and for the score to meet my threshold.
For some reason, it will fail some legitimate users, most pass successfully. When they retry, they are successful.
Is this common? Are there any techniques I should consider to avoid this or to make it more seamless to the user?
Verified that this was due to return of nulls not and issue with returning FALSE or a score issue.
Initial file with payment form
….
<script>
grecaptcha.ready(function() {
console.log("function");
grecaptcha.execute('************************', {action: 'usaepayform'}).then(function(token) {
console.log(token);
document.getElementById("token").value = token;
});
});
</script>
……
<form id="epayform" name="epayform" action="./transaction_soap.php" method="POST" autocomplete="off">
….
<input type="hidden" id="token" name="token">
</form>
<input type="button" id="submitbutton" name="submitbutton" data-plus-as-tab="false" value="Process Payment >>">
…..
then in transaction_soap.php
$tokenn = $_POST['token'];
$ip = $_SERVER['REMOTE_ADDR'];
if(isset($_POST["TotalAmount"])) {
$url = "https://www.google.com/recaptcha/api/siteverify";
$data = array(
'secret' => "##################",
'response' => $_POST['token'],
'remoteip' => $ip
);
$verify = curl_init();
curl_setopt($verify, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($verify, CURLOPT_POST, true);
curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($verify, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($verify);
$responseKeys = json_decode($res, true);
//get response along side with all results
if($responseKeys['success'] == true) {
if ($responseKeys['score'] >= 0.3){
……...
} else {
echo "Recaptcha Score Not Met";
}
} else {
echo "Recaptcha not successfully validated. Please, try again before reporting as an error.";
}
}```
I would expect a return of true from real uesers.

Synchronous XMLHttpRequest on the main thread is deprecated / AJAX & API

I am looking to create an ajax function with the MailChimp list API however I am facing the following error 'Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects '. PHP code works fine but when I try to introduce ajax it all goes wrong.
Honestly, I don't know where to start with this as have little experience in using ajax with API.
Could someone please be kind enough to review the below code and give me their thoughts?
$(document).ready(function() {
$("#subCard").submit(function(event) {
event.preventDefault();
var emailSub = $("#emailSub").val();
var fNameSub = $("#fNameSub").val();
var lNameSub = $("#lNameSub").val();
var subSubmit = $("#subSubmit").val();
$(".form-message").load("action.php", {
emailSub: emailSub,
fNameSub: fNameSub,
lNameSub: lNameSub,
subSubmit: subSubmit
});
});
});
<?php
session_start();
if(isset($_POST['subSubmit'])){
$emailSub = $_POST['emailSub'];
$fNameSub = $_POST['fNameSub'];
$lNameSub = $_POST['lNameSub'];
if(!empty($emailSub) && !filter_var($emailSub, FILTER_VALIDATE_EMAIL) === false){
// MailChimp API credentials
$apiKey = 'user API key';
$listID = 'user list ID';
// MailChimp API URL
$memberID = md5(strtolower($emailSub));
$dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
$url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listID . '/members/' . $memberID;
// member information
$json = json_encode([
'email_address' => $emailSub,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $fNameSub,
'LNAME' => $lNameSub
]
]);
// send a HTTP POST request with curl
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// store the status message based on response code
if ($httpCode == 200) {
$_SESSION['msg'] = '<p style="color: #ffffff">You have successfully subscribed to AquaCodeStudio.</p>';
} else {
switch ($httpCode) {
case 214:
$msg = 'You are already subscribed.';
break;
default:
$msg = 'Sorry a problem occurred, please try again.';
break;
}
$_SESSION['msg'] = '<p style="color: #EA4335">'.$msg.'</p>';
}
}else{
$_SESSION['msg'] = '<p style="color: #EA4335">Please enter a valid email address.</p>';
}
}
// redirect to homepage
header('location:about.php');
?>
.load in itself is synchronous, unless something else is specified in the global jQuery AJAX settings.
The redirect to the about.php page after processing the form data seems to be the culprit here.
It actually redirects the AJAX request in the background - so first the data is send to load.php and processed there, and then the browser makes another (GET) request for about.php. What is then inserted into your original document is the content of the latter. Not sure how exactly this causes the “Synchronous…” warning, but maybe that page itself contains code that makes AJAX requests again, or something like that. (.load, when executed without a suffixed selector expression, executes <script> elements contained in the loaded HTML automatically.)

bbPress RTX integration

Im currently working on a RTX/Janrain integration with bbPress, but im stuck with a SQL query which doesnt give me any results even though I've been trying with wildcards and an e-mail adress i know is registered.
Sign In
$rpxApiKey = 'xxxxx';
if(isset($_POST['token'])) { /*
STEP 1: Extract token POST parameter
*/ $token = $_POST['token'];
/* STEP 2: Use the token to make the
auth_info API call */ $post_data =
array('token' => $_POST['token'],
'apiKey' => $rpxApiKey,
'format' => 'json');
$curl = curl_init();
curl_setopt($curl,
CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL,
'https://rpxnow.com/api/v2/auth_info');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_HEADER,
false); curl_setopt($curl,
CURLOPT_SSL_VERIFYPEER, false);
$raw_json = curl_exec($curl);
curl_close($curl);
/* STEP 3: Parse the JSON auth_info
response */ $auth_info =
json_decode($raw_json, true);
if ($auth_info['stat'] == 'ok') {
/* STEP 3 Continued: Extract the 'identifier' from the response */
$profile = $auth_info['profile'];
$identifier = $profile['identifier'];
$profile['identifier'];
if (isset($profile['photo'])) {
$photo_url = $profile['photo'];
}
if (isset($profile['displayName'])) {
$name = $profile['displayName'];
}
if (isset($profile['email'])) {
$email = $profile['email'];
}
/* Step 5, Check if user existis in database, if so login, if
not create new user then login*/
global $bbdb; $querystr = "
SELECT * FROM $bbdb->bb_users
WHERE user_email = $email LIMIT
1"; $rtx_user_id =
$bbdb->get_results($querystr, OBJECT);
print_r($rtx_user_id);
if ($rtx_user_id) {
echo "Great success";
wp_set_auth_cookie( (int) $rtx_user_id, 0 ); // 0 = don't
remember, short login, todo: use form
value do_action('bb_user_login',
(int) $rtx_user_id ); } if
(!$rtx_user_id) { echo "Not great
success";}
/* STEP 6: Use the identifier as the unique key to sign the user into
your system.
This will depend on your website implementation, and you should
add your own
code here.
*/
/* an error occurred */ }
else { // gracefully handle the
error. Hook this into your native
error handling system. echo 'An
error occured: ' .
$auth_info['err']['msg']; } } } ?>
The problem accrues in Step 5 which is to check if the user exists.
Thanks in advance,
Marten
As we talked on twitter, the query line should be
$querystr = "SELECT * FROM $bbdb->users WHERE user_email = '$email' LIMIT 1";

Categories