Permission issue on /{page-id}/conversations with Facebook Graph API - node.js

I'm working with Facebook Graph API and can't figure out why I can't accept the following route : /{page-id}/conversations
When I do I receive the following error : (#283) Requires extended permission: manage_pages
Here is the way I get my token :
First I get an acces_token for the user using the usual login, I ask for ['read_page_mailboxes', 'manage_pages']as permissions.
With this access token I call /me/accounts to get the list of pages for this user. In my case the user only have a single page, from this page I take the ID and access_token.
Being able to retrieve an access_token for the page means thaht the manage_pages permission is indeed granted.
Then I try to call /{page-id}/conversations with the page access_token and I face the error mentioned earlier.
Here is a snippet for node.js which is basically what I do in my app in a single function :
var options = {
url: getFbUrl('/me/accounts'),
qs: { // Query string parameters
access_token: userAccessToken,
},
method: 'GET'
};
request(options, function (err, response, body) {
if (err)
return done(err);
body = JSON.parse(body);
var pageAccessToken = body.data[0].access_token,
pageId = body.data[0].id;
var pageOptions = {
url: getFbUrl('/' + pageId + '/conversations'),
qs: {
access_token: pageAccessToken
},
method: 'GET'
};
request(pageOptions, function (err, response, body) {
if (err)
return done(err);
console.log(response.statusCode);
console.log('PAGE BODY', body);
done();
});
});
I've been stuck on this for way longer than I'd like, any help or tips appreciated.
Have a nice day.

It's a reported bug and here is the link: https://developers.facebook.com/bugs/380833342117530/

Related

Node.js back-end application on Firebase to access Azure Active Directory users

I have a Node.js back which currently is running on Firebase in the form of cloud functions. Except for that, I also have an Azure Active Directory with some users that I have invited
So, I want to be able to access them from the Node.js get a list of their emails and names. From what I understood, I can achieve that by making a reference to Microsoft's Graph API and more specifically to their Users API. As every request to Azure AD needs to be OAuth2 authenticated, I was wondering what is the best way of achieving that in my situation. What client flow do I need to implement? I am currently focused on the one which is based on client credentials.
Thanks in advance and whatever general suggestion are more than welcome!
This issue gets Access token and calls Microsoft Graph API using node.js.
The user API of Azure Active Directory Graph API is no longer updating. This MS graph API is newer.
Get access token using client credentials flow:
const request = require("request");
const endpoint = "https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token";
const requestParams = {
grant_type: "client_credentials",
client_id: "[ApplicationID]",
client_secret: "[Key]",
scope: "https://graph.microsoft.com/.default"
};
request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log("error");
}
else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
}
else {
console.log("Access Token=" + parsedBody.access_token);
}
}
});
Call MS Graph API:
function testListGroupGraphAPI(accessToken) {
request.get({
url:"https://graph.microsoft.com/v1.0/users",
headers: {
"Authorization": "Bearer " + accessToken
}
}, function(err, response, body) {
console.log(body);
});
}

Need to get project/issues from JIRA using JIRA REST API with NodeJS

