Sign in with Paypal API: get basic user info - javascript

I am using JavaScript to login with PayPal.
My JavaScript code is as follows and seems to work fine.
<script type="text/javascript" src="https://www.paypalobjects.com/js/external/api.js"></script>
<script type="text/javascript">
paypal.use( ["login"], function(login) {
login.render ({
"appid": "<%=paypalAppId%>",
"scopes": "profile email address phone https://uri.paypal.com/services/paypalattributes",
"containerid": "paypalLogin",
"locale": "en-gb",
"returnurl": "http://www.domain.net/plogin.html"
});
});
</script>
However, I am struggling with the next step. Using either JavaScript or classic ASP, I am trying to obtain the following data about the signed in user:
Email address
First name
Family name
unique id (optional)
Address (optional)
Telephone number
I have done this with Facebook, Google & LinkedIn, using examples available on the respective sites. However, with Paypal, I cannot find any useful examples of how to do this...

I manage to achieve that with the next code. It never worked for me the way paypal does it. So I do everything on one code instead of jumping.
testingPaypalIdentity.php is the url callback that i put as 'return url' and is the same that you must put on your paypal app.
Basically the code checks if there's a code wich is user permission, if there's one then creates the tokens, if there's a refresh token then it search for user info and print it.
require __DIR__ . '/bootstrap.php';
use PayPal\Api\OpenIdSession;
use PayPal\Api\OpenIdTokeninfo;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Api\OpenIdUserinfo;
$baseUrl = getBaseUrl() . '/testingPaypalIdentity.php?success=true';
$tmp;
//Get Authorization URL returns the redirect URL that could be used to get user's consent
$redirectUrl = OpenIdSession::getAuthorizationUrl(
$baseUrl,
array('openid', 'profile', 'address', 'email', 'phone',
'https://uri.paypal.com/services/paypalattributes',
'https://uri.paypal.com/services/expresscheckout',
'https://uri.paypal.com/services/invoicing'),
null,
null,
null,
$apiContext
);
$refreshToken='';
if (isset($_GET['code']) && $_GET['code'] != '') {
$code = $_GET['code'];
try {
$accessToken = OpenIdTokeninfo::createFromAuthorizationCode(array('code' => $code), null, null, $apiContext);
} catch (PayPalConnectionException $ex) {
echo $_GET['code']." ".$ex;
//ResultPrinter::printError("Obtained Access Token", "Access Token", null, $_GET['code'], $ex);
exit(1);
}
$refreshToken=$accessToken->getRefreshToken();
print_r($accessToken);
//ResultPrinter::printResult("Obtained Access Token", "Access Token", $accessToken->getAccessToken(), $_GET['code'], $accessToken);
}
if($refreshToken!='') {
try {
$tokenInfo = new OpenIdTokeninfo();
$tokenInfo = $tokenInfo->createFromRefreshToken(array('refresh_token' => $refreshToken), $apiContext);
$params = array('access_token' => $tokenInfo->getAccessToken());
$userInfo = OpenIdUserinfo::getUserinfo($params, $apiContext);
} catch (Exception $ex) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
echo $ex;
exit(1);
}
$tmp=$userInfo;
print_r($userInfo);
}
And check OpenIdUserinfo class to obtain the info needed, for example:
$email = $userInfo.getEmail();
Sorry for bad english, and if you required further information, please ask.
Greetings

Related

MS graph API: 400 AuthenticationError with "/me/onlineMeetings" request

