Ionic 3 WP-REST API Post request 401 (unauthorized) error - javascript

I am developing a simple application to create a user in Wordpress (woocommerce) through wp-rest api.
but when I try to create a new customers it shows 401 Unauthorised error in console. heres is my code for request.
signup(){
let customerData = {
customer : {}
}
customerData.customer = {
"email": this.newUser.email,
"first_name": this.newUser.first_name,
...
"billing_address": {
"first_name": this.newUser.first_name,
...
},
"shipping_address": {
"first_name": this.newUser.first_name,
...
}
}
if(this.billing_shipping_same){
this.newUser.shipping_address = this.newUser.shipping_address;
}
this.WooCommerce.postAsync('customers', customerData).then( (data) => {
console.log(JSON.parse(data.body));
})
}
by the way the key client & secret are correct

You need an https connection, add the following lines to your woocommerce init :
verifySsl: false,
queryStringAuth: true
Any post request requires an https connection.

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.

How to use OAuth 2.0 flow in Google One tap Sign In?

I know that I can use the access token that I receive in the response can be use to authenticate users.
But I want it to be more secure So I want the code that we get in oAuth 2.0.
Is there any way to get the code in the background to authenticate the user in one tap sign In?
An authorization code response that we get from the server is like this in url:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
componentDidMount() {
this.registerNewUser();
}
retrievePromise() {
window.googleyolo.retrieve({
supportedAuthMethods: [
'https://accounts.google.com',
],
supportedIdTokenProviders: [
{
uri: 'https://accounts.google.com',
// Replace with your client Id
clientId: 'XXX...XXX.apps.googleusercontent.com',
},
],
});
}
// eslint-disable-next-line class-methods-use-this
registerNewUser() {
window.googleyolo.hint({
supportedAuthMethods: [
'https://accounts.google.com',
],
supportedIdTokenProviders: [{
uri: 'https://accounts.google.com',
// Replace with your client Id
clientId: 'XXX...XXX.apps.googleusercontent.com',
}],
context: 'signUp',
}).then((credential) => {
console.log(credential);
this.props.doGoogleLogin('login');
this.props.decideWhichSocialLogin(this.props.location);
/* hit backend api and API TOKEN here */
/* Also save basic details that we get here */
}, (error) => {
console.log('Error occurred: ', error.type);
});
}

How can I send email notifications with Parse and Mandrill?

