Twilio send optional parameters TwiML JavaScript Ajax Phonegap - javascript

Is it possible to send optinal parameters to my twilio twiml file and use them in a php script? Its because im using a generated userid in my phonegap app. If the call is connected i want to send the user id to twiml and check in the php if the call was "completed" and set then values in a mysql db for the userid.
Somethinglike:
Twiml:
<Response>
<Dial action="http://blabla.com/dial.php" method="POST">
555-5555
</Dial>
</Response>
JavaScript:
$("#dialButton").click(function() {
params = { "userid" : $(userid).val()};
connection = Twilio.Device.connect(params);
});
Php:
$user = $_POST["userid"];
Is this the right way?If not how can i solve the problemt?

Here are the attributes that will be sent to the action URL:
https://www.twilio.com/docs/api/twiml/dial#attributes-action-parameters
It looks like it doesn't contain the userID (I assume you mean accountSID or subaccountSID?).
According to this article (https://www.twilio.com/blog/2011/05/how-to-track-and-report-your-twilio-usage.html) you may want to use the StatusCallback paramater when making a call, I don't know how that plays with what's going on with your phonegap application, I'm not familiar with that technology.
https://www.twilio.com/docs/api/rest/making-calls#post-parameters-optional
I hope this helps or at least gets you in the direction you need to go.

Related

Fetch POST to send DELETE query to MySQL - is it safe?

Since many web hosting websites (such as infinityfree and 000webhost) block HTTP DELETE requests I found a way how to send DELETE query to MySQL by adding a password to HTTP POST body which triggers PHP to send DELETE query to MySQL.
But is this safe since the password is visible in Front End and so visible to any site visitor? Can someone do harm to my database by using this password like making SQL injection?
In React JS:
async function sendDeleteRequest(i) {
const bodyWithPassword = {
...props.updatedProducts[i],
password: "kfI2KiIMOibKn0X98ufe$#!G^z78FNbbvI!fng0p*vk",
};
await fetch(Links["products"], {
method: "POST",
body: JSON.stringify(bodyWithPassword),
headers: {
"Content-Type": "application/json",
},
});
await props.refreshProductListContent();
}
In PHP:
//If HTTP body has password send DELETE query.
if ($json["password"] = "kfI2KiIMOibKn0X98ufe$#!G^z78FNbbvI!fng0p*vk") {
$deleteProduct = new $json["productType"]($json);
$deleteProduct->deleteProduct($json);
return;
}
//If password isn't added in the body add product to database
$newProduct = new $json["productType"]($json);
$newProduct->addProduct($json, $newProduct);
The short answer is - This is not safe
Having a hard-coded password in ReactJS, which is a client-based Javascript code, means that it's accessible to anyone who visits and loads the Javascript file. Anyone can read it, use it and abuse it.
There is not enough code provided to see if there is a SQL injection vulnerability as such. You should review deleteProduct and addProduct functions and see if you have parameterized all the parameters passed to a SQL query.
In a scenario where your code was vulnerable to a SQL injection, anyone can grab the client-side encoded password and abuse the SQL injection vulnerability.
Regarding the request type, there is no actual difference between a POST and a DELETE request (technically speaking), apart from how your server side code processes it, which is what you write and decide. Obviously the development world has agreed to common sense on which each of the methods does here https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods, which you should oblige by when doing development.

Send email from React application

I have an application, built using React. If I want to send an email to a user after another user successfully completes an action, what are some technologies I need to or can use? To clarify, I have no backend server set up yet.
Check sendgrid! You can do in your backend(nodejs in this case):
const SGmail = require ('#sendgrid/mail')
SGmail.setApiKey(process.env.REACT_APP_SG_API)
app.post('/your/endpoint', (req,res) => {
const data = req.body
const mailOptions = {
from: data.email,
to:'email#example.com',
subject:'Subject',
html:`<p>${data.name}</p>
<p>${data.email}</p>
<p>${data.message}</p>`
}
SGmail.send(mailOptions).then((err,res)=>{res.redirect('/')})
})
Check out SendGrid, they offer a generous free tier.
If you're not expected to do the actual email sending, you could, in JS, build an .eml file and have the user "download" it. They would then send it in their client of choice.
Otherwise you will need, at the very least, access to a mail server, to send this multipart-mime to, or, a little safer, build the message on the server and send it internally.

Generate Google ReCaptcha from a local website

I'm crawling a website using the python requests module. A form on this website requires to solve a ReCaptcha. I've managed to recreate this ReCaptcha on a local website with the same site-key. If I solve the ReCaptcha on my local website and get the 'g-captcha-response' key, would I be able to post this key to the original website? If so, would this work or is Google requiring other informations other than the response key?
# I get the response key from my local website
CaptchaKey = response-key
# I post the response key on the original website
request.post(SubmitURL, data={'g-captcha-response': CaptchaKey}
Would this work? If so, how do I check if the request has been successfully posted?
Google captcha key won't be enough. You should consider a method with selenium+requests.
first part:
from selenium import webdriver
driver = webdriver.Chrome("C:\chromedriver.exe")
driver.get('desiredurl')
#somesleep/waittill element/anything to wait till you solve the recaptcha
cookies = driver.get_cookies()
part 2
session = requests.Session()
for cookie in cookies:
session.cookies.set(cookie['name'], cookie['value'])
payload = { 'username' : '',
'password' : '',
'g-captcha-response': CaptchaKey}
login = session.post('DESIREDURL', data = payload)
This method should work

How to request, store, and use an access token in Meteor while using the Instagram API

How does one request, store, and use an access token from an API in the Meteor framework? I am currently trying to make requests from the (Instagram API)[https://instagram.com/developer/authentication/], but I first need to request an access token and store it for later use.
What is the general structure for doing this? I have my Client Id and Client Secret stored in the settings.json and have the services configuration package loaded. I think I need to create some sort of Method using http.get, but if someone could give a brief walkthrough that would be greatly appreciated ! Not much on this in the Meteor Docs.
You can use Bozhao Package for this.
Just install it.
meteor add bozhao:accounts-instagram
And this will work exactly like tha core accounts - facebook || google || twitter
and you can do something like this on the accountsOnCreateUser Methods
if (user.services.instagram) {
console.log("-- REGISTED USER WITH INSTAGRAM ");
instagramProfile = {
socialProfileUrl: user.services.instagram.profile_picture,
socialName: user.services.instagram.full_name,
service: "Instagram",
profileUrl: "https://instagram.com/"+ user.services.instagram.username
};
user.profile = instagramProfile;
}
Now knowing this, you can see that we have the user data inside the user.services.instagram object, there should be a accessToken and id field that you make POST / GET http request to the https://instagram.com/api/v1/.
I have never done a HTTP request to the Instagram API but it should be similar to facebook (if not sorry the below code dosnt help you to much).
Simple http call using the params.
Meteor.http.get("https://instagram.com/api/v1/", {
headers: {
"User-Agent": "Meteor/1.0"
},
params: {
access_token: user.services.accessToken
}
},function(error,result){
if(!error){
console.log(result);
}
});

HTTP Authorization Header in EventSource (Server Sent Events)

I need to set an Authorization header to an HTML5 EventSource. As Server Sent Events seems to be disused since Websockets appeared, I cannot find any useful documentation. The approach I have already found is to pass the authorization data within the url... but I don't like this method.
I am using AngularJS and set interceptors on $httpProvider, but the EventSource is not intercepted by AngularJS, so I cannot add any header.
I realize your post was over a year ago, but I found myself in the same boat with now good answers. I'm hoping this may help someone, or at least give them some ideas...
Cookies seem easy enough, but what happens if someone is blocking cookies? I would have to prompt them to enable cookies to use the site. At that point they start to wonder if they can trust the site since they disabled cookies for 'security reasons'. All the while, I want cookies enabled for security reasons!
Using AJAX, one can easily POST authentication data over SSL, but that's just not possible with SSE. I've seen many posts where people then say, "just use the querystring", but I don't want to compromise a customer's security by sending the auth data in plain text (example.com/stream?sessionID=idvalue) which someone could snoop.
After racking my brain for a couple hours I realized that I CAN accomplish the the overall goal without compromising the customer's auth data. Just to clarify, I haven't discovered some way to POST when establishing an EventSource connection, but it does allow the browser to securely pass an authentication token with the EventSource each time it reconnects. They key is to get the desired sessionID/token into the lastEventID.
The user can authenticate as usual with a username/password (or by AJAX POSTing a token you keep in localstorage). The AJAX auth process will pass back a JSON object with a short-lived-token (expires in 60 seconds, or when used) which would be saved in your desired backend (eg: mySQL) along with a longer-lasting token. At this point you initiate your SSE connection like:
qString = "?slt=" + "value-that-expires-within-seconds";
streamURL = "http://example.com/stream.php";
var streamSource = new EventSource(streamURL + qString);
streamSource.addEventListener('auth',function(e) {
var authStatus = JSON.parse(e.data);
if (authStatus.session !== 'valid') {
qString = "";
streamSource.close();
}
})
In the corresponding PHP you would do something like this:
header("Content-Type: text/event-stream\n");
ob_end_flush();
ob_start();
if (isThisShortLivedTokenValid($_GET["slt"])) {
// The short-lived-token is still valid... so we will lookup
// the value of the corresponding longer-lasting token and
// IMMEDIATELY invalidate the short-lived-token in the db.
sendMsg($realToken,'auth','session','valid');
exit;
} else if (isThisRealTokenValid($_SERVER["HTTP_LAST_EVENT_ID"])){
while (1) {
// normal code goes here
// if ($someCondition == 'newDataAvailable') sendMsg($realToken,'chat','msg-id','msg-content');
}
} else {
http_response_code(404); // stop the browser from reconnecting.
exit; //quit the PHP script and don't send anything.
}
function sendMsg($id, $event, $key, $val) {
echo "{" . PHP_EOL;
echo "event: " . $event . PHP_EOL;
echo "id: $id" . PHP_EOL;
echo 'data: {"' . $key . '" : "' . $val . '"}' . PHP_EOL;
echo "}" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
function isThisShortLivedTokenValid($sltValue) {
//stuff to connect to DB and determine if the
//value is still valid for authentication
return $dbResult == $sltValue ? TRUE : FALSE;
}
SSE connects with the short-lived-token, PHP validates against the short-lived-token and deletes it from the DB so it will never be able to AUTH again. This is somewhat similar when you get texted a 6-digit code to login to online banking. We use PHP to push the REAL token (that expires much later) which we retrieved from the database as the event ID. It's not really necessary for Javascript to do anything with this event-- the server will end the connection automatically, but you can listen to the event if you want to do more with it.
At this point, the SSE connection has ended since PHP finished the script. However, the browser will automatically reestablish the connection (usually with 3 seconds). This time, it will send the lastEventId... which we set to the token value before we dropped the connection. On the next connection, this value will be used as our token and the app will run as expected. It's not really necessary to drop the connection as long as you start using the real token as the event-ID when you send messages/events. This token value is transmitted completely encrypted over SSL both when the browser receives it, and in every subsequent connection to the server. The value that was transmitted 'in the clear' was expired within seconds from when we receive & used it and it can no longer be used by anyone that discovers it. If someone does attempt to use it they will receive a 404 RESPONSE.
If you already use the event-stream ID for some other purpose, this may not work 'out of the box' unless you concatenate the auth-token and the previously used value, and split it into variables so it's transparent to the rest of the app. Something like:
// when sending data, send both values
$sseID = $token_value . "_" . $previouslyUsedID;
sendMsg($sseID,'chat','msg-id','msg-content');
// when a new connection is established, break apart the values
$manyIDs = explode("_", $_SERVER["HTTP_LAST_EVENT_ID"])
$token_value = $manyIDs[0]
$previouslyUsedID = $manyIDs[1]
EventSource doesn't have an API for sending HTTP headers to server. I was struggling with this problem too when I was building realtime-chat using SSE.
However I think cookies will be sent automatically if your SSE server is the same server as your authentication server.
This polyfill adds Authorization Header support: https://github.com/Yaffle/EventSource/
So you can do:
new EventSource("https://domain/stream", { authorizationHeader: "Bearer ..." });
The window.EventSource doesn't seem to support passing additional headers yet. Good news is there are some other popular implementations of EventSource that support additional headers. Some of them are as follows:
eventsource
event-source-polyfill
const eventSource = new EventSource(resoureUrl, {
headers: {
'Authorization': 'Bearer ' + authorizationToken
}
});
eventSource.onmessage = result => {
const data = JSON.parse(result.data);
console.log('Data: ', data);
};
eventSource.onerror = err => {
console.log('EventSource error: ', err);
};
If you use this fork of the event-source polyfill you will be able to add authorization headers similarly to the way rafaelzlisboa describes:
https://github.com/AlexGalays/EventSource#923b9a0998fcfd7753040e09aa83764b3cc0230d
Ï don't know if you can provide the authentication header as a second argument like in rafaelzlisboa's example, I got it to work by creating a headers object, and putting my authorization header in there, like this:
new EventSource("https://domain/stream", { headers: { Authorization: Bearer.... }});
the other way to pass auth token is through the URL as query param, but you should take security in consideration. Also add support of authorization through query param on the sever side.
I solved this by additional rest before sse call, this rest is ordinary rest will require the same security protocol that we need for SSE call and get and OTP in response.
And send this OTP to see call query param and validate this OTP in Web filter and replace it with authentication header.
I went through quite a few posts in an attempt to figuring out if the auth token be sent in the EventSource() call. Although there are polyfill alternatives that allow adding headers : https://github.com/whatwg/html/issues/2177
while others mentioned sending auth token over ssl.
Instead of using polyfill EventSource() or sending the auth token in the query params over ssl, send a eventSource identifier (eventSrcUUID) in the params of EventSource url over ssl as follows :-
On user authentication, eventSrcUUID is generated along with the sseEmitter on the server and place in a sseEmitterMap.
Client retrieves the eventSrcUUID from the response and invokes the EventSource() call with the eventSrcUUID in the param. On the server, the sseEmitterMap is referenced to retrieve the the eventSrc object. The sseEmitter object saved in session data is used to send event notifications to client.

Categories

Resources