I am building a NodeJS application from where I want to get project/issues from JIRA using REST APIs provided by JIRA. My jira is running on some server ('http://example.com:8080/secure/Dashboard.jspa') and I am able to use REST APIs from POSTMAN using BASIC AUTH to get all kind of data but when I tried to log in to JIRA using REST APIs and NodeJS, I am getting some response but I am not able to understand it how I am going to use that information to call other APIs.
What I am doing is, I am passing username and password as a command-line args then I am sending those creds to login to JIRA. Then I am going to use the 'node-fetch' package to get information from REST APIs.
Below is my code:
const fetch = require("node-fetch");
const yargs = require("yargs");
var JiraClient = require("jira-connector");
var request = require("request");
const jiraBaseUrl = "http://example.com:8080/secure/Dashboard.jspa";
const loginUrl = "auth/1/session";
const username = yargs.argv.u;
const password = yargs.argv.p;
const projectName = yargs.argv.n;
var headers = {
"Content-Type": "application/json"
};
var options = {
url: "http://example.com:8080/rest/api/2/issue/createmeta",
headers: headers,
auth: {
user: username,
pass: password
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);
Can somebody please tell me what I am doing wrong or what do I need to do with the data I am getting in order to use other APIs like ('http://example.com:8080/rest/api/2/issue/10008')? Or am I doing something wrong to login?
I have read the documentation on the JIRA website but was not able to understand correctly.
If you look at the Jira Rest API documentation, rest/api/2/issue/createmeta is the end point for Get create issue metadata. It "returns details of projects, issue types within projects, and, when requested, the create screen fields for each issue type for the user. " This data is supposed to be huge since it returns the details of all projects, and all issue types within projects.
If you want to use other API just change the url to the appropriate url with the correct endpoints (documentation) and follow the documentation on what to send as the body data.
Here is one example of getting the details of one issue:
Put the issueIdOrKey you want to get in the brackets
var options = {
method: 'GET',
url: 'http://example.com:8080/rest/api/latest/issue/{issueIdOrKey}',
auth: { username: username, password: password },
headers: {
'Accept': 'application/json'
}
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(
'Response: ' + response.statusCode + ' ' + response.statusMessage
);
console.log(body); //this would log all the info (in json) of the issue
// you can use a online json parser to look at this information in a formatted way
});

How to get Microsoft Graph API Access token from Node Script?

I'd like to use this library to interact with the graph API for my AD - https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/concepts/nodejs.md
However, all of the existing javascript libraries I've found to return access tokens expect a return URL to be passed in, as well as some other web-specific stuff, leading me to believe this is some kind of requirement on Microsoft's end.
Is there any good way to authenticate/receive an access token while running a backend node script (nothing web related) so that I can begin to make calls against the Microsoft Graph API? Thanks in advance for the advice.
BU0's answer didn't work correctly for me because Microsoft changed their way of using the graph API so I wasn't able to get all the data I needed. Here's how I did it using BU0 answer and this tutorial:
const request = require("request");
const endpoint = "https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token";
const requestParams = {
grant_type: "client_credentials",
client_id: "[ApplicationID]",
client_secret: "[Key]",
scope: "https://graph.microsoft.com/.default"
};
request.post({ url: endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log("error");
}
else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
}
else {
console.log("Access Token=" + parsedBody.access_token);
}
}
});
function testGraphAPI(accessToken) {
request.get({
url:"https://graph.microsoft.com/v1.0/users",
headers: {
"Authorization": "Bearer " + accessToken
}
}, function(err, response, body) {
console.log(body);
});
}
To run a back-end non-user-authenticated daemon connected to the Graph API, you want to use the app-only authentication flow. Here's a quick summary of the official steps:
Create your Azure AD Tenant. Note the yourtenant.onmicrosoft.com name, and copy this value down.
Register an application through the global Azure Active Directory blade's App Registrations section, not directly within the tenant properties. Copy the Application ID; we'll need it later.
Create a key tied to the registration and remember to copy it down. Once you click out, you can't get the key value back, so make sure to copy it.
Also update the registration's permissions to what you need, click Save, and then also hit the Grant Permissions button.
Make an HTTP request to the login.microsoftonline.com domain to obtain an access token.
Use the access token to make Graph API requests.
Here's a link to Microsofts Node.js example, and here's a link to the direct documentation on the HTTP call to make to retrieve an access token. And here's a super stripped-down example that will output the retrieved access token. Replace the [Tenant], [ApplicationID], and [Key] values:
const request = require("request");
const endpoint = "https://login.microsoftonline.com/[Tenant].onmicrosoft.com/oauth2/token";
const requestParams = {
grant_type: "client_credentials",
client_id: "[ApplicationID]",
client_secret: "[Key]",
resource: "https://graph.windows.net"
};
request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
if (err) {
console.log("error");
}
else {
console.log("Body=" + body);
let parsedBody = JSON.parse(body);
if (parsedBody.error_description) {
console.log("Error=" + parsedBody.error_description);
}
else {
console.log("Access Token=" + parsedBody.access_token);
}
}
});
Once we have the access_token, we can call out to the Graph API. Assuming the apps permissions were configured correctly and applied from step #4, we can start making Graph API requests:
function testGraphAPI(accessToken) {
request.get({
url:"https://graph.windows.net/[Tenant]/users?api-version=1.6",
headers: {
"Authorization": accessToken
}
}, function(err, response, body) {
console.log(body);
});
}
I had somewhat of an issue for using the url string for the const endpoint
https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token
Instead, I passed tenant in this way instead from Microsoft graph api docs:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
Reference from docs -> Request an authorization code
Another way:
'use strict';
const axios = require('axios');
const qs = require('qs');
const accessTokenWithCredentials = (tenantId, clientId, clientSecret, resource) => {
const data = {
resource: resource,
grant_type: 'client_credentials',
};
return axios({
url: `https://login.windows.net/${tenantId}/oauth2/token`,
method: "post",
headers: { 'content-type': 'application/x-www-form-urlencoded' },
auth: {
username: clientId,
password: clientSecret,
},
data: qs.stringify(data)
}).catch(error => {
throw error;
})
};
To call the function:
accessTokenWithCredentials(<tenantId>, <clientId>, <clientSecret>, 'https://graph.microsoft.com').then(response => {
console.log(`Got access token`);
const token = JSON.stringify(response.data.access_token);
// do what you need to do
}).catch(err => {
console.log("err " + err);
throw err;
});

