How detect/check if message body is tnef format (winmail.dat) using PHP?
I don't want to decode, just want to check. I using imap_fetchbody and imap_body for get BODY, I need get mimetype (or like) for check if is "tnef format", like this:
if (in_array($bodyMimeType, array('application/tnef', 'application/x-tnef', 'application/ms-tnef'))) {
//Decode
}
I tried:
$structure = imap_fetchstructure($imap, $messageId, FT_UID);
echo 'sub-type:', $structure->subtype, PHP_EOL;
echo 'encoding:', $structure->encoding, PHP_EOL;
I think there's no way to know without decoding, I'm decoding it and check the status if it is successful using exec(), exec("tnef {$datfile} 2>&1", $output, $status), if it is successfully decoded, $status will be 0.
Related
I have an application mostly written in PHP, but there is a npm package that has functionality that I need to incorporate into my application. I must pass a string of HTML into the Node.js application but am having issues in getting things correct. I'm using:
exec('node '.$rootPath.'node/app.js '.$imageId.' email '.escapeshellcmd($emailString).' 2>&1', $output, $retVar);
to send the data to my Node.js application, but I'm unsure as to how to decode it once it gets there and needs to be processed via JavaScript. Is there a way to unescape escapeshellcmd() in JavaScript? Or is there a different way I should pass these long strings of HTML over the command-line?
EDIT: Here is the exact method I'm using to pass my info to Node.js:
try{
$emailString = escapeshellcmd($decoded);
//`node $rootPath'node/app.js' $imageId email $emailString 2>&1`;
exec('node '.$rootPath.'node/app.js '.$imageId.' email "'.$emailString.'" 2>&1', $output, $retVar);
print_r($output);
}catch(Exception $e){
echo $e->getMessage()."\n";
}
And here is app.js:
process.argv.forEach(function(value, index, array){
if(index == 2){
id = value;
}
if(index == 3){
type = value;
}
if(index == 4){
visual = value;
}
});
console.log('******* FROM NODE********');
console.log(visual);
It seems like only the first line is getting passed or collected and printed back, and it looks like it's still encoded (unless the console is re-encoding when printing). Also I'm not sure why it seems to be appending values instead of overwriting them:
Array
(
[0] => ******* FROM NODE********
\<head\>\<style type=text/css\>body \{padding:0\; margin:0\; text-align:center\;.tbl1 \{background-color:\#a53f0f\; color:\#fff\; text-align:center\; font-size:\<body data-gramm=true data-gramm_editor=true data-gramm_id=ccdbd45c-b0bf-4691-9\<table border=0 cellpadding=0 cellspacing=0 style=background-color:
)
Array
(
[0] => ******* FROM NODE********
\<head\>\<style type=text/css\>body \{padding:0\; margin:0\; text-align:center\;.tbl1 \{background-color:\#a53f0f\; color:\#fff\; text-align:center\; font-size:\<body data-gramm=true data-gramm_editor=true data-gramm_id=ccdbd45c-b0bf-4691-9\<table border=0 cellpadding=0 cellspacing=0 style=background-color:
[2] => ******* FROM NODE********
\<html xmlns=http://www.w3.org/1999/xhtml xmlns:v=urn:schemas-microsoft-com:vml \<meta name=viewport content=width=device-width,e\>
)
Note: You should use streams over arguments for data to be processed. This is the common way as commands work in the Unix world.
In your code you try to use escapeshellcmd to escape double quote " an encapsulated argument string. This does not work. There is an escapeshellarg PHP function as well. It will encapsulate the string in single quotes ' and escape characters that are even in single quoted strings treated in a special way by the shell.
Assuming $decoded is something like
$decoded = '<body lang="en">very boring message</body>';
then you do not enclose it into quotes yourself. Let escapeshellarg do the trick.
$emailString = escapeshellarg($decoded);
$imageIdString = escapeshellarg($imageId);
exec("node app.js {$imageIdString} email {$emailString} 2>&1", $output, $retVar);
As mentioned above, you really should consider to work on streams instead of arguments. The advantage is that the data can grow to an arbitrary size. Further more proc_open handles STDOUT and STDERR separately. This can be done like that:
try
{
if($handle = proc_open("node app.js {$imageId} email";, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $streams))
{
[$stdin, $stdout, $stderr] = $streams;
fwrite($stdin, $decoded);
fclose($stdin);
$output = stream_get_contents($stdout);
fclose($stdout);
$error = stream_get_contents($stderr);
fclose($stderr);
proc_close($handle);
}
echo 'OUTPUT:', PHP_EOL, $output, PHP_EOL;
echo 'ERRORS:', PHP_EOL, $error, PHP_EOL;
}
catch(Exception $e)
{
echo $e->getMessage(), PHP_EOL;
}
Here is an example node.js script handling both, data by arg as well as by stdin:
(() =>
{
'use strict';
console.log('******* FROM NODE********');
const
getStdin = require('get-stdin');
var id, type, visual;
[,, id, type, visual] = process.argv;
// if 4th command line argument is present, use that
if(undefined !== visual)
processData(visual);
// otherwise read data from stdin stream
else
getStdin().then(visual =>
{
processData(visual);
});
function processData(data)
{
console.log('id' , id );
console.log('type', type);
console.log('STDIN:', data);
console.error('no errors');
console.log('******* DONE *******');
}
})();
While Quasimodo's clone's answer does work, his comment on the question made me think about passing the large strings of HTML. I have instead opted to write the html to file and reference with the id.
How to receive raw JSON response from HTTP POST webhook?
I am working with an API and to verify that the POST to the webhook is indeed from the appropriate company API, they suggest this method:
To allow a client to verify a webhook message has in fact come from SIGNIFYD, an X-SIGNIFYD-SEC-HMAC-SHA256 header is included in each webhook POST message. The contents of this header is the Base64 encoded output of the HMAC SHA256 encoding of the JSON body of the message, using the team's API key as the encryption key. To verify the authenticity of the webhook message, you should calculate this value yourself and verify it equals the value contained in the header.
For the test environment, the "secret" key is ABCDE instead of the "Team API key."
I am receiving it in PHP like so:
<?php
// Get relevant Signifyd custom headers to be used for verification
$header_sig_topic = $_SERVER['HTTP_X_SIGNIFYD_TOPIC'];
$header_sig_sec_hmac = $_SERVER['HTTP_X_SIGNIFYD_SEC_HMAC_SHA256'];
// Get POST body
$webhookContent = "";
$webhook = fopen('php://input' , 'r');
while (!feof($webhook)) {
$webhookContent .= fread($webhook, 4096);
}
fclose($webhook);
?>
then I am processing it into the hash like so:
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
However, I am going wrong somewhere, because the hash I calculate is
OTc1YzExZDY2ZTE1MTVmYmJmNWNhNDRhNWMxZGIzZDk0NmM3OGE4NDU2N2JkYTJmZDJlYWI0ODRhNjlhNTdiYg==
while the header for an identical sample response header always comes with
W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=
I thought I was getting the JSOn body wrong somehow so I've tried every combination of json_encode and json_decode but nothing helps, my hash never matches.
I've also tried using $webhookContent = json_decode(file_get_contents('php://input'), true); to store the POST body but that just comes up empty ($_POST doesn't work either).
Am I doing something else wrong other than receiving the JSON?
The JSON that comes as the body of the test response which always comes with W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY= as the hash key to be used for verification:
{ "analysisUrl": "https://signifyd.com/v2/cases/1/analysis",
"entriesUrl": "https://signifyd.com/v2/cases/1/entries", "notesUrl":
"https://signifyd.com/v2/cases/1/notes", "orderUrl":
"https://signifyd.com/v2/cases/1/order", "guaranteeEligible":false,
"status":"DISMISSED", "uuid":"709b9107-eda0-4cdd-bdac-a82f51a8a3f3",
"headline":"John Smith", "reviewDisposition":null, "associatedTeam":{
"teamName":"anyTeam", "teamId":26, "getAutoDismiss":true,
"getTeamDismissalDays":2 }, "orderId":"19418",
"orderDate":"2013-06-17T06:20:47-0700", "orderAmount":365.99,
"createdAt":"2013-11-05T14:23:26-0800",
"updatedAt":"2013-11-05T14:23:26-0800",
"adjustedScore":262.6666666666667, "investigationId":1,
"score":262.6666666666667, "caseId":1,
"guaranteeDisposition":"APPROVED"}
If it helps to see where I'm going wrong, an example is provided but it's in Python:
Mac sha256HMAC = javax.crypto.Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(teamAPIKEY.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String encodedHMAC256 = Base64.encodeBase64String(sha256HMAC.doFinal(jsonBody.getBytes("UTF-8")));
My error was in simply not specifying the $raw_output parameter of the hash_hmac() function as true.
raw_output
When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
So, since I wasn't specifying $raw_output as true, I was getting hexits instead of raw binary output, which looked like this: 975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb.
EDIT: The answer here is
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret, true);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
I am working with the SendGrid PHP Library (https://sendgrid.com/docs/Integrate/Code_Examples/php.html).
The response is sent ass JSON - e.g. should be something like:
{"message":"success"}
I can send a simple email via:
<?php
$root="../../";
require $root . 'vendor/autoload.php';
$sendgrid = new SendGrid($SendGrid);
$email = new SendGrid\Email();
$email
//->addTo('you#me.com')
->addTo('you#me.com')
->setFrom('me#bar.com')
->setSubject('Subject goes here')
->setText('Hello World!')
->setHtml('<strong>Hello World!</strong>')
;
$res = $sendgrid->send($email);
?>
When I display the output of $res e.g. using PHP-REF (https://github.com/digitalnature/php-ref) I can see that it looks like this:
It appears the response is an Object - presumably JSON?
However, I can't access the data as JSON because if I try this:
$newtxt = json_decode($res);
I get this error:
Warning: json_decode() expects parameter 1 to be string, object given in C:\xampp\htdocs\jim\001-jimpix\contact_old\test-send-grid.php on line 24
And if I try this:
$j_array = json_decode($res, true);
I get the same error.
I can hard code the "$res" value as:
$res = "{\"message\":\"success\"}";
And then that works.
However, I can't work out how to access the JSON returned by SendGrid.
I've tried various things like:
$res = json_decode(json_encode($res),TRUE);
Presumably there is a way to access the JSON returned by SendGrid so I can access the JSON data.
But I don't know how?
As you can see from the PHP-REF response, $res is not the raw JSON.
You can access the result simply by using $res->getBody(). This will give you the parsed JSON from SendGrid.
You do not need to json_decode this.
I'm using a simple PHP script to verify Android order to parse download for the customer.
$receipt = $_GET['purchaseData'];
$billInfo = json_decode($receipt,true);
$signature = $_GET['dataSignature'];
$public_key_base64 = "xxxxxxxxxxxxxxxx";
$key = "-----BEGIN PUBLIC KEY-----\n".
chunk_split($public_key_base64, 64,"\n").
'-----END PUBLIC KEY-----';
$key = openssl_get_publickey($key);
$signature = base64_decode($signature);
//$result = openssl_verify($billInfo, $signature, $key);
$result = openssl_verify($receipt, $signature, $key);
if (0 === $result) {
echo "0";
} else if (1 !== $result) {
echo "1";
} else {
echo "Hello World!";
}
//added the var_dump($result); as asked by A-2-A
var_dump($result);
result is 0int(0)
I made a real order through the App after I published it and when trying to validate the order I get "0" as result.
I tried direct HTTP access
https://domain.com/thankyou.php?purchaseData={"packageName":"com.example.app","orderId":"GPA.1234-5678-1234-98608","productId":"product","developerPayload":"mypurchasetoken","purchaseTime":1455346586453,"purchaseState":0,"developerPayload":"mypurchasetoken","purchaseToken":"ggedobflmccnemedgplmodhp...."}&dataSignature=gwmBf...
I'm keeping the first of the question because my result is still a guess. After further investigation I think it's the signature not being read in a nice clean way as sent by google.
The signature=gwmBfgGudpG5iPp3L0OnepNlx while the browser is reading it as ƒ ~®v‘¹ˆúw
How is it possible to let it be read in the right way?
To verify the signature you want to make sure of the following:
INAPP_PURCHASE_DATA is not mutated in any way. Any encoding or escaping changes will result in a invalid verification. The best way to ensure it gets to your server intact is to base64 encoded it.
INAPP_DATA_SIGNATURE also must remain intact, it should already base64 encoded so sending that to your server should not be a problem.
openssl_verify expects both data and signature arguments to be in their raw state, so base64 decode before verifying.
It also takes signature_alg as the last argument, in this case sha1WithRSAEncryption should work as should the default, but if in doubt try a few other sha1 algorithms to see which ones work.
My best guess why it's not working for you right now is that you're not receiving the INAPP_PURCHASE_DATA on your server in the same condition that it was received on the app. This Stackoverflow question had the same problem.
I'm trying to use PHP for a command-line script. I pass in a json string to it, and I'm trying to read the values out but getting an error when I do echo $user_inputs["foo"];, why is this? Am I forgetting something about json_decode, or is it about using STDIN?
my_test.php
// Get the STDIN.
$stdin = fopen('php://stdin', 'r');
// Initialize user_inputs_json which will be the entire stdin.
$user_inputs_json = "";
// Read all of stdin.
while($line = fgets($stdin)) {
$user_inputs_json .= $line;
}
// Create the decoded json object.
$user_inputs = json_decode($user_inputs_json);
// Try to echo a value. This is where I get my error (written out below).
echo $user_inputs["foo"];
fclose($stdin);
Run this in command line to pass JSON into it:
$ echo '{"foo":"hello world!", "bar": "goodnight moon!"}' | php my_test.php
I get this error:
Fatal error: Cannot use object of type stdClass as array in /Users/don/Desktop/my_test.php on line 20
By default json_decode converts JSON string into PHP object. If you want to get PHP array, use the second parameter of json_decode:
$user_inputs_array = json_decode($user_inputs_json, true);
If you need to always handle the passed in JSON as an array, set the second json_decode parameter to true to force it to decode as an array:
$user_inputs = json_decode($user_inputs_json, 1);