I am trying to create an online meeting and recover its URL like explained here in the docs, but when the request is run I get this error:
{
"statusCode": 400,
"code": "AuthenticationError",
"message": "Error authenticating with resource",
"requestId": "652ea3be-6a97-47e8-bfc6-3d7d1d51d425",
"date": "2020-09-01T12:53:41.000Z",
"body": "{
"code":"AuthenticationError",
"message":"Error authenticating with resource",
"innerError":{
"date":"2020-09-01T13:53:41",
"request-id":"652ea3be-6a97-47e8-bfc6-3d7d1d51d425"
}
}"
}
I tried also the get started projet for JS and it's working fine so I can't spot the problem.
here is what I used:
const msalConfig = {
auth: {
clientId: 'my_app_id',
redirectUri: 'http://localhost:8080'
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
forceRefresh: false
}
};
const loginRequest = { scopes: [
'openid',
'profile',
'user.read',
'calendars.read',
'User.Read.All',
'User.Export.All'
]
}
const options = new MicrosoftGraph.MSALAuthenticationProviderOptions([
'user.read',
'calendars.read',
'OnlineMeetings.ReadWrite'
]);
const onlineMeeting = {
startDateTime:"2020-09-01T16:00:34.2444915-07:00",
endDateTime:"2020-09-01T16:30:34.2464912-07:00",
subject:"test meeting"
};
const authProvider = new MicrosoftGraph.ImplicitMSALAuthenticationProvider(msalClient, options);
// Initialize the Graph client
const graphClient = MicrosoftGraph.Client.initWithMiddleware({authProvider});
// then I call this inside an async function
let events = await graphClient.api('/users/my_UserPrincipalName/onlineMeetings').post(onlineMeeting);
//let events = await graphClient.api('/me/onlineMeetings').post(onlineMeeting);
// I tried with both calls and none of them worked
and here are the permissions on azure active directory:
So any ideas on how to solve this ?
thanks
You didn't provide a correct access token.
Since Create onlineMeeting only supports Delegated (work or school account) permission type, you need to get the access token with Auth code flow or Implicit flow.
The started project for JS is using Implicit flow. So you can use Implicit flow to get the access token.
Here is the example in Postman:
The Auth URL above is https://login.microsoftonline.com/{your tenant}/oauth2/v2.0/authorize.
I figured out how to make it work in my code:
let's call my user, which I used all this time, user "A", all I did is that I simply created another user "B" in Azure Active Directory and then logging in with this new user "B" in the login screen instead of the admin user "A" that I used before..... and now it's working.
But this does not explain the issue, so if anyone can explain the difference or why it didn't work with the first account, that would be very helpful.

Vuejs: Show error messages as popups