Node/react best practice: How do I keep track on the current client/user in OAuth2 flow?

I'm a beginner with Node and React, and web programming in general. I want to import user credentials from LinkedIn's API and for that I need to authenticate using OAuth2.
My approach so far is to make an API-call from the client side to the LinkedIn oauth API with the relevant parameters, including a redirect URI which leads to an API endpoint on my node server. When the user has been redirected and approved LinkedIn's authentication dialog box, they will be redirected to the node server with an access token.
My question is as follows: I now want to update the user in my database with their corresponding access token, but how do I know which user to update when I can't get any information about the client in my function that handles the last redirect and fetches the access token?
Here's my node function that handles the redirect from LinkedIn:
router.get('/redirect', (req, res) => {
// Handle cancel by user
if(req.query.error){
console.log(req.query.error_description)
return
}
// Extract variables
const code = req.query.code
const state = req.query.state
// Check that state matches
if (state !== testState) {
console.log("State doesnt match")
return
}
// Exchange Authorization Code for an Access Token
var options = {
method: 'POST',
url: 'https://www.linkedin.com/oauth/v2/accessToken',
form: {
client_id: 'theClientID',
client_secret: 'theClienSecret',
grant_type: 'authorization_code',
code: code,
redirect_uri: 'http://localhost:3000/api/linkedin/redirect'
},
headers:
{ 'cache-control': 'no-cache',
"content-type": "application/json",
'user-agent': 'node.js' },
json: true };
// make the actual request
request(options, (error, response, body) => {
if (error) {
res.status(500).json({
message: error
})
return
}
// Extract access token
const token = body.access_token;
// Here I want to save access token to DB with the corresponding
// user, but I don't know which user to update
})
// Redirect user to profile
res.writeHead(301, {
Location: 'http://localhost:3000/profile'
})
res.end()
})
I had a really hard time formulating this question but I hope that my message gets through.

Google Cloud Print API: User credentials required

I'm trying to use the Google Cloud Print library to get a list of the cloud printers available to the users, but when I do a request I get an error: "User credentials required"
This is how I send the request:
var request = require('request');
var options = {
url: 'https://www.google.com/cloudprint/search',
headers: {
'X-CloudPrint-Proxy': 'APP_NAME',
'Authorization': 'GoogleLogin auth=ACCESS_TOKEN_HERE'
}
};
function callback(err, response, body) {
console.log(err);
console.log(response);
console.log(body);
}
request(options, callback);
In order to make this work (as there is no exact documentation).
Add https://www.googleapis.com/auth/cloudprint to the scope of the login procedure.
If you look here: https://github.com/dpsm/android-print/blob/master/src/main/java/com/github/dpsm/android/print/GoogleCloudPrint.java
They want the Authorization to be
Bearer ACCESS_TOKEN_HERE
instead of
GoogleLogin auth=ACCESS_TOKEN_HERE

Resources