I am trying to use Mandrill to send an event-based email notification to the users of my web app. I am using Parse with Back4App.
In this tutorial (https://docs.back4app.com/docs/integrations/parse-server-mandrill/), the hosting providers suggest using the following method to call the Mandrill cloud code from an Android application:
public class Mandrill extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId("your back4app app id”)
.clientKey(“your back4app client key ")
.server("https://parseapi.back4app.com/").build()
);
Map < String, String > params = new HashMap < > ();
params.put("text", "Sample mail body");
params.put("subject", "Test Parse Push");
params.put("fromEmail", "someone#example.com");
params.put("fromName", "Source User");
params.put("toEmail", "other#example.com");
params.put("toName", "Target user");
params.put("replyTo", "reply-to#example.com");
ParseCloud.callFunctionInBackground("sendMail", params, new FunctionCallback < Object > () {
#Override
public void done(Object response, ParseException exc) {
Log.e("cloud code example", "response: " + response);
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mandrill);
}
}
How can I implement this in JavaScript with the Parse JavaScript SDK?
This is what I've done so far but it won't send an email. I have Mandrill set up, as well as a verified email domain and valid DKIM and SPF.
// Run email Cloud code
Parse.Cloud.run("sendMail", {
text: "Email Test",
subject: "Email Test",
fromEmail: "no-reply#test.ca",
fromName: "TEST",
toEmail: "test#gmail.com",
toName: "test",
replyTo: "no-reply#test.ca"
}).then(function(result) {
// make sure to set the email sent flag on the object
console.log("result :" + JSON.stringify(result));
}, function(error) {
// error
});
I don't even get a result in the console, so I figure the cloud code is not even executing.
You have to add the Mandrill Email Adapter to the initialisation of your Parse Server, as described on their Github page. Also check the Parse Server Guide for how to initialise or use their example project.
Then set up Cloud Code by following the guide. You'll want to either call a Cloud Code function using your Android app or from any Javascript app, or use beforeSave or afterSave hooks of a Parse Object directly in Cloud Code, which allow you to send Welcome Emails when a user signs up. That could come in handy if you want to implement behaviour based emails based on object updates. Plus, because it is on the server and not the client, it is easier to maintain and scale.
To make the Cloud Code function actually send an email via Mandrill, you need to add some more code to your Cloud Code function. First, add a file with these contents:
var _apiUrl = 'mandrillapp.com/api/1.0';
var _apiKey = process.env.MANDRILL_API_KEY || '';
exports.initialize = function(apiKey) {
_apiKey = apiKey;
};
exports.sendTemplate = function(request, response) {
request.key = _apiKey;
return Parse.Cloud.httpRequest({
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
url: 'https://' + _apiUrl + '/messages/send-template.json',
body: request,
success: function(httpResponse) {
if (response) {
response.success(httpResponse);
}
return Parse.Promise.resolve(httpResponse);
},
error: function(httpResponse) {
if (response) {
response.error(httpResponse);
}
return Parse.Promise.reject(httpResponse);
}
});
};
Require that file in your Cloud Code file, and use it like any other Promise.
var Mandrill = require("./file");
Mandrill.sendTemplate({
template_name: "TEMPLATE_NAME",
template_content: [{}],
key: process.env.MANDRILL_API_KEY,
message: {
global_merge_vars: [{
name: "REPLACABLE_CONTENT_NAME",
content: "YOUR_CONTENT",
}],
subject: "SUBJECT",
from_email: "YOUR#EMAIL.COM",
from_name: "YOUR NAME",
to: [{
email: "RECIPIENT#EMAIL.COM",
name: "RECIPIENT NAME"
}],
important: true
},
async: false
})
.then(
function success() {
})
.catch(
function error(error) {
});
Make sure you create a template on Mailchimp, right click it and choose "Send to Mandrill", so that you can use that template's name when sending via the API.
It's a bit involved, but once set up, it works like a charm. Good luck!

How can I retrieve a service account OAuth2 token from Google Api with Javascript?

I need to use a google projects service account to access google API using JavaScript. In order to do this I need to OAuth2 to google API servers to get an auth token.
I understand that Google provides a library (GAPI) for use on node servers, but I need a solution that will work in other secure JavaScript environments.
There are two major divisions to this task.
Configuring
Coding
First the Configuration steps.
If you don't have a google account:
Navigate to google.com
Find and Click "Sign In"
Click "More Options"
Click "Create Account"
Follow the steps to create an account
Navigate to the api dashboard: console.developers.google.com/apis/dashboard
Select or create a project by clicking on the current project. The project I have showing is called "My Project"
Click and enable those API you plan to work with
navigate to the credentials section: console.developers.google.com/apis/credentials
Click and select "Service account key"
If you create a new service account, for testing set the role to "project" "owner". You'll want to read up on google Api roles eventually. See Managing Roles and Granting Roles to Service Accounts
Ensure "Key Type" is "Json" and click "Create". You're key/cert will automatically download
Now for the Coding portion.
First download jsrsasign and add reference to "jsrsasign-all-min.js". If you want you can download just "jsrsasign-all-min.js" from github
Second update the following script with your cert/key (downloaded earlier):
function postJWT(jwt, callback) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200 && callback) {
callback(this.responseText);
return;
}
if (console) console.log(this.responseText);
}
};
var parameters = "grant_type=" + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer") + "&assertion=" + encodeURIComponent(jwt);
xhttp.open("POST", "https://www.googleapis.com/oauth2/v4/token", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(parameters);
}
function getCert() {
var cert = //your json key (downloaded earlier) goes here
{
"type": "service_account",
"project_id": "proj..",
"private_key_id": "e18..",
"private_key": "-----BEGIN PRIVATE KEY-----\nMII..==\n-----END PRIVATE KEY-----\n",
"client_email": "service-account#...iam.gserviceaccount.com",
"client_id": "5761..",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..service-account%40...iam.gserviceaccount.com"
};
return cert;
}
function getJWT() {
var cert = getCert();
var key = KEYUTIL.getKey(cert.private_key);
var headers = { "alg": "RS256", "typ": "JWT" };
var issued = Math.floor(new Date().getTime()/1000);
var claims = {
"iss": cert.client_email,
"scope": "https://www.googleapis.com/auth/analytics.readonly",
"aud": "https://www.googleapis.com/oauth2/v4/token",
"exp": issued + 3600,
"iat": issued
};
var jwt = KJUR.jws.JWS.sign(headers.alg, headers, JSON.stringify(claims), key);
return jwt;
}
When you test your code you should receive a json object back with an auth token. You can test your implementation like so:
postJWT(getJWT(text), function(){
let token = JSON.parse(response).access_token;
//Do your api calls here using the token.
//Reuse the token for up to 1 hour.
});
Here is an example successful json object with token:
{
"access_token": "ya29.c.ElkABZznrLNLK6ZAq2ybiH5lsRJpABE8p7MlZZJ0WCKcDNDv75lh-o1iRX__uMNUKSySiawm4YJGsbfqJH2JH61nRK6O2m0GJR7DgkEmo6ZlKtrvzke9C3xpwA",
"token_type": "Bearer",
"expires_in": 3600
}
Please note that this approach requires that the key/cert be accessible from your javascript environment. If this environment is public your api is vulnerable.

Triggering Javascript Code from PHP Laravel Controller

I'm using OAuth for login in my Laravel Controller. Its working fine but the thing is when the user is registered for the first time, I wanna trigger the HTML 5 geolocation API to fetch the user's current location and do some mixpanel stuff. Earlier I was using AJAX in the JS for the login so there was no such problem but now that I've implemented a complete server side solution, I'm stuck with this one problem.
The Laravel Controller code looks something like this :
function callback(){
\\ fetch the access token and graph data
if($res = \Auth::mjAuthenticate('facebook', $fbData)){
$user = \Auth::scope()->getUser();
return \Redirect::to('events');
}
if (\Auth::mjRegister('facebook', $fbData)) {
$user = \Auth::scope()->getUser();
return \Redirect::to('events');
}
return $this->handleFailure('Some Problem Occured');
}
The Earlier JS Code was :
ajax
.post('auth/login', {
data: {
oauth_provider: 'facebook',
oauth_token: accessToken
},
cache: false
})
.done(function(data) {
mixpanel.track('User Logged In', {
id: data.resource.id,
provider: 'Facebook',
email: data.resource.email,
first_name: data.resource.first_name,
last_name: data.resource.last_name
});
if (data.msg == 'Resource registered') {
if(navigator.geolocation){
// Prompt for Allow Deny Geolocation popup.
}
}
});

Categories

Resources