I have created a login section using Vuex and Axios to authenticate the login by allowing the user to enter the email and password. I have created and stored the variables I need by using a getter. I have also, placed the tokens I needed into a function, post url and console.
But, know I need to show the responses according to the tokens being seen in the inspector/console.
What I need is to show the error messages when the user tries to login. So, when the console responds showing 200 (email and password is correct) I need it to store that token, when the console responds showing 400 (incorrect/missing characters in either email or password) I need it to print out the error messages that I have already placed with an array, lastly, when the console responds showing 401 (both email and password incorrect) I need it to print out the messageFour that is in the array.
HTML:
<template>
<form>
<div class="login">
<div>
<input type="text" v-model="email" placeholder="Email" class="eSection" id="email">
<p v-for="message in errorM" :key="message.errorM" v-show="message in errorM">
{{ message }}
</p>
<input type="password" v-model="password" placeholder="Password" class="pSection" id="password">
<p v-for="message in errorM" :key="message.errorM">
{{message}}
</p>
<button type="button" class="log" #click="login">LogIn</button>
</div>
</div>
</form>
</template>
Javascript:
<script>
import axios from 'axios';
export default {
data() {
return {
email: "test#gmail.com",
password: "123456",
flag: false,
errorM:[],
errorMessages: [
{
messageOne: "The email that has been entered is incorrect. Please try again!"
},
{
messageTwo: "Email/Password is missing. Please try again!"
},
{
messageThree: "The password that has been entered is incorrect. Please try again!"
},
{
messageFour: "Both Email and Password that have been entered are incorrect!"
},
]
}
},
methods: {
login: function (index) {
axios.post(`https://api.ticket.co/auth/login`, {
email: this.email,
password: this.password
})
.then(response => {
// JSON responses are automatically parsed.
console.log(response.data)
console.log(response.status)
})
.catch(e => {
console.log(e)
console.log(e.response.status)
var vueObject = this
switch (e.response.status) {
case 400:
if(!vueObject.email || !vueObject.password){
vueObject.errorM.push(vueObject.errorMessages.messageTwo)
};
if(!vueObject.email){
vueObject.errorM.push(vueObject.errorMessages.messageOne)
};
if(!vueObject.password){
vueObject.errorM.push(vueObject.errorMessages.messageThree)
};
break;
case 401:
if(vueObject.email && vueObject.password == ""){
vueObject.errorM.push(vueObject.errorMessages.messageFour)
}
break;
}
})
},
},
}
</script>
Many thanks!
It's not clear from the description what's not working, so I'll just point out some issues I see.
One thing to mention is, there is no evidence of you using vuex, no getters, no setters, no state.
Most notable is that you have the messages defined as an array of objects, which makes it difficult to look up
instead of this, which is harder to look up:
errorMessages: [
{
messageOne: "The email that has been entered is incorrect. Please try again!"
},
// etc... {}, {}, {}
]
... you should do
errorMessages: {
messageOne: "The email that has been entered is incorrect. Please try again!",
messageTwo: "Email/Password is missing. Please try again!",
messageThree: "The password that has been entered is incorrect. Please try again!",
messageFour: "Both Email and Password that have been entered are incorrect!",
}
so that you can find a message using this.errorMessages.messageTwo
Or better yet, define it outside of your vue component, since you're not using them in your template
const MESSAGE_INCORRECTEMAIL = "The email that has been entered is incorrect. Please try again!";
const MESSAGE_MISSINGFIELD = "Email/Password is missing. Please try again!";
const MESSAGE_INCORRECTPASSWORD = "The password that has been entered is incorrect. Please try again!";
const MESSAGE_INCORRECTEMAILPASSWORD = "Both Email and Password that have been entered are incorrect!";
and then just call them as MESSAGE_MISSINGFIELD from your script
From security standpoint, it's a bad idea to indicate whether the username or the password is wrong, as it makes hacking easier by confirming what usernames exist.
You can determine if the user had errors or fields are missing before sending the form for remote processing.
to do that, you would call
login: function (index) {
if (this.email.trim() === '' || vueObject.password.trim() === ''){
this.errorM.push(MESSAGE_MISSINGFIELD);
return // <- prevents further execution
}
// repeat for other local validations before remote request
// ... then process request
axios.post(`https://api.ticket.co/auth/login`, {
anyway, you might also need t break your question up into individual errors you encounter.

How do I make mail contact form in Firebase hosting?

I'm trying to migrate my website to Firebase hosting, but I have a contact form PHP mail that I want to use in Firebase too. Can I do It? And How?
Thanks!
You can create form and then submit the user data to Firebase Database and view it from your Admin Dashboard.
You can do something like this:
//Handling Contact Form
document.getElementById('submit').addEventListener('click', event => {
const leadName = document.getElementById('client_name').value;
const leadEmail = document.getElementById('client_email').value;
const leadMobile = document.getElementById('client_mobile').value;
const leadMessage = document.getElementById('client_message').value;
if(leadMobile != "" && leadEmail != "" && leadName != "") {
const leadTimestamp = Math.floor(Date.now() / 1000);
firebase.database().ref('leads').once('value', snapshot => {
var totalLeads = snapshot.numChildren();
totalLeads++;
firebase.database().ref('leads').child(totalLeads).set({
name: leadName,
mobile: leadMobile,
email: leadEmail,
message: leadMessage,
timestamp: leadTimestamp
});
$('.contact-form').hide();
$('.message-sent-success').show();
}, function(error) {
console.log(error);
});
} else {
alert('Please fill all the fields.');
}
});
The above code takes 4 user values, generates timestamp and inserts the data in Firebase Database and if you have an admin dashboard, you can use it to view it and perform further actions on it from there.
Here's how you can send email using emailjs.com
emailjs.send("gmail", "<template_name>", { //template_name is set via emailjs.com dashboard
content: email_description // you can store user data in any such variable
}).then(
function(response) {
document.write("Email sent successfully!");
},
function(error) {
document.write("Failed to send email.");
console.log(error);
}
);
Firebase hosting only serves static content, this means you can't use PHP or any server-side language there.
On the other hand, you can still use Firebase functions to send an email using an HTTP trigger via AJAX with Javascript.
This way, you can make a fully functional contact form without using server-side languages in your site.

Semantic-UI search does not read JSON from server response

I'm currently using Semantic-UI in a project. I use the search module to get the results from input. Here's my JavaScript code:
$('.ui.search')
.search({
apiSettings: {
action: 'search',
url: 'process.php?q={query}',
onSuccess(response, element, xhr){
console.log(response);
}
},
fields: {
results: 'songs', // array of results (standard)
title: 'title', // result title
url: 'videoID'
},
showNoResults: true,
onResults(response) {
console.log(response);
}
})
;
I get the JSON response from process.php. Here it is:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Content-Type: application/json; charset=UTF-8");
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
$videos = array();
// $videos["action"]["url"] = "youtube.com";
if (isset($_GET['q'])) {
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = 'MY_API_KEY';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $_GET['q'],
'maxResults' => 2
));
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach ($searchResponse['items'] as $searchResult) {
switch ($searchResult['id']['kind']) {
case 'youtube#video':
$videos["songs"][] = array('title' => $searchResult['snippet']['title'], 'videoID' => $searchResult["id"]["videoId"]);
break;
}
}
} catch (Google_Service_Exception $e) {
die($e->getMessage());
}
}
echo json_encode($videos);
The problem is that once I start typing in the search input, nothing shows up, even though my JSON structure is valid. I have assigned the Semantic UI properties correctly. I'm following the standard JSON response that Semantic UI has suggested. Here's my JSON response
{
"songs":[
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth [Official Video] Furious 7 Soundtrack",
"videoID":"RgKAFK5djSk"
},
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth (MattyBRaps ft Carissa Adee Cover)",
"videoID":"Rpm8ZJuGEu4"
}
]
}
I've tried everything. It doesn't work. I would really appreciate your help

use mailgun api and send email with javascript?

I am trying to use mailgun.com for sending emails. But it happened that I need to send it with js (cause sometimes I built websites with rubyonrails, sometimes with python. And now I need to built a simple landing page with mail sending.
And hosting (which is free ad suits me only supports php which I don't know)
So I decided to use js and obfuscate this code and paste it somewhere in somelibrary.So no one will ever find my secret key)
Can someone help with translating some of this examples into js code?
This is python example:
def send_simple_message():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
auth=("api", "YOUR_API_KEY"),
data={"from": "Excited User <mailgun#YOUR_DOMAIN_NAME>",
"to": ["bar#example.com", "YOU#YOUR_DOMAIN_NAME"],
"subject": "Hello",
"text": "Testing some Mailgun awesomness!"})
This is c# example
public static IRestResponse SendSimpleMessage() {
RestClient client = new RestClient();
client.BaseUrl = new Uri("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest();
request.AddParameter("domain",
"YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/messages";
request.AddParameter("from", "Excited User <mailgun#YOUR_DOMAIN_NAME>");
request.AddParameter("to", "bar#example.com");
request.AddParameter("to", "YOU#YOUR_DOMAIN_NAME");
request.AddParameter("subject", "Hello");
request.AddParameter("text", "Testing some Mailgun awesomness!");
request.Method = Method.POST;
return client.Execute(request);
}
This is php example
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = new Mailgun('YOUR_API_KEY');
$domain = "YOUR_DOMAIN_NAME";
# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
'from' => 'Excited User <mailgun#YOUR_DOMAIN_NAME>',
'to' => 'Baz <YOU#YOUR_DOMAIN_NAME>',
'subject' => 'Hello',
'text' => 'Testing some Mailgun awesomness!'
));
This is rails example:
def send_simple_message
RestClient.post "https://api:YOUR_API_KEY"\
"#api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
:from => "Excited User <mailgun#YOUR_DOMAIN_NAME>",
:to => "bar#example.com, YOU#YOUR_DOMAIN_NAME",
:subject => "Hello",
:text => "Testing some Mailgun awesomness!"
end
Obfuscated code just slows down the naughty coder who is trying to mess up, its not a perfect layer of security. Since you say your host supports php use the php code. all you have to do is send a post request to the php script
example code considering you are sending using jQuery library for javascript
<?php
require 'vendor/autoload.php';
use Mailgun\Mailgun;
if(isset($_POST['variable1']) && isset($_POST['variable2']))
{
$msg = $_POST['variable1']." ".$_POST['variable1'];
$mgClient = new Mailgun('key');
$domain = "your domain";
$result = $mgClient->sendMessage($domain, array(
'from' => 'from adress',
'to' => 'to adress',
'subject' => 'some subject',
'html' => $msg
));
$result = objectToArray($result);
echo json_encode($result);
}
?>
jquery code to send post request
$("button").click(function(){
$.post("mailer.php",
{
variable1: "Donald Duck",
variable2: "Duckburg"
},
function(data, status){
console.log(data);
});
});
The above code sends a post request to your php file, where the php file validates if it contains the variables 1 and 2 and continues with the execution

Categories

Resources